diff --git a/res/fp/flag_icons.png b/res/fp/flag_icons.png index f845ee77..f0108b85 100644 Binary files a/res/fp/flag_icons.png and b/res/fp/flag_icons.png differ diff --git a/src/commands.c b/src/commands.c index 4b4419a6..14862ded 100644 --- a/src/commands.c +++ b/src/commands.c @@ -227,6 +227,11 @@ void commandImportSaveProc(void) { } void commandSaveGameProc(void) { + pm_gCurrentSaveFile.globalBytes[GB_MARIO_PEACH] = pm_gGameStatus.peachFlags & 1; + pm_gCurrentSaveFile.globalBytes[GB_USING_PARTNER] = + pm_gPartnerStatus.partnerActionState && + (pm_gPlayerData.currentPartner == PARTNER_WATT || pm_gPlayerData.currentPartner == PARTNER_SUSHIE || + pm_gPlayerData.currentPartner == PARTNER_LAKILESTER); pm_entity_SaveBlock_save_data(); pm_sfx_play_sound(0x10); fpLog("saved to slot %d", pm_gGameStatus.saveSlot); @@ -245,6 +250,11 @@ void commandLoadGameProc(void) { if (pm_fio_validate_globals_checksums(file)) { pm_gCurrentSaveFile = *file; pm_fio_deserialize_state(); + pm_gGameStatus.peachFlags = (pm_gGameStatus.peachFlags & ~1) | pm_gCurrentSaveFile.globalBytes[GB_MARIO_PEACH]; + if (pm_gCurrentSaveFile.globalBytes[GB_USING_PARTNER] && !(pm_gGameStatus.peachFlags & 1)) { + pm_gPartnerStatus.partnerActionState = 1; + pm_gGameStatus.keepUsingPartnerOnMapChange = 1; + } fpWarp(file->areaID, file->mapID, file->entryID); fpLog("loaded from slot %d", pm_gGameStatus.saveSlot); } else { diff --git a/src/fp.c b/src/fp.c index cf63fed9..ee13ccb6 100644 --- a/src/fp.c +++ b/src/fp.c @@ -74,6 +74,7 @@ void fpInit(void) { menuAddSubmenu(fp.mainMenu, 0, menuIndex++, &watches, "watches"); menuAddSubmenu(fp.mainMenu, 0, menuIndex++, createDebugMenu(), "debug"); menuAddSubmenu(fp.mainMenu, 0, menuIndex++, createSettingsMenu(), "settings"); + menuAddSubmenu(fp.mainMenu, 0, menuIndex++, createAboutMenu(), "about"); // populate watches menu watches.selector = menuAddSubmenu(&watches, 0, 0, NULL, "return"); @@ -172,8 +173,6 @@ void fpEmergencySettingsReset(u16 padPressed) { } } -#define STRINGIFY(S) STRINGIFY_(S) -#define STRINGIFY_(S) #S void fpDrawVersion(struct GfxFont *font, s32 cellWidth, s32 cellHeight, u8 menuAlpha) { static struct GfxTexture *fpIconTex; if (pm_gGameStatus.introState == 5) { @@ -304,7 +303,7 @@ void fpUpdateCheats(void) { if (CHEAT_ACTIVE(CHEAT_FP)) { pm_gPlayerData.curFP = pm_gPlayerData.curMaxFP; } - if (CHEAT_ACTIVE(CHEAT_ATTACK)) { + if (CHEAT_ACTIVE(CHEAT_POWER)) { pm_gBattleStatus.merleeAttackBoost = 127; } if (CHEAT_ACTIVE(CHEAT_COINS)) { diff --git a/src/fp.h b/src/fp.h index c168fc6a..dd6fe204 100644 --- a/src/fp.h +++ b/src/fp.h @@ -91,9 +91,10 @@ struct Menu *createCheatsMenu(void); struct Menu *createPlayerMenu(void); struct Menu *createFileMenu(void); struct Menu *createPracticeMenu(void); +struct Menu *createCameraMenu(void); struct Menu *createDebugMenu(void); struct Menu *createSettingsMenu(void); -struct Menu *createCameraMenu(void); +struct Menu *createAboutMenu(void); #define CHEAT_ACTIVE(cheat) (settings->cheats & (1 << cheat)) diff --git a/src/fp/file/fp_file.c b/src/fp/file/fp_file.c index 94197cfa..2ee732f3 100644 --- a/src/fp/file/fp_file.c +++ b/src/fp/file/fp_file.c @@ -120,6 +120,11 @@ s32 fpImportFile(const char *path, void *data) { if (pm_fio_validate_globals_checksums(file)) { pm_gCurrentSaveFile = *file; pm_fio_deserialize_state(); + pm_gGameStatus.peachFlags |= pm_gCurrentSaveFile.globalBytes[GB_MARIO_PEACH]; + if (pm_gCurrentSaveFile.globalBytes[GB_USING_PARTNER] && !(pm_gGameStatus.peachFlags & 1)) { + pm_gPartnerStatus.partnerActionState = 1; + pm_gGameStatus.keepUsingPartnerOnMapChange = 1; + } fpWarp(file->areaID, file->mapID, file->entryID); } else { fpLog("save file corrupt"); @@ -236,8 +241,8 @@ struct Menu *createFileMenu(void) { y++; menuAddStatic(&menu, 0, y, "quizmo", 0xC0C0C0); - struct MenuItem *quizmoInput = - menuAddIntinput(&menu, menuX, y++, 10, 2, menuByteModProc, &pm_gCurrentSaveFile.globalBytes[0x161]); + struct MenuItem *quizmoInput = menuAddIntinput(&menu, menuX, y++, 10, 2, menuByteModProc, + &pm_gCurrentSaveFile.globalBytes[GB_COMPLETED_QUIZZES]); menuItemAddChainLink(quizmoInput, progressInput, MENU_NAVIGATE_UP); menuAddStatic(&menu, 0, y, "toy box 1", 0xC0C0C0); menuAddOption(&menu, menuX, y++, diff --git a/src/fp/fp_about.c b/src/fp/fp_about.c new file mode 100644 index 00000000..f413cea1 --- /dev/null +++ b/src/fp/fp_about.c @@ -0,0 +1,32 @@ +#include "fp.h" +#include "menu/menu.h" + +struct Menu *createAboutMenu(void) { + static struct Menu menu; + menuInit(&menu, MENU_NOVALUE, MENU_NOVALUE, MENU_NOVALUE); + + s32 y = 0; + menu.selector = menuAddSubmenu(&menu, 0, y++, NULL, "return"); + menuAddStatic(&menu, 0, y++, "fp version:", 0xC0C0C0); + menuAddStatic(&menu, 0, y++, STRINGIFY(FP_VERSION), 0xFF0000); + y++; + menuAddStatic(&menu, 0, y++, "manual:", 0xC0C0C0); + menuAddStatic(&menu, 0, y++, "https://fp-docs.starhaven.dev/", 0x99C3FF); + y++; + menuAddStatic(&menu, 0, y++, "github:", 0xC0C0C0); + menuAddStatic(&menu, 0, y++, "https://github.com/JCog/fp", 0x99C3FF); + s32 creditY = ++y; + menuAddStatic(&menu, 0, y++, "contributors:", 0xC0C0C0); + menuAddStatic(&menu, 0, y++, "JCog", 0xFFFFFF); + menuAddStatic(&menu, 0, y++, "imaandrew", 0xFFFFFF); + menuAddStatic(&menu, 0, y++, "fig02", 0xFFFFFF); + menuAddStatic(&menu, 0, y++, "Rainchus", 0xFFFFFF); + menuAddStatic(&menu, 0, y++, "rnadrich", 0xFFFFFF); + y = creditY; + s32 xOffset = 15; + menuAddStatic(&menu, xOffset, y++, "special thanks:", 0xC0C0C0); + menuAddStatic(&menu, xOffset, y++, "glankk", 0xFFFFFF); + menuAddStatic(&menu, xOffset, y++, "krimtonz", 0xFFFFFF); + + return &menu; +} diff --git a/src/fp/fp_cheats.c b/src/fp/fp_cheats.c index 3b5aa62b..e4f9449a 100644 --- a/src/fp/fp_cheats.c +++ b/src/fp/fp_cheats.c @@ -3,7 +3,7 @@ #include "sys/settings.h" static const char *labels[] = { - "hp", "fp", "attack", "coins", "star power", "star pieces", + "hp", "fp", "power", "coins", "star power", "star pieces", "peril", "auto mash", "action commands", "power bounce", "peekaboo", "brighten room", "hide hud", "mute music", "quizmo spawns", }; diff --git a/src/fp/practice/trainer.c b/src/fp/practice/trainer.c index c6f2fd84..b2793cef 100644 --- a/src/fp/practice/trainer.c +++ b/src/fp/practice/trainer.c @@ -181,10 +181,15 @@ static s32 trainerPositionProc(struct MenuItem *item, enum MenuCallbackReason re } static void lzsDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) { + if (!fp.menuActive) { + u32 colorBlackT = GPACK_RGB24A8(0x000000, 0x60); + gfxTextBackgroundDraw(x, y, 12, 2, chWidth, chHeight, colorBlackT); + } + gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); s32 menuY = 0; - gfxPrintf(font, x, y + chHeight * menuY++, "current lzs jumps: %d", lzsCurrentJumps); - gfxPrintf(font, x, y + chHeight * menuY++, "record lzs jumps: %d", lzsRecordJumps); + gfxPrintf(font, x, y + chHeight * menuY++, "current: %d", lzsCurrentJumps); + gfxPrintf(font, x, y + chHeight * menuY++, "record: %d", lzsRecordJumps); } static s32 lzsDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { @@ -217,6 +222,7 @@ static void spinDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeig // black background s32 bgY = y - 11; s32 bgHeight = 0; + s32 bgWidth = 88; u8 count = 0; if (settings->trainerSpinJumpTiming) { count++; @@ -240,10 +246,7 @@ static void spinDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeig if (bgHeight > 0) { bgHeight += 3; } - gfxModeSet(GFX_MODE_COLOR, colorBlackT); - gfxModeReplace(GFX_MODE_COMBINE, G_CC_MODE(G_CC_PRIMITIVE, G_CC_PRIMITIVE)); - gfxDisp(gsSPScisTextureRectangle(qs102(x - 2), qs102(bgY), qs102(x + 86), qs102(bgY + bgHeight), 0, 0, 0, 0, 0)); - gfxModePop(GFX_MODE_COMBINE); + gfxRectangleDraw(x - 2, bgY, bgWidth, bgHeight, colorBlackT); s32 textX = x + 17; s32 textY = y; @@ -345,8 +348,6 @@ static void spinDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeig } static void issDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) { - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); - s32 xPos = ceil(pm_gPlayerStatus.position.x); s32 zPos = ceil(pm_gPlayerStatus.position.z); bool goodPos = FALSE; @@ -371,8 +372,12 @@ static void issDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeigh u32 colorYellow = GPACK_RGB24A8(0xFFFF00, 0xFF); u32 colorRed = GPACK_RGB24A8(0xFF0000, 0xFF); u32 colorWhite = GPACK_RGB24A8(0xFFFFFF, 0xFF); - s32 menuY = 0; + u32 colorBlackT = GPACK_RGB24A8(0x000000, 0x60); + + gfxTextBackgroundDraw(x, y, 19, 4, chWidth, chHeight, colorBlackT); + s32 menuY = 0; + gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); gfxPrintf(font, x, y + chHeight * menuY++, "x: %.4f", pm_gPlayerStatus.position.x); gfxPrintf(font, x, y + chHeight * menuY++, "z: %.4f", pm_gPlayerStatus.position.z); gfxPrintf(font, x, y + chHeight * menuY, "angle:"); @@ -403,7 +408,6 @@ static s32 issDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) } static void aceDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) { - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); s32 effectCount = 0; s32 i; for (i = 0; i < 96; i++) { @@ -415,7 +419,13 @@ static void aceDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeigh u32 colorGreen = GPACK_RGB24A8(0x00FF00, 0xFF); u32 colorRed = GPACK_RGB24A8(0xFF0000, 0xFF); u32 colorWhite = GPACK_RGB24A8(0xFFFFFF, 0xFF); + u32 colorBlackT = GPACK_RGB24A8(0x000000, 0x60); + if (!fp.menuActive) { + gfxTextBackgroundDraw(x, y, 17, 3, chWidth, chHeight, colorBlackT); + } + + gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); gfxPrintf(font, x + chWidth * 0, y + chHeight * 0, "effects:"); gfxPrintf(font, x + chWidth * 0, y + chHeight * 1, "flags:"); gfxPrintf(font, x + chWidth * 0, y + chHeight * 2, "frame window:"); @@ -930,10 +940,12 @@ void trainerDrawSpinBar(s32 x, s32 y, struct GfxFont *font, u32 color, u8 alpha) } barWidth *= barMult; barGoal *= barMult; + u16 bgHeight = 34; + u16 markerWidth = 2; u16 barX = x - barWidth / 2; u16 barGoalX = barX + barGoal; - u16 barFullX = barX + spinFrame * barMult; - u16 barYBottom = y + 10; + u16 barFullWidth = spinFrame * barMult; + u16 barHeight = 10; s32 iconY = y + 12; s32 textY = iconY + 11; @@ -942,28 +954,11 @@ void trainerDrawSpinBar(s32 x, s32 y, struct GfxFont *font, u32 color, u8 alpha) s32 delayIconX = x + 2; s32 delayTextX = delayIconX + 17; - // draw background - gfxModeSet(GFX_MODE_COLOR, colorBlackT); - gfxModeReplace(GFX_MODE_COMBINE, G_CC_MODE(G_CC_PRIMITIVE, G_CC_PRIMITIVE)); - gfxDisp(gsSPScisTextureRectangle(qs102(barX - 4), qs102(y - 4), qs102(barX + barWidth + 4), qs102(y + 30), 0, 0, 0, - 0, 0)); - - // draw bar - // background - gfxModeSet(GFX_MODE_COLOR, colorBackground); - gfxDisp(gsSPScisTextureRectangle(qs102(barX - 1), qs102(y - 1), qs102(barX + barWidth + 1), qs102(barYBottom + 1), - 0, 0, 0, 0, 0)); - // empty bar - gfxModeSet(GFX_MODE_COLOR, colorEmpty); - gfxDisp(gsSPScisTextureRectangle(qs102(barX), qs102(y), qs102(barX + barWidth), qs102(barYBottom), 0, 0, 0, 0, 0)); - // full bar - gfxModeSet(GFX_MODE_COLOR, colorFull); - gfxDisp(gsSPScisTextureRectangle(qs102(barX), qs102(y), qs102(barFullX), qs102(barYBottom), 0, 0, 0, 0, 0)); - // goal marker - gfxModeSet(GFX_MODE_COLOR, colorYellow); - gfxDisp( - gsSPScisTextureRectangle(qs102(barGoalX - 1), qs102(y), qs102(barGoalX + 1), qs102(barYBottom), 0, 0, 0, 0, 0)); - gfxModePop(GFX_MODE_COMBINE); + gfxRectangleDraw(barX - 4, y - 4, barWidth + 8, bgHeight, colorBlackT); // background + gfxRectangleDraw(barX - 1, y - 1, barWidth + 2, barHeight + 2, colorBackground); // bar + gfxRectangleDraw(barX, y, barWidth, barHeight, colorEmpty); // empty bar + gfxRectangleDraw(barX, y, barFullWidth, barHeight, colorFull); // full bar + gfxRectangleDraw(barGoalX - 1, y, markerWidth, barHeight, colorYellow); // goal marker gfxModeSet(GFX_MODE_COLOR, colorWhite); gfxModeReplace(GFX_MODE_DROPSHADOW, 0); diff --git a/src/macros.h b/src/macros.h index 7a817ffb..f8398586 100644 --- a/src/macros.h +++ b/src/macros.h @@ -16,4 +16,7 @@ #define SQ(x) ((x) * (x)) +#define STRINGIFY(S) STRINGIFY_H(S) +#define STRINGIFY_H(S) #S + #endif // MACROS_H diff --git a/src/pm64.h b/src/pm64.h index d5908200..8a6ba411 100644 --- a/src/pm64.h +++ b/src/pm64.h @@ -5,13 +5,17 @@ #include #include -#define JP 0x00 -#define US 0x01 +#define JP 0x00 +#define US 0x01 -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 240 +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 -#define ICON_PALETTE_SIZE 32 +#define ICON_PALETTE_SIZE 32 + +#define GB_COMPLETED_QUIZZES 0x160 +#define GB_MARIO_PEACH 0x1B4 // GB_Unused_1B4 +#define GB_USING_PARTNER 0x1B5 // GB_Unused_1B5 #if PM64_VERSION == US #define SCRIPTS_GLOBAL_START 0x801049B0 diff --git a/src/sys/gfx.c b/src/sys/gfx.c index f3ec9431..5e702589 100644 --- a/src/sys/gfx.c +++ b/src/sys/gfx.c @@ -596,6 +596,18 @@ void gfxSpriteDraw(const struct GfxSprite *sprite) { gfxSynced = FALSE; } +void gfxRectangleDraw(s16 x, s16 y, s16 width, s16 height, u32 color) { + gfxModeReplace(GFX_MODE_COLOR, color); + gfxModeReplace(GFX_MODE_COMBINE, G_CC_MODE(G_CC_PRIMITIVE, G_CC_PRIMITIVE)); + gfxDisp(gsSPScisTextureRectangle(qs102(x), qs102(y), qs102(x + width), qs102(y + height), 0, 0, 0, 0, 0)); + gfxModePop(GFX_MODE_COLOR); + gfxModePop(GFX_MODE_COMBINE); +} + +void gfxTextBackgroundDraw(s16 x, s16 y, u8 chCountW, u8 chCountH, s32 chWidth, s32 chHeight, u32 color) { + gfxRectangleDraw(x - 3, y - chHeight - 2, chWidth * chCountW + 6, chHeight * (chCountH + 1) - 1, color); +} + s32 gfxFontXheight(const struct GfxFont *font) { return font->baseline - font->median; } diff --git a/src/sys/gfx.h b/src/sys/gfx.h index 1657eefb..489056c2 100644 --- a/src/sys/gfx.h +++ b/src/sys/gfx.h @@ -115,6 +115,9 @@ void gfxRdpLoadTile(const struct GfxTexture *texture, s16 textureTile, s8 palett void gfxSpriteDraw(const struct GfxSprite *sprite); +void gfxRectangleDraw(s16 x, s16 y, s16 width, s16 height, u32 color); +void gfxTextBackgroundDraw(s16 x, s16 y, u8 chCountW, u8 chCountH, s32 chWidth, s32 chHeight, u32 color); + s32 gfxFontXheight(const struct GfxFont *font); void gfxPrintf(const struct GfxFont *font, s32 x, s32 y, const char *format, ...); void gfxPrintfN(const struct GfxFont *font, s32 x, s32 y, const char *format, ...); diff --git a/src/sys/settings.c b/src/sys/settings.c index 653e6af3..8f615d70 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -83,12 +83,12 @@ void settingsLoadDefault(void) { d->binds[COMMAND_START_TIMER] = bindMake(0); d->binds[COMMAND_RESET_TIMER] = bindMake(0); d->binds[COMMAND_SHOW_HIDE_TIMER] = bindMake(0); - d->binds[COMMAND_BREAK_FREE] = bindMake(2, BUTTON_L, BUTTON_D_DOWN); + d->binds[COMMAND_BREAK_FREE] = bindMake(3, BUTTON_R, BUTTON_L, BUTTON_D_DOWN); d->binds[COMMAND_TOGGLE_INPUT_DISPLAY] = bindMake(0); - d->binds[COMMAND_CLIPPY] = bindMake(0); - d->binds[COMMAND_STORE_ABILITY] = bindMake(0); - d->binds[COMMAND_IGNORE_WALLS] = bindMake(0); - d->binds[COMMAND_FLOOR_CLIP] = bindMake(0); + d->binds[COMMAND_CLIPPY] = bindMake(2, BUTTON_L, BUTTON_D_UP); + d->binds[COMMAND_STORE_ABILITY] = bindMake(2, BUTTON_B, BUTTON_D_LEFT); + d->binds[COMMAND_IGNORE_WALLS] = bindMake(2, BUTTON_B, BUTTON_D_UP); + d->binds[COMMAND_FLOOR_CLIP] = bindMake(2, BUTTON_L, BUTTON_D_DOWN); d->cheatEnemyContact = 0; d->controlStickRange = 90; d->controlStick = 2; diff --git a/src/sys/settings.h b/src/sys/settings.h index 347e1429..b23dcb42 100644 --- a/src/sys/settings.h +++ b/src/sys/settings.h @@ -17,7 +17,7 @@ enum Cheats { CHEAT_HP, CHEAT_FP, - CHEAT_ATTACK, + CHEAT_POWER, CHEAT_COINS, CHEAT_STAR_POWER, CHEAT_STAR_PIECES,