From 2d6d88cd6da8165c236694b4f5b334dd4cc16c1e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 26 Nov 2022 19:53:48 +1000 Subject: [PATCH] ntsc-beta, pal-beta and pal-final: Introduce support for gcc --- README.md | 2 +- include/PR/libaudio.h | 1 + src/game/bg.c | 21 ++-- src/game/bondgun.c | 38 +++++++- src/game/bossfile.c | 1 + src/game/challenge.c | 13 +-- src/game/cheats.c | 1 + src/game/chraction.c | 61 ++++++------ src/game/chraicommands.c | 25 +++-- src/game/endscreen.c | 1 + src/game/file.c | 3 +- src/game/game_1531a0.c | 152 +++++++++++++++-------------- src/game/gamefile.c | 1 + src/game/hudmsg.c | 7 +- src/game/lang.c | 95 ++++++++++++++++-- src/game/langinit.c | 4 +- src/game/langtick.c | 2 + src/game/lv.c | 1 + src/game/mainmenu.c | 35 +++---- src/game/pak.c | 31 +++--- src/game/player.c | 1 + src/game/setuputils.c | 1 + src/game/texdecompress.c | 3 +- src/game/title.c | 18 +++- src/game/training.c | 33 ++++--- src/game/vtxstore.c | 1 + src/include/bss.h | 2 + src/include/game/debug.h | 9 ++ src/include/game/lang.h | 3 + src/include/game/mplayer/mplayer.h | 2 + src/include/game/pak.h | 9 +- src/include/lib/boot.h | 1 + src/include/lib/sched.h | 2 + src/include/types.h | 21 ---- src/lib/crash.c | 6 +- src/lib/debughud.c | 1 + src/lib/dma.c | 1 + src/lib/main.c | 116 +++++++++++++++++++++- src/lib/mema.c | 1 + src/lib/memp.c | 1 + src/lib/music.c | 33 ++++++- src/lib/snd.c | 9 ++ src/lib/ultra/io/pfsinitpak.c | 1 + src/lib/ultra/libc/llcvt.c | 24 +++-- src/lib/vi.c | 1 + src/lib/vm.c | 60 ++++++++++-- 46 files changed, 616 insertions(+), 239 deletions(-) diff --git a/README.md b/README.md index 8fcc1080f..a6165579b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ To build the project, you must already have a Perfect Dark ROM. The project can See the [Perfect Dark Decompilation Status Page](https://ryandwyer.gitlab.io/pdstatus/). -The ntsc-1.0 and ntsc-final versions are fully decompiled, but a small handful of functions are not yet byte-matching even though they are functionally the same. The status page doesn't show these as 100% because it counts matching functions only. +With the exception of jpn-final, all other versions are fully decompiled but a small handful of functions are not yet byte-matching even though they are functionally the same. The status page doesn't show these as 100% because it counts matching functions only. ## Installation Requirements diff --git a/include/PR/libaudio.h b/include/PR/libaudio.h index b162b2ffb..d5c070a4d 100644 --- a/include/PR/libaudio.h +++ b/include/PR/libaudio.h @@ -406,6 +406,7 @@ Acmd *alAudioFrame(Acmd *cmdList, s32 *cmdLen, s16 *outBuf, s32 outLen); #define AL_STATE3 3 #define AL_STATE4 4 #define AL_STATE5 5 +#define AL_STARTING 6 #define AL_DEFAULT_PRIORITY 5 #define AL_DEFAULT_VOICE 0 diff --git a/src/game/bg.c b/src/game/bg.c index 233d175c6..1f4938656 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -29,16 +29,17 @@ #include "game/texdecompress.h" #include "game/wallhit.h" #include "bss.h" +#include "lib/crash.h" +#include "lib/dma.h" #include "lib/lib_17ce0.h" +#include "lib/lib_2f490.h" +#include "lib/main.h" +#include "lib/mema.h" +#include "lib/memp.h" +#include "lib/mtx.h" +#include "lib/rng.h" #include "lib/rzip.h" #include "lib/vi.h" -#include "lib/dma.h" -#include "lib/main.h" -#include "lib/memp.h" -#include "lib/mema.h" -#include "lib/rng.h" -#include "lib/mtx.h" -#include "lib/lib_2f490.h" #include "data.h" #include "gbiex.h" #include "types.h" @@ -2997,7 +2998,7 @@ u32 bgInflate(u8 *src, u8 *dst, u32 len) src[8], src[9], src[10], src[11], src[12], src[13], src[14], src[15]); - crashSetMessage(&message); + crashSetMessage(message); CRASH(); } #endif @@ -4518,11 +4519,11 @@ void bgLoadRoom(s32 roomnum) g_Rooms[roomnum].colours = NULL; dyntexSetCurrentRoom(-1); - } #if VERSION < VERSION_NTSC_1_0 - bgVerifyLightSums("bg.c", 7474); + bgVerifyLightSums("bg.c", 7474); #endif + } } #endif diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 5a011b8ad..1fd6d86b5 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -182,9 +182,10 @@ char var800700bc[][10] = { { 'x','x','x' }, // "xxx" }; -#if VERSION >= VERSION_NTSC_1_0 +#if !MATCHING || VERSION >= VERSION_NTSC_1_0 void bgunRumble(s32 handnum, s32 weaponnum) { +#if VERSION >= VERSION_NTSC_1_0 u32 stack; s32 contpadtouse1; s32 contpadtouse2; @@ -232,6 +233,41 @@ void bgunRumble(s32 handnum, s32 weaponnum) pakRumble(contpad1, 0.2f, 2, 4); } } +#else + s32 stack1; + s32 stack2; + s8 contpad1; + s8 contpad2; + bool contpad1hasrumble; + bool contpad2hasrumble; + s32 contpadtouse1; + s32 contpadtouse2; + + if (optionsGetControlMode(g_Vars.currentplayerstats->mpindex) >= CONTROLMODE_21) { + contpad1hasrumble = pakGetType(g_Vars.currentplayernum) == PAKTYPE_RUMBLE; + contpad2hasrumble = pakGetType(g_Vars.currentplayernum + PLAYERCOUNT()) == PAKTYPE_RUMBLE; + + if (contpad1hasrumble && contpad2hasrumble) { + contpadtouse1 = g_Vars.currentplayernum; + + if (handnum == HAND_LEFT) { + contpadtouse1 += PLAYERCOUNT(); + } + + pakRumble(contpadtouse1, 0.2f, 2, 4); + } else { + contpadtouse2 = g_Vars.currentplayernum; + + if (contpad2hasrumble) { + contpadtouse2 += PLAYERCOUNT(); + } + + pakRumble(contpadtouse2, 0.2f, 2, 4); + } + } else { + pakRumble(g_Vars.currentplayernum, 0.2f, 2, 4); + } +#endif } #else GLOBAL_ASM( diff --git a/src/game/bossfile.c b/src/game/bossfile.c index 3838a5f4b..2b162150b 100644 --- a/src/game/bossfile.c +++ b/src/game/bossfile.c @@ -3,6 +3,7 @@ #include "constants.h" #include "game/camdraw.h" #include "game/cheats.h" +#include "game/lang.h" #include "game/player.h" #include "game/savebuffer.h" #include "game/bossfile.h" diff --git a/src/game/challenge.c b/src/game/challenge.c index 8be46a0e2..c34eeeac8 100644 --- a/src/game/challenge.c +++ b/src/game/challenge.c @@ -1,18 +1,19 @@ #include #include "constants.h" -#include "game/chrai.h" -#include "game/chraicommands.h" -#include "game/prop.h" #include "game/atan2f.h" -#include "game/playermgr.h" -#include "game/mplayer/setup.h" #include "game/bot.h" #include "game/challenge.h" -#include "game/training.h" +#include "game/chrai.h" +#include "game/chraicommands.h" +#include "game/debug.h" #include "game/lang.h" #include "game/mplayer/mplayer.h" #include "game/mplayer/scenarios.h" +#include "game/mplayer/setup.h" #include "game/pad.h" +#include "game/playermgr.h" +#include "game/prop.h" +#include "game/training.h" #include "bss.h" #include "lib/dma.h" #include "lib/rng.h" diff --git a/src/game/cheats.c b/src/game/cheats.c index 87b038649..1c3123985 100644 --- a/src/game/cheats.c +++ b/src/game/cheats.c @@ -12,6 +12,7 @@ #include "game/pak.h" #include "bss.h" #include "data.h" +#include "string.h" #include "types.h" u32 g_CheatsActiveBank0; diff --git a/src/game/chraction.c b/src/game/chraction.c index 222d168e3..d1da6a5ca 100644 --- a/src/game/chraction.c +++ b/src/game/chraction.c @@ -1,46 +1,47 @@ #include #include "constants.h" -#include "game/chraction.h" -#include "game/chrai.h" -#include "game/debug.h" -#include "game/dlights.h" -#include "game/footstep.h" -#include "game/game_006900.h" -#include "game/pdmode.h" -#include "game/chr.h" -#include "game/body.h" -#include "game/prop.h" -#include "game/propsnd.h" -#include "game/objectives.h" -#include "game/atan2f.h" #include "game/acosfasinf.h" -#include "game/bondgun.h" -#include "game/gunfx.h" -#include "game/game_0b0fd0.h" -#include "game/modelmgr.h" -#include "game/tex.h" -#include "game/camera.h" -#include "game/player.h" -#include "game/inv.h" -#include "game/playermgr.h" -#include "game/explosions.h" -#include "game/sparks.h" +#include "game/atan2f.h" #include "game/bg.h" -#include "game/game_1531a0.h" -#include "game/stagetable.h" -#include "game/env.h" -#include "game/lv.h" +#include "game/body.h" +#include "game/bondgun.h" #include "game/bot.h" #include "game/botact.h" #include "game/botcmd.h" #include "game/botinv.h" +#include "game/camera.h" +#include "game/chr.h" +#include "game/chraction.h" +#include "game/chrai.h" +#include "game/debug.h" +#include "game/dlights.h" +#include "game/env.h" +#include "game/explosions.h" +#include "game/footstep.h" +#include "game/game_006900.h" +#include "game/game_0b0fd0.h" +#include "game/game_1531a0.h" +#include "game/gunfx.h" +#include "game/inv.h" +#include "game/lv.h" +#include "game/modelmgr.h" #include "game/mplayer/mplayer.h" +#include "game/mpstats.h" +#include "game/objectives.h" +#include "game/options.h" #include "game/pad.h" #include "game/padhalllv.h" #include "game/pak.h" +#include "game/pdmode.h" +#include "game/player.h" +#include "game/playermgr.h" +#include "game/prop.h" #include "game/propobj.h" +#include "game/propsnd.h" +#include "game/sparks.h" +#include "game/stagetable.h" +#include "game/tex.h" #include "game/wallhit.h" -#include "game/mpstats.h" #include "bss.h" #include "lib/joy.h" #include "lib/lib_17ce0.h" @@ -6705,7 +6706,7 @@ bool chrIsReadyForOrders(struct chrdata *chr) return false; } - switch (chr->actiontype) { + switch ((s32) chr->actiontype) { case ACT_DIE: case ACT_DEAD: case ACT_PREARGH: diff --git a/src/game/chraicommands.c b/src/game/chraicommands.c index 30f6b7888..547918d3b 100644 --- a/src/game/chraicommands.c +++ b/src/game/chraicommands.c @@ -8527,7 +8527,7 @@ glabel var7f1a9d64 /* f059bac: 8e0e0424 */ lw $t6,0x424($s0) /* f059bb0: 3406ffff */ dli $a2,0xffff /* f059bb4: 0fc2433d */ jal func0f0926bc -/* f059bb8: 8dc4001c */ lw $a0,%lo(invanim_devastator_reload+0x58)($t6) +/* f059bb8: 8dc4001c */ lw $a0,0x1c($t6) /* f059bbc: 8e0f0424 */ lw $t7,0x424($s0) /* f059bc0: 3c01bf80 */ lui $at,0xbf80 /* f059bc4: 44810000 */ mtc1 $at,$f0 @@ -8848,7 +8848,11 @@ bool aiSayQuip(void) s32 distance; // 116 - not referenced s32 row = cmd[3]; // 112 u32 playernum; // 108 - not referenced +#ifdef __sgi + u8 headshotted = (g_Vars.chrdata->hidden2 & CHRH2FLAG_HEADSHOTTED); // 107 +#else u8 headshotted = (g_Vars.chrdata->hidden2 & CHRH2FLAG_HEADSHOTTED) & 0xff; // 107 +#endif struct chrdata *loopchr; // 100 // Choose bank @@ -8922,7 +8926,7 @@ bool aiSayQuip(void) // If soundgap permits talking at this time and probability passes // 494 - if ((g_Vars.chrdata->soundgap == 0 || g_Vars.chrdata->soundgap * 60 < g_Vars.chrdata->soundtimer) + if ((g_Vars.chrdata->soundgap == 0 || g_Vars.chrdata->soundgap * TICKS(60) < g_Vars.chrdata->soundtimer) && probability > (u8)random()) { // Try and find a chr in the same squadron who is currently talking // 4dc @@ -8940,7 +8944,7 @@ bool aiSayQuip(void) numnearbychrs++; // 594 - if (loopchr->soundtimer < 60 && cmd[6] != 0 && cmd[6] != 255) { + if (loopchr->soundtimer < TICKS(60) && cmd[6] != 0 && cmd[6] != 255) { issomeonetalking = true; } } @@ -9006,14 +9010,20 @@ bool aiSayQuip(void) text = langGet(g_QuipTexts[cmd[8] - 1][1 + column]); - if (!sndIsFiltered(audioid)) { +#if VERSION >= VERSION_NTSC_1_0 + if (!sndIsFiltered(audioid)) +#endif + { // 8ac hudmsgCreateWithColour(text, HUDMSGTYPE_INGAMESUBTITLE, cmd[9]); } } else if (cmd[8]) { text = langGet(g_QuipTexts[cmd[8] - 1][1 + g_Vars.chrdata->tude]); - if (!sndIsFiltered(audioid)) { +#if VERSION >= VERSION_NTSC_1_0 + if (!sndIsFiltered(audioid)) +#endif + { // 904 hudmsgCreateWithColour(text, HUDMSGTYPE_INGAMESUBTITLE, cmd[9]); } @@ -9067,7 +9077,10 @@ bool aiSayQuip(void) if (cmd[8]) { text = langGet(g_QuipTexts[cmd[8] - 1][i]); - if (!sndIsFiltered(audioid)) { +#if VERSION >= VERSION_NTSC_1_0 + if (!sndIsFiltered(audioid)) +#endif + { // b78 hudmsgCreateWithColour(text, HUDMSGTYPE_INGAMESUBTITLE, cmd[9]); } diff --git a/src/game/endscreen.c b/src/game/endscreen.c index b6e27672f..de91560f9 100644 --- a/src/game/endscreen.c +++ b/src/game/endscreen.c @@ -7,6 +7,7 @@ #include "game/pdmode.h" #include "game/objectives.h" #include "game/bondgun.h" +#include "game/debug.h" #include "game/game_0b0fd0.h" #include "game/player.h" #include "game/savebuffer.h" diff --git a/src/game/file.c b/src/game/file.c index 7bed7c732..7a5e0ea49 100644 --- a/src/game/file.c +++ b/src/game/file.c @@ -3,10 +3,11 @@ #include "game/file.h" #include "game/stubs/game_175f50.h" #include "bss.h" -#include "lib/rzip.h" +#include "lib/crash.h" #include "lib/dma.h" #include "lib/memp.h" #include "lib/rng.h" +#include "lib/rzip.h" #include "data.h" #include "types.h" diff --git a/src/game/game_1531a0.c b/src/game/game_1531a0.c index 93737a88a..191ab7479 100644 --- a/src/game/game_1531a0.c +++ b/src/game/game_1531a0.c @@ -67,7 +67,7 @@ u32 var800a463c; #if VERSION == VERSION_JPN_FINAL s32 var800800f0jf = 0; s32 g_ScaleX = 1; -u32 var80080104jf = 0; +bool var80080104jf = false; s32 var8007fac4 = 0; bool g_TextRotated90 = false; s32 g_WrapIndentCount = 0; @@ -1063,6 +1063,7 @@ u16 func0f154968jf(u8 value) void textMapCodeUnitToChar(char **text, struct fontchar **arg1, struct fontchar **arg2, struct fontchar *chars, u8 *prevchar); #if VERSION == VERSION_JPN_FINAL +#if MATCHING GLOBAL_ASM( glabel textMapCodeUnitToChar /* f154b00: 27bdffd0 */ addiu $sp,$sp,-48 @@ -1211,75 +1212,78 @@ glabel textMapCodeUnitToChar u32 ope = 0; const char var7f1b8068jf[] = "ope"; +#else +void textMapCodeUnitToChar(char **text, struct fontchar **arg1, struct fontchar **arg2, struct fontchar *chars, u8 *prevchar) +{ + u16 c; + u8 c1; + u8 c2; + u16 sp2a; + u8 sp29; -//void textMapCodeUnitToChar(char **text, struct fontchar **arg1, struct fontchar **arg2, struct fontchar *chars, u8 *prevchar) -//{ -// u16 c; -// u8 c1; -// u8 c2; -// u16 sp2a; -// u8 sp29; -// -// c = **text; -// -// if (c < 0x80) { -// if (chars == NULL || var800800f0jf) { -// g_TmpJpnChar.index = 0; -// g_TmpJpnChar.baseline = 0; -// g_TmpJpnChar.height = 12; -// g_TmpJpnChar.width = 12; -// g_TmpJpnChar.unk06 = 0; -// g_TmpJpnChar.pixeldata = NULL; -// -// g_TmpJpnChar.index = 0x80 + func0f154968jf(c); -// -// *arg1 = &g_TmpJpnChar; -// *arg2 = &g_TmpJpnChar; -// } else { -// *arg1 = &chars[c - 0x21]; -// *arg2 = &chars[*prevchar - 0x21]; -// } -// -// *prevchar = **text; -// *text += 1; -// return; -// } -// -// g_TmpJpnChar.index = 0; -// g_TmpJpnChar.baseline = 0; -// g_TmpJpnChar.height = 11; -// g_TmpJpnChar.width = 11; -// g_TmpJpnChar.unk06 = 0; -// g_TmpJpnChar.pixeldata = NULL; -// -// c1 = **text; -// *text = *text + 1; -// c2 = **text; -// *text = *text + 1; -// -// sp2a = ((c1 & 0x7f) << 7) | (c2 & 0x7f); -// sp29 = 0; -// -// mainOverrideVariable("ope", &ope); -// -// if (ope) { -// sp29 = func0f154784jf(sp2a); -// } -// -// if (sp29 == 0 || chars == NULL) { -// if ((sp2a & 0x1fff) >= 0x400) { -// sp2a = 2; -// } -// -// g_TmpJpnChar.index = sp2a + 0x80; -// -// *arg1 = &g_TmpJpnChar; -// *arg2 = &g_TmpJpnChar; -// } else { -// *arg1 = &chars[sp29 - 0x21]; -// *arg2 = &g_TmpJpnChar; -// } -//} + static u32 ope = 0; + + c = **text; + + if (c < 0x80) { + if (chars == NULL || var800800f0jf) { + g_TmpJpnChar.index = 0; + g_TmpJpnChar.baseline = 0; + g_TmpJpnChar.height = 12; + g_TmpJpnChar.width = 12; + g_TmpJpnChar.kerningindex = 0; + g_TmpJpnChar.pixeldata = NULL; + + g_TmpJpnChar.index = 0x80 + func0f154968jf(c); + + *arg1 = &g_TmpJpnChar; + *arg2 = &g_TmpJpnChar; + } else { + *arg1 = &chars[c - 0x21]; + *arg2 = &chars[*prevchar - 0x21]; + } + + *prevchar = **text; + *text += 1; + return; + } + + g_TmpJpnChar.index = 0; + g_TmpJpnChar.baseline = 0; + g_TmpJpnChar.height = 11; + g_TmpJpnChar.width = 11; + g_TmpJpnChar.kerningindex = 0; + g_TmpJpnChar.pixeldata = NULL; + + c1 = **text; + *text = *text + 1; + c2 = **text; + *text = *text + 1; + + sp2a = ((c1 & 0x7f) << 7) | (c2 & 0x7f); + sp29 = 0; + + mainOverrideVariable("ope", &ope); + + if (ope) { + sp29 = func0f154784jf(sp2a); + } + + if (sp29 == 0 || chars == NULL) { + if ((sp2a & 0x1fff) >= 0x400) { + sp2a = 2; + } + + g_TmpJpnChar.index = sp2a + 0x80; + + *arg1 = &g_TmpJpnChar; + *arg2 = &g_TmpJpnChar; + } else { + *arg1 = &chars[sp29 - 0x21]; + *arg2 = &g_TmpJpnChar; + } +} +#endif #elif VERSION >= VERSION_PAL_BETA void textMapCodeUnitToChar(char **text, struct fontchar **arg1, struct fontchar **arg2, struct fontchar *chars, u8 *prevchar) { @@ -1377,7 +1381,7 @@ void textMapCodeUnitToChar(char **text, struct fontchar **arg1, struct fontchar } #endif -#if VERSION >= VERSION_JPN_FINAL +#if MATCHING && VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel text0f154f38 /* f154d10: 27bdffb0 */ addiu $sp,$sp,-80 @@ -1719,14 +1723,14 @@ Gfx *text0f154f38(Gfx *gdl, s32 *arg1, struct fontchar *curchar, struct fontchar if (curchar->index >= 0x80) { if (!var80080104jf) { gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, osVirtualToPhysical(var800801d8jf)); - var80080104jf = 1; + var80080104jf = true; gDPLoadSync(gdl++); gDPLoadTLUTCmd(gdl++, 6, 15); } } else { if (var80080104jf) { gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, osVirtualToPhysical(var8007fb3c)); - var80080104jf = 0; + var80080104jf = false; gDPLoadSync(gdl++); gDPLoadTLUTCmd(gdl++, 6, 15); } @@ -2340,7 +2344,7 @@ Gfx *textRenderProjected(Gfx *gdl, s32 *x, s32 *y, char *text, struct fontchar * #if VERSION >= VERSION_JPN_FINAL gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, osVirtualToPhysical(var800801d8jf)); - var80080104jf = 1; + var80080104jf = true; #else gDPSetTextureImage(gdl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, osVirtualToPhysical(var8007fb3c)); #endif @@ -2996,7 +3000,7 @@ bool func0f157768jf(s32 arg0, s32 arg1) } #endif -#if VERSION >= VERSION_JPN_FINAL +#if MATCHING && VERSION >= VERSION_JPN_FINAL GLOBAL_ASM( glabel textWrap /* f157778: 27bdff48 */ addiu $sp,$sp,-184 diff --git a/src/game/gamefile.c b/src/game/gamefile.c index 3dd2182cc..b1fab0bd2 100644 --- a/src/game/gamefile.c +++ b/src/game/gamefile.c @@ -7,6 +7,7 @@ #include "game/savebuffer.h" #include "game/bg.h" #include "game/challenge.h" +#include "game/lang.h" #include "game/training.h" #include "game/gamefile.h" #include "game/mplayer/mplayer.h" diff --git a/src/game/hudmsg.c b/src/game/hudmsg.c index 7b8090f04..3efcaab36 100644 --- a/src/game/hudmsg.c +++ b/src/game/hudmsg.c @@ -14,11 +14,12 @@ #include "game/options.h" #include "game/propobj.h" #include "bss.h" -#include "lib/vi.h" -#include "lib/snd.h" -#include "lib/str.h" +#include "lib/lib_317f0.h" #include "lib/memp.h" #include "lib/mtx.h" +#include "lib/snd.h" +#include "lib/str.h" +#include "lib/vi.h" #include "data.h" #include "types.h" #include "string.h" diff --git a/src/game/lang.c b/src/game/lang.c index 16f1b7186..7c740722e 100644 --- a/src/game/lang.c +++ b/src/game/lang.c @@ -2,6 +2,8 @@ #include "constants.h" #include "game/file.h" #include "game/lang.h" +#include "game/mplayer/mplayer.h" +#include "game/utils.h" #include "bss.h" #include "lib/dma.h" #include "data.h" @@ -210,7 +212,7 @@ u32 langGetLangBankIndexFromStagenum(s32 stagenum) return bank; } -#if VERSION == VERSION_JPN_FINAL +#if MATCHING && VERSION == VERSION_JPN_FINAL const char var7f1b8850jf[] = "tmul"; const char var7f1b8858jf[] = "tload"; u32 var80084810jf = 0; @@ -460,6 +462,82 @@ extern u8 _jpndata2; struct var800aabb4 *lang0f16e3fc(s32 arg0) { +#if VERSION == VERSION_JPN_FINAL + s32 i; + s32 t2 = -1; + s32 t3 = -1; + bool t0 = false; + + static u32 var80084810jf = 0; + static u32 var80084814jf = 8; + + if (arg0 & 0x2000) { + if (1); + t0 = true; + } + + mainOverrideVariable("tmul", &var80084814jf); + mainOverrideVariable("tload", &var80084810jf); + + if (var80084810jf) { + arg0 = var80084810jf; + } + + if (arg0 && arg0); + + for (i = 0; i < var8009d140jf; i++) { + if ((t0 || arg0 != var800aabb8[i].unk00_02) + && (!t0 || i + 1 >= var8009d140jf + || arg0 != var800aabb8[i].unk00_02 + || arg0 != var800aabb8[i + 1].unk00_02)) { + if (var800aabb8[i].unk00_00 == 0) { + if (1); + t2 = i; + } + + if (var800aabb8[i].unk00_00 == 0 && var800aabb8[i + 1].unk00_00 == 0 && i + 1 < var8009d140jf) { + t3 = i; + } + } else { + break; + } + } + + if (i < var8009d140jf) { + if (!t0) { + var800aabb8[i].unk00_00 = 2; + + return &var800aabb4[i * var80084814jf]; + } else { + var800aabb8[i + 0].unk00_00 = 2; + var800aabb8[i + 1].unk00_00 = 2; + + return &var800aabb4[var80084814jf * i]; + } + } + + if (!t0 && t2 >= 0) { + var800aabb8[t2].unk00_00 = 2; + var800aabb8[t2].unk00_02 = arg0; + + dmaExec((u8 *) (t2 * (var80084814jf * 0x0c) + (u32)&var800aabb4[0]), + (u32) &_jpndata1 + ((arg0 * var80084814jf) * 0xc + var80084814jf * (24 * 0xc)), + var80084814jf * 0x0c); + + return &var800aabb4[var80084814jf * t2]; + } + + if (t0 && t3 >= 0) { + var800aabb8[t3 + 0].unk00_00 = 2; + var800aabb8[t3 + 1].unk00_00 = 2; + var800aabb8[t3 + 0].unk00_02 = arg0; + var800aabb8[t3 + 1].unk00_02 = arg0; + return &var800aabb4[0]; + } else { + var8009d370jf++; + return &var800aabb4[0]; + } +#else s32 i; s32 t2 = -1; s32 t3 = -1; @@ -494,12 +572,12 @@ struct var800aabb4 *lang0f16e3fc(s32 arg0) if (!t0) { var800aabb8[i].unk00_00 = 2; - return &var800aabb4[i]; + return &var800aabb4[i * 8]; } else { var800aabb8[i + 0].unk00_00 = 2; var800aabb8[i + 1].unk00_00 = 2; - return &var800aabb4[i]; + return &var800aabb4[i * 8]; } } @@ -507,9 +585,9 @@ struct var800aabb4 *lang0f16e3fc(s32 arg0) var800aabb8[t2].unk00_00 = 2; var800aabb8[t2].unk00_02 = arg0 >> 1; - dmaExec(&var800aabb4[t2], (u32)&_jpndata1 + (arg0 >> 1) * 0x60, 0x60); + dmaExec(&var800aabb4[t2 * 8], (u32)&_jpndata1 + (arg0 >> 1) * 0x60, 0x60); - return &var800aabb4[t2]; + return &var800aabb4[t2 * 8]; } if (t0 && t3 >= 0) { @@ -518,12 +596,13 @@ struct var800aabb4 *lang0f16e3fc(s32 arg0) var800aabb8[t3 + 0].unk00_02 = arg0 >> 1; var800aabb8[t3 + 1].unk00_02 = arg0 >> 1; - dmaExec(&var800aabb4[t3], (u32)&_jpndata2 + ((arg0 & 0x1fff) >> 1) * 0x80, 0x80); + dmaExec(&var800aabb4[t3 * 8], (u32)&_jpndata2 + ((arg0 & 0x1fff) >> 1) * 0x80, 0x80); - return &var800aabb4[t3]; + return &var800aabb4[t3 * 8]; } return &var800aabb4[0]; +#endif } #endif @@ -613,7 +692,7 @@ void langReload(void) { s32 i; - g_LangBufferPos = (u8 *)align32(g_LangBuffer); + g_LangBufferPos = (u8 *) align32((u32) g_LangBuffer); for (i = 0; i < ARRAYCOUNT(g_LangBanks); i++) { if (g_LangBanks[i] != NULL) { diff --git a/src/game/langinit.c b/src/game/langinit.c index dc9af31e0..18ea5dfae 100644 --- a/src/game/langinit.c +++ b/src/game/langinit.c @@ -16,7 +16,7 @@ void langInit(void) #if VERSION >= VERSION_JPN_FINAL var8009d140jf = IS4MB() ? 124 : 174; - var800aabb4 = mempAlloc(var8009d140jf * sizeof(struct var800aabb4), MEMPOOL_PERMANENT); + var800aabb4 = mempAlloc(var8009d140jf * (sizeof(struct var800aabb4) * 8), MEMPOOL_PERMANENT); var800aabb8 = mempAlloc(ALIGN16(var8009d140jf * sizeof(struct var800aabb8)), MEMPOOL_PERMANENT); for (i = 0; i < var8009d140jf; i++) { @@ -25,7 +25,7 @@ void langInit(void) } #else if (g_Jpn) { - var800aabb4 = mempAlloc(124 * sizeof(struct var800aabb4), MEMPOOL_PERMANENT); + var800aabb4 = mempAlloc(124 * (sizeof(struct var800aabb4) * 8), MEMPOOL_PERMANENT); var800aabb8 = mempAlloc(ALIGN16(124 * sizeof(struct var800aabb8)), MEMPOOL_PERMANENT); for (i = 0; i < 124; i++) { diff --git a/src/game/langtick.c b/src/game/langtick.c index d5bb3f195..767c49baf 100644 --- a/src/game/langtick.c +++ b/src/game/langtick.c @@ -1,6 +1,8 @@ #include #include "constants.h" +#include "game/lang.h" #include "game/room.h" +#include "lib/main.h" #include "bss.h" #include "data.h" #include "types.h" diff --git a/src/game/lv.c b/src/game/lv.c index 02f4c28a6..0840672e3 100644 --- a/src/game/lv.c +++ b/src/game/lv.c @@ -83,6 +83,7 @@ #include "lib/anim.h" #include "lib/args.h" #include "lib/collision.h" +#include "lib/crash.h" #include "lib/joy.h" #include "lib/lib_06440.h" #include "lib/lib_317f0.h" diff --git a/src/game/mainmenu.c b/src/game/mainmenu.c index 01c1bd953..1d1caa9e2 100644 --- a/src/game/mainmenu.c +++ b/src/game/mainmenu.c @@ -1,28 +1,29 @@ #include #include "constants.h" -#include "game/bossfile.h" -#include "game/cheats.h" -#include "game/setup.h" -#include "game/title.h" -#include "game/pdmode.h" -#include "game/objectives.h" #include "game/bondgun.h" -#include "game/game_0b0fd0.h" -#include "game/tex.h" -#include "game/player.h" -#include "game/menu.h" -#include "game/mainmenu.h" -#include "game/filemgr.h" -#include "game/inv.h" -#include "game/game_1531a0.h" -#include "game/lv.h" -#include "game/mplayer/ingame.h" +#include "game/bossfile.h" #include "game/challenge.h" -#include "game/training.h" +#include "game/cheats.h" +#include "game/debug.h" +#include "game/filemgr.h" +#include "game/game_0b0fd0.h" +#include "game/game_1531a0.h" #include "game/gamefile.h" +#include "game/inv.h" #include "game/lang.h" +#include "game/lv.h" +#include "game/mainmenu.h" +#include "game/menu.h" +#include "game/mplayer/ingame.h" #include "game/mplayer/mplayer.h" +#include "game/objectives.h" #include "game/options.h" +#include "game/pdmode.h" +#include "game/player.h" +#include "game/setup.h" +#include "game/tex.h" +#include "game/title.h" +#include "game/training.h" #include "bss.h" #include "lib/vi.h" #include "lib/joy.h" diff --git a/src/game/pak.c b/src/game/pak.c index c05cb3cce..3e9c9fe60 100644 --- a/src/game/pak.c +++ b/src/game/pak.c @@ -7,10 +7,13 @@ #include "game/menu.h" #include "game/crc.h" #include "game/gamefile.h" +#include "game/lv.h" +#include "game/mplayer/mplayer.h" #include "game/pak.h" #include "game/utils.h" #include "bss.h" #include "lib/args.h" +#include "lib/crash.h" #include "lib/joy.h" #include "lib/lib_06440.h" #include "lib/main.h" @@ -195,7 +198,7 @@ #define LINE_3948 3573 #define LINE_4140 3779 #define LINE_4394 4029 -#define LINE_4742 4347 +#define LINE_4742 4377 #define LINE_4801 4436 #endif @@ -418,7 +421,7 @@ s32 pakCreateCameraFile(s8 device, s32 *outfileid) return _pakCreateCameraFile(device, outfileid); } -u32 pakGetType(s8 device) +s32 pakGetType(s8 device) { return _pakGetType(device); } @@ -640,7 +643,7 @@ s32 _pakDeleteFile(s8 device, s32 fileid) u32 result; u32 tmp = pakFindFile(device, fileid, &header); - if (tmp && (!tmp || tmp >= pakGetPdNumBytes(device) || (pakGetBlockSize(device) - 1U & tmp))) { + if (tmp && (!tmp || tmp >= pakGetPdNumBytes(device) || ((pakGetBlockSize(device) - 1U) & tmp))) { return 3; } @@ -1219,19 +1222,17 @@ PakErr1 pakFindNote(OSPfs *pfs, u16 company_code, u32 game_code, char *game_name *file_no = 0; return PAK_ERR1_OK; #else - u8 sp64[8]; + struct pakfileheader header; u32 ret; - u16 sp56[2]; - u32 b; - u16 sp44[4]; + u16 calcedsum[4]; *file_no = 0; - ret = pakReadWriteBlock(SAVEDEVICE_GAMEPAK, 0, 0, 0, 0, align16(0x10), (u8 *)sp56); + ret = pakReadWriteBlock(SAVEDEVICE_GAMEPAK, 0, 0, 0, 0, align16(0x10), (u8 *) &header); if (pakHandleResult(ret, SAVEDEVICE_GAMEPAK, true, LINE_1551)) { - pakCalculateChecksum(sp64, sp64 + sizeof(sp64), sp44); + pakCalculateChecksum((u8 *) &header + 8, (u8 *) (&header + 1), calcedsum); - if (sp56[0] == sp44[0] && sp56[1] == sp44[1]) { + if (header.headersum[0] == calcedsum[0] && header.headersum[1] == calcedsum[1]) { return PAK_ERR1_OK; } @@ -2576,7 +2577,11 @@ void pakCorrupt(void) * * NTSC Beta forgets to include return values. */ +#if VERSION >= VERSION_NTSC_1_0 bool pakCreateInitialFiles(s8 device) +#else +void pakCreateInitialFiles(s8 device) +#endif { struct pakfileheader header; s32 i; @@ -3626,7 +3631,7 @@ bool pakReplaceFileAtOffsetWithBlank(s8 device, u32 offset) return false; } -#if VERSION >= VERSION_NTSC_1_0 +#if !MATCHING || VERSION >= VERSION_NTSC_1_0 s32 pakWriteFileAtOffset(s8 device, u32 offset, u32 filetype, u8 *newdata, s32 bodylenarg, s32 *outfileid, u8 *olddata, u32 fileid, u32 generation) { u8 headerbytes[sizeof(struct pakfileheader)]; @@ -3658,6 +3663,10 @@ s32 pakWriteFileAtOffset(s8 device, u32 offset, u32 filetype, u8 *newdata, s32 b // Build the header bytes on the stack headerptr = (struct pakfileheader *) headerbytes; +#if VERSION < VERSION_NTSC_1_0 + if (headerptr); +#endif + headerptr->fileid = fileid ? fileid : ++g_Paks[device].maxfileid; headerptr->deviceserial = g_Paks[device].serial; headerptr->filelen = filelen; diff --git a/src/game/player.c b/src/game/player.c index a16c411c8..f31a669de 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -9,6 +9,7 @@ #include "game/nbomb.h" #include "game/title.h" #include "game/chr.h" +#include "game/debug.h" #include "game/body.h" #include "game/prop.h" #include "game/propsnd.h" diff --git a/src/game/setuputils.c b/src/game/setuputils.c index 7be7c6838..bb0d25451 100644 --- a/src/game/setuputils.c +++ b/src/game/setuputils.c @@ -6,6 +6,7 @@ #include "game/bg.h" #include "game/modeldef.h" #include "game/propobj.h" +#include "lib/main.h" #include "lib/model.h" #include "bss.h" #include "data.h" diff --git a/src/game/texdecompress.c b/src/game/texdecompress.c index 03584439b..7af45cd07 100644 --- a/src/game/texdecompress.c +++ b/src/game/texdecompress.c @@ -3,10 +3,11 @@ #include "game/tex.h" #include "game/texdecompress.h" #include "bss.h" -#include "lib/rzip.h" +#include "lib/crash.h" #include "lib/dma.h" #include "lib/main.h" #include "lib/memp.h" +#include "lib/rzip.h" #include "data.h" #include "types.h" diff --git a/src/game/title.c b/src/game/title.c index 14519301c..1516e9821 100644 --- a/src/game/title.c +++ b/src/game/title.c @@ -7002,7 +7002,11 @@ Gfx *titleRenderPdLogo(Gfx *gdl) // b74 if (g_PdLogoIsFirstTick) { g_PdLogoYRotCur = 4.2404751777649f; +#if VERSION >= VERSION_PAL_FINAL + g_PdLogoYRotSpeed = PALUPF(0.018846554681659f); +#else g_PdLogoYRotSpeed = 0.018846554681659f; +#endif g_PdLogoXRotCur = 0.47116386890411f; g_PdLogoXRotSpeed = 0.0f; g_PdLogoScale = 0.35f; @@ -7065,7 +7069,11 @@ Gfx *titleRenderPdLogo(Gfx *gdl) g_PdLogoYRotStopping = false; } } else /*e18*/ if (g_PdLogoYRotEnabled) { +#if VERSION >= VERSION_PAL_FINAL + g_PdLogoYRotCur += g_PdLogoYRotSpeed * g_Vars.lvupdate60; +#else g_PdLogoYRotCur += g_PdLogoYRotSpeed * g_Vars.lvupdate60freal; +#endif if (g_PdLogoYRotCur >= M_BADTAU) { g_PdLogoYRotCur -= M_BADTAU; @@ -7076,7 +7084,7 @@ Gfx *titleRenderPdLogo(Gfx *gdl) // e90 if (g_PdLogoPreMorphTimer != 0) { - s32 duration = 80; + s32 duration = TICKS(80); g_PdLogoPreMorphTimer += g_Vars.lvupdate60; @@ -7125,14 +7133,14 @@ Gfx *titleRenderPdLogo(Gfx *gdl) } } - if (g_PdLogoMorphEndTimer > 30 && g_PdLogoMorphEndTimer - g_Vars.lvupdate60 <= 30) { + if (g_PdLogoMorphEndTimer > TICKS(30) && g_PdLogoMorphEndTimer - g_Vars.lvupdate60 <= TICKS(30)) { // Start slowing the spinning rotation g_PdLogoYRotEnabled = false; g_PdLogoYRotStopping = true; g_PdLogoEndYRot = ((s32) (g_PdLogoYRotCur * 4.0f / M_BADTAU) + 2) * M_BADTAU * 0.25f; } - if (g_PdLogoMorphEndTimer > 100 && g_PdLogoMorphEndTimer - g_Vars.lvupdate60 <= 100) { + if (g_PdLogoMorphEndTimer > TICKS(100) && g_PdLogoMorphEndTimer - g_Vars.lvupdate60 <= TICKS(100)) { g_PdLogoDarkenEnabled = true; } @@ -7161,7 +7169,7 @@ Gfx *titleRenderPdLogo(Gfx *gdl) if (g_PdLogoPreTitleTimer != 0) { g_PdLogoPreTitleTimer += g_Vars.lvupdate60; - if (g_PdLogoPreTitleTimer > 20) { + if (g_PdLogoPreTitleTimer > TICKS(20)) { g_PdLogoPreTitleTimer = 0; g_PdLogoPointlessTimerEnabled = true; } @@ -7233,7 +7241,7 @@ Gfx *titleRenderPdLogo(Gfx *gdl) if (g_PdLogoExitTimer != 0) { g_PdLogoExitTimer += g_Vars.lvupdate60; - if (g_PdLogoExitTimer > 60) { + if (g_PdLogoExitTimer > TICKS(60)) { g_PdLogoExitTimer = 0; g_PdLogoTriggerExit = true; } diff --git a/src/game/training.c b/src/game/training.c index 3e6a6b483..d5563718a 100644 --- a/src/game/training.c +++ b/src/game/training.c @@ -1,29 +1,30 @@ #include #include "constants.h" -#include "game/chraction.h" -#include "game/dlights.h" -#include "game/prop.h" -#include "game/propsnd.h" -#include "game/objectives.h" #include "game/atan2f.h" -#include "game/bondgun.h" -#include "game/game_0b0fd0.h" -#include "game/player.h" -#include "game/hudmsg.h" -#include "game/menu.h" -#include "game/filemgr.h" -#include "game/inv.h" -#include "game/explosions.h" -#include "game/game_1531a0.h" #include "game/bg.h" -#include "game/trainingmenus.h" -#include "game/training.h" +#include "game/bondgun.h" +#include "game/chraction.h" +#include "game/debug.h" +#include "game/dlights.h" +#include "game/explosions.h" +#include "game/filemgr.h" +#include "game/game_0b0fd0.h" +#include "game/game_1531a0.h" #include "game/gamefile.h" +#include "game/hudmsg.h" +#include "game/inv.h" #include "game/lang.h" +#include "game/menu.h" +#include "game/objectives.h" #include "game/pad.h" #include "game/padhalllv.h" +#include "game/player.h" +#include "game/prop.h" #include "game/propobj.h" +#include "game/propsnd.h" #include "game/shards.h" +#include "game/training.h" +#include "game/trainingmenus.h" #include "game/wallhit.h" #include "bss.h" #include "lib/vi.h" diff --git a/src/game/vtxstore.c b/src/game/vtxstore.c index 86c5e7a90..fac1397a1 100644 --- a/src/game/vtxstore.c +++ b/src/game/vtxstore.c @@ -1,5 +1,6 @@ #include #include "constants.h" +#include "game/bg.h" #include "game/chraction.h" #include "game/chr.h" #include "game/vtxstore.h" diff --git a/src/include/bss.h b/src/include/bss.h index 505b91a53..33c91f95c 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -287,5 +287,7 @@ extern u8 g_AmBotCommands[16]; extern struct mpsetup g_MpSetup; extern struct bossfile g_BossFile; extern struct chrdata *g_MpBotChrPtrs[MAX_BOTS]; +extern s32 var8009d140jf; +extern s32 var8009d370jf; #endif diff --git a/src/include/game/debug.h b/src/include/game/debug.h index d80e43fd1..12f842e66 100644 --- a/src/include/game/debug.h +++ b/src/include/game/debug.h @@ -9,6 +9,8 @@ u32 dprint(); s32 debug0f11ed70(void); bool debugIsBgRenderingEnabled(void); bool debugIsPropRenderingEnabled(void); +bool debug0f11990cnb(void); +bool debugIsManPosEnabled(void); bool debug0f11edb0(void); bool debugIsObjDeformDebugEnabled(void); bool debugIsRoomStateDebugEnabled(void); @@ -16,6 +18,8 @@ s32 debugIsTurboModeEnabled(void); bool debugForceAllObjectivesComplete(void); bool debugIsZBufferDisabled(void); bool debug0f11ee40(void); +bool debug0f1199f0nb(void); +bool debug0f119a14nb(void); s32 debugGetSlowMotion(void); s32 debugGetTilesDebugMode(void); s32 debugGetPadsDebugMode(void); @@ -23,9 +27,14 @@ bool debug0f11eea8(void); bool debugDangerousProps(void); s32 debugGetMotionBlur(void); bool debugIsFootstepsEnabled(void); +bool debugIsAllChallengesEnabled(void); +bool debugIsAllBuddiesEnabled(void); +bool debugIsSetCompleteEnabled(void); +bool debugIsAllTrainingEnabled(void); bool debugAllowEndLevel(void); bool debugIsChrStatsEnabled(void); bool debug0f11ef80(void); +bool debugIsMemInfoEnabled(void); s32 dmenuGetSelectedOption(void); void dmenuSetSelectedOption(s32 option); diff --git a/src/include/game/lang.h b/src/include/game/lang.h index 84a849068..e2cc7a248 100644 --- a/src/include/game/lang.h +++ b/src/include/game/lang.h @@ -4,6 +4,8 @@ #include "data.h" #include "types.h" +extern u8 *g_LangBuffer; + void langInit(void); void langReset(s32 stagenum); void langTick(void); @@ -16,6 +18,7 @@ void langLoad(s32 bank); void langLoadToAddr(s32 bank, u8 *dst, s32 size); void langClearBank(s32 bank); char *langGet(s32 textid); +void langReload(void); void langSetEuropean(u32 arg0); #endif diff --git a/src/include/game/mplayer/mplayer.h b/src/include/game/mplayer/mplayer.h index 1326c0e0c..ac8332163 100644 --- a/src/include/game/mplayer/mplayer.h +++ b/src/include/game/mplayer/mplayer.h @@ -14,6 +14,8 @@ void func0f187fec(void); void mpPlayerSetDefaults(s32 playernum, bool autonames); void func0f1881d4(s32 index); void mpInit(void); +void mpGetTeamsWithDefaultName(u8 *mask); +void mpSetTeamNamesToDefault(u8 mask); void mpSetDefaultNamesIfEmpty(void); s32 mpCalculateTeamScoreLimit(void); void mpApplyLimits(void); diff --git a/src/include/game/pak.h b/src/include/game/pak.h index 4f95d1fa1..af25246f0 100644 --- a/src/include/game/pak.h +++ b/src/include/game/pak.h @@ -17,7 +17,7 @@ s32 pakSaveAtGuid(s8 device, s32 fileid, s32 filetype, u8 *body, s32 *outfileid, bool pakDeleteFile(s8 device, s32 fileid); s32 pakDeleteGameNote(s8 device, u16 company_code, u32 game_code, char *game_name, char *ext_name); s32 pak0f1168c4(s8 device, struct pakdata **arg1); -u32 pakGetType(s8 device); +s32 pakGetType(s8 device); s32 pakGetSerial(s8 device); void pak0f11698c(s8 device); void pak0f116994(void); @@ -66,6 +66,7 @@ s32 _pakCreateCameraFile(s8 device, s32 *outfileid); bool pakResizeNote(s8 device, s32 numpages); void pak0f1185e0(s8 device, s32 arg1, s32 arg2); u32 pak0f118674(s8 device, u32 filetype, s32 *outfileid); +void pak0f1189d0(void); void paksInit(void); void pakCalculateChecksum(u8 *arg0, u8 *arg1, u16 *arg2); s32 _pakReadBodyAtGuid(s8 device, s32 fileid, u8 *body, s32 arg3); @@ -80,7 +81,13 @@ bool pakWriteBlankFile(s8 device, u32 offset, struct pakfileheader *header); bool pakRepairAsBlank(s8 device, u32 *offset, struct pakfileheader *header); s32 pakRepairFilesystem(s8 device); void pakCorrupt(void); + +#if VERSION >= VERSION_NTSC_1_0 bool pakCreateInitialFiles(s8 device); +#else +void pakCreateInitialFiles(s8 device); +#endif + s32 pakFindMaxFileId(s8 device); void pakMergeBlanks(s8 device); void paksReset(void); diff --git a/src/include/lib/boot.h b/src/include/lib/boot.h index 38c406dc1..10d82748e 100644 --- a/src/include/lib/boot.h +++ b/src/include/lib/boot.h @@ -6,5 +6,6 @@ void bootPhase1(void); s32 bootGetMemSize(void); void *bootAllocateStack(s32 threadid, s32 size); void bootPhase2(void *arg); +void bootCheckStackOverflow(void); #endif diff --git a/src/include/lib/sched.h b/src/include/lib/sched.h index f38910a9f..8fe290e25 100644 --- a/src/include/lib/sched.h +++ b/src/include/lib/sched.h @@ -2,6 +2,7 @@ #define _IN_BOOT_SCHED_H #include #include +#include "types.h" void schedSetCrashEnable2(s32 enable); void schedAppendTasks(OSSched *sc, OSScTask *t); @@ -21,5 +22,6 @@ void schedIncrementWriteArtifacts(void); void schedIncrementFrontArtifacts(void); void schedUpdatePendingArtifacts(void); void schedConsiderScreenshot(void); +void schedSetCrashedUnexpectedly(bool enable); #endif diff --git a/src/include/types.h b/src/include/types.h index 7e2cf12c8..450ac74e9 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -5120,27 +5120,6 @@ struct var800aabb4 { /*0x00*/ u32 unk00; /*0x04*/ u32 unk04; /*0x08*/ u32 unk08; - /*0x0c*/ u32 unk0c; - /*0x10*/ u32 unk10; - /*0x14*/ u32 unk14; - /*0x18*/ u32 unk18; - /*0x1c*/ u32 unk1c; - /*0x20*/ u32 unk20; - /*0x24*/ u32 unk24; - /*0x28*/ u32 unk28; - /*0x2c*/ u32 unk2c; - /*0x30*/ u32 unk30; - /*0x34*/ u32 unk34; - /*0x38*/ u32 unk38; - /*0x3c*/ u32 unk3c; - /*0x40*/ u32 unk40; - /*0x44*/ u32 unk44; - /*0x48*/ u32 unk48; - /*0x4c*/ u32 unk4c; - /*0x50*/ u32 unk50; - /*0x54*/ u32 unk54; - /*0x58*/ u32 unk58; - /*0x5c*/ u32 unk5c; }; struct var800aabb8 { diff --git a/src/lib/crash.c b/src/lib/crash.c index f3e39783d..476ad8cd6 100644 --- a/src/lib/crash.c +++ b/src/lib/crash.c @@ -6,6 +6,8 @@ #include "lib/crash.h" #include "lib/dma.h" #include "lib/rmon.h" +#include "lib/sched.h" +#include "lib/str.h" #include "lib/vi.h" #include "data.h" #include "types.h" @@ -231,9 +233,9 @@ u32 var8009710cnb; char *var80097110nb; char *var80097114nb; u32 var80097118nb[24]; -u8 var80097178nb[MAX_LINES + 1][71]; +char var80097178nb[MAX_LINES + 1][71]; #elif VERSION == VERSION_PAL_BETA -u8 var80097178nb[MAX_LINES + 1][71]; +char var80097178nb[MAX_LINES + 1][71]; #endif /** diff --git a/src/lib/debughud.c b/src/lib/debughud.c index 3bf38968a..d7e1eb921 100644 --- a/src/lib/debughud.c +++ b/src/lib/debughud.c @@ -2,6 +2,7 @@ #include "constants.h" #include "bss.h" #include "lib/debughud.h" +#include "lib/vi.h" #include "game/gfxmemory.h" #include "data.h" #include "types.h" diff --git a/src/lib/dma.c b/src/lib/dma.c index 1244f853f..056342195 100644 --- a/src/lib/dma.c +++ b/src/lib/dma.c @@ -1,6 +1,7 @@ #include #include "constants.h" #include "bss.h" +#include "lib/crash.h" #include "lib/dma.h" #include "data.h" #include "types.h" diff --git a/src/lib/main.c b/src/lib/main.c index 40fe387fa..e644f92a9 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -311,7 +311,7 @@ extern u8 _copyrightSegmentRomStart; extern u8 _copyrightSegmentRomEnd; extern u8 _bssSegmentEnd; -#if VERSION >= VERSION_NTSC_1_0 +#if !MATCHING || VERSION >= VERSION_NTSC_1_0 /** * Initialise various subsystems, display the copyright or accessing pak texture, * then initialise more subsystems. @@ -354,14 +354,17 @@ void mainInit(void) joyDebugJoy(); } +#if VERSION >= VERSION_NTSC_1_0 if (1); if (1); +#endif } if (argFindByPrefix(1, "-level_") == NULL) { var8005d9b0 = true; } +#if VERSION >= VERSION_NTSC_1_0 // If holding start on any controller, open boot pak menu if (joyGetButtons(0, START_BUTTON) == 0 && joyGetButtons(1, START_BUTTON) == 0 @@ -522,6 +525,115 @@ void mainInit(void) } #endif +#else + // NTSC beta + if (osTvType != OS_TV_NTSC) { + var8005d9b0 = true; + + while (1); + } + + if (joyGetButtons(0, START_BUTTON) == 0 + && joyGetButtons(1, START_BUTTON) == 0 + && joyGetButtons(2, START_BUTTON) == 0 + && joyGetButtons(3, START_BUTTON) == 0) { + OSMesg receivedmsg = NULL; + OSScMsg scdonemsg = { OS_SC_DONE_MSG }; + u8 scratch[1024 * 5]; + u16 *texture; + s32 numpages; + + g_DoBootPakMenu = false; + + // Choose where to place the temporary framebuffer. + // In 4MB mode, place it close to the end of memory, + // but before the thread stacks and VM system. + // In 8MB mode, put it at the end of the expansion pak. + if (osGetMemSize() <= 4 * 1024 * 1024) { + addr = K0BASE + 4 * 1024 * 1024; + addr -= STACKSIZE_MAIN; + addr -= STACKSIZE_IDLE; + addr -= STACKSIZE_RMON; + addr -= STACKSIZE_SCHED; + addr -= STACKSIZE_AUDIO; + addr -= g_VmNumPages * 8; // vm state table + addr -= 266 * 4096; // vm loaded pages buffer + addr -= addr % 0x2000; // align down to a multiple of 0x2000 + addr -= 0x1c80; // buffer for single biggest game zip + } else { + addr = K0BASE + 8 * 1024 * 1024; + } + + addr -= 640 * 480 * 2; // the framebuffer itself + addr -= 0x40; // align down to a multiple of 0x40 + + fb = (u16 *) ALIGN64(PHYS_TO_K0(addr)); + + // Prepare space for the unzipped texture immediately before the framebuffer. + // Both textures are 507x48. + texture = fb - 507 * 48; + + // DMA the compressed texture from the ROM to the framebuffer. + // It's using the framebuffer as a temporary data buffer. + start = &_copyrightSegmentRomStart; + end = &_copyrightSegmentRomEnd; + dmaExec(fb, (u32) start, end - start); + + // Unzip the compressed texture from fb to texture + rzipInflate(fb, texture, scratch); + + // Clear the framebuffer except for the bottom 48 rows, + // because that's where the texture will go. + // The increment here is too small, so some pixels are zeroed twice. + for (dsty = 0; dsty < (480 - 48) * 640; dsty += 576) { + for (x = 0; x < 640; x++) { + fb[dsty + x] = 0; + } + + if (1); + } + + // Copy the texture to the framebuffer. + // The framebuffer will be displayed at 576 wide, + // and the texture is right aligned. + dsty = 0; + + for (srcy = 0; srcy < 507 * 48; srcy += 507) { + for (x = 0; x < 507; x++) { + fb[dsty + (576 - 507) + x] = texture[srcy + x]; + } + + dsty += 576; + } + + viSetMode(VIMODE_HI); + viConfigureForCopyright(fb); + + g_RdpOutBufferStart = texture; + g_RdpOutBufferEnd = texture + 0x400; // 0x800 bytes, because texture is u16 + + while (osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_NOBLOCK) == 0) { + if (i); + } + + i = 0; + + while (i < 6) { + osRecvMesg(&g_SchedMesgQueue, &receivedmsg, OS_MESG_BLOCK); + + j = (s32) &scdonemsg; + + if (*(s16 *) receivedmsg == 1) { + viUpdateMode(); + rdpCreateTask(var8005dcc8, var8005dcf0, 0, (void *) j); + i++; + } + } + } else { + g_DoBootPakMenu = true; + } +#endif + vmInit(); func0f1a78b0(); filesInit(); @@ -1040,7 +1152,7 @@ void mainLoop(void) s32 numplayers; u32 stack; -#if VERSION < VERSION_NTSC_1_0 +#if VERSION < VERSION_NTSC_1_0 && MATCHING if ((ptr[0] != 'OJ' && ptr[0] != 'LS' && ptr[0] != 'PM' && ptr[0] != 'MP') || (ptr[1] != 'FS' && ptr[1] != 'RE')) { fail = true; diff --git a/src/lib/mema.c b/src/lib/mema.c index 662e4f3ad..8753675ba 100644 --- a/src/lib/mema.c +++ b/src/lib/mema.c @@ -1,6 +1,7 @@ #include #include "constants.h" #include "bss.h" +#include "game/debug.h" #include "lib/debughud.h" #include "lib/mema.h" #include "lib/memp.h" diff --git a/src/lib/memp.c b/src/lib/memp.c index ed8fe9428..aeba8348d 100644 --- a/src/lib/memp.c +++ b/src/lib/memp.c @@ -2,6 +2,7 @@ #include "constants.h" #include "bss.h" #include "lib/boot.h" +#include "lib/crash.h" #include "lib/memp.h" #include "data.h" #include "types.h" diff --git a/src/lib/music.c b/src/lib/music.c index 875793350..0169db55e 100644 --- a/src/lib/music.c +++ b/src/lib/music.c @@ -72,6 +72,21 @@ s32 musicHandlePlayEvent(struct musicevent *event, s32 result) if (result == RESULT_FAIL) { // Find an unused channel for (i = 0; i < 3; i++) { + /** + * @bug: When adding a new track, the seqp's state remains at AL_STOPPED + * and is only changed to AL_PLAYING once the audio thread has run. + * Scheduling two sequences in quick succession will cause it to choose + * the same sequence player if the audio thread hasn't run between + * the two calls and updated the state. + * + * With IDO, the compiled code is so inefficient that the audio thread + * is likely to run between two consecutive calls. However it does + * still happen occasionally. Eg. sometimes when unpausing the stage's + * main theme does not resume. + * + * For GCC, it's more likely to occur, so we introduce a new state: + * AL_STARTING. This is assigned to the sequence player in seqPlay. + */ if (n_alCSPGetState(g_SeqInstances[i].seqp) == AL_STOPPED) { osSyncPrintf("MUSIC(Play) : Starting, Guid=%u, Midi=%d, Tune=%d\n", event->id, 0, event->tracktype); @@ -905,9 +920,11 @@ void musicTickEvents(void) for (i = g_MusicEventQueueLength - 1; i >= 0; i--) { event = &g_MusicEventQueue[i]; +#if VERSION >= VERSION_NTSC_1_0 if (event->eventtype == MUSICEVENTTYPE_5) { continue; } +#endif if (event->tracktype == TRACKTYPE_NONE) { continue; @@ -921,9 +938,11 @@ void musicTickEvents(void) continue; } +#if VERSION >= VERSION_NTSC_1_0 if (earlier->eventtype == MUSICEVENTTYPE_5) { continue; } +#endif if (earlier->tracktype == TRACKTYPE_NONE) { continue; @@ -977,22 +996,26 @@ void musicTickEvents(void) switch (event->eventtype) { case MUSICEVENTTYPE_PLAY: - result = musicHandlePlayEvent(event, 0); + result = musicHandlePlayEvent(event, result); break; case MUSICEVENTTYPE_STOP: - result = musicHandleStopEvent(event, 0); + result = musicHandleStopEvent(event, result); break; case MUSICEVENTTYPE_FADE: - result = musicHandleFadeEvent(event, 0); + result = musicHandleFadeEvent(event, result); break; case MUSICEVENTTYPE_STOPALL: - result = musicHandleStopAllEvent(0); + result = musicHandleStopAllEvent(result); break; +#if VERSION >= VERSION_NTSC_1_0 case MUSICEVENTTYPE_5: - result = musicHandleEvent5(event, 0); + result = musicHandleEvent5(event, result); break; +#endif } + if (result); + if (result != RESULT_FAIL) { // Remove the item from the queue g_MusicEventQueueLength--; diff --git a/src/lib/snd.c b/src/lib/snd.c index bcf6ba43d..b7d15ce5d 100644 --- a/src/lib/snd.c +++ b/src/lib/snd.c @@ -8,6 +8,7 @@ #include "lib/rzip.h" #include "lib/args.h" #include "lib/audiomgr.h" +#include "lib/crash.h" #include "lib/dma.h" #include "lib/snd.h" #include "lib/memp.h" @@ -1641,6 +1642,14 @@ bool seqPlay(struct seqinstance *seq, s32 tracknum) } #endif +#if AVOID_UB + // To avoid undefined behaviour, we must change the sequence player's state + // from AL_STOPPED to something else. Otherwise a race condition can occur + // where the same sequence player is used for two sequences if the audio + // thread hasn't run between the two calls and updated its state. + seq->seqp->state = AL_STARTING; +#endif + n_alCSeqNew(&seq->seq, seq->data); n_alCSPSetSeq(seq->seqp, &seq->seq); seqSetVolume(seq, seqGetVolume(seq)); diff --git a/src/lib/ultra/io/pfsinitpak.c b/src/lib/ultra/io/pfsinitpak.c index db2c89bce..ff8343c86 100644 --- a/src/lib/ultra/io/pfsinitpak.c +++ b/src/lib/ultra/io/pfsinitpak.c @@ -1,5 +1,6 @@ #include "versions.h" #include +#include "lib/rmon.h" #include "controller.h" #include "siint.h" diff --git a/src/lib/ultra/libc/llcvt.c b/src/lib/ultra/libc/llcvt.c index ce6797516..b60482f82 100644 --- a/src/lib/ultra/libc/llcvt.c +++ b/src/lib/ultra/libc/llcvt.c @@ -15,6 +15,7 @@ long long __f_to_ll(float f) } #if VERSION < VERSION_NTSC_1_0 +#if MATCHING GLOBAL_ASM( glabel __d_to_ull /* 5ad8: 444ef800 */ cfc1 $t6,$31 @@ -60,11 +61,12 @@ glabel __d_to_ull /* 5b6c: 03e00008 */ jr $ra /* 5b70: 0002103f */ dsra32 $v0,$v0,0x0 ); - -//unsigned long long __d_to_ull(double d) -//{ -// return d; -//} +#else +unsigned long long __d_to_ull(double d) +{ + return d; +} +#endif #endif #if MATCHING @@ -135,6 +137,7 @@ float __ll_to_f(long long s) #endif #if VERSION < VERSION_NTSC_1_0 +#if MATCHING GLOBAL_ASM( glabel __ull_to_d /* 5c40: afa40000 */ sw $a0,0x0($sp) @@ -151,11 +154,12 @@ glabel __ull_to_d /* 5c68: 03e00008 */ jr $ra /* 5c6c: 00000000 */ sll $zero,$zero,0x0 ); - -//double __ull_to_d(unsigned long long u) -//{ -// return u; -//} +#else +double __ull_to_d(unsigned long long u) +{ + return u; +} +#endif #endif float __ull_to_f(unsigned long long u) diff --git a/src/lib/vi.c b/src/lib/vi.c index ce310d45d..f5385b0f0 100644 --- a/src/lib/vi.c +++ b/src/lib/vi.c @@ -6,6 +6,7 @@ #include "game/file.h" #include "game/game_176080.h" #include "game/gfxmemory.h" +#include "game/menu.h" #include "game/options.h" #include "bss.h" #include "lib/vi.h" diff --git a/src/lib/vm.c b/src/lib/vm.c index bb88d7177..6fa693e4b 100644 --- a/src/lib/vm.c +++ b/src/lib/vm.c @@ -3,6 +3,7 @@ #include "constants.h" #include "bss.h" #include "lib/boot.h" +#include "lib/crash.h" #include "lib/rzip.h" #include "lib/dma.h" #include "lib/lib_48150.h" @@ -105,7 +106,11 @@ extern u32 *g_VmZipTable; #define PAGE_SIZE (1024 * 4) +#if VERSION >= VERSION_NTSC_1_0 #define MAX_LOADED_PAGES 268 +#else +#define MAX_LOADED_PAGES 266 +#endif #if MATCHING #if VERSION >= VERSION_NTSC_1_0 @@ -671,7 +676,7 @@ glabel vmInit /* 75c4: 3c01803f */ lui $at,0x803f /* 75c8: 342150c1 */ ori $at,$at,0x50c1 /* 75cc: 0301082b */ sltu $at,$t8,$at -/* 75d0: 3c117f00 */ lui $s1,%hi(_gameSegmentStart) +/* 75d0: 3c117f00 */ lui $s1,0x7f00 /* 75d4: 10200018 */ beqz $at,.NB00007638 /* 75d8: 24100002 */ addiu $s0,$zero,0x2 /* 75dc: 3c160001 */ lui $s6,0x1 @@ -707,7 +712,7 @@ glabel vmInit /* 764c: ac2030ec */ sw $zero,%lo(g_VmNumPageReplaces)($at) /* 7650: 00002025 */ or $a0,$zero,$zero /* 7654: 0c012548 */ jal osInvalICache -/* 7658: 24054000 */ addiu $a1,$zero,%lo(_gameSegmentEnd) +/* 7658: 24054000 */ addiu $a1,$zero,0x4000 /* 765c: 8fbf0074 */ lw $ra,0x74($sp) /* 7660: 8fb00054 */ lw $s0,0x54($sp) /* 7664: 8fb10058 */ lw $s1,0x58($sp) @@ -803,7 +808,12 @@ void vmInit(void) rzipInit(); - if (bootGetMemSize() <= 0x400000) { +#if VERSION >= VERSION_NTSC_1_0 + if (bootGetMemSize() <= 0x400000) +#else + if (osGetMemSize() <= 0x400000) +#endif + { u32 t8; u32 sp1474; u32 stackstart; @@ -811,7 +821,11 @@ void vmInit(void) g_Is4Mb = true; +#if VERSION >= VERSION_NTSC_1_0 stackstart = STACK_START - 8; +#else + stackstart = STACK_START; +#endif g_VmNumPages = (s32)((&_gameSegmentEnd - &_gameSegmentStart) + (PAGE_SIZE - 1)) / PAGE_SIZE; @@ -857,8 +871,14 @@ void vmInit(void) ptr = g_VmStateTable; statetablelen = (g_VmNumPages * 8) >> 2; - for (i = 0; i < statetablelen; i++) { // s1 - ptr[i] = 0; + { +#if VERSION < VERSION_NTSC_1_0 + s32 i; +#endif + + for (i = 0; i < statetablelen; i++) { // s1 + ptr[i] = 0; + } } tlb0000113c(); @@ -867,7 +887,11 @@ void vmInit(void) g_Is4Mb = false; t8 = (u32)((&_gameSegmentEnd - &_gameSegmentStart) + (PAGE_SIZE - 1)) / PAGE_SIZE; - s7 = (u8 *)(STACK_START - 8); +#if VERSION >= VERSION_NTSC_1_0 + s7 = (u8 *) (STACK_START - 8); +#else + s7 = (u8 *) STACK_START; +#endif gameseg = (u8 *) ((u32) (s7 - (u8 *) ALIGN64((u32) &_gameSegmentEnd - (u32) &_gameSegmentStart)) & 0xfffe0000); s5 = (u32 *) (((u32) gameseg - ((t8 + 5) << 2)) & ~0xf); @@ -887,10 +911,34 @@ void vmInit(void) chunkbuffer = (u8 *) ((u32)s5 - PAGE_SIZE * 2); zip = chunkbuffer + 2; +#if VERSION >= VERSION_NTSC_1_0 for (i = 0; i < sp1474 - 1; i++) { \ dmaExec(chunkbuffer, s5[i], ALIGN16(s5[i + 1] - s5[i])); \ s2 += rzipInflate(zip, s2, sp68); } +#else + for (i = 0; i < sp1474 - 1; i++) { + s32 len; + char spa8[128]; + + dmaExec(chunkbuffer, s5[i], ALIGN16(s5[i + 1] - s5[i])); + + len = rzipInflate(zip, s2, sp68); + + if (len == 0) { + sprintf(spa8, "DMA-Crash %s %d Ram: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + "vm_m.c", 298, + chunkbuffer[0], chunkbuffer[1], chunkbuffer[2], chunkbuffer[3], + chunkbuffer[4], chunkbuffer[5], chunkbuffer[6], chunkbuffer[7], + chunkbuffer[8], chunkbuffer[9], chunkbuffer[10], chunkbuffer[11], + chunkbuffer[12], chunkbuffer[13], chunkbuffer[14], chunkbuffer[15]); + crashSetMessage(spa8); + CRASH(); + } + + s2 += len; + } +#endif // This loop sets the following TLB entries: // entry 2: 0x7f000000 to 0x7f010000 and 0x7f010000 to 0x7f020000