From 916c10b9b087e8a72a5074a3797e9bb795247c0f Mon Sep 17 00:00:00 2001 From: JCog <42006114+JCog@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:04:48 -0500 Subject: [PATCH 1/5] allow flag logging --- src/fp.c | 7 ++++++- src/fp/debug/flags.c | 36 +++++++++++++++++++++--------------- src/fp/fp_settings.c | 2 ++ src/sys/settings.c | 1 + src/sys/settings.h | 1 + 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/fp.c b/src/fp.c index 9665ddbe..f2a2c450 100644 --- a/src/fp.c +++ b/src/fp.c @@ -1,6 +1,7 @@ #include "fp.h" #include "commands.h" #include "common.h" +#include "fp/debug/flags.h" #include "fp/practice/timer.h" #include "fp/practice/trainer.h" #include "fp/warps/bosses.h" @@ -508,6 +509,10 @@ void fpUpdate(void) { } fpCamUpdate(); + if (settings->flagLogging) { + updateFlagRecords(); + } + while (fp.menuActive && menuThink(fp.mainMenu)) { // wait } @@ -608,7 +613,7 @@ HOOK s32 fpIsAbilityActive(s32 ability) { return pm_is_ability_active(ability); } -HOOK pm_Npc *fpGetNpcUnsafe(s16 npcId) { +HOOK pm_Npc *fpGetNpcUnsafe(s16 npcId) { // NOLINT if (npcId == BOSSES_DUMMY_ID) { bossesDummyNpc.pos = pm_gPlayerStatus.position; return &bossesDummyNpc; diff --git a/src/fp/debug/flags.c b/src/fp/debug/flags.c index 0b3416b2..a7448b13 100644 --- a/src/fp/debug/flags.c +++ b/src/fp/debug/flags.c @@ -1,5 +1,6 @@ #include "flags.h" #include "common.h" +#include "fp.h" #include "menu/menu.h" #include "sys/gfx.h" #include "sys/resource.h" @@ -62,6 +63,9 @@ static void addEvent(s32 recordIndex, s32 flagIndex, bool value) { e->value = value; snprintf(e->description, sizeof(e->description), "%s[0x%0*lx] := %i", r->name, r->indexLength % 10, flagIndex, value); + if (settings->flagLogging) { + fpLog(e->description); + } } static u32 getFlagWord(void *data, size_t wordSize, s32 index) { @@ -103,22 +107,9 @@ static void modifyFlag(void *data, size_t wordSize, s32 flagIndex, bool value) { } static s32 logThinkProc(struct MenuItem *item) { - for (s32 i = 0; i < records.size; ++i) { - struct FlagRecord *r = vector_at(&records, i); - for (s32 j = 0; j < r->length; ++j) { - u32 wd = getFlagWord(r->data, r->wordSize, j); - u32 wc = getFlagWord(r->comp, r->wordSize, j); - u32 d = wd ^ wc; - if (d != 0) { - for (s32 k = 0; k < r->wordSize * 8; ++k) { - if ((d >> k) & 1) { - addEvent(i, r->wordSize * 8 * j + k, (wd >> k) & 1); - } - } - } - } + if (!settings->flagLogging) { + updateFlagRecords(); } - updateFlagRecords(); return 0; } @@ -271,6 +262,21 @@ void flagMenuCreate(struct Menu *menu) { } void updateFlagRecords(void) { + for (s32 i = 0; i < records.size; ++i) { + struct FlagRecord *r = vector_at(&records, i); + for (s32 j = 0; j < r->length; ++j) { + u32 wd = getFlagWord(r->data, r->wordSize, j); + u32 wc = getFlagWord(r->comp, r->wordSize, j); + u32 d = wd ^ wc; + if (d != 0) { + for (s32 k = 0; k < r->wordSize * 8; ++k) { + if ((d >> k) & 1) { + addEvent(i, r->wordSize * 8 * j + k, (wd >> k) & 1); + } + } + } + } + } for (s32 i = 0; i < records.size; ++i) { struct FlagRecord *r = vector_at(&records, i); memcpy(r->comp, r->data, r->wordSize * r->length); diff --git a/src/fp/fp_settings.c b/src/fp/fp_settings.c index a590afc1..02cde877 100644 --- a/src/fp/fp_settings.c +++ b/src/fp/fp_settings.c @@ -184,6 +184,8 @@ struct Menu *createSettingsMenu(void) { menuAddStatic(&menuDisplay, 0, y, "logging", 0xC0C0C0); menuAddCheckbox(&menuDisplay, menuX, y, menuByteCheckboxProc, &settings->log); menuAddPositioning(&menuDisplay, menuX + 2, y++, logPositionProc, NULL); + menuAddStatic(&menuDisplay, 0, y, "flag logging", 0xC0C0C0); + menuAddCheckbox(&menuDisplay, menuX, y++, menuByteCheckboxProc, &settings->flagLogging); y++; menuAddStatic(&menuDisplay, 0, y, "input display", 0xC0C0C0); menuAddCheckbox(&menuDisplay, menuX, y, menuByteCheckboxProc, &settings->inputDisplay); diff --git a/src/sys/settings.c b/src/sys/settings.c index 93c416e7..b97f357f 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -39,6 +39,7 @@ void settingsLoadDefault(void) { d->menuBackgroundAlpha = 0xC0; d->inputDisplay = 0; d->log = 1; + d->flagLogging = 0; d->timerLogging = 0; d->timerShow = 0; d->battleDebug = 0; diff --git a/src/sys/settings.h b/src/sys/settings.h index 05ea0f36..ded7a88d 100644 --- a/src/sys/settings.h +++ b/src/sys/settings.h @@ -63,6 +63,7 @@ struct SettingsData { s8 menuBackgroundAlpha; u8 inputDisplay; u8 log; + u8 flagLogging; u8 timerShow; u8 timerLogging; u8 trainerBowserEnabled; From c27cd1039191ba5d41442374039f8a0f28371fcf Mon Sep 17 00:00:00 2001 From: JCog <42006114+JCog@users.noreply.github.com> Date: Fri, 27 Jun 2025 19:27:49 -0500 Subject: [PATCH 2/5] implement ignore walls command --- .gitignore | 1 + genhooks | 5 +++++ lib/libpm-jp.a | 6 ++++++ lib/libpm-us.a | 6 ++++++ src/commands.c | 11 +++++++++++ src/commands.h | 2 ++ src/fp.c | 9 +++++++++ src/fp.h | 1 + src/pm64.h | 2 ++ src/sys/settings.c | 1 + 10 files changed, 44 insertions(+) diff --git a/.gitignore b/.gitignore index a0b69435..7f2152a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ +.temp/ .vs/ build/ venv/ diff --git a/genhooks b/genhooks index 9bbe22f2..20db625b 100755 --- a/genhooks +++ b/genhooks @@ -47,6 +47,11 @@ genhook "$sym_flush_backups_hook_1" "nop;" # Remove calls to update backup save genhook "$sym_flush_backups_hook_2" "nop;" genhook "$sym_update_camera_zone_interp_hook" "jal $sym_fpUpdateCameraZoneInterpHook;" genhook "$sym_get_npc_unsafe_hook" "jal $sym_fpGetNpcUnsafe;" +genhook "$sym_no_walls_hook_1" "jal $sym_fpIgnoreWalls;" +genhook "$sym_no_walls_hook_2" "jal $sym_fpIgnoreWalls;" +genhook "$sym_no_walls_hook_3" "jal $sym_fpIgnoreWalls;" +genhook "$sym_no_walls_hook_4" "jal $sym_fpIgnoreWalls;" +genhook "$sym_no_walls_hook_5" "jal $sym_fpIgnoreWalls;" genhook "$sym_update_player_input_rom_hook" "jal $sym_fpUpdateInput;" genhook "$sym_peekaboo_hook" "jal $sym_fpIsAbilityActive;" genhook "$sym_fire_flower_hook" "nop;" # Fix wii vc fire flower crash diff --git a/lib/libpm-jp.a b/lib/libpm-jp.a index 066e348c..27dc5ee4 100644 --- a/lib/libpm-jp.a +++ b/lib/libpm-jp.a @@ -83,6 +83,7 @@ __osGetActiveQueue = 0x80066260; osViSwapBuffer = 0x80066FF0; osViBlack = 0x80067350; osViRepeatLine = 0x800673B0; +pm_player_raycast_general = 0x800DEE3C; pm_disable_player_input = 0x800E0158; pm_update_player_input = 0x800E1F70; pm_is_ability_active = 0x800E9CE8; @@ -108,6 +109,11 @@ flush_backups_hook_1 = 0x8002B064; flush_backups_hook_2 = 0x8002B074; update_camera_zone_interp_hook = 0x8002D188; get_npc_unsafe_hook = 0x8004165C; +no_walls_hook_1 = 0x8009CDD8; +no_walls_hook_2 = 0x8009D31C; +no_walls_hook_3 = 0x8009D3B0; +no_walls_hook_4 = 0x8009D62C; +no_walls_hook_5 = 0x8009D6E4; update_player_input_rom_hook = 0x8009D914; peekaboo_hook = 0x801AF3A0; fire_flower_hook = 0x803AD0A0; diff --git a/lib/libpm-us.a b/lib/libpm-us.a index 17a3b305..bdbd93fd 100644 --- a/lib/libpm-us.a +++ b/lib/libpm-us.a @@ -83,6 +83,7 @@ __osGetActiveQueue = 0x80066290; osViSwapBuffer = 0x80067020; osViBlack = 0x80067380; osViRepeatLine = 0x800673E0; +pm_player_raycast_general = 0x800DEE5C; pm_disable_player_input = 0x800E0178; pm_update_player_input = 0x800E1F90; pm_is_ability_active = 0x800E9D48; @@ -108,6 +109,11 @@ flush_backups_hook_1 = 0x8002B0A4; flush_backups_hook_2 = 0x8002B0B4; update_camera_zone_interp_hook = 0x8002D4F8; get_npc_unsafe_hook = 0x8004199C; +no_walls_hook_1 = 0x8009CDF8; +no_walls_hook_2 = 0x8009D33C; +no_walls_hook_3 = 0x8009D3D0; +no_walls_hook_4 = 0x8009D64C; +no_walls_hook_5 = 0x8009D704; update_player_input_rom_hook = 0x8009D934; peekaboo_hook = 0x801A7110; fire_flower_hook = 0x803A4DA0; diff --git a/src/commands.c b/src/commands.c index a6ddb155..38db875c 100644 --- a/src/commands.c +++ b/src/commands.c @@ -29,6 +29,7 @@ struct Command fpCommands[COMMAND_MAX] = { {"toggle in. disp.", COMMAND_PRESS_ONCE, 0, commandToggleInpDispProc }, {"clippy", COMMAND_PRESS_ONCE, 0, commandClippyProc }, {"store ability", COMMAND_PRESS_ONCE, 0, commandStoreAbility }, + {"ignore walls", COMMAND_PRESS_ONCE, 0, commandIgnoreWalls }, }; void showMenu(void) { @@ -300,3 +301,13 @@ void commandStoreAbility(void) { fpLog("partner ability stored"); } } + +void commandIgnoreWalls(void) { + if (fp.ignoreWalls) { + fp.ignoreWalls = FALSE; + fpLog("walls enabled"); + } else { + fp.ignoreWalls = TRUE; + fpLog("walls disabled"); + } +} diff --git a/src/commands.h b/src/commands.h index 47c246b4..5b1d6d8e 100644 --- a/src/commands.h +++ b/src/commands.h @@ -23,6 +23,7 @@ enum Commands { COMMAND_TOGGLE_INPUT_DISPLAY, COMMAND_CLIPPY, COMMAND_STORE_ABILITY, + COMMAND_IGNORE_WALLS, COMMAND_MAX }; @@ -59,6 +60,7 @@ void commandBreakFreeProc(void); void commandToggleInpDispProc(void); void commandClippyProc(void); void commandStoreAbility(void); +void commandIgnoreWalls(void); extern struct Command fpCommands[COMMAND_MAX]; diff --git a/src/fp.c b/src/fp.c index f2a2c450..a7e4c4be 100644 --- a/src/fp.c +++ b/src/fp.c @@ -621,6 +621,15 @@ HOOK pm_Npc *fpGetNpcUnsafe(s16 npcId) { // NOLINT return pm_get_npc_unsafe(npcId); } +HOOK s32 fpIgnoreWalls(s32 mode, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, + f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz) { + if (fp.ignoreWalls) { + return -1; + } + return pm_player_raycast_general(mode, startX, startY, startZ, dirX, dirY, dirZ, hitX, hitY, hitZ, hitDepth, hitNx, + hitNy, hitNz); +} + #include #include #include diff --git a/src/fp.h b/src/fp.h index bf44f6f2..e462b9a0 100644 --- a/src/fp.h +++ b/src/fp.h @@ -69,6 +69,7 @@ typedef struct { pm_Camera savedCam; u16 freeCamMoveSpeed; u16 freeCamPanSpeed; + bool ignoreWalls; } FpCtxt; extern FpCtxt fp; diff --git a/src/pm64.h b/src/pm64.h index 99f59427..893a2316 100644 --- a/src/pm64.h +++ b/src/pm64.h @@ -1378,6 +1378,8 @@ OSThread *__osGetActiveQueue(void); void osViSwapBuffer(void *vaddr); void osViBlack(u8 active); void osViRepeatLine(u8 active); +s32 pm_player_raycast_general(s32 mode, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, + f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz); void pm_disable_player_input(void); void pm_update_player_input(void); s32 pm_is_ability_active(s32 arg0); diff --git a/src/sys/settings.c b/src/sys/settings.c index b97f357f..aeef5f07 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -77,6 +77,7 @@ void settingsLoadDefault(void) { 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->cheatEnemyContact = 0; d->controlStickRange = 90; d->controlStick = 0; From 2995eb2f95f081a59bc8702525cd7833b5a29400 Mon Sep 17 00:00:00 2001 From: JCog <42006114+JCog@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:08:23 -0500 Subject: [PATCH 3/5] add ability to pin trainers --- src/fp.c | 22 ++++---- src/fp.h | 1 + src/fp/fp_settings.c | 11 ++++ src/fp/practice/trainer.c | 111 +++++++++++++++++++++++++++----------- src/fp/practice/trainer.h | 7 +++ src/sys/settings.c | 5 +- src/sys/settings.h | 5 ++ 7 files changed, 122 insertions(+), 40 deletions(-) diff --git a/src/fp.c b/src/fp.c index a7e4c4be..cb2ee45e 100644 --- a/src/fp.c +++ b/src/fp.c @@ -534,15 +534,6 @@ void fpDraw(void) { s32 cellWidth = menuGetCellWidth(fp.mainMenu, TRUE); s32 cellHeight = menuGetCellHeight(fp.mainMenu, TRUE); - if (settings->inputDisplay) { - fpDrawInputDisplay(font, cellWidth, cellHeight, menuAlpha); - } - - if (fp.timerMoving || (timerState == TIMER_STOPPED && !fp.menuActive) || - (settings->timerShow && !fp.menuActive && timerState != TIMER_INACTIVE)) { - fpDrawTimer(font, cellWidth, cellHeight, menuAlpha); - } - if (fp.menuActive) { if (settings->menuBackground) { gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(0x000000, settings->menuBackgroundAlpha)); @@ -555,6 +546,19 @@ void fpDraw(void) { menuDraw(fp.mainMenu); } + if (settings->inputDisplay) { + fpDrawInputDisplay(font, cellWidth, cellHeight, menuAlpha); + } + + if (fp.timerMoving || (timerState == TIMER_STOPPED && !fp.menuActive) || + (settings->timerShow && !fp.menuActive && timerState != TIMER_INACTIVE)) { + fpDrawTimer(font, cellWidth, cellHeight, menuAlpha); + } + + if (fp.trainerMoving || (settings->trainerDisplayPinned && !fp.menuActive)) { + trainerDrawPinned(settings->trainerX, settings->trainerY, font, cellWidth, cellHeight, 0xC0C0C0, menuAlpha); + } + if (!fp.versionShown) { fpDrawVersion(font, cellWidth, cellHeight, menuAlpha); } diff --git a/src/fp.h b/src/fp.h index e462b9a0..a0435948 100644 --- a/src/fp.h +++ b/src/fp.h @@ -41,6 +41,7 @@ typedef struct { s64 cpuCounter; s32 cpuCounterFreq; bool timerMoving; + bool trainerMoving; bool menuActive; struct LogEntry log[SETTINGS_LOG_MAX]; Vec3f savedPos; diff --git a/src/fp/fp_settings.c b/src/fp/fp_settings.c index 02cde877..8b54340e 100644 --- a/src/fp/fp_settings.c +++ b/src/fp/fp_settings.c @@ -28,6 +28,15 @@ static s32 controlStickRangeProc(struct MenuItem *item, enum MenuCallbackReason return 0; } +static s32 trainerPositionProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { + if (reason == MENU_CALLBACK_ACTIVATE) { + fp.trainerMoving = TRUE; + } else if (reason == MENU_CALLBACK_DEACTIVATE) { + fp.trainerMoving = FALSE; + } + return menuGenericPositionProc(item, reason, &settings->trainerX); +} + static void profileDecProc(struct MenuItem *item, void *data) { fp.profile += SETTINGS_PROFILE_MAX - 1; fp.profile %= SETTINGS_PROFILE_MAX; @@ -186,6 +195,8 @@ struct Menu *createSettingsMenu(void) { menuAddPositioning(&menuDisplay, menuX + 2, y++, logPositionProc, NULL); menuAddStatic(&menuDisplay, 0, y, "flag logging", 0xC0C0C0); menuAddCheckbox(&menuDisplay, menuX, y++, menuByteCheckboxProc, &settings->flagLogging); + menuAddStatic(&menuDisplay, 0, y, "pinned trainer", 0xC0C0C0); + menuAddPositioning(&menuDisplay, menuX, y++, trainerPositionProc, &settings->trainerX); y++; menuAddStatic(&menuDisplay, 0, y, "input display", 0xC0C0C0); menuAddCheckbox(&menuDisplay, menuX, y, menuByteCheckboxProc, &settings->inputDisplay); diff --git a/src/fp/practice/trainer.c b/src/fp/practice/trainer.c index 86fe820a..95f0ef6e 100644 --- a/src/fp/practice/trainer.c +++ b/src/fp/practice/trainer.c @@ -135,13 +135,38 @@ asm(".set noreorder;" "JR $ra;" "SW $t1, 0x0000 ($t0);"); -static s32 issDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(drawParams->color, drawParams->alpha)); - struct GfxFont *font = drawParams->font; - s32 chHeight = menuGetCellHeight(item->owner, TRUE); - s32 chWidth = menuGetCellWidth(item->owner, TRUE); - s32 x = drawParams->x; - s32 y = drawParams->y; +static void unpinProc(struct MenuItem *item, void *data) { + settings->trainerDisplayPinned = FALSE; +} + +static s32 pinnedTrainerProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { + enum PinnedTrainer p = (u32)data; + if (reason == MENU_CALLBACK_SWITCH_ON) { + settings->pinnedTrainer = p; + settings->trainerDisplayPinned = TRUE; + } else if (reason == MENU_CALLBACK_SWITCH_OFF) { + settings->trainerDisplayPinned = FALSE; + } else if (reason == MENU_CALLBACK_THINK) { + menuCheckboxSet(item, settings->trainerDisplayPinned && settings->pinnedTrainer == p); + } + return 0; +} + +static void lzsDraw(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) { + 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); +} + +static s32 lzsDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { + lzsDraw(drawParams->x, drawParams->y, drawParams->font, menuGetCellWidth(item->owner, TRUE), + menuGetCellHeight(item->owner, TRUE), drawParams->color, drawParams->alpha); + return 1; +} + +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); @@ -178,7 +203,7 @@ static s32 issDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) gfxModeSet(GFX_MODE_COLOR, colorWhite); } gfxPrintf(font, x + chWidth * 7, y + chHeight * menuY++, "%.2f", pm_gPlayerStatus.currentYaw); - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(drawParams->color, drawParams->alpha)); + gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); gfxPrintf(font, x, y + chHeight * menuY, "pos:"); if (goodPos) { gfxModeSet(GFX_MODE_COLOR, colorGreen); @@ -190,17 +215,16 @@ static s32 issDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) gfxModeSet(GFX_MODE_COLOR, colorRed); gfxPrintf(font, x + chWidth * 7, y + chHeight * menuY, "bad"); } - return 1; } -static s32 aceDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(drawParams->color, drawParams->alpha)); - struct GfxFont *font = drawParams->font; - s32 chHeight = menuGetCellHeight(item->owner, TRUE); - s32 chWidth = menuGetCellWidth(item->owner, TRUE); - s32 x = drawParams->x; - s32 y = drawParams->y; +static s32 issDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { + issDraw(drawParams->x, drawParams->y, drawParams->font, menuGetCellWidth(item->owner, TRUE), + menuGetCellHeight(item->owner, TRUE), drawParams->color, drawParams->alpha); + return 1; +} +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++) { @@ -235,7 +259,7 @@ static s32 aceDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) gfxPrintf(font, x + chWidth * 14, y + chHeight * 2, "%d", fp.aceFrameWindow); if (fp.aceLastTimer != 0) { - gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(drawParams->color, drawParams->alpha)); + gfxModeSet(GFX_MODE_COLOR, GPACK_RGB24A8(color, alpha)); gfxPrintf(font, x + chWidth * 0, y + chHeight * 7, "last attempt status:"); gfxPrintf(font, x + chWidth * 0, y + chHeight * 8, "timer:"); gfxPrintf(font, x + chWidth * 0, y + chHeight * 9, "flags:"); @@ -273,6 +297,11 @@ static s32 aceDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) gfxPrintf(font, x + chWidth * 0, y + chHeight * 11, "failure"); } } +} + +static s32 aceDrawProc(struct MenuItem *item, struct MenuDrawParams *drawParams) { + aceDraw(drawParams->x, drawParams->y, drawParams->font, menuGetCellWidth(item->owner, TRUE), + menuGetCellHeight(item->owner, TRUE), drawParams->color, drawParams->alpha); return 1; } @@ -548,6 +577,14 @@ void trainerUpdate(void) { updateClippyTrainer(); } +void trainerDrawPinned(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) { + switch (settings->pinnedTrainer) { + case TRAINER_LZS: lzsDraw(x, y, font, chWidth, chHeight, color, alpha); break; + case TRAINER_ISS: issDraw(x, y, font, chWidth, chHeight, color, alpha); break; + case TRAINER_ACE: aceDraw(x, y, font, chWidth, chHeight, color, alpha); break; + } +} + void createTrainerMenu(struct Menu *menu) { static struct Menu lzsMenu; static struct Menu issMenu; @@ -598,25 +635,39 @@ void createTrainerMenu(struct Menu *menu) { lastOption = menuAddSubmenuIcon(menu, xOffset, y++, &aceMenu, wrench, 0, 0, 1.0f); #endif y++; - struct MenuItem *saveButton = menuAddButton(menu, 0, y++, "save settings", fpSaveSettingsProc, NULL); + struct MenuItem *unpinButton = menuAddButton(menu, 0, y++, "unpin trainer", unpinProc, NULL); + menuAddButton(menu, 0, y++, "save settings", fpSaveSettingsProc, NULL); menuItemAddChainLink(menu->selector, firstOption, MENU_NAVIGATE_DOWN); - menuItemAddChainLink(saveButton, lastOption, MENU_NAVIGATE_UP); + menuItemAddChainLink(unpinButton, lastOption, MENU_NAVIGATE_UP); /*build lzs jump menu*/ - lzsMenu.selector = menuAddSubmenu(&lzsMenu, 0, 0, NULL, "return"); - menuAddStatic(&lzsMenu, 0, 1, "current lzs jumps: ", 0xC0C0C0); - menuAddWatch(&lzsMenu, 20, 1, (u32)&lzsCurrentJumps, WATCH_TYPE_U16); - menuAddStatic(&lzsMenu, 0, 2, "record lzs jumps: ", 0xC0C0C0); - menuAddWatch(&lzsMenu, 20, 2, (u32)&lzsRecordJumps, WATCH_TYPE_U16); + y = 0; + lzsMenu.selector = menuAddSubmenu(&lzsMenu, 0, y++, NULL, "return"); + menuAddStatic(&lzsMenu, 0, y, "pin", 0xC0C0C0); + menuAddCheckbox(&lzsMenu, 4, y++, pinnedTrainerProc, (void *)TRAINER_LZS); + y++; + menuAddStaticCustom(&lzsMenu, 0, y++, lzsDrawProc, NULL, 0xC0C0C0); /*build iss menu*/ - issMenu.selector = menuAddSubmenu(&issMenu, 0, 0, NULL, "return"); - menuAddStaticCustom(&issMenu, 0, 1, issDrawProc, NULL, 0xC0C0C0); + y = 0; + issMenu.selector = menuAddSubmenu(&issMenu, 0, y++, NULL, "return"); + menuAddStatic(&issMenu, 0, y, "pin", 0xC0C0C0); + menuAddCheckbox(&issMenu, 4, y++, pinnedTrainerProc, (void *)TRAINER_ISS); + y++; + menuAddStaticCustom(&issMenu, 0, y++, issDrawProc, NULL, 0xC0C0C0); /*build ace menu*/ - aceMenu.selector = menuAddSubmenu(&aceMenu, 0, 0, NULL, "return"); - menuAddStaticCustom(&aceMenu, 0, 1, aceDrawProc, NULL, 0xC0C0C0); - menuAddButton(&aceMenu, 0, 5, "practice payload", acePracticePayloadProc, NULL); - menuAddButton(&aceMenu, 0, 6, "oot instruction", aceOotInstrProc, NULL); + y = 0; + aceMenu.selector = menuAddSubmenu(&aceMenu, 0, y++, NULL, "return"); + menuAddStatic(&aceMenu, 0, y, "pin", 0xC0C0C0); + struct MenuItem *pinCheckbox = menuAddCheckbox(&aceMenu, 4, y++, pinnedTrainerProc, (void *)TRAINER_ACE); + y++; + menuAddStaticCustom(&aceMenu, 0, y, aceDrawProc, NULL, 0xC0C0C0); + y += 4; + struct MenuItem *payloadOption = menuAddButton(&aceMenu, 0, y++, "practice payload", acePracticePayloadProc, NULL); + menuAddButton(&aceMenu, 0, y++, "oot instruction", aceOotInstrProc, NULL); + + menuItemAddChainLink(aceMenu.selector, pinCheckbox, MENU_NAVIGATE_DOWN); + menuItemAddChainLink(payloadOption, pinCheckbox, MENU_NAVIGATE_UP); } diff --git a/src/fp/practice/trainer.h b/src/fp/practice/trainer.h index 2f3505e4..e3c994c0 100644 --- a/src/fp/practice/trainer.h +++ b/src/fp/practice/trainer.h @@ -2,7 +2,14 @@ #define TRAINER_H #include "menu/menu.h" +enum PinnedTrainer { + TRAINER_LZS, + TRAINER_ISS, + TRAINER_ACE, +}; + void trainerUpdate(void); +void trainerDrawPinned(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha); void createTrainerMenu(struct Menu *menu); #endif diff --git a/src/sys/settings.c b/src/sys/settings.c index aeef5f07..7dda9d78 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -49,6 +49,7 @@ void settingsLoadDefault(void) { d->trainerBowserEnabled = 0; d->trainerClippyEnabled = 0; d->trainerLzsEnabled = 0; + d->trainerDisplayPinned = 0; d->menuX = 16; d->menuY = 60; d->inputDisplayX = 16; @@ -57,6 +58,8 @@ void settingsLoadDefault(void) { d->logY = SCREEN_HEIGHT - 33; d->timerX = 16; d->timerY = 68; + d->trainerX = 16; + d->trainerY = 68; d->binds[COMMAND_MENU] = bindMake(2, BUTTON_R, BUTTON_D_UP); d->binds[COMMAND_RETURN] = bindMake(2, BUTTON_R, BUTTON_D_LEFT); d->binds[COMMAND_LEVITATE] = bindMake(1, BUTTON_D_UP); @@ -80,7 +83,7 @@ void settingsLoadDefault(void) { d->binds[COMMAND_IGNORE_WALLS] = bindMake(0); d->cheatEnemyContact = 0; d->controlStickRange = 90; - d->controlStick = 0; + d->controlStick = 2; d->nWatches = 0; } diff --git a/src/sys/settings.h b/src/sys/settings.h index ded7a88d..dc562a14 100644 --- a/src/sys/settings.h +++ b/src/sys/settings.h @@ -3,6 +3,7 @@ #include "commands.h" #include "common.h" #include "fp/practice/timer.h" +#include "fp/practice/trainer.h" #define SETTINGS_SAVE_FILE_SIZE 0x1380 #define SETTINGS_PROFILE_MAX 4 @@ -43,6 +44,7 @@ struct SettingsData { u32 watchAddress[SETTINGS_WATCHES_MAX]; u32 cheats; enum TimerMode timerMode; + enum PinnedTrainer pinnedTrainer; s16 menuX; s16 menuY; s16 inputDisplayX; @@ -51,6 +53,8 @@ struct SettingsData { s16 logY; s16 timerX; s16 timerY; + s16 trainerX; + s16 trainerY; s16 watchX[SETTINGS_WATCHES_MAX]; s16 watchY[SETTINGS_WATCHES_MAX]; u16 binds[SETTINGS_BIND_MAX]; @@ -70,6 +74,7 @@ struct SettingsData { u8 trainerLzsEnabled; u8 trainerAcEnabled; u8 trainerClippyEnabled; + u8 trainerDisplayPinned; u8 battleDebug; u8 quickLaunch; u8 watchesVisible; From 229b3bd48bdd57769de019137e123bf4c64e72dc Mon Sep 17 00:00:00 2001 From: JCog <42006114+JCog@users.noreply.github.com> Date: Sat, 28 Jun 2025 19:14:52 -0500 Subject: [PATCH 4/5] add command to clip through floor, fix load pos y when riding laki --- src/commands.c | 15 ++++++++++++++- src/commands.h | 2 ++ src/sys/settings.c | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/commands.c b/src/commands.c index 38db875c..4b4419a6 100644 --- a/src/commands.c +++ b/src/commands.c @@ -30,6 +30,7 @@ struct Command fpCommands[COMMAND_MAX] = { {"clippy", COMMAND_PRESS_ONCE, 0, commandClippyProc }, {"store ability", COMMAND_PRESS_ONCE, 0, commandStoreAbility }, {"ignore walls", COMMAND_PRESS_ONCE, 0, commandIgnoreWalls }, + {"floor clip", COMMAND_PRESS_ONCE, 0, commandFloorClip }, }; void showMenu(void) { @@ -174,11 +175,12 @@ void commandLoadPosProc(void) { pm_gPlayerStatus.targetYaw = fp.savedMovementAngle; if (pm_gPlayerStatus.actionState & ACTION_STATE_RIDE) { - pm_Npc *partner = pm_get_npc_safe(-4); + pm_Npc *partner = pm_get_npc_safe(-4); // NPC_PARTNER if (partner) { partner->pos.x = fp.savedPos.x; partner->pos.y = fp.savedPos.y; partner->pos.z = fp.savedPos.z; + partner->moveToPos.y = fp.savedPos.y; partner->yaw = fp.savedMovementAngle; } } @@ -311,3 +313,14 @@ void commandIgnoreWalls(void) { fpLog("walls disabled"); } } + +void commandFloorClip(void) { + pm_gPlayerStatus.position.y -= 20; + if (pm_gPlayerStatus.actionState & ACTION_STATE_RIDE) { + pm_Npc *partner = pm_get_npc_safe(-4); // NPC_PARTNER + if (partner) { + partner->pos.y -= 20; + partner->moveToPos.y -= 20; + } + } +} diff --git a/src/commands.h b/src/commands.h index 5b1d6d8e..28793f26 100644 --- a/src/commands.h +++ b/src/commands.h @@ -24,6 +24,7 @@ enum Commands { COMMAND_CLIPPY, COMMAND_STORE_ABILITY, COMMAND_IGNORE_WALLS, + COMMAND_FLOOR_CLIP, COMMAND_MAX }; @@ -61,6 +62,7 @@ void commandToggleInpDispProc(void); void commandClippyProc(void); void commandStoreAbility(void); void commandIgnoreWalls(void); +void commandFloorClip(void); extern struct Command fpCommands[COMMAND_MAX]; diff --git a/src/sys/settings.c b/src/sys/settings.c index 7dda9d78..977aba85 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -81,6 +81,7 @@ void settingsLoadDefault(void) { 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->cheatEnemyContact = 0; d->controlStickRange = 90; d->controlStick = 2; From 25ab4d5da820833162b085a9407927179511cb2b Mon Sep 17 00:00:00 2001 From: JCog <42006114+JCog@users.noreply.github.com> Date: Sat, 28 Jun 2025 19:23:55 -0500 Subject: [PATCH 5/5] rearrange story progress in file menu --- src/fp/file/fp_file.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fp/file/fp_file.c b/src/fp/file/fp_file.c index 7a25c980..94197cfa 100644 --- a/src/fp/file/fp_file.c +++ b/src/fp/file/fp_file.c @@ -42,11 +42,11 @@ static s32 storyProgressDrawProc(struct MenuItem *item, struct MenuDrawParams *d char buffer[24]; if (chapter == 0) { - snprintf(buffer, sizeof(buffer), "pro. (%d/%d) -", chapterProgress, chapterMax); + snprintf(buffer, sizeof(buffer), "pro. (%d/%d)", chapterProgress, chapterMax); } else if (chapter > 8) { - snprintf(buffer, sizeof(buffer), "invalid -"); + snprintf(buffer, sizeof(buffer), "invalid"); } else { - snprintf(buffer, sizeof(buffer), "ch%d (%d/%d) -", chapter, chapterProgress, chapterMax); + snprintf(buffer, sizeof(buffer), "ch%d (%d/%d)", chapter, chapterProgress, chapterMax); } gfxPrintf(font, x, y, buffer); return 1; @@ -228,9 +228,9 @@ struct Menu *createFileMenu(void) { menuItemAddChainLink(importButton, minusButton, MENU_NAVIGATE_DOWN); y++; - menuAddStatic(&menu, 0, y++, "story progress", 0xC0C0C0); - menuAddStaticCustom(&menu, 0, y, storyProgressDrawProc, NULL, 0xC0C0C0); - struct MenuItem *progressInput = menuAddIntinput(&menu, 14, y++, 16, 2, menuByteModProc, &STORY_PROGRESS); + menuAddStatic(&menu, 0, y, "story progress", 0xC0C0C0); + struct MenuItem *progressInput = menuAddIntinput(&menu, 15, y++, 16, 2, menuByteModProc, &STORY_PROGRESS); + menuAddStaticCustom(&menu, 0, y++, storyProgressDrawProc, NULL, 0xC0C0C0); menuItemAddChainLink(minusButton, progressInput, MENU_NAVIGATE_DOWN); menuItemAddChainLink(plusButton, progressInput, MENU_NAVIGATE_DOWN); y++;