diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 89d696e2..6ff8583a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,12 +4,12 @@ Contributions are welcome! If you want to fix a bug or implement a feature yours ## Dependencies -Apart from glank's n64 toolchain, you will need to install clang-format and clang-tidy of at least version 16. +Apart from glank's n64 toolchain, you will need to install `clang-format` and `clang-tidy` of at least version 16. Instuctions for adding the llvm apt repository for Ubuntu and Debian can be found [here](https://apt.llvm.org/). -If the only clang-format or clang-tidy versions available for you are older than 16, you will have to build clang from source. You can find everything you need for this at the [LLVM GitHub repository](https://github.com/llvm/llvm-project) +If the only `clang-format` or `clang-tidy` versions available for you are older than 16, you will have to build clang from source. You can find everything you need for this at the [LLVM GitHub repository](https://github.com/llvm/llvm-project) ## Pull Requests -Before you create a pull request with your changes, make sure your code actually builds and anything you changed works. Next, run the `format.py` script to ensure that everything matches fp's code style. Once you've done that, you're ready to create a pull request! When creating a pull request, make sure that it is to the `develop` branch and that any commit and pull request names accurately describe what your changes are. +Before you create a pull request with your changes, make sure your code actually builds and anything you changed works. Next, run the `format.py` script to ensure that everything matches fp's code style. Once you've done that, you're ready to create a pull request! Just be sure that any commit messages and pull request names/descriptions accurately describe what your changes are to help us out while we're reviewing. diff --git a/README.md b/README.md index 0d19b4e8..4394de6d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # About -This is practice tool for Paper Mario 64 intended for use on N64 with an Everdrive and Wii/Wii U through the Virtual Console. It's also known informally as "the practice rom". +This is practice tool for Paper Mario 64 intended for use on N64 with an EverDrive and Wii/Wii U through the Virtual Console. It's also known informally as "the practice rom". # Download The latest release can be downloaded using the [web patcher](https://fp-patcher.starhaven.dev/). @@ -8,7 +8,7 @@ The latest release can be downloaded using the [web patcher](https://fp-patcher. See the [user manual](https://fp-docs.starhaven.dev/) for information on how to use fp. # Building -To build from source, refer to [this guide](https://github.com/jcog/fp/blob/develop/BUILDING.md). +To build from source, refer to [this guide](BUILDING.md). # Feedback If you found a bug or have an idea for an enhancement or feature, please [create an issue](https://github.com/JCog/fp/issues). @@ -16,12 +16,12 @@ If you found a bug or have an idea for an enhancement or feature, please [create For bugs, be sure to include all necessary steps to reproduce the bug, and describe the expected and observed behavior in detail. For enhancements or features, include a detailed description of your proposed changes, how they should be designed, how they will fit in with the current design, and possibly how they should be implemented. Do not submit suggestions that are too subjective to be considered improvements. # Contributing -For instructions on how to contribute, follow [this guide](https://github.com/jcog/fp/blob/develop/CONTRIBUTING.md). +For instructions on how to contribute, follow [this guide](CONTRIBUTING.md). # Thanks First and foremost, this project wouldn't be possible without [glank](https://github.com/glankk) and the Ocarina of Time practice ROM, [gz](https://github.com/glankk/gz). The same toolchain is used for fp, and many parts of the code are lifted straight from gz. -Second, a big thank you goes to [fig02](https://github.com/fig02) and [krimtonz](https://github.com/krimtonz). Fig was the one to initially setup the fp repo and get the project started, and krim was instrumental in getting the project working in the first place. +Second, a big thank-you goes to [fig02](https://github.com/fig02) and [krimtonz](https://github.com/krimtonz). Fig was the one to initially set up the fp repo and get the project started, and krim was instrumental in getting the project working in the first place. The work that the [Paper Mario decompilation](https://github.com/pmret/papermario) team has put in has also been incredibly useful. Many of the features in fp would have either been much harder, or even downright impossible to get working without the insight into Paper Mario's code that decomp has provided. diff --git a/lib/libpm-jp.a b/lib/libpm-jp.a index f8d7d976..066e348c 100644 --- a/lib/libpm-jp.a +++ b/lib/libpm-jp.a @@ -1,41 +1,42 @@ -osMemSize = 0x80000318; -pm_gGameStatus = 0x80074004; -pm_gCurrentCameraID = 0x800773E0; -pm_gItemTable = 0x800878B0; -pm_gItemHudScripts = 0x8008A650; -pm_gAreas = 0x800934C0; -nuScRetraceCounter = 0x80093B64; -pm_gEncounterSubState = 0x8009A5B0; -pm_timeFreezeMode = 0x8009A5B8; -pm_gEncounterState = 0x8009A5E0; -pm_gSoundManager = 0x8009A620; -nuGfxCfb_ptr = 0x8009A62C; -pm_gOverrideFlags = 0x8009A630; -pm_gMainGfxPos = 0x8009A64C; -pm_LogicalSaveInfo = 0x8009BA10; -pm_CurGameMode = 0x8009E700; -pm_gMapTransitionAlpha = 0x8009E750; -pm_gMapTransitionState = 0x8009E754; -pm_gCurrentEncounter = 0x800B0EF0; -pm_gCameras = 0x800B1D60; -pm_gEffectInstances = 0x800B4378; -pm_gSaveGlobals = 0x800D95C8; -__osEventStateTab = 0x800D9F60; -pm_gCurrentSaveFile = 0x800DACA0; -pm_gBattleState = 0x800DC048; -pm_gBattleStatus = 0x800DC050; -pm_gBattleSubState = 0x800DC4BC; -pm_PlayerActionsTable = 0x800F7E1C; -pm_gPopupState = 0x8010D800; -pm_gPartnerActionStatus = 0x8010ED70; -pm_gUiStatus = 0x8010F118; -pm_gPlayerStatus = 0x8010F188; -pm_gHudElementSizes = 0x8015406C; -pm_MusicCurrentVolume = 0x8015EA66; -pm_gActionCommandStatus = 0x8029FED0; -pm_gNumScripts = 0x802DA488; -pm_gCurrentScriptListPtr = 0x802DA890; -pm_gScriptIndexList = 0x802DA898; +osMemSize = 0x80000318; +pm_gGameStatus = 0x80074004; +pm_gCurrentCameraID = 0x800773E0; +pm_gItemTable = 0x800878B0; +pm_gItemHudScripts = 0x8008A650; +pm_gAreas = 0x800934C0; +nuScRetraceCounter = 0x80093B64; +pm_gEncounterSubState = 0x8009A5B0; +pm_timeFreezeMode = 0x8009A5B8; +pm_gEncounterState = 0x8009A5E0; +pm_gSoundManager = 0x8009A620; +nuGfxCfb_ptr = 0x8009A62C; +pm_gOverrideFlags = 0x8009A630; +pm_gMainGfxPos = 0x8009A64C; +pm_LogicalSaveInfo = 0x8009BA10; +pm_CurGameMode = 0x8009E700; +pm_gMapTransitionAlpha = 0x8009E750; +pm_gMapTransitionState = 0x8009E754; +pm_gCurrentEncounter = 0x800B0EF0; +pm_gCameras = 0x800B1D60; +pm_gEffectInstances = 0x800B4378; +pm_gSaveGlobals = 0x800D95C8; +__osEventStateTab = 0x800D9F60; +pm_gCurrentSaveFile = 0x800DACA0; +pm_gBattleState = 0x800DC048; +pm_gBattleStatus = 0x800DC050; +pm_gBattleSubState = 0x800DC4BC; +pm_PlayerActionsTable = 0x800F7E1C; +pm_gPopupState = 0x8010D800; +pm_gPartnerStatus = 0x8010ED70; +pm_gUiStatus = 0x8010F118; +pm_gPlayerStatus = 0x8010F188; +pm_gHudElementSizes = 0x8015406C; +pm_MusicCurrentVolume = 0x8015EA66; +pm_gActionCommandStatus = 0x8029FED0; +pm_battle_move_power_bounce_BaseHitChance = 0x802A2730; +pm_gNumScripts = 0x802DA488; +pm_gCurrentScriptListPtr = 0x802DA890; +pm_gScriptIndexList = 0x802DA898; osSyncPrintf = 0x80025CFC; pm_step_game_loop = 0x80026710; diff --git a/lib/libpm-us.a b/lib/libpm-us.a index 16b06135..17a3b305 100644 --- a/lib/libpm-us.a +++ b/lib/libpm-us.a @@ -1,41 +1,42 @@ -osMemSize = 0x80000318; -pm_gGameStatus = 0x80074024; -pm_gCurrentCameraID = 0x80077410; -pm_gItemTable = 0x800878E0; -pm_gItemHudScripts = 0x8008A680; -pm_gAreas = 0x800934F0; -nuScRetraceCounter = 0x80093B94; -pm_gEncounterSubState = 0x8009A5D0; -pm_timeFreezeMode = 0x8009A5D8; -pm_gEncounterState = 0x8009A600; -pm_gSoundManager = 0x8009A640; -nuGfxCfb_ptr = 0x8009A64C; -pm_gOverrideFlags = 0x8009A650; -pm_gMainGfxPos = 0x8009A66C; -pm_LogicalSaveInfo = 0x8009BA30; -pm_CurGameMode = 0x800A08F0; -pm_gMapTransitionAlpha = 0x800A0940; -pm_gMapTransitionState = 0x800A0944; -pm_gCurrentEncounter = 0x800B0F10; -pm_gCameras = 0x800B1D80; -pm_gEffectInstances = 0x800B4398; -pm_gSaveGlobals = 0x800D95E8; -__osEventStateTab = 0x800D9F80; -pm_gCurrentSaveFile = 0x800DACC0; -pm_gBattleState = 0x800DC068; -pm_gBattleStatus = 0x800DC070; -pm_gBattleSubState = 0x800DC4DC; -pm_PlayerActionsTable = 0x800F7C8C; -pm_gPopupState = 0x8010D640; -pm_gPartnerActionStatus = 0x8010EBB0; -pm_gUiStatus = 0x8010EF58; -pm_gPlayerStatus = 0x8010EFC8; -pm_gHudElementSizes = 0x8014EFCC; -pm_MusicCurrentVolume = 0x80159AE6; -pm_gActionCommandStatus = 0x8029FBE0; -pm_gNumScripts = 0x802DA488; -pm_gCurrentScriptListPtr = 0x802DA890; -pm_gScriptIndexList = 0x802DA898; +osMemSize = 0x80000318; +pm_gGameStatus = 0x80074024; +pm_gCurrentCameraID = 0x80077410; +pm_gItemTable = 0x800878E0; +pm_gItemHudScripts = 0x8008A680; +pm_gAreas = 0x800934F0; +nuScRetraceCounter = 0x80093B94; +pm_gEncounterSubState = 0x8009A5D0; +pm_timeFreezeMode = 0x8009A5D8; +pm_gEncounterState = 0x8009A600; +pm_gSoundManager = 0x8009A640; +nuGfxCfb_ptr = 0x8009A64C; +pm_gOverrideFlags = 0x8009A650; +pm_gMainGfxPos = 0x8009A66C; +pm_LogicalSaveInfo = 0x8009BA30; +pm_CurGameMode = 0x800A08F0; +pm_gMapTransitionAlpha = 0x800A0940; +pm_gMapTransitionState = 0x800A0944; +pm_gCurrentEncounter = 0x800B0F10; +pm_gCameras = 0x800B1D80; +pm_gEffectInstances = 0x800B4398; +pm_gSaveGlobals = 0x800D95E8; +__osEventStateTab = 0x800D9F80; +pm_gCurrentSaveFile = 0x800DACC0; +pm_gBattleState = 0x800DC068; +pm_gBattleStatus = 0x800DC070; +pm_gBattleSubState = 0x800DC4DC; +pm_PlayerActionsTable = 0x800F7C8C; +pm_gPopupState = 0x8010D640; +pm_gPartnerStatus = 0x8010EBB0; +pm_gUiStatus = 0x8010EF58; +pm_gPlayerStatus = 0x8010EFC8; +pm_gHudElementSizes = 0x8014EFCC; +pm_MusicCurrentVolume = 0x80159AE6; +pm_gActionCommandStatus = 0x8029FBE0; +pm_battle_move_power_bounce_BaseHitChance = 0x802A2730; +pm_gNumScripts = 0x802DA488; +pm_gCurrentScriptListPtr = 0x802DA890; +pm_gScriptIndexList = 0x802DA898; osSyncPrintf = 0x80025CFC; pm_step_game_loop = 0x80026740; diff --git a/src/commands.c b/src/commands.c index f78e4307..a6ddb155 100644 --- a/src/commands.c +++ b/src/commands.c @@ -28,6 +28,7 @@ struct Command fpCommands[COMMAND_MAX] = { {"break free", COMMAND_PRESS_ONCE, 0, commandBreakFreeProc }, {"toggle in. disp.", COMMAND_PRESS_ONCE, 0, commandToggleInpDispProc }, {"clippy", COMMAND_PRESS_ONCE, 0, commandClippyProc }, + {"store ability", COMMAND_PRESS_ONCE, 0, commandStoreAbility }, }; void showMenu(void) { @@ -228,19 +229,13 @@ void commandSaveGameProc(void) { fpLog("saved to slot %d", pm_gGameStatus.saveSlot); } -void commandStartStopTimerProc(void) { - timerStartStop(); -} - -void commandResetTimerProc(void) { - timerReset(); -} - -void commandShowHideTimerProc(void) { - settings->timerShow = !settings->timerShow; -} - void commandLoadGameProc(void) { + // prevent loading before being in game + if (pm_CurGameMode < 4 || pm_CurGameMode >= 12 || pm_gGameStatus.demoState) { + fpLog("can't load right now"); + return; + } + pm_SaveData *file = malloc(sizeof(*file)); pm_fio_fetch_saved_file_info(); pm_fio_read_flash(pm_LogicalSaveInfo[pm_gGameStatus.saveSlot][0], file, sizeof(*file)); @@ -255,6 +250,18 @@ void commandLoadGameProc(void) { free(file); } +void commandStartStopTimerProc(void) { + timerStartStop(); +} + +void commandResetTimerProc(void) { + timerReset(); +} + +void commandShowHideTimerProc(void) { + settings->timerShow = !settings->timerShow; +} + void commandBreakFreeProc(void) { s32 thirdByteMask = 0xFFFF00FF; s32 checkMask = 0x0000FF00; @@ -272,11 +279,24 @@ void commandToggleInpDispProc(void) { void commandClippyProc(void) { if (pm_gPlayerStatus.enableCollisionOverlapsCheck) { pm_gPlayerStatus.enableCollisionOverlapsCheck = 0; - pm_gPartnerActionStatus.shouldResumeAbility = 0; + pm_gPartnerStatus.shouldResumeAbility = 0; fpLog("clippy disabled"); } else { pm_gPlayerStatus.enableCollisionOverlapsCheck = 1; - pm_gPartnerActionStatus.shouldResumeAbility = 1; + pm_gPartnerStatus.shouldResumeAbility = 1; fpLog("clippy enabled"); } } + +void commandStoreAbility(void) { + // useful for getting sushie glitch and warping to entrances over lava with laki + if (pm_gGameStatus.keepUsingPartnerOnMapChange) { + pm_gPartnerStatus.partnerActionState = 0; + pm_gGameStatus.keepUsingPartnerOnMapChange = 0; + fpLog("partner ability disabled"); + } else { + pm_gPartnerStatus.partnerActionState = 1; + pm_gGameStatus.keepUsingPartnerOnMapChange = 1; + fpLog("partner ability stored"); + } +} diff --git a/src/commands.h b/src/commands.h index 2eb34977..47c246b4 100644 --- a/src/commands.h +++ b/src/commands.h @@ -22,6 +22,7 @@ enum Commands { COMMAND_BREAK_FREE, COMMAND_TOGGLE_INPUT_DISPLAY, COMMAND_CLIPPY, + COMMAND_STORE_ABILITY, COMMAND_MAX }; @@ -57,6 +58,7 @@ void commandShowHideTimerProc(void); void commandBreakFreeProc(void); void commandToggleInpDispProc(void); void commandClippyProc(void); +void commandStoreAbility(void); extern struct Command fpCommands[COMMAND_MAX]; diff --git a/src/fp.c b/src/fp.c index f993a9b5..9665ddbe 100644 --- a/src/fp.c +++ b/src/fp.c @@ -16,7 +16,7 @@ #include #include -FpCtxt fp = {.savedArea = 0x1c, .camDistMin = 100, .camDistMax = 1000}; +FpCtxt fp = {.savedArea = 0x1c, .camDistMin = 100, .camDistMax = 1000, .freeCamMoveSpeed = 250, .freeCamPanSpeed = 70}; // Initializes and uses new stack instead of using games main thread stack. static void initStack(void (*func)(void)) { @@ -320,7 +320,7 @@ void fpUpdateCheats(void) { pm_gPlayerStatus.playerData.curHP = 1; } if (CHEAT_ACTIVE(CHEAT_AUTO_MASH)) { - if (pm_gGameStatus.isBattle) { + if (pm_gGameStatus.isBattle == 1) { pm_gActionCommandStatus.barFillLevel = 10000; } } @@ -329,6 +329,11 @@ void fpUpdateCheats(void) { pm_gActionCommandStatus.autoSucceed = pm_gActionCommandStatus.actionCommandID != 23 || pm_gActionCommandStatus.unk_5D < 14; } + if (CHEAT_ACTIVE(CHEAT_POWER_BOUNCE)) { + if (pm_gBattleStatus.selectedMoveID == 0x20) { + pm_battle_move_power_bounce_BaseHitChance = 200; + } + } if (CHEAT_ACTIVE(CHEAT_BRIGHTEN_ROOM)) { pm_set_screen_overlay_alpha(1, 0); } @@ -442,6 +447,14 @@ void fpUpdate(void) { if (pm_CurGameMode == 0) { // GAME_MODE_STARTUP pm_fio_load_globals(); + // normally set during GAME_MODE_STARTUP + pm_gGameStatus.soundOutputMode = !pm_gSaveGlobals.useMonoSound; + if (pm_gSaveGlobals.useMonoSound) { + pm_audio_set_mono(); + } else { + pm_audio_set_stereo(); + } + if (settings->quickLaunch && pm_fio_load_game(pm_gSaveGlobals.lastFileSelected)) { // quick launch pm_set_game_mode(7); // GAME_MODE_ENTER_WORLD diff --git a/src/fp.h b/src/fp.h index 3607320a..bf44f6f2 100644 --- a/src/fp.h +++ b/src/fp.h @@ -67,8 +67,8 @@ typedef struct { FpControllerMask inputMask; bool camEnabledBefore; pm_Camera savedCam; - s8 freeCamMoveSpeed; - s8 freeCamPanSpeed; + u16 freeCamMoveSpeed; + u16 freeCamPanSpeed; } FpCtxt; extern FpCtxt fp; @@ -82,8 +82,6 @@ s32 fpImportFile(const char *path, void *data); void fpSetInputMask(u32 pad, s8 x, s8 y); void fpUpdateCam(void); void fpSaveSettingsProc(struct MenuItem *item, void *data); -void setFreeCamMoveSpeed(s8 s); -void setFreeCamPanSpeed(s8 s); struct Menu *createWarpsMenu(void); struct Menu *createCheatsMenu(void); diff --git a/src/fp/fp_camera.c b/src/fp/fp_camera.c index a1692c95..067a3472 100644 --- a/src/fp/fp_camera.c +++ b/src/fp/fp_camera.c @@ -3,6 +3,21 @@ #include "sys/input.h" #include +static bool firstUse = TRUE; + +static void resetCam(void) { + pm_Camera cam = pm_gCameras[pm_gCurrentCameraID]; + pm_gCameras[pm_gCurrentCameraID].targetPos = pm_gPlayerStatus.position; + pm_gCameras[pm_gCurrentCameraID].updateMode = 3; + pm_update_cameras(); + fp.cam.eye = pm_gCameras[pm_gCurrentCameraID].lookAt_eye; + fp.cam.obj = pm_gCameras[pm_gCurrentCameraID].lookAt_obj; + fp.cam.pitch = pm_gCameras[pm_gCurrentCameraID].currentPitch; + fp.cam.yaw = pm_gCameras[pm_gCurrentCameraID].currentYaw; + pm_gCameras[pm_gCurrentCameraID] = cam; + fp.resetCam = TRUE; +} + static void setCamInputMask(void) { if (fp.freeCam && !fp.lockCam) { fpSetInputMask(BUTTON_C_RIGHT | BUTTON_C_LEFT | BUTTON_C_DOWN | BUTTON_C_UP | BUTTON_Z | BUTTON_L, 0xFF, 0xFF); @@ -13,6 +28,10 @@ static void setCamInputMask(void) { static s32 enableCamProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { if (reason == MENU_CALLBACK_SWITCH_ON) { + if (firstUse) { + resetCam(); + firstUse = FALSE; + } fp.freeCam = TRUE; setCamInputMask(); } else if (reason == MENU_CALLBACK_SWITCH_OFF) { @@ -40,40 +59,7 @@ static s32 lockCamProc(struct MenuItem *item, enum MenuCallbackReason reason, vo } static void resetCamProc(struct MenuItem *item, void *data) { - pm_Camera cam = pm_gCameras[pm_gCurrentCameraID]; - pm_gCameras[pm_gCurrentCameraID].targetPos = pm_gPlayerStatus.position; - pm_gCameras[pm_gCurrentCameraID].updateMode = 3; - pm_update_cameras(); - fp.cam.eye = pm_gCameras[pm_gCurrentCameraID].lookAt_eye; - fp.cam.obj = pm_gCameras[pm_gCurrentCameraID].lookAt_obj; - fp.cam.pitch = pm_gCameras[pm_gCurrentCameraID].currentPitch; - fp.cam.yaw = pm_gCameras[pm_gCurrentCameraID].currentYaw; - pm_gCameras[pm_gCurrentCameraID] = cam; - fp.resetCam = TRUE; -} - -static s32 camMoveSpeedProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { - if (reason == MENU_CALLBACK_CHANGED) { - fp.freeCamMoveSpeed = menuIntinputGets(item); - setFreeCamMoveSpeed(fp.freeCamMoveSpeed); - } else if (reason == MENU_CALLBACK_THINK) { - if (menuIntinputGets(item) != fp.freeCamMoveSpeed) { - menuIntinputSet(item, fp.freeCamMoveSpeed); - } - } - return 0; -} - -static s32 camPanSpeedProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { - if (reason == MENU_CALLBACK_CHANGED) { - fp.freeCamPanSpeed = menuIntinputGets(item); - setFreeCamPanSpeed(fp.freeCamPanSpeed); - } else if (reason == MENU_CALLBACK_THINK) { - if (menuIntinputGets(item) != fp.freeCamPanSpeed) { - menuIntinputSet(item, fp.freeCamPanSpeed); - } - } - return 0; + resetCam(); } struct Menu *createCameraMenu(void) { @@ -103,9 +89,9 @@ struct Menu *createCameraMenu(void) { menuAddStatic(&menu, 0, y, "distance max", 0xC0C0C0); menuAddIntinput(&menu, menuX, y++, 10, 4, menuHalfwordModProc, &fp.camDistMax); menuAddStatic(&menu, 0, y, "move speed", 0xC0C0C0); - menuAddIntinput(&menu, menuX, y++, -10, 2, camMoveSpeedProc, NULL); + menuAddIntinput(&menu, menuX, y++, 10, 3, menuHalfwordModProc, &fp.freeCamMoveSpeed); menuAddStatic(&menu, 0, y, "pan speed", 0xC0C0C0); - menuAddIntinput(&menu, menuX, y++, -10, 2, camPanSpeedProc, NULL); + menuAddIntinput(&menu, menuX, y++, 10, 3, menuHalfwordModProc, &fp.freeCamPanSpeed); menuItemAddChainLink(menu.selector, enableButton, MENU_NAVIGATE_DOWN); menuItemAddChainLink(lockButton, resetButton, MENU_NAVIGATE_DOWN); diff --git a/src/fp/fp_cheats.c b/src/fp/fp_cheats.c index 071f2712..3b5aa62b 100644 --- a/src/fp/fp_cheats.c +++ b/src/fp/fp_cheats.c @@ -3,20 +3,9 @@ #include "sys/settings.h" static const char *labels[] = { - "hp", - "fp", - "attack", - "coins", - "star power", - "star pieces", - "peril", - "auto mash", - "action commands", - "peekaboo", - "brighten room", - "hide hud", - "mute music", - "quizmo spawns", + "hp", "fp", "attack", "coins", "star power", "star pieces", + "peril", "auto mash", "action commands", "power bounce", "peekaboo", "brighten room", + "hide hud", "mute music", "quizmo spawns", }; static s32 cheatProc(struct MenuItem *item, enum MenuCallbackReason reason, void *data) { diff --git a/src/fp/practice/trainer.c b/src/fp/practice/trainer.c index fec4af1b..86fe820a 100644 --- a/src/fp/practice/trainer.c +++ b/src/fp/practice/trainer.c @@ -519,7 +519,7 @@ static void updateBlockTrainer(void) { static void updateClippyTrainer(void) { if (settings->trainerClippyEnabled) { if (pm_gGameStatus.pressedButtons[0].cRight && pm_gCurrentEncounter.firstStrikeType != 2) { - if (pm_gEncounterState == 2 && pm_gPartnerActionStatus.partnerActionState == 1) { + if (pm_gEncounterState == 2 && pm_gPartnerStatus.partnerActionState == 1) { clippyStatus = CLIPPY_EARLY; } else if (clippyFramesSinceBattle > 0) { clippyStatus = CLIPPY_LATE; diff --git a/src/menu/menu_option.c b/src/menu/menu_option.c index c1d698cc..7bc0109c 100644 --- a/src/menu/menu_option.c +++ b/src/menu/menu_option.c @@ -116,6 +116,9 @@ s32 menuOptionGet(struct MenuItem *item) { void menuOptionSet(struct MenuItem *item, s32 value) { struct ItemData *data = item->data; data->value = value; + if (value >= (s32)data->options.size) { + return; + } char **option = vector_at(&data->options, data->value); item->text = *option; } diff --git a/src/pm64.h b/src/pm64.h index e7a517df..99f59427 100644 --- a/src/pm64.h +++ b/src/pm64.h @@ -183,7 +183,7 @@ typedef struct pm_GameStatus { /* 0x16C */ char unk_16C[12]; } pm_GameStatus; // size = 0x178 -typedef struct pm_PartnerActionStatus { +typedef struct pm_PartnerStatus { /* 0x000 */ s8 partnerActionState; /* 0x001 */ s8 shouldResumeAbility; /* 0x002 */ s8 partnerAction_unk_2; @@ -195,7 +195,7 @@ typedef struct pm_PartnerActionStatus { /* 0x10 */ s32 heldButtons; /* 0x14 */ s8 inputDisabled; /* 0x15 */ char unk_15[3]; -} pm_PartnerActionStatus; // size = 0x18 +} pm_PartnerStatus; // size = 0x18 typedef struct pm_UiStatus { /* 0x00 */ u32 hpText; @@ -1329,12 +1329,13 @@ extern_data pm_BattleStatus pm_gBattleStatus; extern_data s32 pm_gBattleSubState; extern_data pm_Action pm_PlayerActionsTable[39]; extern_data s32 pm_gPopupState; -extern_data pm_PartnerActionStatus pm_gPartnerActionStatus; +extern_data pm_PartnerStatus pm_gPartnerStatus; extern_data pm_UiStatus pm_gUiStatus; extern_data pm_PlayerStatus pm_gPlayerStatus; extern_data pm_HudElementSize pm_gHudElementSizes[26]; extern_data s16 pm_MusicCurrentVolume; extern_data pm_ActionCommandStatus pm_gActionCommandStatus; +extern_data s32 pm_battle_move_power_bounce_BaseHitChance; extern_data s32 pm_gNumScripts; extern_data pm_ScriptList *pm_gCurrentScriptListPtr; extern_data s32 pm_gScriptIndexList[128]; diff --git a/src/sys/settings.c b/src/sys/settings.c index cc84a8e3..93c416e7 100644 --- a/src/sys/settings.c +++ b/src/sys/settings.c @@ -75,6 +75,7 @@ void settingsLoadDefault(void) { d->binds[COMMAND_BREAK_FREE] = bindMake(2, 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->cheatEnemyContact = 0; d->controlStickRange = 90; d->controlStick = 0; diff --git a/src/sys/settings.h b/src/sys/settings.h index 11a2d2fb..05ea0f36 100644 --- a/src/sys/settings.h +++ b/src/sys/settings.h @@ -23,6 +23,7 @@ enum Cheats { CHEAT_PERIL, CHEAT_AUTO_MASH, CHEAT_AUTO_ACTION_CMD, + CHEAT_POWER_BOUNCE, CHEAT_PEEKABOO, CHEAT_BRIGHTEN_ROOM, CHEAT_HIDE_HUD, diff --git a/src/util/camera.c b/src/util/camera.c index 3315dd1c..a07f83b6 100644 --- a/src/util/camera.c +++ b/src/util/camera.c @@ -5,25 +5,19 @@ #include #include -static f32 joyMspeed = 0.25f; -static f32 joyRspeed = 0.0007f; static const f32 joyMax = 60.f; -#define PITCH_LIM (M_PI / 2.f - joyRspeed) static const f32 folMspeed = 1.f / 3.f; static const f32 folRspeed = 1.f / 3.f; -void setFreeCamMoveSpeed(s8 s) { - if (s < 0) { - joyMspeed = (s + 14) / joyMax; - } else { - joyMspeed = (s + 1) * 15 / joyMax; - } +static f32 getFreeCamMoveSpeed() { + return 0.001f * fp.freeCamMoveSpeed; } - -void setFreeCamPanSpeed(s8 s) { - joyRspeed = 0.0007 + s * 0.00005; +static f32 getFreeCamPanSpeed() { + return 0.00001f * fp.freeCamPanSpeed; } +#define PITCH_LIM (M_PI / 2.f - getFreeCamPanSpeed()) + s32 adjustJoystick(s32 v) { if (v < 0) { if (v > -8) { @@ -54,6 +48,8 @@ static void camManual(void) { Vec3f move; vec3fPy(&vf, fp.cam.pitch, fp.cam.yaw); vec3fPy(&vr, 0.f, fp.cam.yaw - M_PI / 2.f); + f32 joyMspeed = getFreeCamMoveSpeed(); + f32 joyRspeed = getFreeCamPanSpeed(); if (inputPad().z) { vec3fScale(&move, &vf, y * joyMspeed); @@ -185,6 +181,8 @@ static void camRadial(void) { if (!fp.lockCam) { s32 x = adjustJoystick(inputX()); s32 y = adjustJoystick(inputY()); + f32 joyMspeed = getFreeCamMoveSpeed(); + f32 joyRspeed = getFreeCamPanSpeed(); if (inputPad().z) { dist -= y * joyMspeed; diff --git a/watches/watches-jp.txt b/watches/watches-jp.txt index 81ce8f95..27b3c96c 100644 --- a/watches/watches-jp.txt +++ b/watches/watches-jp.txt @@ -1,5 +1,5 @@ -8010F1B0 # x coordinate -8010F1B4 # y coordinate -8010F1B8 # z coordinate -8029FF18 # mash bar -800DBD50 # story progress \ No newline at end of file +"x coordinate" f32 0x8010F1B0 +"y coordinate" f32 0x8010F1B4 +"z coordinate" f32 0x8010F1B8 +"mash bar" s16 0x8029FF18 +"story progress" x8 0x800DBD50 diff --git a/watches/watches-us.txt b/watches/watches-us.txt index 1649519b..fe5a9677 100644 --- a/watches/watches-us.txt +++ b/watches/watches-us.txt @@ -1,5 +1,5 @@ -8010EFF0 # x coordinate -8010EFF4 # y coordinate -8010EFF8 # z coordinate -8029FC28 # mash bar -800DBD70 # story progress \ No newline at end of file +"x coordinate" f32 0x8010EFF0 +"y coordinate" f32 0x8010EFF4 +"z coordinate" f32 0x8010EFF8 +"mash bar" s16 0x8029FC28 +"story progress" x8 0x800DBD70