diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f9f0227 --- /dev/null +++ b/Makefile @@ -0,0 +1,145 @@ +# Sample Makefile for Marsdev (SGDK version) + +# Default paths, can be overridden by setting MARSDEV before calling make +MARSDEV ?= ${HOME}/mars +MARSBIN = $(MARSDEV)/m68k-elf/bin +TOOLSBIN = $(MARSDEV)/bin + +# GCC and Binutils +CC = $(MARSBIN)/m68k-elf-gcc +CXX = $(MARSBIN)/m68k-elf-g++ +AS = $(MARSBIN)/m68k-elf-as +LD = $(MARSBIN)/m68k-elf-ld +NM = $(MARSBIN)/m68k-elf-nm +OBJC = $(MARSBIN)/m68k-elf-objcopy +# SGDK Tools +BINTOS = $(TOOLSBIN)/bintos +PCMTORAW = $(TOOLSBIN)/pcmtoraw +RESCOMP = $(TOOLSBIN)/rescomp +WAVTORAW = $(TOOLSBIN)/wavtoraw +XGMTOOL = $(TOOLSBIN)/xgmtool +# Use rescomp jar for SGDK > 1.33 +ifneq ("$(wildcard $(TOOLSBIN)/rescomp.jar)","") + RESCOMP = java -jar $(TOOLSBIN)/rescomp.jar + WAVTORAW = @echo "wavtoraw no longer available!" ## + PCMTORAW = @echo "pcmtoraw no longer available!" ## +endif + +# Some files needed are in a versioned directory +GCC_VER := $(shell $(CC) -dumpversion) + +# Need the LTO plugin so NM can dump our symbol table +PLUGIN = $(MARSDEV)/m68k-elf/libexec/gcc/m68k-elf/$(GCC_VER) +LTO_SO = liblto_plugin.so +ifeq ($(OS),Windows_NT) + LTO_SO = liblto_plugin-0.dll +endif + +# Includes: Local + GCC + SGDK + Newlib +INCS = -Isrc -Ires -Iinc +INCS += -I$(MARSDEV)/m68k-elf/lib/gcc/m68k-elf/$(GCC_VER)/include +INCS += -I$(MARSDEV)/m68k-elf/include +INCS += -I$(MARSDEV)/m68k-elf/m68k-elf/include + +# Libraries: GCC + Newlib (SGDK libs are with release/debug targets) +# If you plan on using Newlib, uncomment the line with -lnosys +LIBS = -L$(MARSDEV)/m68k-elf/lib/gcc/m68k-elf/$(GCC_VER) -lgcc +#LIBS += -L$(MARSDEV)/m68k-elf/m68k-elf/lib -lnosys + +# Force libgcc math routines to be available at link time +LIBS += -u __modsi3 -u __divsi3 -u __mulsi3 -u __umodsi3 -u __udivsi3 -u __umulsi3 + +# Any C or C++ standard should be fine here as long as GCC support it +CCFLAGS = -m68000 -Wall -Wextra -std=c99 -ffreestanding -fcommon +CXXFLAGS = -m68000 -Wall -Wextra -std=c++17 -ffreestanding + +# Extra options set by debug or release target +OPTIONS = +ASFLAGS = -m68000 --register-prefix-optional +LDFLAGS = -T $(MARSDEV)/ldscripts/sgdk.ld -nostdlib -fcommon + +RESS = $(wildcard res/*.res) +CS = $(wildcard src/*.c) +CPPS = $(wildcard src/*.cpp) +SS = $(wildcard src/*.s) + +OBJS = $(RESS:.res=.o) +OBJS += $(CS:.c=.o) +OBJS += $(CPPS:.cpp=.o) +OBJS += $(SS:.s=.o) + +ASMO = $(RESS:.res=.o) +ASMO += $(CS:%.c=asmout/%.s) + +.SECONDARY: out.elf + +.PHONY: all release asm debug + +all: release + +release: OPTIONS = -O3 -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer +release: OPTIONS += -fshort-enums -flto -fuse-linker-plugin +release: LIBS += -L$(MARSDEV)/m68k-elf/lib -lmd +release: out.bin symbol.txt + +asm: OPTIONS = -O3 -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer +asm: OPTIONS += -fshort-enums +asm: LIBS += -L$(MARSDEV)/m68k-elf/lib -lmd +asm: asm-dir $(ASMO) + +# Gens-KMod, BlastEm and UMDK support GDB tracing, enabled by this target +debug: OPTIONS = -g -Og -DDEBUG -DKDEBUG -fno-web -fno-gcse -fno-unit-at-a-time -fshort-enums +debug: LIBS += -L$(MARSDEV)/m68k-elf/lib -lmd-debug +debug: out.bin symbol.txt + +# This generates a symbol table that is very helpful in debugging crashes, +# even with an optimized release build! +# Cross reference symbol.txt with the addresses displayed in the crash handler +symbol.txt: out.bin + $(NM) --plugin=$(PLUGIN)/$(LTO_SO) -n out.elf > symbol.txt + +boot/sega.o: boot/rom_head.bin + @echo "AS $<" + @$(AS) $(ASFLAGS) boot/sega.s -o $@ + +boot/rom_head.bin: boot/rom_head.c + @echo "CC $<" + @$(CC) $(CFLAGS) $(INCS) -nostdlib -Wl,--oformat=binary $< -o $@ + +%.bin: %.elf + @echo "Stripping ELF header..." + @$(OBJC) -O binary $< temp.bin + @dd if=temp.bin of=$@ bs=8192 conv=sync + @rm -f temp.bin + +%.elf: boot/sega.o $(OBJS) + $(CC) -o $@ $(LDFLAGS) boot/sega.o $(OBJS) $(LIBS) + +%.o: %.c + @echo "CC $<" + @$(CC) $(CCFLAGS) $(OPTIONS) $(INCS) -c $< -o $@ + +%.o: %.cpp + @echo "CXX $<" + @$(CXX) $(CXXFLAGS) $(OPTIONS) $(INCS) -c $< -o $@ + +%.o: %.s + @echo "AS $<" + @$(AS) $(ASFLAGS) $< -o $@ + +%.s: %.res + $(RESCOMP) $< $@ + +# For asm target +asm-dir: + mkdir -p asmout/src + +asmout/%.s: %.c + $(CC) $(CCFLAGS) $(OPTIONS) $(INCS) -S $< -o $@ + +.PHONY: clean + +clean: + rm -f $(OBJS) out.bin out.elf symbol.txt + rm -f boot/sega.o boot/rom_head.o boot/rom_head.bin + rm -rf asmout diff --git a/README.md b/README.md index 099a64a..ae3c8ab 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,2 @@ -# 2hustation3 - -vanguard-type thing for the genesis \ No newline at end of file +# eohp +touhou pride jam 4 entry diff --git a/bible.txt b/bible.txt new file mode 100644 index 0000000..615e1c1 --- /dev/null +++ b/bible.txt @@ -0,0 +1,32 @@ +########## +# THEMES # +########## + - + +############ +# GAMEPLAY # +############ + - The player controls a ship which automatically flies forward through scrolling levels. + - It has a limited amount of fuel that constantly depletes. + - Fuel is replenished by destroying enemies + +########## +# LEVELS # +########## + - Tunnel 1 + - Mountain Zone + - Rainbow Zone + - Styx Zone + - Rainbow Zone 2 + - Stripe Zone + - Rainbow Zone 3 + - Bleak Zone + - Last Zone + - Tunnel 2 + - Mountain Zone + - Stripe Zone + - Styx Zone + - Rainbow Zone + - Bleak Zone + - Last Zone + - At the end of each tunnel the player must defeat a boss guarded by two moving force fields with holes in them. \ No newline at end of file diff --git a/boot/rom_head.c b/boot/rom_head.c new file mode 100644 index 0000000..87678c3 --- /dev/null +++ b/boot/rom_head.c @@ -0,0 +1,43 @@ +#include "types.h" + +__attribute__((externally_visible)) +const struct +{ + char console[16]; /* Console Name (16) */ + char copyright[16]; /* Copyright Information (16) */ + char title_local[48]; /* Domestic Name (48) */ + char title_int[48]; /* Overseas Name (48) */ + char serial[14]; /* Serial Number (2, 12) */ + u16 checksum; /* Checksum (2) */ + char IOSupport[16]; /* I/O Support (16) */ + u32 rom_start; /* ROM Start Address (4) */ + u32 rom_end; /* ROM End Address (4) */ + u32 ram_start; /* Start of Backup RAM (4) */ + u32 ram_end; /* End of Backup RAM (4) */ + char sram_sig[2]; /* "RA" for save ram (2) */ + u16 sram_type; /* 0xF820 for save ram on odd bytes (2) */ + u32 sram_start; /* SRAM start address - normally 0x200001 (4) */ + u32 sram_end; /* SRAM end address - start + 2*sram_size (4) */ + char modem_support[12]; /* Modem Support (24) */ + char notes[40]; /* Memo (40) */ + char region[16]; /* Country Support (16) */ +} rom_header = { + "SEGA MEGA DRIVE ", + "TBODDY ", + "th station ", + "th station ", + "GM 00000000-00", + 0x0000, + "JD ", + 0x00000000, + 0x00100000, + 0x00FF0000, + 0x00FFFFFF, + " ", + 0x0000, + 0x00200000, + 0x002001FF, + " ", + "th station ", + "JUE " +}; diff --git a/boot/sega.s b/boot/sega.s new file mode 100644 index 0000000..56302b8 --- /dev/null +++ b/boot/sega.s @@ -0,0 +1,462 @@ +.section .text.keepboot + +*------------------------------------------------------- +* +* Sega startup code for the GNU Assembler +* Translated from: +* Sega startup code for the Sozobon C compiler +* Written by Paul W. Lee +* Modified by Charles Coty +* Modified by Stephane Dallongeville +* +*------------------------------------------------------- + + .globl _hard_reset + + .org 0x00000000 + +_Start_Of_Rom: +_Vecteurs_68K: + dc.l 0x00000000 /* Stack address */ + dc.l _Entry_Point /* Program start address */ + dc.l _Bus_Error + dc.l _Address_Error + dc.l _Illegal_Instruction + dc.l _Zero_Divide + dc.l _Chk_Instruction + dc.l _Trapv_Instruction + dc.l _Privilege_Violation + dc.l _Trace + dc.l _Line_1010_Emulation + dc.l _Line_1111_Emulation + dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception + dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception + dc.l _Error_Exception, _Error_Exception, _Error_Exception, _Error_Exception + dc.l _Error_Exception, _INT, _EXTINT, _INT + dc.l _HINT + dc.l _INT + dc.l _VINT + dc.l _INT + dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT + dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT + dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT + dc.l _INT,_INT,_INT,_INT,_INT,_INT,_INT,_INT + + .incbin "boot/rom_head.bin" + +_Entry_Point: + move #0x2700,%sr + tst.l 0xa10008 + bne.s SkipJoyDetect + + tst.w 0xa1000c + +SkipJoyDetect: + bne.s SkipSetup + + lea Table,%a5 + movem.w (%a5)+,%d5-%d7 + movem.l (%a5)+,%a0-%a4 +* Check Version Number + move.b -0x10ff(%a1),%d0 + andi.b #0x0f,%d0 + beq.s WrongVersion + +* Sega Security Code (SEGA) + move.l #0x53454741,0x2f00(%a1) +WrongVersion: + move.w (%a4),%d0 + moveq #0x00,%d0 + movea.l %d0,%a6 + move %a6,%usp + move.w %d7,(%a1) + move.w %d7,(%a2) + +* Jump to initialisation process now... + + jmp _start_entry + +SkipSetup: + jmp _reset_entry + + +Table: + dc.w 0x8000,0x3fff,0x0100 + dc.l 0xA00000,0xA11100,0xA11200,0xC00000,0xC00004 + + +*------------------------------------------------ +* +* interrupt functions +* +*------------------------------------------------ + +registersDump: + move.l %d0,registerState+0 + move.l %d1,registerState+4 + move.l %d2,registerState+8 + move.l %d3,registerState+12 + move.l %d4,registerState+16 + move.l %d5,registerState+20 + move.l %d6,registerState+24 + move.l %d7,registerState+28 + move.l %a0,registerState+32 + move.l %a1,registerState+36 + move.l %a2,registerState+40 + move.l %a3,registerState+44 + move.l %a4,registerState+48 + move.l %a5,registerState+52 + move.l %a6,registerState+56 + move.l %a7,registerState+60 + rts + +busAddressErrorDump: + move.w 4(%sp),ext1State + move.l 6(%sp),addrState + move.w 10(%sp),ext2State + move.w 12(%sp),srState + move.l 14(%sp),pcState + jmp registersDump + +exception4WDump: + move.w 4(%sp),srState + move.l 6(%sp),pcState + move.w 10(%sp),ext1State + jmp registersDump + +exceptionDump: + move.w 4(%sp),srState + move.l 6(%sp),pcState + jmp registersDump + + +_Bus_Error: + jsr busAddressErrorDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l busErrorCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Address_Error: + jsr busAddressErrorDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l addressErrorCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Illegal_Instruction: + jsr exception4WDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l illegalInstCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Zero_Divide: + jsr exceptionDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l zeroDivideCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Chk_Instruction: + jsr exception4WDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l chkInstCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Trapv_Instruction: + jsr exception4WDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l trapvInstCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Privilege_Violation: + jsr exceptionDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l privilegeViolationCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Trace: + jsr exceptionDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l traceCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Line_1010_Emulation: +_Line_1111_Emulation: + jsr exceptionDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l line1x1xCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_Error_Exception: + jsr exceptionDump + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l errorExceptionCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_INT: + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l intCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_EXTINT: + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l eintCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_HINT: + movem.l %d0-%d1/%a0-%a1,-(%sp) + move.l hintCB, %a0 + jsr (%a0) + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + +_VINT: + movem.l %d0-%d1/%a0-%a1,-(%sp) + ori.w #0x0001, intTrace /* in V-Int */ + addq.l #1, vtimer /* increment frame counter (more a vint counter) */ + btst #3, VBlankProcess+1 /* PROCESS_XGM_TASK ? (use VBlankProcess+1 as btst is a byte operation) */ + beq.s _no_xgm_task + + jsr XGM_doVBlankProcess /* do XGM vblank task */ + +_no_xgm_task: + btst #1, VBlankProcess+1 /* PROCESS_BITMAP_TASK ? (use VBlankProcess+1 as btst is a byte operation) */ + beq.s _no_bmp_task + + jsr BMP_doVBlankProcess /* do BMP vblank task */ + +_no_bmp_task: + move.l vintCB, %a0 /* load user callback */ + jsr (%a0) /* call user callback */ + andi.w #0xFFFE, intTrace /* out V-Int */ + movem.l (%sp)+,%d0-%d1/%a0-%a1 + rte + + +*------------------------------------------------ +* +* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg +* +* Permission is granted to anyone to use this software for any purpose +* on any computer system, and to redistribute it freely, with the +* following restrictions: +* 1) No charge may be made other than reasonable charges for reproduction. +* 2) Modified versions must be clearly marked as such. +* 3) The authors are not responsible for any harmful consequences +* of using this software, even if they result from defects in it. +* +*------------------------------------------------ + +ldiv: + move.l 4(%a7),%d0 + bpl ld1 + neg.l %d0 +ld1: + move.l 8(%a7),%d1 + bpl ld2 + neg.l %d1 + eor.b #0x80,4(%a7) +ld2: + bsr i_ldiv /* d0 = d0/d1 */ + tst.b 4(%a7) + bpl ld3 + neg.l %d0 +ld3: + rts + +lmul: + move.l 4(%a7),%d0 + bpl lm1 + neg.l %d0 +lm1: + move.l 8(%a7),%d1 + bpl lm2 + neg.l %d1 + eor.b #0x80,4(%a7) +lm2: + bsr i_lmul /* d0 = d0*d1 */ + tst.b 4(%a7) + bpl lm3 + neg.l %d0 +lm3: + rts + +lrem: + move.l 4(%a7),%d0 + bpl lr1 + neg.l %d0 +lr1: + move.l 8(%a7),%d1 + bpl lr2 + neg.l %d1 +lr2: + bsr i_ldiv /* d1 = d0%d1 */ + move.l %d1,%d0 + tst.b 4(%a7) + bpl lr3 + neg.l %d0 +lr3: + rts + +ldivu: + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + bsr i_ldiv + rts + +lmulu: + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + bsr i_lmul + rts + +lremu: + move.l 4(%a7),%d0 + move.l 8(%a7),%d1 + bsr i_ldiv + move.l %d1,%d0 + rts +* +* A in d0, B in d1, return A*B in d0 +* +i_lmul: + move.l %d3,%a2 /* save d3 */ + move.w %d1,%d2 + mulu %d0,%d2 /* d2 = Al * Bl */ + + move.l %d1,%d3 + swap %d3 + mulu %d0,%d3 /* d3 = Al * Bh */ + + swap %d0 + mulu %d1,%d0 /* d0 = Ah * Bl */ + + add.l %d3,%d0 /* d0 = (Ah*Bl + Al*Bh) */ + swap %d0 + clr.w %d0 /* d0 = (Ah*Bl + Al*Bh) << 16 */ + + add.l %d2,%d0 /* d0 = A*B */ + move.l %a2,%d3 /* restore d3 */ + rts +* +*A in d0, B in d1, return A/B in d0, A%B in d1 +* +i_ldiv: + tst.l %d1 + bne nz1 + +* divide by zero +* divu #0,%d0 /* cause trap */ + move.l #0x80000000,%d0 + move.l %d0,%d1 + rts +nz1: + move.l %d3,%a2 /* save d3 */ + cmp.l %d1,%d0 + bhi norm + beq is1 +* AB and B is not 0 +norm: + cmp.l #1,%d1 + bne not1 +* B==1, so ret A, rem 0 + clr.l %d1 + move.l %a2,%d3 /* restore d3 */ + rts +* check for A short (implies B short also) +not1: + cmp.l #0xffff,%d0 + bhi slow +* A short and B short -- use 'divu' + divu %d1,%d0 /* d0 = REM:ANS */ + swap %d0 /* d0 = ANS:REM */ + clr.l %d1 + move.w %d0,%d1 /* d1 = REM */ + clr.w %d0 + swap %d0 + move.l %a2,%d3 /* restore d3 */ + rts +* check for B short +slow: + cmp.l #0xffff,%d1 + bhi slower +* A long and B short -- use special stuff from gnu + move.l %d0,%d2 + clr.w %d2 + swap %d2 + divu %d1,%d2 /* d2 = REM:ANS of Ahi/B */ + clr.l %d3 + move.w %d2,%d3 /* d3 = Ahi/B */ + swap %d3 + + move.w %d0,%d2 /* d2 = REM << 16 + Alo */ + divu %d1,%d2 /* d2 = REM:ANS of stuff/B */ + + move.l %d2,%d1 + clr.w %d1 + swap %d1 /* d1 = REM */ + + clr.l %d0 + move.w %d2,%d0 + add.l %d3,%d0 /* d0 = ANS */ + move.l %a2,%d3 /* restore d3 */ + rts +* A>B, B > 1 +slower: + move.l #1,%d2 + clr.l %d3 +moreadj: + cmp.l %d0,%d1 + bhs adj + add.l %d2,%d2 + add.l %d1,%d1 + bpl moreadj +* we shifted B until its >A or sign bit set +* we shifted #1 (d2) along with it +adj: + cmp.l %d0,%d1 + bhi ltuns + or.l %d2,%d3 + sub.l %d1,%d0 +ltuns: + lsr.l #1,%d1 + lsr.l #1,%d2 + bne adj +* d3=answer, d0=rem + move.l %d0,%d1 + move.l %d3,%d0 + move.l %a2,%d3 /* restore d3 */ + rts diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..d0c2e7c --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +rm res/resources.o res/resources.h out.bin out.elf symbol.txt +make +./blastem/blastem out.bin \ No newline at end of file diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000..6e24737 --- /dev/null +++ b/compile.sh @@ -0,0 +1,2 @@ +rm out.bin out.elf symbol.txt +make \ No newline at end of file diff --git a/res/bg/1_1.png b/res/bg/1_1.png new file mode 100644 index 0000000..7ecb2c6 Binary files /dev/null and b/res/bg/1_1.png differ diff --git a/res/chrome/frame1.png b/res/chrome/frame1.png new file mode 100644 index 0000000..b8b00cf Binary files /dev/null and b/res/chrome/frame1.png differ diff --git a/res/chrome/frame2.png b/res/chrome/frame2.png new file mode 100644 index 0000000..f266ebc Binary files /dev/null and b/res/chrome/frame2.png differ diff --git a/res/chrome/frame3.png b/res/chrome/frame3.png new file mode 100644 index 0000000..05785c3 Binary files /dev/null and b/res/chrome/frame3.png differ diff --git a/res/font.png b/res/font.png new file mode 100644 index 0000000..45907a4 Binary files /dev/null and b/res/font.png differ diff --git a/res/player/player.png b/res/player/player.png new file mode 100644 index 0000000..49461d3 Binary files /dev/null and b/res/player/player.png differ diff --git a/res/resources.res b/res/resources.res new file mode 100644 index 0000000..e7850fa --- /dev/null +++ b/res/resources.res @@ -0,0 +1,12 @@ +IMAGE font "font.png" BEST NONE + +IMAGE tile1_1 "tiles/1_1.png" FAST +IMAGE tile1_2 "tiles/1_2.png" FAST + +IMAGE bg1_1 "bg/1_1.png" FAST + +IMAGE frame1 "chrome/frame1.png" FAST +IMAGE frame2 "chrome/frame2.png" FAST +IMAGE frame3 "chrome/frame3.png" FAST + +SPRITE reimu "player/player.png" 4 4 FAST 0 \ No newline at end of file diff --git a/res/tiles/1_1.png b/res/tiles/1_1.png new file mode 100644 index 0000000..f7ea718 Binary files /dev/null and b/res/tiles/1_1.png differ diff --git a/res/tiles/1_2.png b/res/tiles/1_2.png new file mode 100644 index 0000000..5896b2c Binary files /dev/null and b/res/tiles/1_2.png differ diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..b27cb9e --- /dev/null +++ b/run.sh @@ -0,0 +1 @@ +./blastem/blastem out.bin \ No newline at end of file diff --git a/src/background.h b/src/background.h new file mode 100644 index 0000000..8eadfeb --- /dev/null +++ b/src/background.h @@ -0,0 +1,47 @@ +// bg + +#define BG_I 512 + +#define BG_W GAME_W_T + 8 +#define BG_H WIN_H_T + +#define BG_SIZE 64 + + +// draw + +static void drawBg(){ + for(u16 x = 0; x < BG_W; x++) for(u16 y = 0; y < BG_H; y++){ + if(x % 8 == 0 && y % 8 == 0){ + VDP_drawImageEx(BG_B, &bg1_1, TILE_ATTR_FULL(PAL2, 0, 0, 0, BG_I), x, y, 0, DMA); + } + } +} + + +// update + +#define BG_SPEED_X -FIX16(0.2) +#define BG_SPEED_Y FIX16(0.1) +#define BG_SIZE_F FIX16(BG_SIZE) +Vect2D_f16 bgPos; + +static void scrollBg(){ + VDP_setHorizontalScroll(BG_B, fix16ToInt(bgPos.x)); + VDP_setVerticalScroll(BG_B, fix16ToInt(bgPos.y)); + bgPos.x = fix16Add(bgPos.x, BG_SPEED_X); + bgPos.y = fix16Add(bgPos.y, BG_SPEED_Y); + if(bgPos.x <= -BG_SIZE_F) bgPos.x = 0; + if(bgPos.y >= BG_SIZE_F) bgPos.y = 0; +} + + +// loop + +void loadBg(){ + drawBg(); +} + +void updateBg(){ + // scrollBg(); +} \ No newline at end of file diff --git a/src/chrome.h b/src/chrome.h new file mode 100644 index 0000000..38f6241 --- /dev/null +++ b/src/chrome.h @@ -0,0 +1,76 @@ +// chrome + +#define CHROME_I 32 + +static void loadChromeI(){ + VDP_loadTileSet(frame1.tileset, CHROME_I, DMA); + VDP_loadTileSet(frame2.tileset, CHROME_I + 1, DMA); + VDP_loadTileSet(frame3.tileset, CHROME_I + 2, DMA); +} + +static void drawFrame(){ + VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL1, 0, 0, 0, CHROME_I), 0, 0, WIN_W_T, GAME_Y_T - 1); + VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL1, 0, 0, 0, CHROME_I + 1), 0, GAME_Y_T - 1, WIN_W_T, 1); +} + + +// score + +#define SCORE_X 3 +#define SCORE_Y 2 +#define SCORE_LENGTH 6 + +u32 lastScore; +char scoreStr[SCORE_LENGTH]; + +static void loadScore(){ + VDP_drawText("hi", 1, 1); + VDP_drawText("000000", SCORE_X, 1); + VDP_drawText("sc", 1, 2); + intToStr(score, scoreStr, SCORE_LENGTH); + VDP_drawText(scoreStr, SCORE_X, SCORE_Y); +} + +static void updateScore(){ + if(lastScore != score){ + intToStr(score, scoreStr, SCORE_LENGTH); + VDP_drawText(scoreStr, SCORE_X, SCORE_Y); + lastScore = score; + } + score++; +} + + +// lives + +#define LIVES_Y 4 + +static void loadLives(){ + VDP_drawText("ENERGY 69", 1, LIVES_Y); +} + + +// dialogue + +#define DIALOGUE_Y 24 + +static void loadDialogue(){ + VDP_drawText("FLANDRE", 1, DIALOGUE_Y); + VDP_drawText("\"Are you morbid?", 1, DIALOGUE_Y + 1); + VDP_drawText("Are you morbid?\"", 1, DIALOGUE_Y + 2); +} + + +// loop + +void loadChrome(){ + // loadChromeI(); + // drawFrame(); + // loadScore(); + // loadLives(); + // loadDialogue(); +} + +void updateChrome(){ + // updateScore(); +} \ No newline at end of file diff --git a/src/controls.h b/src/controls.h new file mode 100644 index 0000000..53b7d5f --- /dev/null +++ b/src/controls.h @@ -0,0 +1,21 @@ +// controls + +struct controls { + bool left, right, up, down, a, b, c, start; +}; + +struct controls ctrl; + +void updateControls(u16 joy, u16 changed, u16 state){ + if(joy == JOY_1){ + if(changed){} + ctrl.left = (state & BUTTON_LEFT); + ctrl.right = (state & BUTTON_RIGHT); + ctrl.up = (state & BUTTON_UP); + ctrl.down = (state & BUTTON_DOWN); + ctrl.a = (state & BUTTON_A); + ctrl.b = (state & BUTTON_B); + ctrl.c = (state & BUTTON_C); + ctrl.start = (state & BUTTON_START); + } +} \ No newline at end of file diff --git a/src/global.h b/src/global.h new file mode 100644 index 0000000..5fc4b7f --- /dev/null +++ b/src/global.h @@ -0,0 +1,25 @@ +// globals + +#define WIN_W_T 32 +#define WIN_H_T 28 + +#define WIN_W WIN_W_T * 8 +#define WIN_H WIN_H_T * 8 + +#define GAME_W_T WIN_W_T +#define GAME_H_T WIN_H_T + +#define GAME_W GAME_W_T * 8 +#define GAME_H GAME_H_T * 8 + +#define GAME_X_T 0 +#define GAME_Y_T 0 + +#define GAME_X 0 +#define GAME_Y 0 + +#define CLOCK_LIMIT 32000 + +s16 clock; + +u32 score; \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..1fd341d --- /dev/null +++ b/src/main.c @@ -0,0 +1,51 @@ +// main + +#include +#include + +#include "global.h" +#include "controls.h" +#include "background.h" +#include "tiles.h" +#include "player.h" +#include "chrome.h" + +// game loop + +static void loadInternals(){ + JOY_init(); + JOY_setEventHandler(&updateControls); + SPR_init(127, 0, 0); + VDP_setScreenWidth256(); + VDP_setPalette(PAL1, tile1_1.palette -> data); + VDP_setPalette(PAL2, bg1_1.palette -> data); + VDP_loadFont(font.tileset, DMA); + VDP_setTextPalette(1); +} + +static void loadGame(){ + loadBg(); + loadTiles(); + loadChrome(); +} + +static void updateGame(){ + updateBg(); + updateChrome(); + updateTiles(); + clock++; + if(clock >= CLOCK_LIMIT) clock -= CLOCK_LIMIT; +} + +// main loop + +int main(){ + loadInternals(); + loadGame(); + while(1){ + updateGame(); + SPR_update(); + SYS_doVBlankProcess(); + } + return(0); +} \ No newline at end of file diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..4e3e7c9 --- /dev/null +++ b/src/player.h @@ -0,0 +1,32 @@ +// player + +#define PLAYER_OFF FIX16(16) +#define PLAYER_INIT_X FIX16(32) +#define PLAYER_INIT_Y FIX16(32) + +struct playerStruct { + Vect2D_f16 pos; + Sprite* image; +}; +struct playerStruct player; + + +// spawn + +static void spawnPlayer(){ + player.pos.x = 0; + player.pos.y = 0; + player.image = SPR_addSprite(&reimu, + fix16ToInt(fix16Sub(player.pos.x, PLAYER_OFF)), + fix16ToInt(fix16Sub(player.pos.y, PLAYER_OFF)), + TILE_ATTR(PAL1, 0, 0, 0)); +} + + +// loop + +void loadPlayer(){} + +void updatePlayer(){ + spawnPlayer(); +} \ No newline at end of file diff --git a/src/tiles.h b/src/tiles.h new file mode 100644 index 0000000..a1515dc --- /dev/null +++ b/src/tiles.h @@ -0,0 +1,84 @@ +// tiles + +#define TILE_I 128 +#define TILE_W 128 + +#define TILE_COUNT 3072 +u16 tileMap[TILE_COUNT]; + +u16 tileC; + +static void loadTilesI(){ + VDP_loadTileSet(tile1_1.tileset, TILE_I, DMA); +} + + +static void spawnTileRows(s16 y1, s16 y2, bool trig){ + tileC = 0; + for(u16 y = 0; y < GAME_H_T; y++) for(u16 x = 0; x < TILE_W; x++){ + if((y == y1 && tileMap[tileC - TILE_W] > 0 && random() % 4 < 3) || (y == y2 && tileMap[tileC + TILE_W] > 0 && trig)) tileMap[tileC] = 1; + tileC++; + } +} + +static void spawnTiles(){ + + // initial ceiling and floor + tileC = 0; + for(u16 y = 0; y < GAME_H_T; y++) for(u16 x = 0; x < TILE_W; x++){ + tileMap[tileC] = 0; + if(y == 0 || y == 23) tileMap[tileC] = 1; + tileC++; + } + + // first go around + spawnTileRows(1, 22, random() % 4 < 3); + + // second go around + spawnTileRows(2, 21, random() % 4 < 2); + + // third go around + spawnTileRows(3, 20, random() % 4 < 1); + + // draw small + tileC = 0; + for(u16 y = 0; y < GAME_H_T; y++) for(u16 x = 0; x < TILE_W; x++){ + if(tileMap[tileC] > 0) + VDP_setTileMapXY(BG_A, TILE_ATTR_FULL(PAL1, 0, 0, 0, TILE_I), x, y + 4); + tileC++; + } + + + // if(tileMap[tileC] > 0 && x % 2 == 0 && y % 2 == 0) VDP_drawImageEx(BG_A, &tile1_2, TILE_ATTR_FULL(PAL1, 0, 0, 0, TILE_I + 1), x, y + 4, 0, DMA); + // if(x % 2 == 0 && tileC % 256 < 128 && tileMap[tileC] > 0){ + // VDP_drawImageEx(BG_A, &tile1_2, TILE_ATTR_FULL(PAL1, 0, 0, 0, TILE_I + 1), x, 4, 0, DMA); + // } + // tileC++; + // } + // } + +} + +#define TILE_SPEED -1 +#define TILE_LIMIT -TILE_W * 8 +s16 tilePos[GAME_H_T]; +static void scrollTiles(){ + for(u16 y = 0; y < GAME_H_T; y++){ + tilePos[y] += TILE_SPEED; + if(tilePos[y] <= TILE_LIMIT) tilePos[y] = 0; + } + VDP_setHorizontalScrollTile(BG_A, 4, tilePos, GAME_H_T, DMA); +} + + +// loop + +void loadTiles(){ + // loadTilesI(); + // VDP_setScrollingMode(HSCROLL_TILE, VSCROLL_PLANE); + // spawnTiles(); +} + +void updateTiles(){ + // scrollTiles(); +} \ No newline at end of file