diff --git a/genctx.py b/genctx.py index 105eba435..a172347be 100644 --- a/genctx.py +++ b/genctx.py @@ -25,28 +25,32 @@ def search_directories(*patterns): return it.chain.from_iterable(glob.iglob(pattern,recursive=True) for pattern in patterns) -for filename in search_directories('./src/**/*.h', './include/**/*.h'): +for filename in search_directories('./include/**/*.h'): with open(filename) as header: header_name = "/".join(filename.split('/')[2:]) - - # not needed for decomp work - if header_name.startswith("platform"): - continue if not header_name in depends_on: depends_on[header_name] = set() - if not header_name.startswith("gba/") and header_name != "global.h" and header_name != "functions.h": - depends_on[header_name].add("global.h") - - if header_name.startswith("gba/") and not header_name.endswith("types.h") and not header_name.endswith("defines.h"): - depends_on[header_name].add("gba/types.h") + + if not header_name.startswith("gba/"): + if header_name != "global.h" \ + and header_name != "config.h" \ + and header_name != "functions.h": + depends_on[header_name].add("global.h") - if header_name.startswith("gba/") and not header_name.endswith("multiboot.h") and not header_name.endswith("types.h"): - depends_on[header_name].add("gba/multiboot.h") + else: # header_name.startswith("gba/") + if not header_name.endswith("types.h") \ + and not header_name.endswith("defines.h"): + depends_on[header_name].add("gba/types.h") + elif not header_name.endswith("multiboot.h") \ + and not header_name.endswith("types.h"): + depends_on[header_name].add("gba/multiboot.h") data[header_name] = "" for line in header.readlines(): - if "#include" in line and not line.startswith("//") and '<' not in line: + if "#include" in line \ + and not line.startswith("//") \ + and '<' not in line: requires = line.split('"')[1] depends_on[header_name].add(requires) continue @@ -58,7 +62,6 @@ def search_directories(*patterns): print_order = tuple(ts.static_order()) with open('ctx.c', 'w') as context: - context.write("#define PLATFORM_GBA 1\n") for header in print_order: exclude = False for e in excluded: diff --git a/include/config.h b/include/config.h index afadc0557..ee95e6bad 100644 --- a/include/config.h +++ b/include/config.h @@ -3,13 +3,23 @@ /* TODO: Move config.h into a different location? */ -#define GAME_SA1 1 -#define GAME_SA2 2 -#define GAME_SA3 3 +#define GAME_SA1 1 +#define GAME_SA2 2 +#define GAME_SA3 3 +#define GAME_KATAM 4 -// TODO: Define this in Makefile through a compiler macro! +#define ENGINE_1 1 +#define ENGINE_2 2 +#define ENGINE_3 3 +#define ENGINE_4 4 + +// TODO: Define this in Makefile through a compiler macro? #define GAME GAME_SA2 +// TODO: Do SA1 and SA2 use the same engine ver? +// TODO: Do SA3 and KATAM use the same engine ver? +#define ENGINE GAME + // TODO: Put somewhere else? #if PLATFORM_GBA #define USE_NEW_DMA 0 diff --git a/include/core.h b/include/core.h index ca6fa4e34..16e80022b 100644 --- a/include/core.h +++ b/include/core.h @@ -368,7 +368,7 @@ extern struct MultiBootParam gMultiBootParam; extern const struct SpriteTables *gRefSpriteTables; -void GameInit(void); -void GameLoop(void); +void EngineInit(void); +void EngineMainLoop(void); #endif diff --git a/include/game/game.h b/include/game/game.h index 7cc1af7f5..1d5e6edc6 100644 --- a/include/game/game.h +++ b/include/game/game.h @@ -3,6 +3,6 @@ #include "global.h" -void GameStart(void); +void GameInit(void); #endif // GUARD_GAME_H diff --git a/include/game/parameters/characters.h b/include/game/parameters/characters.h index c4900bf24..265989455 100644 --- a/include/game/parameters/characters.h +++ b/include/game/parameters/characters.h @@ -3,6 +3,8 @@ #include "constants/zones.h" +// TODO: Be consistent about whether these are Q() or I() values! + /*** Common ***/ #define PLAYER_FLYING_END_GRAVITY (0.033) // = (8. / 256.) #define PLAYER_GRAVITY 42.0 / 256.0 diff --git a/include/sprite.h b/include/sprite.h index 0649d23a5..207e98ba3 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -93,11 +93,18 @@ typedef struct { } Background; /* size = 0x40 */ typedef struct { +#if (ENGINE >= ENGINE_3) + // In SA3 flip-bits are integrated into the oamIndex. + // X-Flip: Bit 14 + // Y-Flip: Bit 15 + /* 0x00 */ u16 oamIndex; +#else /* 0x00 */ u8 flip; // every animation has an associated oamData pointer, oamIndex starts at // 0 for every new animation and ends at variantCount-1 /* 0x01 */ u8 oamIndex; +#endif // some sprite frames consist of multiple images (of the same size // as GBA's Object Attribute Memory, e.g. 8x8, 8x32, 32x64, ...) diff --git a/ldscript.txt b/ldscript.txt index 9464d07c2..38fd76a22 100644 --- a/ldscript.txt +++ b/ldscript.txt @@ -39,6 +39,7 @@ SECTIONS /* engine */ src/core.o(.data); + src/input_recorder.o(.data); /* "SA1 Leftovers" */ . = ALIGN(32); diff --git a/src/core.c b/src/core.c index dfe1ce94f..ff3e64a39 100644 --- a/src/core.c +++ b/src/core.c @@ -35,7 +35,10 @@ u8 gNumHBlankIntrs = 0; struct BlendRegs gBldRegs ALIGNED(8) = {}; u8 gOamFreeIndex = 0; struct Task gEmptyTask ALIGNED(16) = {}; -BgAffineReg gBgAffineRegs[NUM_AFFINE_BACKGROUNDS] ALIGNED(8) = {}; + +// NOTE: gNextFreeAffineIndex introduced in SA3, unused before. +u8 gNextFreeAffineIndex = 0; +BgAffineReg gBgAffineRegs[NUM_AFFINE_BACKGROUNDS] = {}; void *gVramHeapStartAddr = NULL; u16 gUnknown_03001944 ALIGNED(4) = 0; u8 gUnknown_03001948 ALIGNED(4) = 0; @@ -124,8 +127,6 @@ FuncType_030053A0 gUnknown_030053A0[] ALIGNED(16) = {}; const u8 *gInputPlaybackData = NULL; bool8 gExecSoundMain ALIGNED(4) = FALSE; s32 gPseudoRandom = 0; -struct InputRecorder gInputRecorder ALIGNED(8) = {}; -u16 *gInputRecorderTapeBuffer = NULL; static void UpdateScreenDma(void); static void UpdateScreenCpuSet(void); @@ -179,7 +180,7 @@ static VBlankFunc const sVblankFuncs[] = { sub_8002B20, }; -void GameInit(void) +void EngineInit(void) { s16 i; u16 errorIdentifying; @@ -252,6 +253,9 @@ void GameInit(void) gBgAffineRegs[1].x = 0; gBgAffineRegs[1].y = 0; +#if (ENGINE >= ENGINE_3) + gNextFreeAffineIndex = 0; +#endif gUnknown_03001944 = 0; gUnknown_030017F0 = 0x100; gUnknown_03005394 = 0x100; @@ -358,7 +362,7 @@ void GameInit(void) MultiSioInit(0); } -void GameLoop(void) +void EngineMainLoop(void) { while (TRUE) { gExecSoundMain = FALSE; @@ -379,6 +383,10 @@ void GameLoop(void) gFlagsPreVBlank = gFlags; VBlankIntrWait(); +#if (ENGINE >= ENGINE_3) + gNextFreeAffineIndex = 0; +#endif + if (gFlags & FLAGS_4000) { UpdateScreenCpuSet(); diff --git a/src/game/game.c b/src/game/game.c index fa0bfd94c..9646bb539 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -30,7 +30,7 @@ #include "data/sprite_tables.h" -void GameStart(void) +void GameInit(void) { u32 i; bool32 hasProfile = FALSE; @@ -77,7 +77,7 @@ void GameStart(void) hasProfile = TRUE; } - // This flag is only set in GameInit + // This flag is only set in EngineInit if (gFlags & FLAGS_200) { ShowSinglePakResults(); return; diff --git a/src/game/math.c b/src/game/math.c index b00d30a8a..0123f7224 100644 --- a/src/game/math.c +++ b/src/game/math.c @@ -27,6 +27,15 @@ u32 gRngValue = 0; const u16 gUnknown_080E0290[] = { 0x0AAA, 0x02AA }; +typedef struct { + void *unk0; + void *start; + void *next; + void *unkC; +} UNK_8085DEC; + +bool8 sub_8085D98(UNK_8085DEC *thing, UNK_8085DEC *target); + #define RAND_CONST 0x37119371; NONMATCH("asm/non_matching/game/math/unused_sub_80832FC.inc", void sub_80832FC()) { } @@ -609,15 +618,6 @@ void sub_8085D14(UNK_8085D14 *p1, u32 p2, u32 p3, u32 p4) p1->unk12 = p4; } -typedef struct { - void *unk0; - void *start; - void *next; - void *unkC; -} UNK_8085DEC; - -bool8 sub_8085D98(UNK_8085DEC *thing, UNK_8085DEC *target); - void sub_8085D44(UNK_8085DEC *thing) { thing->unk0 = NULL; diff --git a/src/game/title_screen.c b/src/game/title_screen.c index e9be28940..a7f935fba 100644 --- a/src/game/title_screen.c +++ b/src/game/title_screen.c @@ -553,7 +553,13 @@ static void InitTitleScreenUI(TitleScreen *titleScreen) s->graphics.anim = SA2_ANIM_TITLE_COPYRIGHT; s->variant = SA2_ANIM_VARIANT_COPYRIGHT_2003; s->prevVariant = -1; +#if PLATFORM_GBA s->x = 0; +#else + // Only display the COPYRIGHT message, not the "Licensed by ***" msg + // TODO: Split the graphics properly. + s->x = DISPLAY_WIDTH - 136; +#endif s->y = DISPLAY_HEIGHT - 30; // set to the screen's bottom s->graphics.size = 0; s->oamFlags = SPRITE_OAM_ORDER(4); @@ -1892,9 +1898,7 @@ static void Task_StartTitleScreenDemo(void) gSelectedCharacter = CHARACTER_SONIC; gCurrentLevel = sDemoLevels[0]; - gDemoPlayCounter++; - // Don't count higher than 3 - gDemoPlayCounter &= 3; + gDemoPlayCounter = (gDemoPlayCounter + 1) % 4u; gGameMode = GAME_MODE_SINGLE_PLAYER; diff --git a/src/input_recorder.c b/src/input_recorder.c index 0c41fb2a0..e47954b64 100644 --- a/src/input_recorder.c +++ b/src/input_recorder.c @@ -11,6 +11,9 @@ #define TAPE_LENGTH 0x800 #endif +struct InputRecorder gInputRecorder ALIGNED(8) = { 0 }; +u16 *gInputRecorderTapeBuffer = NULL; + static void Task_InputRecorder(void); static void InputRecorderEject(struct Task *); diff --git a/src/main.c b/src/main.c index 547787dd1..4c79283d0 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,7 @@ void AgbMain(void) { + EngineInit(); GameInit(); - GameStart(); - GameLoop(); + EngineMainLoop(); } diff --git a/src/multi_sio.c b/src/multi_sio.c index c580b3265..ceb29fdd8 100644 --- a/src/multi_sio.c +++ b/src/multi_sio.c @@ -1,4 +1,5 @@ #include "global.h" +#include "game/game.h" #include "multi_sio.h" #include "sio32_multi_load.h" @@ -10,7 +11,9 @@ u32 gMultiSioIntrFuncBuf[0x120 / 4] = {}; // Interrupt Routine RAM Execution Buf struct MultiSioArea gMultiSioArea = {}; +#if (GAME <= GAME_SA2) UNUSED u32 gUnusedMultiSioSpace[2] = {}; +#endif #ifdef MULTI_SIO_DI_FUNC_FAST u32 gMultiSioRecvFuncBuf[0x40 / 4] = {}; // Receive Data/Check Buffer Change Routine RAM Execution Buffer diff --git a/src/platform/pret_sdl/sdl2.c b/src/platform/pret_sdl/sdl2.c index 138bed81a..4b6f385db 100644 --- a/src/platform/pret_sdl/sdl2.c +++ b/src/platform/pret_sdl/sdl2.c @@ -243,7 +243,7 @@ int main(int argc, char **argv) #if ENABLE_VRAM_VIEW VramDraw(vramTexture); #endif - // Prevent the multiplayer screen from being drawn ( see core.c:GameInit() ) + // Prevent the multiplayer screen from being drawn ( see core.c:EngineInit() ) REG_RCNT = 0x8000; REG_KEYINPUT = 0x3FF; diff --git a/src/platform/win32/win32.c b/src/platform/win32/win32.c index d52d2cdbe..47d9dbf7d 100644 --- a/src/platform/win32/win32.c +++ b/src/platform/win32/win32.c @@ -4,9 +4,7 @@ #include "global.h" #include "core.h" -extern void GameInit(void); -extern void GameStart(void); -extern void GameLoop(void); +void GameInit(void); DWORD WINAPI GameThread(void *pThreadParam); @@ -25,8 +23,8 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR lpCmdLine, REG_RCNT = 0x8000; REG_KEYINPUT = 0x3FF; + EngineInit(); GameInit(); - GameStart(); DWORD threadId; HANDLE GameThreadHandle = CreateThread(NULL, 0, GameThread, NULL, 0, &threadId); @@ -39,7 +37,7 @@ DWORD WINAPI GameThread(void *pThreadParam) REG_KEYINPUT &= ~START_BUTTON; while (1) { gFlags |= 0x4000; - GameLoop(); + EngineMainLoop(); REG_KEYINPUT ^= (A_BUTTON | START_BUTTON); REG_KEYINPUT |= (DPAD_RIGHT); } diff --git a/src/sprite.c b/src/sprite.c index cd9caa152..205579b59 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -629,12 +629,12 @@ void DisplaySprite(Sprite *sprite) } } -void sub_081569A0(Sprite *sprite, u16 *sp08, u8 sp0C) +void DisplaySprites(Sprite *sprite, Vec2_16 *positions, u8 numPositions) { vs32 x, y; s32 sprWidth, sprHeight; u8 subframe, i; - u32 x1, y1, sp24, sp28; + s32 x1, y1, centerOffsetX, centerOffsetY; if (sprite->dimensions != (void *)-1) { const SpriteOffset *sprDims = sprite->dimensions; @@ -671,8 +671,8 @@ void sub_081569A0(Sprite *sprite, u16 *sp08, u8 sp0C) } } - sp24 = x - sprite->x; - sp28 = y - sprite->y; + centerOffsetX = x - sprite->x; + centerOffsetY = y - sprite->y; if (x + sprWidth >= 0 && x <= DISPLAY_WIDTH && y + sprHeight >= 0 && y <= DISPLAY_HEIGHT) { for (subframe = 0; subframe < sprDims->numSubframes; ++subframe) { const u16 *oamData = gRefSpriteTables->oamData[sprite->graphics.anim]; @@ -728,7 +728,7 @@ void sub_081569A0(Sprite *sprite, u16 *sp08, u8 sp0C) } oam->all.attr2 += GET_TILE_NUM(sprite->graphics.dest); - for (i = 0; i < sp0C; ++i) { + for (i = 0; i < numPositions; ++i) { OamData *r5 = OamMalloc(GET_SPRITE_OAM_ORDER(sprite)); if (iwram_end == oam) @@ -736,8 +736,8 @@ void sub_081569A0(Sprite *sprite, u16 *sp08, u8 sp0C) DmaCopy16(3, oam, r5, sizeof(OamDataShort)); r5->all.attr1 &= 0xFE00; r5->all.attr0 &= 0xFF00; - r5->all.attr0 += (sp08[2 * i + 1] + sp28 + y1) & 0xFF; - r5->all.attr1 += (sp08[2 * i + 0] + sp24 + x1) & 0x1FF; + r5->all.attr0 += (positions[i].y + centerOffsetY + y1) & 0xFF; + r5->all.attr1 += (positions[i].x + centerOffsetX + x1) & 0x1FF; } } }