From 66ec623542c16e92d69f9150fcd2883458a9cb7b Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Tue, 12 Jul 2022 18:40:18 -0400 Subject: [PATCH 01/38] Free Camera (#337) * wip free cam * Almost done, needs collision still * Added free cam behind cvar * added WIP collision * Fixed & implemented "Manual mode" from WW & TP * Fixed camera not rotating when Link is moving * fixed initialized camera rotation * Fixed camera getting stuck + made it smoother * reduced deadzone * fixed epona camera height + added WW z-target free camera * Adjusted player camera height & fixed fov * Fixed camera roll * fixed fov when moving the camera while in z-target * Camera resets to Auto when going through doors or changing maps * Fixed building * touch * more touch work * Added WIP mouse support to the free cam * gui stuff * fixed building * fixed building error * ok fixed building for real this time * oops * Fix compilation issues * removed mouse stuff that magically appeared in this branch * smoothed out stick values & removed remains of mouse support * re-added manual camera when pressing Z * reduced minimum Y position of camera * Addressed dcsv's nitpicks * part 2 * oops Co-authored-by: David Chavez --- libultraship/libultraship/Controller.cpp | 17 +- libultraship/libultraship/Controller.h | 5 +- libultraship/libultraship/ImGuiImpl.cpp | 2 + .../Lib/Fast3D/U64/PR/ultra64/controller.h | 8 +- libultraship/libultraship/SDLController.cpp | 28 +++- libultraship/libultraship/SDLController.h | 2 +- libultraship/libultraship/UltraController.h | 4 +- soh/include/z64.h | 3 + soh/src/code/z_camera.c | 155 ++++++++++++++++++ soh/src/code/z_play.c | 4 + .../gamestates/ovl_file_choose/file_choose.h | 5 + .../ovl_file_choose/z_file_choose.c | 8 +- 12 files changed, 221 insertions(+), 20 deletions(-) diff --git a/libultraship/libultraship/Controller.cpp b/libultraship/libultraship/Controller.cpp index e400f6e182..7cad7f178f 100644 --- a/libultraship/libultraship/Controller.cpp +++ b/libultraship/libultraship/Controller.cpp @@ -2,6 +2,12 @@ #include "GlobalCtx2.h" #include "stox.h" #include +#include +#if __APPLE__ +#include +#else +#include +#endif namespace Ship { Controller::Controller(int32_t dwControllerNumber) : dwControllerNumber(dwControllerNumber) { @@ -16,8 +22,12 @@ namespace Ship { void Controller::Read(OSContPad* pad) { ReadFromSource(); + SDL_PumpEvents(); + + // Button Inputs pad->button |= dwPressedButtons & 0xFFFF; + // Stick Inputs if (pad->stick_x == 0) { if (dwPressedButtons & BTN_STICKLEFT) { pad->stick_x = -128; @@ -42,8 +52,13 @@ namespace Ship { } } + // Gyro pad->gyro_x = wGyroX; pad->gyro_y = wGyroY; + + // Right Stick + pad->cam_x = wCamX; + pad->cam_y = wCamY; } void Controller::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) { @@ -93,4 +108,4 @@ namespace Ship { std::string Controller::GetBindingConfSection() { return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1); } -} \ No newline at end of file +} diff --git a/libultraship/libultraship/Controller.h b/libultraship/libultraship/Controller.h index 256b31fee9..d03d70e8a2 100644 --- a/libultraship/libultraship/Controller.h +++ b/libultraship/libultraship/Controller.h @@ -13,7 +13,6 @@ namespace Ship { class Controller { - public: Controller(int32_t dwControllerNumber); @@ -38,7 +37,9 @@ namespace Ship { int8_t wStickY; float wGyroX; float wGyroY; - + float wCamX; + float wCamY; + virtual std::string GetControllerType() = 0; virtual std::string GetConfSection() = 0; virtual std::string GetBindingConfSection() = 0; diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index bade9f04fc..ba51c1e99b 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1143,6 +1143,8 @@ namespace SohImGui { EnhancementCheckbox("Skip Text", "gSkipText"); Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode"); + EnhancementCheckbox("Free Camera", "gFreeCamera"); + ImGui::EndMenu(); } diff --git a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h index c2aafa9196..af95c42123 100644 --- a/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h +++ b/libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h @@ -112,9 +112,11 @@ typedef struct { /* 0x02 */ s8 stick_x; /* 0x03 */ s8 stick_y; /* 0x04 */ u8 err_no; - /* 0x05 */ f32 gyro_x; - /* 0x09 */ f32 gyro_y; -} OSContPad; // size = 0x0D + /* 0x05 */ f32 gyro_x; + /* 0x09 */ f32 gyro_y; + /* 0x1C */ f32 cam_x; + /* 0x20 */ f32 cam_y; +} OSContPad; // size = 0x24 typedef struct { /* 0x00 */ u8 rumble; diff --git a/libultraship/libultraship/SDLController.cpp b/libultraship/libultraship/SDLController.cpp index bc89cc78a7..d0550e7308 100644 --- a/libultraship/libultraship/SDLController.cpp +++ b/libultraship/libultraship/SDLController.cpp @@ -132,7 +132,7 @@ namespace Ship { } - void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold) { + void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick) { //scale {-32768 ... +32767} to {-84 ... +84} auto ax = wAxisValueX * 85.0 / 32767.0; auto ay = wAxisValueY * 85.0 / 32767.0; @@ -163,8 +163,15 @@ namespace Ship { ay *= scale; } - wStickX = +ax; - wStickY = -ay; + if (!isRightStick) { + wStickX = +ax; + wStickY = -ay; + } + else { + //SOHTODO KIRITO: Camera Sensitivity + wCamX = +ax * 15.0f; + wCamY = -ay * 15.0f; + } } void SDLController::ReadFromSource() { @@ -187,6 +194,10 @@ namespace Ship { } } + auto cameraX = SDL_GameControllerGetAxis(Cont, SDL_CONTROLLER_AXIS_RIGHTX); + auto cameraY = SDL_GameControllerGetAxis(Cont, SDL_CONTROLLER_AXIS_RIGHTY); + NormalizeStickAxis(cameraX, cameraY, ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTX], true); + if (SDL_GameControllerHasSensor(Cont, SDL_SENSOR_GYRO)) { size_t contNumber = GetControllerNumber(); @@ -328,7 +339,7 @@ namespace Ship { if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != SDL_CONTROLLER_AXIS_INVALID) { auto AxisValueX = SDL_GameControllerGetAxis(Cont, StickAxisX); auto AxisValueY = SDL_GameControllerGetAxis(Cont, StickAxisY); - NormalizeStickAxis(AxisValueX, AxisValueY, StickDeadzone); + NormalizeStickAxis(AxisValueX, AxisValueY, StickDeadzone, false); } } } @@ -365,12 +376,13 @@ namespace Ship { void SDLController::CreateDefaultBinding() { std::string ConfSection = GetBindingConfSection(); std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ConfigFile& Conf = *pConf.get(); - Conf[ConfSection][STR(BTN_CRIGHT)] = std::to_string((SDL_CONTROLLER_AXIS_RIGHTX + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_CLEFT)] = std::to_string(-(SDL_CONTROLLER_AXIS_RIGHTX + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_CDOWN)] = std::to_string((SDL_CONTROLLER_AXIS_RIGHTY + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_CUP)] = std::to_string(-(SDL_CONTROLLER_AXIS_RIGHTY + AXIS_SCANCODE_BIT)); + Conf[ConfSection][STR(BTN_CRIGHT)] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + Conf[ConfSection][STR(BTN_CLEFT)] = std::to_string(SDL_CONTROLLER_BUTTON_Y); + Conf[ConfSection][STR(BTN_CDOWN)] = std::to_string(SDL_CONTROLLER_BUTTON_X); + Conf[ConfSection][STR(BTN_CUP)] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSTICK); //Conf[ConfSection][STR(BTN_CRIGHT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_X); //Conf[ConfSection][STR(BTN_CLEFT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_Y); //Conf[ConfSection][STR(BTN_CDOWN + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); diff --git a/libultraship/libultraship/SDLController.h b/libultraship/libultraship/SDLController.h index 2493efbbce..d1d671bb99 100644 --- a/libultraship/libultraship/SDLController.h +++ b/libultraship/libultraship/SDLController.h @@ -44,7 +44,7 @@ namespace Ship { std::map ThresholdMapping; void LoadAxisThresholds(); - void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold); + void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick); bool Open(); bool Close(); }; diff --git a/libultraship/libultraship/UltraController.h b/libultraship/libultraship/UltraController.h index 1c18dcd9b3..e08212b979 100644 --- a/libultraship/libultraship/UltraController.h +++ b/libultraship/libultraship/UltraController.h @@ -120,7 +120,9 @@ typedef struct { /* 0x04 */ uint8_t err_no; /* 0x05 */ float gyro_x; /* 0x09 */ float gyro_y; -} OSContPad; // size = 0x0D + /* 0x1C */ float cam_x; + /* 0x20 */ float cam_y; +} OSContPad; // size = 0x24 typedef struct { /* 0x00 */ uint8_t rumble; diff --git a/soh/include/z64.h b/soh/include/z64.h index 2d8a6f4a8d..fdc634e58a 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -1203,6 +1203,9 @@ typedef struct GlobalContext { /* 0x00790 */ Camera* cameraPtrs[NUM_CAMS]; /* 0x007A0 */ s16 activeCamera; /* 0x007A2 */ s16 nextCamera; + /* 0x007A2 */ bool manualCamera; + /* 0x007A2 */ f32 camX; + /* 0x007A2 */ f32 camY; /* 0x007A4 */ SequenceContext sequenceCtx; /* 0x007A8 */ LightContext lightCtx; /* 0x007B8 */ FrameAdvanceContext frameAdvCtx; diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 7f4a5d704a..704062b1b3 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -1409,7 +1409,125 @@ s32 Camera_Noop(Camera* camera) { return true; } +s32 SetCameraManual(Camera* camera) { + f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x; + f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y; + + if ((fabsf(newCamX) >= 15.0f || fabsf(newCamY) >= 15.0f) && camera->globalCtx->manualCamera == false) { + camera->globalCtx->manualCamera = true; + + VecSph eyeAdjustment; + OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, &camera->at, &camera->eye); + + camera->globalCtx->camX = eyeAdjustment.yaw; + camera->globalCtx->camY = eyeAdjustment.pitch; + } + + if (camera->globalCtx->manualCamera) { + return 1; + } + + return 0; +} + +s32 Camera_Free(Camera* camera) { + Normal1* norm1 = (Normal1*)camera->paramData; + + f32 playerHeight = Player_GetHeight(camera->player); + f32 sp94; + CamColChk camBgChk; + PosRot* playerPosRot = &camera->playerPosRot; + Vec3f at; + + sCameraInterfaceFlags = norm1->interfaceFlags; + + if (RELOAD_PARAMS) { + VecSph eyeAdjustment1; + OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment1, &camera->at, &camera->eye); + + camera->globalCtx->camX = eyeAdjustment1.yaw; + camera->globalCtx->camY = eyeAdjustment1.pitch; + + CameraModeValue* values = sCameraSettings[camera->setting].cameraModes[camera->mode].values; + f32 yNormal = (1.0f + PCT(R_CAM_YOFFSET_NORM) - PCT(R_CAM_YOFFSET_NORM) * (68.0f / playerHeight)); + sp94 = yNormal * PCT(playerHeight); + + norm1->yOffset = NEXTSETTING * sp94; + norm1->distMin = NEXTSETTING * sp94; + norm1->distMax = NEXTSETTING * sp94; + norm1->pitchTarget = DEGF_TO_BINANG(NEXTSETTING); + norm1->unk_0C = NEXTSETTING; + norm1->unk_10 = NEXTSETTING; + norm1->unk_14 = NEXTPCT; + norm1->fovTarget = NEXTSETTING; + norm1->atLERPScaleMax = NEXTPCT; + norm1->interfaceFlags = NEXTSETTING; + } + + if (R_RELOAD_CAM_PARAMS) { + Camera_CopyPREGToModeValues(camera); + } + + VecSph eyeAdjustment; + const f32 camSpeed = 0.5f; + + camera->animState = 0; + + at.x = Camera_LERPCeilF(camera->player->actor.world.pos.x, camera->at.x, camSpeed, 1.0f); + at.y = Camera_LERPCeilF(camera->player->actor.world.pos.y + (camera->player->rideActor != NULL ? Player_GetHeight(camera->player) / 2 : Player_GetHeight(camera->player)) / 1.2f, camera->at.y, camSpeed, 1.0f); + at.z = Camera_LERPCeilF(camera->player->actor.world.pos.z, camera->at.z, camSpeed, 1.0f); + + OLib_Vec3fDiffToVecSphGeo(&eyeAdjustment, &at, &camera->eye); + + camBgChk.pos = camera->eye; + + float maxRadius = 160.0f; + if (Camera_BGCheckInfo(camera, &at, &camBgChk)) { + VecSph collSphere; + OLib_Vec3fDiffToVecSphGeo(&collSphere, &at, &camBgChk.pos); + float rad = collSphere.r; + + if (rad >= maxRadius) { + camera->dist = eyeAdjustment.r = Camera_LERPCeilF(maxRadius, camera->dist, camSpeed / 4, 1.0f); + } else { + camera->dist = eyeAdjustment.r = rad; + } + } else { + camera->dist = eyeAdjustment.r = Camera_LERPCeilF(maxRadius, camera->dist, camSpeed / 4, 1.0f); + } + + f32 newCamX = -D_8015BD7C->state.input[0].cur.cam_x; + f32 newCamY = D_8015BD7C->state.input[0].cur.cam_y; + + camera->globalCtx->camX += newCamX; + camera->globalCtx->camY += newCamY; + + if (camera->globalCtx->camY > 0x32A4) { + camera->globalCtx->camY = 0x32A4; + } + if (camera->globalCtx->camY < -0x228C) { + camera->globalCtx->camY = -0x228C; + } + + eyeAdjustment.yaw = camera->globalCtx->camX; + eyeAdjustment.pitch = camera->globalCtx->camY; + + Camera_Vec3fVecSphGeoAdd(&camera->eye, &at, &eyeAdjustment); + + camera->at = at; + camera->fov = Camera_LERPCeilF(60.0f, camera->fov, camSpeed / 2, 1.0f); + camera->roll = 0; + camera->eyeNext = camera->eye; + + return 1; +} + s32 Camera_Normal1(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -1637,6 +1755,11 @@ s32 Camera_Normal1(Camera* camera) { } s32 Camera_Normal2(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -1803,6 +1926,11 @@ s32 Camera_Normal2(Camera* camera) { // riding epona s32 Camera_Normal3(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -1997,6 +2125,8 @@ s32 Camera_Parallel1(Camera* camera) { OLib_Vec3fDiffToVecSphGeo(&atToEyeDir, at, eye); OLib_Vec3fDiffToVecSphGeo(&atToEyeNextDir, at, eyeNext); + camera->globalCtx->manualCamera = false; + switch (camera->animState) { case 0: case 0xA: @@ -2162,6 +2292,11 @@ s32 Camera_Parallel0(Camera* camera) { * Generic jump, jumping off ledges */ s32 Camera_Jump1(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -2307,6 +2442,11 @@ s32 Camera_Jump1(Camera* camera) { // Climbing ladders/vines s32 Camera_Jump2(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -2489,6 +2629,11 @@ s32 Camera_Jump2(Camera* camera) { // swimming s32 Camera_Jump3(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -2946,6 +3091,11 @@ s32 Camera_Battle3(Camera* camera) { * setting value. */ s32 Camera_Battle4(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; @@ -4476,6 +4626,11 @@ s32 Camera_Data4(Camera* camera) { * Hanging off of a ledge */ s32 Camera_Unique1(Camera* camera) { + if (CVar_GetS32("gFreeCamera", 0) && SetCameraManual(camera) == 1) { + Camera_Free(camera); + return 1; + } + Vec3f* eye = &camera->eye; Vec3f* at = &camera->at; Vec3f* eyeNext = &camera->eyeNext; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index d06f9ce4c4..c6938718fc 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -530,6 +530,10 @@ void Gameplay_Update(GlobalContext* globalCtx) { ActorOverlayTable_LogPrint(); } + if (CVar_GetS32("gFreeCamera", 0) && Player_InCsMode(globalCtx)) { + globalCtx->manualCamera = false; + } + gSegments[4] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.mainKeepIndex].segment); gSegments[5] = VIRTUAL_TO_PHYSICAL(globalCtx->objectCtx.status[globalCtx->objectCtx.subKeepIndex].segment); gSegments[2] = VIRTUAL_TO_PHYSICAL(globalCtx->sceneSegment); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h index 0a510eba20..93f4efb76c 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h +++ b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h @@ -203,6 +203,11 @@ void FileChoose_DrawOptions(GameState* thisx); void FileChoose_DrawNameEntry(GameState* thisx); void FileChoose_DrawCharacter(GraphicsContext* gfxCtx, void* texture, s16 vtx); +void HandleMouseInput(Input* input); +u8 HandleMouseCursor(FileChooseContext* this, Input* input, int minx, int miny, int maxx, int maxy); +Vec2f HandleMouseCursorSplit(FileChooseContext* this, Input* input, int minx, int miny, int maxx, int maxy, int countx, + int county); + extern s16 D_808123F0[]; #endif diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 08d0c855b5..d07222768a 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -415,15 +415,15 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { } if ((CVar_GetS32("gNewFileDropped", 0) != 0) || - (CVar_GetS32("gNewSeedGenerated", 0) != 0) || + (CVar_GetS32("gNewSeedGenerated", 0) != 0) || (!fileSelectSpoilerFileLoaded && - SpoilerFileExists(CVar_GetString("gSpoilerLog", "")))) { + SpoilerFileExists(CVar_GetString("gSpoilerLog", "")))) { if (CVar_GetS32("gNewFileDropped", 0) != 0) { CVar_SetString("gSpoilerLog", CVar_GetString("gDroppedFile", "")); } bool silent = true; - if((CVar_GetS32("gNewFileDropped", 0) != 0) || - (CVar_GetS32("gNewSeedGenerated", 0) != 0)) { + if ((CVar_GetS32("gNewFileDropped", 0) != 0) || + (CVar_GetS32("gNewSeedGenerated", 0) != 0)) { silent = false; } CVar_SetS32("gNewSeedGenerated", 0); From 3de58774ba973c16671d79a445288f494c1cd10a Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Tue, 12 Jul 2022 18:50:46 -0400 Subject: [PATCH 02/38] Rando: Allows Malon's Item Check to be obtained by pulling out the Ocarina. [FIXED PR] (#672) * Fixes using the Ocarina to get the check from Malon. Still some cleanup to do here. For some reason the player can shield before receiving the check. It doesn't set the flag if the player does that so they can still try again, but would prefer a different solution if possible. * Prevents Shielding from blocking the Item_Give from happening. * Code Cleanup and comments explaining the new rando flow. * Removes inventory check when pulling out Ocarina This allows OI to properly give the check, which is important for Glitched logic later down the line. Talking to Malon still requires the Ocarina in your inventory. * Prevents non-malon textboxes from triggering the check. Also adds a comment explaining the condtional for getting the check from talking to Malon since it got pretty long. * Actually fixes checking for text boxes. * Relocates a comment for improved clarity. --- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 76 +++++++++++++++---- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index d69e54e658..33e2bad213 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -25,6 +25,7 @@ void func_80AA106C(EnMa1* this, GlobalContext* globalCtx); void func_80AA10EC(EnMa1* this, GlobalContext* globalCtx); void func_80AA1150(EnMa1* this, GlobalContext* globalCtx); void EnMa1_DoNothing(EnMa1* this, GlobalContext* globalCtx); +void EnMa1_WaitForSongGive(EnMa1* this, GlobalContext* globalCtx); const ActorInit En_Ma1_InitVars = { ACTOR_EN_MA1, @@ -356,16 +357,20 @@ void func_80AA0EFC(EnMa1* this, GlobalContext* globalCtx) { void GivePlayerRandoRewardMalon(EnMa1* malon, GlobalContext* globalCtx, RandomizerCheck check) { GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_EPONAS_SONG); - + // Prevents flag from getting set if we weren't able to get the item (i.e. Player is holding shield + // when closing the textbox). if (malon->actor.parent != NULL && malon->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); - } else if (!Flags_GetTreasure(globalCtx, 0x1F) && - (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE) && - Actor_TextboxIsClosing(&malon->actor, globalCtx) && - (globalCtx->msgCtx.textId == 0x2049 || globalCtx->msgCtx.textId == 0x204A)) { + // puts malon in the action that vanilla has her in after learning the song + // (confirmed via breakpoints in a vanilla save). + malon->actionFunc = func_80AA0D88; + } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { func_8002F434(&malon->actor, globalCtx, getItemId, 10000.0f, 100.0f); } + // make malon sing again after giving the item. + malon->unk_1E8.unk_00 = 0; + malon->unk_1E0 = 1; } void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) { @@ -381,12 +386,8 @@ void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) { } } - if (gSaveContext.n64ddFlag) { - GivePlayerRandoRewardMalon(this, globalCtx, RC_SONG_FROM_MALON); - return; - } - if (gSaveContext.eventChkInf[1] & 0x40) { + // When the player pulls out the Ocarina while close to Malon if (player->stateFlags2 & 0x1000000) { player->stateFlags2 |= 0x2000000; player->unk_6A8 = &this->actor; @@ -394,10 +395,19 @@ void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) { Message_StartTextbox(globalCtx, this->actor.textId, NULL); this->unk_1E8.unk_00 = 1; this->actor.flags |= ACTOR_FLAG_16; - this->actionFunc = func_80AA106C; + // when rando'ed, skip to the Item Giving. Otherwise go to the song teaching code. + this->actionFunc = gSaveContext.n64ddFlag ? func_80AA1150 : func_80AA106C; } else if (this->actor.xzDistToPlayer < 30.0f + (f32)this->collider.dim.radius) { + // somehow flags that the player is close to malon so that pulling out the Ocarina + // triggers the code above this. player->stateFlags2 |= 0x800000; } + // If rando'ed, a textbox is closing, it's malon's 'my mom wrote this song' text, AND we do have an ocarina + // in our inventory. This allows us to grant the check when talking to malon with the ocarina in our inventory. + if (gSaveContext.n64ddFlag && (Actor_TextboxIsClosing(&this->actor, globalCtx) && globalCtx->msgCtx.textId == 0x2049) && + (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE || INV_CONTENT(ITEM_OCARINA_TIME) != ITEM_NONE)) { + this->actionFunc = EnMa1_WaitForSongGive; + } } } @@ -419,14 +429,48 @@ void func_80AA10EC(EnMa1* this, GlobalContext* globalCtx) { } } +void EnMa1_WaitForSongGive(EnMa1* this, GlobalContext* globalCtx) { + // Actually give the song check. + GivePlayerRandoRewardMalon(this, globalCtx, RC_SONG_FROM_MALON); +} + +// Sets an Ocarina State necessary to not softlock in rando. +// This function should only be called in rando. +void EnMa1_EndTeachSong(EnMa1* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state == CS_STATE_IDLE) { + this->actionFunc = func_80AA0F44; + globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_04; + } + + if (gSaveContext.n64ddFlag) { + // Transition to the giving the song check on the next update run. + this->actionFunc = EnMa1_WaitForSongGive; + } +} + void func_80AA1150(EnMa1* this, GlobalContext* globalCtx) { GET_PLAYER(globalCtx)->stateFlags2 |= 0x800000; + + // When rando'ed, trigger the "song learned" Ocarina mode. + if (gSaveContext.n64ddFlag && (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CLOSING)) { + globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_03; + } + if (globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_03) { - globalCtx->nextEntranceIndex = 0x157; - gSaveContext.nextCutsceneIndex = 0xFFF1; - globalCtx->fadeTransition = 42; - globalCtx->sceneLoadFlag = 0x14; - this->actionFunc = EnMa1_DoNothing; + if (!gSaveContext.n64ddFlag) { + globalCtx->nextEntranceIndex = 0x157; + gSaveContext.nextCutsceneIndex = 0xFFF1; + globalCtx->fadeTransition = 42; + globalCtx->sceneLoadFlag = 0x14; + this->actionFunc = EnMa1_DoNothing; + } else { + // When rando'ed, skip the cutscene, play the chime, reset some flags, + // and give the song on next update. + func_80078884(NA_SE_SY_CORRECT_CHIME); + this->actionFunc = EnMa1_EndTeachSong; + this->actor.flags &= ~ACTOR_FLAG_16; + globalCtx->msgCtx.ocarinaMode = OCARINA_MODE_00; + } } } From c9fdf8a48011719d0f8eb18cdfb241e23dcba4f1 Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 13 Jul 2022 00:55:01 +0200 Subject: [PATCH 03/38] Fix Rando Water Temple Softlock (#665) We use 3DS logic to generate item placement, but didn't have this specific door in Water Temple unlocked from the beginning like 3DS does. This meant that if people took specific paths through the temple, they could softlock themselves by missing a key. --- soh/src/code/z_sram.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 10daad0558..c88fc9ba1e 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -826,6 +826,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { // Go away ruto (water temple first cutscene) gSaveContext.sceneFlags[05].swch |= (1 << 0x10); + // Opens locked Water Temple door to prevent softlocks + // West door on the middle level that leads to the water raising thing + // Happens in 3DS rando and N64 rando as well + gSaveContext.sceneFlags[05].swch |= (1 << 0x15); + // Skip intro cutscene when bombing mud wall in Dodongo's cavern // this also makes the lower jaw render, and the eyes react to explosives Flags_SetEventChkInf(0xB0); From 2159c006fc5e0883c5bea2141ce8d9bbc0739a5a Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 13 Jul 2022 00:57:02 +0200 Subject: [PATCH 04/38] Rando: GtG and carpenter prompts skip (#663) * Skip gtg and carpenter prompt For rando. Tested and just works. * Fixed missing break --- .../actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 2aff2225c6..314092d494 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -252,12 +252,18 @@ void func_80B3A4F8(EnWonderTalk2* this, GlobalContext* globalCtx) { } this->unk_158 = 0; if (!this->unk_156) { - // whether or not to skip the text in rando + // Whether or not to skip the text in rando bool randoSkipText = false; if (gSaveContext.n64ddFlag) { - // scenes for which all of this type of wonder talk should be skipped. - switch (globalCtx->sceneNum) { - case 0x0007: //shadow temple + // Scenes for which all of this type of wonder talk should be skipped. + switch (globalCtx->sceneNum) { + case 0x0007: // Shadow Temple + randoSkipText = true; + break; + case 0x000B: // Gerudo Training Grounds + randoSkipText = true; + break; + case 0x000C: // Inside Gerudo Fortress randoSkipText = true; break; default: From 97ad234c8c0052801120badd8c4531505e5de2c0 Mon Sep 17 00:00:00 2001 From: vaguerant Date: Wed, 13 Jul 2022 13:58:24 +1000 Subject: [PATCH 05/38] Hide debug overlay behind gDebugEnabled (#660) --- soh/src/code/z_message_PAL.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 501a5b8cd0..9cf592e4fb 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3228,6 +3228,8 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) { * the last value being saved in a static variable. */ void Message_DrawDebugVariableChanged(s16* var, GraphicsContext* gfxCtx) { + if (!CVar_GetS32("gDebugEnabled", 0)) { return; } + static s16 sVarLastValue = 0; static s16 sFillTimer = 0; s32 pad; From 7b04f6788483923a5e43ac05d86542783296a380 Mon Sep 17 00:00:00 2001 From: David Chavez Date: Wed, 13 Jul 2022 06:19:07 +0200 Subject: [PATCH 06/38] Introduce App Directory Path (#572) * Introduce app directory path concept * macos: Remove hacky way of using applicaiton directory * Update the new SaveManager * Address stack user after return * Remove unecessary property * Use std::string for filepath * Improve clang specific detections * Use new path system for imgui files * Improve helper for getting relative paths --- BUILDING.md | 5 +- ZAPDTR/Makefile | 2 +- libultraship/Makefile | 37 +++++++++--- libultraship/libultraship/ConfigFile.cpp | 4 +- libultraship/libultraship/GlobalCtx2.cpp | 30 ++++++++-- libultraship/libultraship/GlobalCtx2.h | 3 + libultraship/libultraship/ImGuiImpl.cpp | 5 ++ libultraship/libultraship/OSXFolderManager.h | 60 +++++++++++++++++++ libultraship/libultraship/OSXFolderManager.mm | 37 ++++++++++++ soh/Makefile | 8 +-- soh/macosx/Info.plist | 2 +- soh/macosx/appsupport.m | 26 -------- soh/macosx/launcher.sh | 9 --- soh/soh/Enhancements/debugconsole.cpp | 9 ++- soh/soh/OTRGlobals.cpp | 3 +- soh/soh/SaveManager.cpp | 16 +++-- 16 files changed, 186 insertions(+), 70 deletions(-) create mode 100644 libultraship/libultraship/OSXFolderManager.h create mode 100644 libultraship/libultraship/OSXFolderManager.mm delete mode 100644 soh/macosx/appsupport.m delete mode 100755 soh/macosx/launcher.sh diff --git a/BUILDING.md b/BUILDING.md index 08ea20b35d..5999f1eb9d 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -63,9 +63,10 @@ make setup -j8 DEBUG=0 # Compile the code (watch the -j parameter as above) make -j8 DEBUG=0 # Create macOS app bundle -make filledappbundle +make appbundle ``` -9. Launch soh app in the soh folder! +9. Copy your OTR file to ~/Library/Application\ Support/com.shipofharkinian.soh +10. Launch soh app in the soh folder! # Compatible Roms ``` diff --git a/ZAPDTR/Makefile b/ZAPDTR/Makefile index d9a85b6dbc..755fd931aa 100644 --- a/ZAPDTR/Makefile +++ b/ZAPDTR/Makefile @@ -49,7 +49,7 @@ LDFLAGS := -lm -ldl \ -L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm ifeq ($(UNAME), Darwin) - LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL + LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation INC += $(shell pkg-config --cflags libpng) else LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse diff --git a/libultraship/Makefile b/libultraship/Makefile index b3b7d28363..819acce9f8 100644 --- a/libultraship/Makefile +++ b/libultraship/Makefile @@ -2,7 +2,7 @@ CXX ?= g++ CC ?= gcc -AR := ar +AR := ar FORMAT := clang-format-11 UNAME := $(shell uname) @@ -11,6 +11,15 @@ DEBUG ?= 1 OPTFLAGS ?= -O0 LTO ?= 0 +# flag to save whether the compiler being used is clang or gcc by checking CXX --version +CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang) +ifeq ($(CXX_IS_CLANG),1) + MXX := $(CXX) +else + MXX ?= clang++ +endif + + WARN := -Wall -Wextra -Werror \ -Wno-unused-variable \ -Wno-unused-parameter \ @@ -29,8 +38,7 @@ WARN := -Wall -Wextra -Werror \ CWARN := CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy -COMPILER_VERSION := $(shell $(CXX) --version) -ifneq '' '$(findstring g++,$(COMPILER_VERSION))' +ifneq ($(CXX_IS_CLANG),1) WARN += -Wno-error=stringop-overflow CXXWARN += -Wno-error=maybe-uninitialized endif @@ -39,12 +47,17 @@ CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0 CPPFLAGS := -MMD -ifeq ($(UNAME), Darwin) #APPLE - CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL +MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc + +# if not using clang, ask clang to use gcc standard library +ifneq ($(CXX_IS_CLANG),1) + STD_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | head -n 1) + CXX_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | tail -n 1) + MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM} endif -ifeq ($(UNAME), Linux) - WARN += -Wno-error=stringop-overflow # This is required with clang on Linux. +ifeq ($(UNAME), Darwin) #APPLE + CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation endif ifneq ($(DEBUG),0) @@ -78,12 +91,19 @@ C_FILES := \ libultraship/mixer.c \ libultraship/Lib/stb/stb_impl.c +MM_FILES := \ + libultraship/OSXFolderManager.mm + FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*") O_FILES := \ $(CXX_FILES:%.cpp=build/%.o) \ $(C_FILES:%.c=build/%.o) +ifeq ($(UNAME), Darwin) #APPLE + O_FILES += $(MM_FILES:%.mm=build/%.o) +endif + D_FILES := $(O_FILES:%.o=%.d) LIB := libultraship.a @@ -117,6 +137,9 @@ build/%.o: %.cpp build/%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@ +build/%.o: %.mm + $(MXX) $(MMFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@ + $(LIB): $(O_FILES) $(AR) rcs $@ $^ diff --git a/libultraship/libultraship/ConfigFile.cpp b/libultraship/libultraship/ConfigFile.cpp index 43dde4d8a9..e8a52d881f 100644 --- a/libultraship/libultraship/ConfigFile.cpp +++ b/libultraship/libultraship/ConfigFile.cpp @@ -56,10 +56,10 @@ namespace Ship { } bool ConfigFile::CreateDefaultConfig() { - (*this)["ARCHIVE"]["Main Archive"] = "oot.otr"; + (*this)["ARCHIVE"]["Main Archive"] = ""; (*this)["ARCHIVE"]["Patches Directory"] = ""; - (*this)["SAVE"]["Save Filename"] = "oot_save.sav"; + (*this)["SAVE"]["Save Filename"] = ""; (*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto"; (*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged"; diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp index 6da7412834..54e64e0ce5 100644 --- a/libultraship/libultraship/GlobalCtx2.cpp +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -8,10 +8,14 @@ #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/sohconsole_sink.h" #include "ModManager.h" +#ifdef __APPLE__ +#include "OSXFolderManager.h" +#endif namespace Ship { std::weak_ptr GlobalCtx2::Context; ModManager* INSTANCE; + std::shared_ptr GlobalCtx2::GetInstance() { return Context.lock(); } @@ -29,6 +33,22 @@ namespace Ship { return GetInstance(); } + std::string GlobalCtx2::GetAppDirectoryPath() { + #ifdef __APPLE__ + FolderManager folderManager; + std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask)); + fpath.append("/com.shipofharkinian.soh"); + return fpath; + #endif + + return "."; + + } + + std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) { + return GlobalCtx2::GetAppDirectoryPath() + "/" + path; + } + GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") { } @@ -40,14 +60,14 @@ namespace Ship { void GlobalCtx2::InitWindow() { InitLogging(); - Config = std::make_shared(GlobalCtx2::GetInstance(), "shipofharkinian.ini"); + Config = std::make_shared(GlobalCtx2::GetInstance(), GetPathRelativeToAppDirectory("shipofharkinian.ini")); MainPath = (*Config)["ARCHIVE"]["Main Archive"]; if (MainPath.empty()) { - MainPath = "oot.otr"; + MainPath = GetPathRelativeToAppDirectory("oot.otr"); } PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"]; if (PatchesPath.empty()) { - PatchesPath = "./"; + PatchesPath = GetAppDirectoryPath() + "/"; } ResMan = std::make_shared(GlobalCtx2::GetInstance(), MainPath, PatchesPath); Win = std::make_shared(GlobalCtx2::GetInstance()); @@ -67,11 +87,13 @@ namespace Ship { void GlobalCtx2::InitLogging() { try { + auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str()); + // Setup Logging spdlog::init_thread_pool(8192, 1); auto SohConsoleSink = std::make_shared(); auto ConsoleSink = std::make_shared(); - auto FileSink = std::make_shared("logs/" + GetName() + ".log", 1024 * 1024 * 10, 10); + auto FileSink = std::make_shared(logPath, 1024 * 1024 * 10, 10); SohConsoleSink->set_level(spdlog::level::trace); ConsoleSink->set_level(spdlog::level::trace); FileSink->set_level(spdlog::level::trace); diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h index 4a7502393a..5736e2b666 100644 --- a/libultraship/libultraship/GlobalCtx2.h +++ b/libultraship/libultraship/GlobalCtx2.h @@ -24,6 +24,9 @@ namespace Ship { std::shared_ptr GetLogger() { return Logger; } std::shared_ptr GetConfig() { return Config; } + static std::string GetAppDirectoryPath(); + static std::string GetPathRelativeToAppDirectory(const char* path); + void WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ba51c1e99b..ebc15ace85 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -304,6 +304,11 @@ namespace SohImGui { SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu"); } + auto imguiIniPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui.ini"); + auto imguiLogPath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("imgui_log.txt"); + io->IniFilename = strcpy(new char[imguiIniPath.length() + 1], imguiIniPath.c_str()); + io->LogFilename = strcpy(new char[imguiLogPath.length() + 1], imguiLogPath.c_str()); + if (UseViewports()) { io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; } diff --git a/libultraship/libultraship/OSXFolderManager.h b/libultraship/libultraship/OSXFolderManager.h new file mode 100644 index 0000000000..476b78d3c7 --- /dev/null +++ b/libultraship/libultraship/OSXFolderManager.h @@ -0,0 +1,60 @@ +// +// OSXFolderManager.h +// libultraship +// +// Created by David Chavez on 28.06.22. +// + +#ifndef OSXFolderManager_h +#define OSXFolderManager_h + +#include +namespace Ship { + enum { + NSApplicationDirectory = 1, + NSDemoApplicationDirectory, + NSDeveloperApplicationDirectory, + NSAdminApplicationDirectory, + NSLibraryDirectory, + NSDeveloperDirectory, + NSUserDirectory, + NSDocumentationDirectory, + NSDocumentDirectory, + NSCoreServiceDirectory, + NSAutosavedInformationDirectory = 11, + NSDesktopDirectory = 12, + NSCachesDirectory = 13, + NSApplicationSupportDirectory = 14, + NSDownloadsDirectory = 15, + NSInputMethodsDirectory = 16, + NSMoviesDirectory = 17, + NSMusicDirectory = 18, + NSPicturesDirectory = 19, + NSPrinterDescriptionDirectory = 20, + NSSharedPublicDirectory = 21, + NSPreferencePanesDirectory = 22, + NSApplicationScriptsDirectory = 23, + NSItemReplacementDirectory = 99, + NSAllApplicationsDirectory = 100, + NSAllLibrariesDirectory = 101, + NSTrashDirectory = 102 + }; + typedef unsigned long SearchPathDirectory; + + enum { + NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~) + NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library) + NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network) + NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System) + NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items + }; + typedef unsigned long SearchPathDomainMask; + + class FolderManager { + public: + const char *pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask); + const char *pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, SearchPathDomainMask domainMask, const char *itemPath, bool create = false); + }; +}; + +#endif /* OSXFolderManager_h */ diff --git a/libultraship/libultraship/OSXFolderManager.mm b/libultraship/libultraship/OSXFolderManager.mm new file mode 100644 index 0000000000..85bfb20a88 --- /dev/null +++ b/libultraship/libultraship/OSXFolderManager.mm @@ -0,0 +1,37 @@ +// +// OSXFolderManager.m +// libultraship +// +// Created by David Chavez on 28.06.22. +// + +#include "OSXFolderManager.h" +#import + +using namespace Ship; + +const char * FolderManager::pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray *URLs = [fileManager URLsForDirectory:(NSSearchPathDirectory)directory inDomains:domainMask]; + if (URLs.count == 0) return NULL; + + NSURL *URL = [URLs objectAtIndex:0]; + NSString *path = URL.path; + + // `fileSystemRepresentation` on an `NSString` gives a path suitable for POSIX APIs + return path.fileSystemRepresentation; +} + +const char * FolderManager::pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, + SearchPathDomainMask domainMask, const char *itemPath, bool create) { + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *nsPath = [fileManager stringWithFileSystemRepresentation:itemPath length:strlen(itemPath)]; + NSURL *itemURL = (nsPath ? [NSURL fileURLWithPath:nsPath] : nil); + + NSURL *URL = [fileManager URLForDirectory:(NSSearchPathDirectory)directory + inDomain:domainMask + appropriateForURL:itemURL + create:create error:NULL]; + return URL.path.fileSystemRepresentation; +} diff --git a/soh/Makefile b/soh/Makefile index 14bb46827b..b05321a60b 100644 --- a/soh/Makefile +++ b/soh/Makefile @@ -120,6 +120,7 @@ ifeq ($(UNAME), Darwin) #APPLE LDLIBS += \ $(addprefix -framework , \ OpenGL \ + Foundation \ ) \ $(shell sdl2-config --libs) $(shell pkg-config --libs glew) endif @@ -224,9 +225,6 @@ appbundle: macosx/$(APPNAME).icns cp macosx/PkgInfo $(APPBUNDLECONTENTS)/ cp macosx/$(APPNAME).icns $(APPBUNDLEICON)/ cp $(TARGET) $(APPBUNDLEEXE)/soh - cp macosx/launcher.sh $(APPBUNDLEEXE)/launcher.sh - clang -ObjC macosx/appsupport.m -arch arm64 -arch x86_64 -framework Foundation -o macosx/appsupport - cp macosx/appsupport $(APPBUNDLEEXE)/appsupport otool -l $(TARGET) | grep -A 2 LC_RPATH | tail -n 1 | awk '{print $2}' | dylibbundler -od -b -x $(APPBUNDLEEXE)/soh -d $(APPBUNDLECONTENTS)/libs macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png @@ -244,7 +242,3 @@ macosx/$(APPNAME).icns: macosx/$(APPNAME)Icon.png cp macosx/$(APPNAME)Icon.png macosx/$(APPNAME).iconset/icon_512x512@2x.png iconutil -c icns -o macosx/$(APPNAME).icns macosx/$(APPNAME).iconset rm -r macosx/$(APPNAME).iconset - -filledappbundle: appbundle - cp ./oot.otr $(APPBUNDLEEXE)/oot.otr - diff --git a/soh/macosx/Info.plist b/soh/macosx/Info.plist index af3ea4de5c..f657ef6578 100644 --- a/soh/macosx/Info.plist +++ b/soh/macosx/Info.plist @@ -7,7 +7,7 @@ CFBundleName Ship of Harkinian CFBundleExecutable - launcher.sh + soh CFBundleGetInfoString 2.0.0 CFBundleIconFile diff --git a/soh/macosx/appsupport.m b/soh/macosx/appsupport.m deleted file mode 100644 index a7df45e676..0000000000 --- a/soh/macosx/appsupport.m +++ /dev/null @@ -1,26 +0,0 @@ -#import -int main(void) { - NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) lastObject]; - //If there isn't an App Support Directory yet ... - if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir isDirectory:NULL]) { - NSError *error = nil; - //Create one - if (![[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:&error]) { - NSLog(@"%@", error.localizedDescription); - } - else { - // *** OPTIONAL *** Mark the directory as excluded from iCloud backups - NSURL *url = [NSURL fileURLWithPath:appSupportDir]; - if (![url setResourceValue:@YES - forKey:NSURLIsExcludedFromBackupKey - error:&error]) - { - NSLog(@"Error excluding %@ from backup %@", url.lastPathComponent, error.localizedDescription); - } - else { - NSLog(@"Yay"); - } - } - } - printf("%s\n", [appSupportDir UTF8String]); -} diff --git a/soh/macosx/launcher.sh b/soh/macosx/launcher.sh deleted file mode 100755 index ef22983de3..0000000000 --- a/soh/macosx/launcher.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -APPPATH="${0%/*}" -cd "${APPPATH}" -APPPATH=$(pwd) -APPSUPPORT=$(./appsupport) -mkdir -p "${APPSUPPORT}/com.shipofharkinian.soh" -cd "${APPSUPPORT}/com.shipofharkinian.soh" -cp "${APPPATH}/oot.otr" . -${APPPATH}/soh diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 445134f2ab..b2981d3615 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -500,8 +500,9 @@ template bool is_number(const std::string& s) { void DebugConsole_LoadCVars() { - if (File::Exists("cvars.cfg")) { - const auto lines = File::ReadAllLines("cvars.cfg"); + auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); + if (File::Exists(cvarsConfig)) { + const auto lines = File::ReadAllLines(cvarsConfig); for (const std::string& line : lines) { std::vector cfg = StringHelper::Split(line, " = "); @@ -535,5 +536,7 @@ void DebugConsole_SaveCVars() output += StringHelper::Sprintf("%s = %f\n", cvar.first.c_str(), cvar.second->value.valueFloat); } - File::WriteAllText("cvars.cfg", output); + + auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); + File::WriteAllText(cvarsConfig, output); } diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 042a4b5e99..3a862d58ab 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -57,7 +57,6 @@ OTRGlobals* OTRGlobals::Instance; SaveManager* SaveManager::Instance; OTRGlobals::OTRGlobals() { - context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian"); gSaveStateMgr = std::make_shared(); gRandomizer = std::make_shared(); @@ -1158,7 +1157,7 @@ std::filesystem::path GetSaveFile(Ship::ConfigFile& Conf) { std::string fileName = Conf.get("SAVE").get("Save Filename"); if (fileName.empty()) { - Conf["SAVE"]["Save Filename"] = "oot_save.sav"; + Conf["SAVE"]["Save Filename"] = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"); Conf.Save(); } std::filesystem::path saveFile = std::filesystem::absolute(fileName); diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 1bbbd3a1ce..cbe4315d3d 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1,4 +1,5 @@ #include "SaveManager.h" +#include "OTRGlobals.h" #include "z64.h" #include "functions.h" @@ -14,11 +15,9 @@ extern "C" SaveContext gSaveContext; -static const std::filesystem::path sSavePath("Save"); // TODO maybe let this be user-configurable? -static const std::filesystem::path sGlobalPath = sSavePath / "global.sav"; - std::filesystem::path SaveManager::GetFileName(int fileNum) { - return sSavePath / (std::string("file") + std::to_string(fileNum + 1) + ".sav"); + const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save")); + return sSavePath / ("file" + std::to_string(fileNum + 1) + ".sav"); } SaveManager::SaveManager() { @@ -128,15 +127,20 @@ void SaveManager::SaveRandomizer() { } void SaveManager::Init() { + const std::filesystem::path sSavePath(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Save")); + const std::filesystem::path sGlobalPath = sSavePath / std::string("global.sav"); + auto sOldSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"); + auto sOldBackupSavePath = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.bak"); + // If the save directory does not exist, create it if (!std::filesystem::exists(sSavePath)) { std::filesystem::create_directory(sSavePath); } // If there is a lingering unversioned save, convert it - if (std::filesystem::exists("oot_save.sav")) { + if (std::filesystem::exists(sOldSavePath)) { ConvertFromUnversioned(); - std::filesystem::rename("oot_save.sav", "oot_save.bak"); + std::filesystem::rename(sOldSavePath, sOldBackupSavePath); } // If the global save file exist, load it. Otherwise, create it. From cff73cccf0acaa413294698f50951366641ba864 Mon Sep 17 00:00:00 2001 From: Baoulettes Date: Wed, 13 Jul 2022 06:23:22 +0200 Subject: [PATCH 07/38] fix hidden wnd (#744) --- libultraship/libultraship/ImGuiImpl.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ebc15ace85..08c72897f6 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1231,12 +1231,13 @@ namespace SohImGui { for (const auto& category : hiddenwindowCategories) { ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::SetNextWindowSize(ImVec2 (0,0)); - ImGui::SetNextWindowPos(ImVec2 (-100,-100)); - ImGui::Begin(category.first.c_str(), nullptr, ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus); + ImGuiWindowFlags HiddenWndFlags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings | + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoDecoration; + ImGui::Begin(category.first.c_str(), nullptr, HiddenWndFlags); ImGui::End(); ImGui::PopStyleColor(); } - if (CVar_GetS32("gStatsEnabled", 0)) { const float framerate = ImGui::GetIO().Framerate; ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); From 4d65a5ff736f65135f64cc1861934742cc5800ad Mon Sep 17 00:00:00 2001 From: earthcrafterman Date: Wed, 13 Jul 2022 00:24:05 -0400 Subject: [PATCH 08/38] Split damage multiplication into its own PR (#656) * Split damage multiplication into its own PR * Found a more elegant implementation of the powers char*[] --- libultraship/libultraship/ImGuiImpl.cpp | 48 ++++++++++++++++--- .../actors/ovl_player_actor/z_player.c | 6 +-- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 08c72897f6..69d05a74d7 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -72,6 +72,18 @@ namespace SohImGui { "None" }; + const char* powers[9] = { + "Vanilla (1x)", + "Double (2x)", + "Quadruple (4x)", + "Octuple (8x)", + "Hexadecuple (16x)", + "Duotrigintuple (32x)", + "Quattuorsexagintuple (64x)", + "Octoviginticentuple (128x)", + "Hexaquinquagintiducentuple (256x)" + }; + std::map> hiddenwindowCategories; std::map> windowCategories; std::map customWindows; @@ -886,12 +898,36 @@ namespace SohImGui { if (ImGui::BeginMenu("Difficulty Options")) { - EnhancementSliderInt("Damage Multiplier %dx", "##DAMAGEMUL", "gDamageMul", 1, 4, ""); - Tooltip("Modifies all sources of damage not affected by other sliders"); - EnhancementSliderInt("Fall Damage Multiplier %dx", "##FALLDAMAGEMUL", "gFallDamageMul", 1, 4, ""); - Tooltip("Modifies all fall damage"); - EnhancementSliderInt("Void Damage Multiplier %dx", "##VOIDDAMAGEMUL", "gVoidDamageMul", 1, 4, ""); - Tooltip("Modifies damage taken after falling into a void"); + ImGui::Text("Damage Multiplier"); + EnhancementCombobox("gDamageMul", powers, 9, 0); + Tooltip("Modifies all sources of damage not affected by other sliders\n\ +2x: Can survive all common attacks from the start of the game\n\ +4x: Dies in 1 hit to any substantial attack from the start of the game\n\ +8x: Can only survive trivial damage from the start of the game\n\ +16x: Can survive all common attacks with max health without double defense\n\ +32x: Can survive all common attacks with max health and double defense\n\ +64x: Can survive trivial damage with max health without double defense\n\ +128x: Can survive trivial damage with max health and double defense\n\ +256x: Cannot survive damage"); + ImGui::Text("Fall Damage Multiplier"); + EnhancementCombobox("gFallDamageMul", powers, 8, 0); + Tooltip("Modifies all fall damage\n\ +2x: Can survive all fall damage from the start of the game\n\ +4x: Can only survive short fall damage from the start of the game\n\ +8x: Cannot survive any fall damage from the start of the game\n\ +16x: Can survive all fall damage with max health without double defense\n\ +32x: Can survive all fall damage with max health and double defense\n\ +64x: Can survive short fall damage with double defense\n\ +128x: Cannot survive fall damage"); + ImGui::Text("Void Damage Multiplier"); + EnhancementCombobox("gVoidDamageMul", powers, 7, 0); + Tooltip("Modifies damage taken after falling into a void\n\ +2x: Can survive void damage from the start of the game\n\ +4x: Cannot survive void damage from the start of the game\n\ +8x: Can survive void damage twice with max health without double defense\n\ +16x: Can survive void damage with max health without double defense\n\ +32x: Can survive void damage with max health and double defense\n\ +64x: Cannot survive void damage"); EnhancementCheckbox("No Random Drops", "gNoRandomDrops"); Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses"); diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 70cf3ebb79..1973a09a44 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -3603,7 +3603,7 @@ s32 func_80837B18_modified(GlobalContext* globalCtx, Player* this, s32 damage, u s32 modifiedDamage = damage; if (modified) { - modifiedDamage *= CVar_GetS32("gDamageMul", 1); + modifiedDamage *= (1 << CVar_GetS32("gDamageMul", 0)); } return Health_ChangeBy(globalCtx, modifiedDamage); @@ -3836,7 +3836,7 @@ s32 func_808382DC(Player* this, GlobalContext* globalCtx) { if (this->unk_A86 != 0) { if (!Player_InBlockingCsMode(globalCtx, this)) { - Player_InflictDamageModified(globalCtx, -16 * CVar_GetS32("gVoidDamageMul", 1), false); + Player_InflictDamageModified(globalCtx, -16 * (1 << CVar_GetS32("gVoidDamageMul", 0)), false); this->unk_A86 = 0; } } @@ -8407,7 +8407,7 @@ s32 func_80843E64(GlobalContext* globalCtx, Player* this) { impactInfo = &D_80854600[impactIndex]; - if (Player_InflictDamageModified(globalCtx, impactInfo->damage * CVar_GetS32("gFallDamageMul", 1), false)) { + if (Player_InflictDamageModified(globalCtx, impactInfo->damage * (1 << CVar_GetS32("gFallDamageMul", 0)), false)) { return -1; } From 7c6d8a6b9caf4d6b2893b364e173668b153afcdc Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Wed, 13 Jul 2022 19:38:25 -0400 Subject: [PATCH 09/38] Fixes Maps, Compasses, and Boss Keys in Vanilla. (#751) --- soh/src/code/z_parameter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 08a9cf520e..0ac1e1048c 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1710,6 +1710,8 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { } else { gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; } + } else { + gSaveContext.inventory.dungeonItems[gSaveContext.mapIndex] |= gBitFlags[item - ITEM_KEY_BOSS]; } return ITEM_NONE; } else if (item == ITEM_KEY_SMALL) { From 2b72b10356ecc041381c8761244bc72abaea6d86 Mon Sep 17 00:00:00 2001 From: Baoulettes Date: Wed, 13 Jul 2022 16:53:19 +0200 Subject: [PATCH 10/38] .xiF slebaL --- .../Enhancements/cosmetics/CosmeticsEditor.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 969488569f..05dbe97641 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -178,28 +178,28 @@ void Draw_Npcs(){ ImGui::TableSetupColumn("Outer colors##Navi", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort, TablesCellsWidth/2); Table_InitHeader(); Draw_HelpIcon("Inner color for Navi (idle flying around)"); - SohImGui::EnhancementColor("Navi Idle", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255, 255, 255, 255), false); + SohImGui::EnhancementColor("Navi Idle (Primary)", "gNavi_Idle_Inner_", navi_idle_i_col, ImVec4(255, 255, 255, 255), false); Table_NextCol(); Draw_HelpIcon("Outer color for Navi (idle flying around)"); - SohImGui::EnhancementColor("Navi Idle", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0, 0, 255, 255), false); + SohImGui::EnhancementColor("Navi Idle (Secondary)", "gNavi_Idle_Outer_", navi_idle_o_col, ImVec4(0, 0, 255, 255), false); Table_NextLine(); Draw_HelpIcon("Inner color for Navi (when Navi fly around NPCs)"); - SohImGui::EnhancementColor("Navi NPC", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150, 150, 255, 255), false); + SohImGui::EnhancementColor("Navi NPC (Primary)", "gNavi_NPC_Inner_", navi_npc_i_col, ImVec4(150, 150, 255, 255), false); Table_NextCol(); Draw_HelpIcon("Outer color for Navi (when Navi fly around NPCs)"); - SohImGui::EnhancementColor("Navi NPC", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150, 150, 255, 255), false); + SohImGui::EnhancementColor("Navi NPC (Secondary)", "gNavi_NPC_Outer_", navi_npc_o_col, ImVec4(150, 150, 255, 255), false); Table_NextLine(); Draw_HelpIcon("Inner color for Navi (when Navi fly around Enemies or Bosses)"); - SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false); + SohImGui::EnhancementColor("Navi Enemy (Primary)", "gNavi_Enemy_Inner_", navi_enemy_i_col, ImVec4(255, 255, 0, 255), false); Table_NextCol(); Draw_HelpIcon("Outer color for Navi (when Navi fly around Enemies or Bosses)"); - SohImGui::EnhancementColor("Navi Enemy", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false); + SohImGui::EnhancementColor("Navi Enemy (Secondary)", "gNavi_Enemy_Outer_", navi_enemy_o_col, ImVec4(220, 155, 0, 255), false); Table_NextLine(); Draw_HelpIcon("Inner color for Navi (when Navi fly around props (signs etc))"); - SohImGui::EnhancementColor("Navi Prop", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0, 255, 0, 255), false); + SohImGui::EnhancementColor("Navi Prop (Primary)", "gNavi_Prop_Inner_", navi_prop_i_col, ImVec4(0, 255, 0, 255), false); Table_NextCol(); Draw_HelpIcon("Outer color for Navi (when Navi fly around props (signs etc))"); - SohImGui::EnhancementColor("Navi Prop", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0, 255, 0, 255), false); + SohImGui::EnhancementColor("Navi Prop (Secondary)", "gNavi_Prop_Outer_", navi_prop_o_col, ImVec4(0, 255, 0, 255), false); ImGui::EndTable(); } SohImGui::EnhancementCheckbox("Custom colors for Keese", "gUseKeeseCol"); From 248f49b3bfa39c80f157fdc2c15500f3e5384007 Mon Sep 17 00:00:00 2001 From: ChristopherJTrent Date: Tue, 12 Jul 2022 23:20:09 -0700 Subject: [PATCH 11/38] Update Keese labels --- soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 05dbe97641..9804d6c69d 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -212,10 +212,10 @@ void Draw_Npcs(){ SohImGui::EnhancementColor("Fire Primary color", "gKeese1_Ef_Prim", Keese1_primcol, ImVec4(255, 255, 100, 255)); Table_NextCol(); Draw_HelpIcon("Affects the primary color of the Ice itself of the Keese"); - SohImGui::EnhancementColor("Fire Primary color", "gKeese2_Ef_Prim", Keese2_primcol, ImVec4(100, 200, 255, 255)); + SohImGui::EnhancementColor("Ice Primary color", "gKeese2_Ef_Prim", Keese2_primcol, ImVec4(100, 200, 255, 255)); Table_NextLine(); Draw_HelpIcon("Affects the secondary color of the Fire itself of the Keese"); - SohImGui::EnhancementColor("Ice Secondary color", "gKeese1_Ef_Env", Keese1_envcol, ImVec4(255, 50, 0, 255)); + SohImGui::EnhancementColor("Fire Secondary color", "gKeese1_Ef_Env", Keese1_envcol, ImVec4(255, 50, 0, 255)); Table_NextCol(); Draw_HelpIcon("Affects the secondary color of the Ice itself of the Keese"); SohImGui::EnhancementColor("Ice Secondary color", "gKeese2_Ef_Env", Keese2_envcol, ImVec4(0, 0, 255, 255)); From 379649beadeeec32f73e4e203887e57d66977658 Mon Sep 17 00:00:00 2001 From: Nicholas Estelami Date: Wed, 13 Jul 2022 21:26:44 -0400 Subject: [PATCH 12/38] Fixed soundfont issues --- soh/src/code/audio_seqplayer.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/soh/src/code/audio_seqplayer.c b/soh/src/code/audio_seqplayer.c index 3ae70719ce..b8fbd9e1f4 100644 --- a/soh/src/code/audio_seqplayer.c +++ b/soh/src/code/audio_seqplayer.c @@ -1176,9 +1176,13 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { if (seqPlayer->defaultFont != 0xFF) { SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]); - int8_t idx = (sDat.numFonts - result - 1); - command = sDat.fonts[abs(idx)]; + // The game apparantely would sometimes do negative array lookups, the result of which would get rejected by AudioHeap_SearchCaches, never + // changing the actual fontid. + if (result > sDat.numFonts) + break; + + command = sDat.fonts[(sDat.numFonts - result - 1)]; } if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) From f7db8868d04a1e3cd0a2c3343a9def5a95f8c481 Mon Sep 17 00:00:00 2001 From: aMannus Date: Thu, 14 Jul 2022 04:04:19 +0200 Subject: [PATCH 13/38] Skip warp song cutscenes in rando (#664) Does it by skipping to the last part of the cutscene data. Tested on all songs, both adult and child. --- soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 32eab2b642..b365b3038a 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -788,7 +788,14 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, GlobalContext* globalCtx) { this->unk_150[i].unk_0.y = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22); this->unk_150[i].unk_0.z = (s16)((Rand_ZeroOne() - 0.5f) * 16.0f * temp_f22); this->unk_150[i].unk_23 = 0; - this->unk_150[i].unk_22++; + + // Skip the first part of warp song cutscenes in rando + if (gSaveContext.n64ddFlag && this->actor.params == DEMOKANKYO_WARP_OUT) { + this->unk_150[i].unk_22 = 2; + } else { + this->unk_150[i].unk_22++; + } + case 1: if (this->actor.params == DEMOKANKYO_WARP_OUT) { if (func_800BB2B4(&camPos, &sWarpRoll, &sWarpFoV, sWarpOutCameraPoints, &this->unk_150[i].unk_20, From cb6876792e99f8420ca0626ac55a9b57c638bc13 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 13 Jul 2022 22:04:48 -0400 Subject: [PATCH 14/38] don't spawn blocking mido after we've already shown him the sword/shield (#675) Co-authored-by: briaguya --- soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 86f07884a7..3bf4fcbb08 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -485,7 +485,10 @@ u8 EnMd_ShouldSpawn(EnMd* this, GlobalContext* globalCtx) { if (globalCtx->sceneNum == SCENE_SPOT04) { if (gSaveContext.n64ddFlag) { // if we have beaten deku tree or have open forest turned on - if (gSaveContext.dungeonsDone[1] || GetRandoSettingValue(RSK_FOREST) == 1) { + // or have already shown mido we have an equipped sword/shield + if (gSaveContext.dungeonsDone[1] || + GetRandoSettingValue(RSK_FOREST) == 1 || + gSaveContext.eventChkInf[0] & 0x10) { return 0; } return 1; From 219804cbe4e9d494f0152f40155115bb308002d4 Mon Sep 17 00:00:00 2001 From: KiritoDev <36680385+KiritoDv@users.noreply.github.com> Date: Wed, 13 Jul 2022 22:12:11 -0500 Subject: [PATCH 15/38] Controller Configuration UI and JSON Config (#760) * Initial controller hud ui * Reverted fbdemo changes * Moved config to json and implemented controller config * fix build on linux, gitignore new config file * fix build * Fix compilation and file directory paths * Call save on cvar save * Fixed cvar loading and added deck slots to the config * Changed control deck port 0 to use a physical device by default * Added gyro and rumble & fixed loading errors * Save config on toggle menubar * fix linux build * Fixed drift calculation * Controller config now saves when pressing F1 * Removed ExitGame hook from ImGuiImpl * Moved mappings to a map * Added GetKeyName * untranslate scancodes * Fixed hud layout on keyboard device * Fixed keyboard read on hud * Fixed crash when reloading controllers * Removed ConfigFile and changed file extension * Changed Dummy to Disconnected and fixed filters * Removed function leftover * Changed ControllerHud to InputEditor Co-authored-by: briaguya Co-authored-by: David Chavez --- .gitignore | 1 + libultraship/Makefile | 2 + libultraship/libultraship/ConfigFile.cpp | 164 ------ libultraship/libultraship/ConfigFile.h | 42 -- libultraship/libultraship/ControlDeck.cpp | 155 ++++++ libultraship/libultraship/ControlDeck.h | 20 + libultraship/libultraship/Controller.cpp | 108 ++-- libultraship/libultraship/Controller.h | 70 ++- libultraship/libultraship/ControllerHud.cpp | 277 ++++++++++ libultraship/libultraship/Cvar.cpp | 3 +- .../libultraship/DisconnectedController.h | 31 ++ libultraship/libultraship/GameSettings.cpp | 14 +- libultraship/libultraship/GlobalCtx2.cpp | 28 +- libultraship/libultraship/GlobalCtx2.h | 11 +- libultraship/libultraship/Hooks.h | 6 +- libultraship/libultraship/ImGuiImpl.cpp | 208 +++++--- libultraship/libultraship/ImGuiImpl.h | 8 +- libultraship/libultraship/InputEditor.cpp | 277 ++++++++++ libultraship/libultraship/InputEditor.h | 20 + .../libultraship/KeyboardController.cpp | 89 +++- .../libultraship/KeyboardController.h | 34 +- .../libultraship/Lib/Fast3D/gfx_dxgi.cpp | 9 + .../libultraship/Lib/Fast3D/gfx_sdl2.cpp | 20 +- .../Lib/Fast3D/gfx_window_manager_api.h | 1 + .../libultraship/Lib/Mercury/Mercury.cpp | 134 +++++ .../libultraship/Lib/Mercury/Mercury.h | 47 ++ .../libultraship}/Lib/nlohmann/LICENSE.MIT | 0 .../libultraship}/Lib/nlohmann/json.hpp | 0 libultraship/libultraship/SDLController.cpp | 504 ++++++++++-------- libultraship/libultraship/SDLController.h | 41 +- libultraship/libultraship/UltraController.h | 4 + libultraship/libultraship/Window.cpp | 171 +++--- libultraship/libultraship/Window.h | 12 +- .../libultraship/libultraship.vcxproj | 22 +- .../libultraship/libultraship.vcxproj.filters | 42 +- soh/include/functions.h | 1 + soh/soh.vcxproj | 3 +- soh/soh.vcxproj.filters | 9 - soh/soh/Enhancements/bootcommands.c | 3 +- soh/soh/Enhancements/debugconsole.cpp | 63 ++- .../randomizer/3drando/spoiler_log.cpp | 2 +- .../Enhancements/randomizer/randomizer.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.h | 5 +- soh/soh/OTRGlobals.cpp | 61 +-- soh/soh/OTRGlobals.h | 4 +- soh/src/code/padmgr.c | 2 +- soh/src/code/z_camera.c | 2 +- soh/src/code/z_fbdemo_wipe1.c | 1 + .../ovl_file_choose/z_file_choose.c | 4 +- 49 files changed, 1841 insertions(+), 896 deletions(-) delete mode 100644 libultraship/libultraship/ConfigFile.cpp delete mode 100644 libultraship/libultraship/ConfigFile.h create mode 100644 libultraship/libultraship/ControlDeck.cpp create mode 100644 libultraship/libultraship/ControlDeck.h create mode 100644 libultraship/libultraship/ControllerHud.cpp create mode 100644 libultraship/libultraship/DisconnectedController.h create mode 100644 libultraship/libultraship/InputEditor.cpp create mode 100644 libultraship/libultraship/InputEditor.h create mode 100644 libultraship/libultraship/Lib/Mercury/Mercury.cpp create mode 100644 libultraship/libultraship/Lib/Mercury/Mercury.h rename {soh/soh => libultraship/libultraship}/Lib/nlohmann/LICENSE.MIT (100%) rename {soh/soh => libultraship/libultraship}/Lib/nlohmann/json.hpp (100%) diff --git a/.gitignore b/.gitignore index 5a201405d7..4b6eb39688 100644 --- a/.gitignore +++ b/.gitignore @@ -405,3 +405,4 @@ tags oot.otr *.sav shipofharkinian.ini +shipofharkinian.json \ No newline at end of file diff --git a/libultraship/Makefile b/libultraship/Makefile index 819acce9f8..18dfca2715 100644 --- a/libultraship/Makefile +++ b/libultraship/Makefile @@ -82,6 +82,7 @@ CXX_FILES := \ $(shell find libultraship/Lib/Fast3D -name "*.cpp") \ $(shell find libultraship -maxdepth 1 -name "*.cpp") \ $(shell find libultraship/Lib/ImGui -maxdepth 1 -name "*.cpp") \ + $(shell find libultraship/Lib/Mercury -maxdepth 1 -name "*.cpp") \ libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \ libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \ libultraship/Lib/StrHash64.cpp \ @@ -114,6 +115,7 @@ INC_DIRS := $(addprefix -I, \ libultraship/Lib/spdlog \ libultraship/Lib/spdlog/include \ libultraship/Lib/ImGui \ + libultraship/Lib/Mercury \ libultraship \ ../StormLib/src \ ) diff --git a/libultraship/libultraship/ConfigFile.cpp b/libultraship/libultraship/ConfigFile.cpp deleted file mode 100644 index e8a52d881f..0000000000 --- a/libultraship/libultraship/ConfigFile.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "ConfigFile.h" -#include "spdlog/spdlog.h" -#include "GlobalCtx2.h" -#include "Window.h" -#include "GameSettings.h" - -namespace Ship { - ConfigFile::ConfigFile(std::shared_ptr Context, const std::string& Path) : Context(Context), Path(Path), File(Path.c_str()) { - if (Path.empty()) { - SPDLOG_ERROR("ConfigFile received an empty file name"); - exit(EXIT_FAILURE); - } - - if (!File.read(Val)) { - if (!CreateDefaultConfig()) { - SPDLOG_ERROR("Failed to create default configs"); - exit(EXIT_FAILURE); - } - } - } - - ConfigFile::~ConfigFile() { - if (!Save()) { - SPDLOG_ERROR("Failed to save configs!!!"); - } - - SPDLOG_INFO("destruct configfile"); - } - - mINI::INIMap& ConfigFile::operator[](const std::string& Section) { - return Val[Section]; - } - - mINI::INIMap ConfigFile::get(const std::string& Section) { - return Val.get(Section); - } - - bool ConfigFile::has(const std::string& Section) { - return Val.has(Section); - } - - bool ConfigFile::remove(const std::string& Section) { - return Val.remove(Section); - } - - void ConfigFile::clear() { - Val.clear(); - } - - std::size_t ConfigFile::size() const { - return Val.size(); - } - - bool ConfigFile::Save() { - return File.write(Val); - } - - bool ConfigFile::CreateDefaultConfig() { - (*this)["ARCHIVE"]["Main Archive"] = ""; - (*this)["ARCHIVE"]["Patches Directory"] = ""; - - (*this)["SAVE"]["Save Filename"] = ""; - - (*this)["CONTROLLERS"]["CONTROLLER 1"] = "Auto"; - (*this)["CONTROLLERS"]["CONTROLLER 2"] = "Unplugged"; - (*this)["CONTROLLERS"]["CONTROLLER 3"] = "Unplugged"; - (*this)["CONTROLLERS"]["CONTROLLER 4"] = "Unplugged"; - - (*this)["KEYBOARD SHORTCUTS"]["KEY_FULLSCREEN"] = std::to_string(0x044); - (*this)["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"] = std::to_string(0x029); - - (*this)["WINDOW"]["WINDOW WIDTH"] = std::to_string(640); - (*this)["WINDOW"]["WINDOW HEIGHT"] = std::to_string(480); - (*this)["WINDOW"]["FULLSCREEN WIDTH"] = std::to_string(1920); - (*this)["WINDOW"]["FULLSCREEN HEIGHT"] = std::to_string(1080); - (*this)["WINDOW"]["FULLSCREEN"] = std::to_string(false); - (*this)["WINDOW"]["GFX BACKEND"] = ""; - - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CRIGHT)] = std::to_string(0x14D); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CLEFT)] = std::to_string(0x14B); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CDOWN)] = std::to_string(0x150); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_CUP)] = std::to_string(0x148); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_R)] = std::to_string(0x013); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_L)] = std::to_string(0x012); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DRIGHT)] = std::to_string(0x023); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DLEFT)] = std::to_string(0x021); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DDOWN)] = std::to_string(0x022); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_DUP)] = std::to_string(0x014); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_START)] = std::to_string(0x039); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_Z)] = std::to_string(0x02C); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_B)] = std::to_string(0x02E); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_A)] = std::to_string(0x02D); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); - (*this)["KEYBOARD CONTROLLER BINDING 1"][STR(BTN_STICKUP)] = std::to_string(0x011); - - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CRIGHT)] = std::to_string(0x14D); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CLEFT)] = std::to_string(0x14B); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CDOWN)] = std::to_string(0x150); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_CUP)] = std::to_string(0x148); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_R)] = std::to_string(0x013); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_L)] = std::to_string(0x012); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DRIGHT)] = std::to_string(0x023); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DLEFT)] = std::to_string(0x021); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DDOWN)] = std::to_string(0x022); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_DUP)] = std::to_string(0x014); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_START)] = std::to_string(0x039); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_Z)] = std::to_string(0x02C); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_B)] = std::to_string(0x02E); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_A)] = std::to_string(0x02D); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); - (*this)["KEYBOARD CONTROLLER BINDING 2"][STR(BTN_STICKUP)] = std::to_string(0x011); - - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CRIGHT)] = std::to_string(0x14D); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CLEFT)] = std::to_string(0x14B); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CDOWN)] = std::to_string(0x150); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_CUP)] = std::to_string(0x148); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_R)] = std::to_string(0x013); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_L)] = std::to_string(0x012); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DRIGHT)] = std::to_string(0x023); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DLEFT)] = std::to_string(0x021); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DDOWN)] = std::to_string(0x022); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_DUP)] = std::to_string(0x014); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_START)] = std::to_string(0x039); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_Z)] = std::to_string(0x02C); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_B)] = std::to_string(0x02E); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_A)] = std::to_string(0x02D); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); - (*this)["KEYBOARD CONTROLLER BINDING 3"][STR(BTN_STICKUP)] = std::to_string(0x011); - - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CRIGHT)] = std::to_string(0x14D); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CLEFT)] = std::to_string(0x14B); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CDOWN)] = std::to_string(0x150); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_CUP)] = std::to_string(0x148); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_R)] = std::to_string(0x013); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_L)] = std::to_string(0x012); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DRIGHT)] = std::to_string(0x023); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DLEFT)] = std::to_string(0x021); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DDOWN)] = std::to_string(0x022); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_DUP)] = std::to_string(0x014); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_START)] = std::to_string(0x039); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_Z)] = std::to_string(0x02C); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_B)] = std::to_string(0x02E); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_A)] = std::to_string(0x02D); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKRIGHT)] = std::to_string(0x020); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKLEFT)] = std::to_string(0x01E); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKDOWN)] = std::to_string(0x01F); - (*this)["KEYBOARD CONTROLLER BINDING 4"][STR(BTN_STICKUP)] = std::to_string(0x011); - - (*this)["ENHANCEMENT SETTINGS"]["TEXT_SPEED"] = "1"; - - (*this)["SDL CONTROLLER 1"]["GUID"] = ""; - (*this)["SDL CONTROLLER 2"]["GUID"] = ""; - (*this)["SDL CONTROLLER 3"]["GUID"] = ""; - (*this)["SDL CONTROLLER 4"]["GUID"] = ""; - - return File.generate(Val); - } -} diff --git a/libultraship/libultraship/ConfigFile.h b/libultraship/libultraship/ConfigFile.h deleted file mode 100644 index b94e22f889..0000000000 --- a/libultraship/libultraship/ConfigFile.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CONFIG_FILE_H -#define CONFIG_FILE_H - -#pragma once - -#include -#include -#include "Lib/mINI/src/mini/ini.h" -#include "UltraController.h" -#include "LUSMacros.h" - -namespace Ship { - class GlobalCtx2; - - class ConfigFile { - public: - ConfigFile(std::shared_ptr Context, const std::string& Path); - ~ConfigFile(); - - bool Save(); - - // Expose the ini values. - mINI::INIMap& operator[](const std::string& Section); - mINI::INIMap get(const std::string& Section); - bool has(const std::string& Section); - bool remove(const std::string& Section); - void clear(); - std::size_t size() const; - std::shared_ptr GetContext() { return Context.lock(); } - - protected: - bool CreateDefaultConfig(); - - private: - mINI::INIStructure Val; - std::weak_ptr Context; - std::string Path; - mINI::INIFile File; - }; -} - -#endif diff --git a/libultraship/libultraship/ControlDeck.cpp b/libultraship/libultraship/ControlDeck.cpp new file mode 100644 index 0000000000..2fbf3d2254 --- /dev/null +++ b/libultraship/libultraship/ControlDeck.cpp @@ -0,0 +1,155 @@ +#include "ControlDeck.h" + +#include "Window.h" +#include "Controller.h" +#include "DisconnectedController.h" +#include "KeyboardController.h" +#include "SDLController.h" +#include + +uint8_t* controllerBits; + +void Ship::ControlDeck::Init(uint8_t* bits) { + ScanPhysicalDevices(); + controllerBits = bits; +} + +void Ship::ControlDeck::ScanPhysicalDevices() { + + virtualDevices.clear(); + physicalDevices.clear(); + + for (int i = 0; i < SDL_NumJoysticks(); i++) { + if (SDL_IsGameController(i)) { + auto sdl = std::make_shared(i); + sdl->Open(); + physicalDevices.push_back(sdl); + } + } + + physicalDevices.push_back(std::make_shared()); + physicalDevices.push_back(std::make_shared()); + + for (const auto& device : physicalDevices) { + for (int i = 0; i < MAXCONTROLLERS; i++) { + device->CreateDefaultBinding(i); + } + } + + for (int i = 0; i < MAXCONTROLLERS; i++) { + virtualDevices.push_back(i == 0 ? 0 : static_cast(physicalDevices.size()) - 1); + } + + LoadControllerSettings(); +} + +void Ship::ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) { + const std::shared_ptr backend = physicalDevices[deviceSlot]; + virtualDevices[slot] = deviceSlot; + *controllerBits |= (backend->Connected()) << slot; +} + +void Ship::ControlDeck::WriteToPad(OSContPad* pad) const { + for (size_t i = 0; i < virtualDevices.size(); i++) { + physicalDevices[virtualDevices[i]]->Read(&pad[i], i); + } +} + +#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), slot, __VA_ARGS__) + +void Ship::ControlDeck::LoadControllerSettings() { + std::shared_ptr Config = GlobalCtx2::GetInstance()->GetConfig(); + + for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) { + int slot = std::stoi(val.key().substr(5)); + + for (size_t dev = 0; dev < physicalDevices.size(); dev++) { + std::string guid = physicalDevices[dev]->GetGuid(); + if(guid != val.value()) continue; + + virtualDevices[slot] = dev; + } + } + + for (size_t i = 0; i < virtualDevices.size(); i++) { + std::shared_ptr backend = physicalDevices[virtualDevices[i]]; + Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid()); + } + + for (const auto& device : physicalDevices) { + + std::string guid = device->GetGuid(); + + for (int slot = 0; slot < MAXCONTROLLERS; slot++) { + + if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue; + + auto& profile = device->profiles[slot]; + auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)]; + + profile.Mappings.clear(); + profile.Thresholds.clear(); + profile.GyroThresholds.clear(); + profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", "")); + profile.RumbleStrength = Config->getBool(NESTED("Rumble.Strength", "")); + profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", "")); + + for (auto const& val : rawProfile["Gyro"]["Thresholds"].items()) { + profile.GyroThresholds[std::stoi(val.key())] = val.value(); + } + + for (auto const& val : rawProfile["Thresholds"].items()) { + profile.Thresholds[static_cast(std::stoi(val.key()))] = val.value(); + } + + for (auto const& val : rawProfile["Mappings"].items()) { + device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value()); + } + } + } +} + +void Ship::ControlDeck::SaveControllerSettings() { + std::shared_ptr Config = GlobalCtx2::GetInstance()->GetConfig(); + + for (size_t i = 0; i < virtualDevices.size(); i++) { + std::shared_ptr backend = physicalDevices[virtualDevices[i]]; + Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid()); + } + + for (const auto& device : physicalDevices) { + + int slot = 0; + std::string guid = device->GetGuid(); + + for (const auto& profile : device->profiles) { + + if (!device->Connected()) continue; + + auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)]; + Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble); + Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength); + Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro); + + for (auto const& val : rawProfile["Mappings"].items()) { + Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1); + } + + for (auto const& [key, val] : profile.GyroThresholds) { + Config->setInt(NESTED("Gyro.Thresholds.%d", key), val); + } + + for (auto const& [key, val] : profile.Thresholds) { + Config->setInt(NESTED("Thresholds.%d", key), val); + } + + for (auto const& [key, val] : profile.Mappings) { + Config->setInt(NESTED("Mappings.BTN_%d", val), key); + } + + slot++; + } + } + + Config->save(); +} \ No newline at end of file diff --git a/libultraship/libultraship/ControlDeck.h b/libultraship/libultraship/ControlDeck.h new file mode 100644 index 0000000000..fbbaca7abf --- /dev/null +++ b/libultraship/libultraship/ControlDeck.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Controller.h" +#include +#include + +namespace Ship { + + class ControlDeck { + public: + std::vector virtualDevices; + std::vector> physicalDevices = {}; + void Init(uint8_t* controllerBits); + void ScanPhysicalDevices(); + void WriteToPad(OSContPad* pad) const; + void LoadControllerSettings(); + void SaveControllerSettings(); + void SetPhysicalDevice(int slot, int deviceSlot); + }; +} diff --git a/libultraship/libultraship/Controller.cpp b/libultraship/libultraship/Controller.cpp index 7cad7f178f..8c0994a854 100644 --- a/libultraship/libultraship/Controller.cpp +++ b/libultraship/libultraship/Controller.cpp @@ -1,8 +1,6 @@ #include "Controller.h" -#include "GlobalCtx2.h" -#include "stox.h" #include -#include +#include #if __APPLE__ #include #else @@ -10,29 +8,29 @@ #endif namespace Ship { - Controller::Controller(int32_t dwControllerNumber) : dwControllerNumber(dwControllerNumber) { - dwPressedButtons = 0; - wStickX = 0; - wStickY = 0; - wGyroX = 0; - wGyroY = 0; + + Controller::Controller() : isRumbling(false), wStickX(0), wStickY(0), wGyroX(0), wGyroY(0), dwPressedButtons(0){ Attachment = nullptr; + profiles.resize(MAXCONTROLLERS); + for(int slot = 0; slot < MAXCONTROLLERS; slot++) { + dwPressedButtons.push_back(0); + } } - void Controller::Read(OSContPad* pad) { - ReadFromSource(); + void Controller::Read(OSContPad* pad, int32_t slot) { + ReadFromSource(slot); SDL_PumpEvents(); // Button Inputs - pad->button |= dwPressedButtons & 0xFFFF; + pad->button |= dwPressedButtons[slot] & 0xFFFF; // Stick Inputs if (pad->stick_x == 0) { - if (dwPressedButtons & BTN_STICKLEFT) { + if (dwPressedButtons[slot] & BTN_STICKLEFT) { pad->stick_x = -128; } - else if (dwPressedButtons & BTN_STICKRIGHT) { + else if (dwPressedButtons[slot] & BTN_STICKRIGHT) { pad->stick_x = 127; } else { @@ -41,10 +39,10 @@ namespace Ship { } if (pad->stick_y == 0) { - if (dwPressedButtons & BTN_STICKDOWN) { + if (dwPressedButtons[slot] & BTN_STICKDOWN) { pad->stick_y = -128; } - else if (dwPressedButtons & BTN_STICKUP) { + else if (dwPressedButtons[slot] & BTN_STICKUP) { pad->stick_y = 127; } else { @@ -52,60 +50,38 @@ namespace Ship { } } + // Stick Inputs + if (pad->cam_x == 0) { + if (dwPressedButtons[slot] & BTN_VSTICKLEFT) { + pad->cam_x = -128 * 10.0f; + } + else if (dwPressedButtons[slot] & BTN_VSTICKRIGHT) { + pad->cam_x = 127 * 10.0f; + } + else { + pad->cam_x = wCamX; + } + } + if (pad->cam_y == 0) { + if (dwPressedButtons[slot] & BTN_VSTICKDOWN) { + pad->cam_y = -128 * 10.0f; + } + else if (dwPressedButtons[slot] & BTN_VSTICKUP) { + pad->cam_y = 127 * 10.0f; + } + else { + pad->cam_y = wCamY; + } + } + // Gyro pad->gyro_x = wGyroX; pad->gyro_y = wGyroY; - - // Right Stick - pad->cam_x = wCamX; - pad->cam_y = wCamY; } - void Controller::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) { - // Update the config value. - std::string ConfSection = GetBindingConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); - Conf[ConfSection][szButtonName] = dwScancode; - - // Reload the button mapping from Config - LoadBinding(); - } - - void Controller::LoadBinding() { - std::string ConfSection = GetBindingConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); - - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT)])] = BTN_CRIGHT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT)])] = BTN_CLEFT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN)])] = BTN_CDOWN; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP)])] = BTN_CUP; - //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CRIGHT + "_2")])] = BTN_CRIGHT; - //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CLEFT + "_2")])] = BTN_CLEFT; - //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CDOWN + "_2")])] = BTN_CDOWN; - //ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_CUP + "_2")])] = BTN_CUP; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_R)])] = BTN_R; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_L)])] = BTN_L; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DRIGHT)])] = BTN_DRIGHT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DLEFT)])] = BTN_DLEFT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DDOWN)])] = BTN_DDOWN; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_DUP)])] = BTN_DUP; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_START)])] = BTN_START; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_Z)])] = BTN_Z; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_B)])] = BTN_B; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_A)])] = BTN_A; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKRIGHT)])] = BTN_STICKRIGHT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKLEFT)])] = BTN_STICKLEFT; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKDOWN)])] = BTN_STICKDOWN; - ButtonMapping[Ship::stoi(Conf[ConfSection][STR(BTN_STICKUP)])] = BTN_STICKUP; - } - - std::string Controller::GetConfSection() { - return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1); - } - - std::string Controller::GetBindingConfSection() { - return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1); + void Controller::SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode) { + std::map& Mappings = profiles[slot].Mappings; + std::erase_if(Mappings, [n64Button](const std::pair& bin) { return bin.second == n64Button; }); + Mappings[dwScancode] = n64Button; } } diff --git a/libultraship/libultraship/Controller.h b/libultraship/libultraship/Controller.h index d03d70e8a2..ffbeeaabff 100644 --- a/libultraship/libultraship/Controller.h +++ b/libultraship/libultraship/Controller.h @@ -1,52 +1,82 @@ #pragma once -#include #include +#include #include -#include #include "stdint.h" #include "UltraController.h" #include "ControllerAttachment.h" +#include +#include #define EXTENDED_SCANCODE_BIT (1 << 8) #define AXIS_SCANCODE_BIT (1 << 9) namespace Ship { + + enum ControllerThresholds { + LEFT_STICK = 1, + RIGHT_STICK = 2, + LEFT_TRIGGER = 3, + RIGHT_TRIGGER = 4, + DRIFT_X = 5, + DRIFT_Y = 6, + SENSITIVITY = 7, + GYRO_SENSITIVITY = 8 + }; + + struct DeviceProfile { + bool UseRumble = false; + bool UseGyro = false; + float RumbleStrength = 1.0f; + std::unordered_map Thresholds; + std::unordered_map GyroThresholds; + std::map Mappings; + }; + class Controller { public: - Controller(int32_t dwControllerNumber); - - void Read(OSContPad* pad); - virtual void ReadFromSource() = 0; - virtual void WriteToSource(ControllerCallback* controller) = 0; + virtual ~Controller() = default; + Controller(); + void Read(OSContPad* pad, int32_t slot); + virtual void ReadFromSource(int32_t slot) = 0; + virtual void WriteToSource(int32_t slot, ControllerCallback* controller) = 0; virtual bool Connected() const = 0; virtual bool CanRumble() const = 0; + virtual bool CanGyro() const = 0; + virtual void CreateDefaultBinding(int32_t slot) = 0; bool isRumbling; + std::vector profiles; - void SetButtonMapping(const std::string& szButtonName, int32_t dwScancode); + virtual void ClearRawPress() = 0; + virtual int32_t ReadRawPress() = 0; + void SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode); std::shared_ptr GetAttachment() { return Attachment; } - int32_t GetControllerNumber() { return dwControllerNumber; } - virtual bool HasPadConf() const = 0; - virtual std::optional GetPadConfSection() = 0; + std::string GetGuid() { return GUID; } + virtual const char* GetButtonName(int slot, int n64Button) = 0; + virtual const char* GetControllerName() = 0; - protected: - int32_t dwPressedButtons; - std::map ButtonMapping; int8_t wStickX; int8_t wStickY; float wGyroX; float wGyroY; - float wCamX; - float wCamY; + float wCamX; + float wCamY; + + protected: + std::vector dwPressedButtons; + std::string GUID; - virtual std::string GetControllerType() = 0; - virtual std::string GetConfSection() = 0; - virtual std::string GetBindingConfSection() = 0; void LoadBinding(); private: std::shared_ptr Attachment; - int32_t dwControllerNumber; }; + + struct ControllerEntry { + uint8_t* controllerBits; + Controller* entryIO; + }; + } diff --git a/libultraship/libultraship/ControllerHud.cpp b/libultraship/libultraship/ControllerHud.cpp new file mode 100644 index 0000000000..e40990b0db --- /dev/null +++ b/libultraship/libultraship/ControllerHud.cpp @@ -0,0 +1,277 @@ +#include "InputEditor.h" +#include "Controller.h" +#include "Window.h" +#include "Lib/ImGui/imgui.h" +#include "ImGuiImpl.h" +#include "Utils/StringHelper.h" +#include "Lib/ImGui/imgui_internal.h" + +namespace Ship { + + extern "C" uint8_t __enableGameInput; + #define SEPARATION() ImGui::Dummy(ImVec2(0, 5)) + + void InputEditor::Init() { + BtnReading = -1; + } + + std::shared_ptr GetControllerPerSlot(int slot) { + const std::vector vDevices = Window::ControllerApi->virtualDevices; + return Window::ControllerApi->physicalDevices[vDevices[slot]]; + } + + void InputEditor::DrawButton(const char* label, int n64Btn) { + const std::shared_ptr backend = GetControllerPerSlot(CurrentPort); + + float size = 40; + bool readingMode = BtnReading == n64Btn; + bool disabled = BtnReading != -1 && !readingMode || !backend->Connected(); + ImVec2 len = ImGui::CalcTextSize(label); + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SetCursorPosY(pos.y + len.y / 4); + ImGui::SetCursorPosX(pos.x + abs(len.x - size)); + ImGui::Text("%s", label); + ImGui::SameLine(); + ImGui::SetCursorPosY(pos.y); + + if(disabled) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + } + + if(readingMode) { + const int32_t btn = backend->ReadRawPress(); + + if(btn != -1) { + backend->SetButtonMapping(CurrentPort, n64Btn, btn); + BtnReading = -1; + } + } + + const char* BtnName = backend->GetButtonName(CurrentPort, n64Btn); + + if (ImGui::Button(StringHelper::Sprintf("%s##HBTNID_%d", readingMode ? "Press a Key..." : BtnName, n64Btn).c_str())) { + BtnReading = n64Btn; + backend->ClearRawPress(); + } + + if(disabled) { + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + } + } + + void InputEditor::DrawVirtualStick(const char* label, ImVec2 stick) { + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5, ImGui::GetCursorPos().y)); + ImGui::BeginChild(label, ImVec2(68, 75), false); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 p = ImGui::GetCursorScreenPos(); + + float sz = 45.0f; + float rad = sz * 0.5f; + ImVec2 pos = ImVec2(p.x + sz * 0.5f + 12, p.y + sz * 0.5f + 11); + + float stickX = (stick.x / 83.0f) * (rad * 0.5f); + float stickY = -(stick.y / 83.0f) * (rad * 0.5f); + + ImVec4 rect = ImVec4(p.x + 2, p.y + 2, 65, 65); + draw_list->AddRect(ImVec2(rect.x, rect.y), ImVec2(rect.x + rect.z, rect.y + rect.w), ImColor(100, 100, 100, 255), 0.0f, 0, 1.5f); + draw_list->AddCircleFilled(pos, rad, ImColor(130, 130, 130, 255), 8); + draw_list->AddCircleFilled(ImVec2(pos.x + stickX, pos.y + stickY), 5, ImColor(15, 15, 15, 255), 7); + ImGui::EndChild(); + } + + void InputEditor::DrawControllerSchema() { + + const std::vector vDevices = Window::ControllerApi->virtualDevices; + const std::vector> devices = Window::ControllerApi->physicalDevices; + + std::shared_ptr Backend = devices[vDevices[CurrentPort]]; + DeviceProfile& profile =Backend->profiles[CurrentPort]; + float sensitivity = profile.Thresholds[SENSITIVITY]; + bool IsKeyboard = Backend->GetGuid() == "Keyboard" || !Backend->Connected(); + const char* ControllerName = Backend->GetControllerName(); + + if (ControllerName != nullptr && ImGui::BeginCombo("##ControllerEntries", ControllerName)) { + for (uint8_t i = 0; i < devices.size(); i++) { + if (ImGui::Selectable(devices[i]->GetControllerName(), i == vDevices[CurrentPort])) { + Window::ControllerApi->SetPhysicalDevice(CurrentPort, i); + } + } + ImGui::EndCombo(); + } + + ImGui::SameLine(); + + if(ImGui::Button("Refresh")) { + Window::ControllerApi->ScanPhysicalDevices(); + } + + SohImGui::BeginGroupPanel("Buttons", ImVec2(150, 20)); + DrawButton("A", BTN_A); + DrawButton("B", BTN_B); + DrawButton("L", BTN_L); + DrawButton("R", BTN_R); + DrawButton("Z", BTN_Z); + DrawButton("START", BTN_START); + SEPARATION(); + SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 48.0f); + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Digital Pad", ImVec2(150, 20)); + DrawButton("Up", BTN_DUP); + DrawButton("Down", BTN_DDOWN); + DrawButton("Left", BTN_DLEFT); + DrawButton("Right", BTN_DRIGHT); + SEPARATION(); + SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 94.0f); + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Analog Stick", ImVec2(150, 20)); + DrawButton("Up", BTN_STICKUP); + DrawButton("Down", BTN_STICKDOWN); + DrawButton("Left", BTN_STICKLEFT); + DrawButton("Right", BTN_STICKRIGHT); + + if (!IsKeyboard) { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); + DrawVirtualStick("##MainVirtualStick", ImVec2(Backend->wStickX, Backend->wStickY)); + ImGui::SameLine(); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + + ImGui::BeginChild("##MSInput", ImVec2(90, 50), false); + ImGui::Text("Deadzone"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MDZone", &profile.Thresholds[LEFT_STICK]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + } else { + ImGui::Dummy(ImVec2(0, 6)); + } + SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 24.0f); + ImGui::SameLine(); + + if (!IsKeyboard) { + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Camera Stick", ImVec2(150, 20)); + DrawButton("Up", BTN_VSTICKUP); + DrawButton("Down", BTN_VSTICKDOWN); + DrawButton("Left", BTN_VSTICKLEFT); + DrawButton("Right", BTN_VSTICKRIGHT); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); + DrawVirtualStick("##CameraVirtualStick", ImVec2(Backend->wCamX / sensitivity, Backend->wCamY / sensitivity)); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + ImGui::BeginChild("##CSInput", ImVec2(90, 85), false); + ImGui::Text("Deadzone"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MDZone", &profile.Thresholds[RIGHT_STICK]); + ImGui::PopItemWidth(); + ImGui::Text("Sensitivity"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MSensitivity", &profile.Thresholds[SENSITIVITY]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + SohImGui::EndGroupPanel(14.0f); + } + + if(Backend->CanGyro()) { + ImGui::SameLine(); + + SohImGui::BeginGroupPanel("Gyro Options", ImVec2(175, 20)); + float cursorX = ImGui::GetCursorPosX() + 5; + ImGui::SetCursorPosX(cursorX); + ImGui::Checkbox("Enable Gyro", &profile.UseGyro); + ImGui::SetCursorPosX(cursorX); + ImGui::Text("Gyro Sensitivity: %d%%", profile.Thresholds[GYRO_SENSITIVITY]); + ImGui::PushItemWidth(135.0f); + ImGui::SetCursorPosX(cursorX); + ImGui::SliderInt("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0, 100, ""); + ImGui::PopItemWidth(); + ImGui::Dummy(ImVec2(0, 1)); + ImGui::SetCursorPosX(cursorX); + if (ImGui::Button("Recalibrate Gyro##RGyro")) { + profile.Thresholds[DRIFT_X] = 0; + profile.Thresholds[DRIFT_Y] = 0; + } + ImGui::SetCursorPosX(cursorX); + DrawVirtualStick("##GyroPreview", ImVec2(Backend->wGyroX, Backend->wGyroY)); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + ImGui::BeginChild("##GyInput", ImVec2(90, 85), false); + ImGui::Text("Drift X"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##GDriftX", &profile.Thresholds[DRIFT_X]); + ImGui::PopItemWidth(); + ImGui::Text("Drift Y"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##GDriftY", &profile.Thresholds[DRIFT_Y]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + SohImGui::EndGroupPanel(14.0f); + } + + ImGui::SameLine(); + + const ImVec2 cursor = ImGui::GetCursorPos(); + + SohImGui::BeginGroupPanel("C-Buttons", ImVec2(158, 20)); + DrawButton("Up", BTN_CUP); + DrawButton("Down", BTN_CDOWN); + DrawButton("Left", BTN_CLEFT); + DrawButton("Right", BTN_CRIGHT); + ImGui::Dummy(ImVec2(0, 5)); + SohImGui::EndGroupPanel(); + + ImGui::SetCursorPosX(cursor.x); + ImGui::SetCursorPosY(cursor.y + 120); + SohImGui::BeginGroupPanel("Options", ImVec2(158, 20)); + float cursorX = ImGui::GetCursorPosX() + 5; + ImGui::SetCursorPosX(cursorX); + ImGui::Checkbox("Rumble Enabled", &profile.UseRumble); + if (Backend->CanRumble()) { + ImGui::SetCursorPosX(cursorX); + ImGui::Text("Rumble Force: %d%%", static_cast(100 * profile.RumbleStrength)); + ImGui::SetCursorPosX(cursorX); + ImGui::PushItemWidth(135.0f); + ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0, 1.0f, ""); + ImGui::PopItemWidth(); + } + ImGui::Dummy(ImVec2(0, 5)); + SohImGui::EndGroupPanel(IsKeyboard ? 0.0f : 2.0f); + } + + void InputEditor::DrawHud() { + + __enableGameInput = true; + + if (!this->Opened) { + BtnReading = -1; + return; + } + + ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290)); + //OTRTODO: Disable this stupid workaround ( ReadRawPress() only works when the window is on the main viewport ) + ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); + ImGui::Begin("Controller Configuration", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); + + ImGui::BeginTabBar("##Controllers"); + + for (int i = 0; i < 4; i++) { + if (ImGui::BeginTabItem(StringHelper::Sprintf("Port %d", i + 1).c_str())) { + CurrentPort = i; + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + + // Draw current cfg + + DrawControllerSchema(); + + ImGui::End(); + } +} diff --git a/libultraship/libultraship/Cvar.cpp b/libultraship/libultraship/Cvar.cpp index 55fc70793e..231308fe7e 100644 --- a/libultraship/libultraship/Cvar.cpp +++ b/libultraship/libultraship/Cvar.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "imgui_internal.h" std::map, std::less<>> cvars; @@ -70,7 +71,7 @@ extern "C" void CVar_SetString(const char* name, const char* value) { cvar = std::make_unique(); } cvar->type = CVAR_TYPE_STRING; - cvar->value.valueStr = value; + cvar->value.valueStr = ImStrdup(value); } extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) { diff --git a/libultraship/libultraship/DisconnectedController.h b/libultraship/libultraship/DisconnectedController.h new file mode 100644 index 0000000000..9cbc2b99c2 --- /dev/null +++ b/libultraship/libultraship/DisconnectedController.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include + +#include "Controller.h" + +class DisconnectedController final : public Ship::Controller { +public: + DisconnectedController() { + GUID = "Disconnected"; + } + + std::map, int32_t> ReadButtonPress(); + void ReadFromSource(int32_t slot) override {} + const char* GetControllerName() override { return "Disconnected"; } + const char* GetButtonName(int slot, int n64Button) override { return "None"; } + void WriteToSource(int32_t slot, ControllerCallback* controller) override { } + bool Connected() const override { return false; } + bool CanRumble() const override { return false; } + bool CanGyro() const override { return false; } + + void ClearRawPress() override {} + int32_t ReadRawPress() override { return -1; } + bool HasPadConf() const { return true; } + std::optional GetPadConfSection() { return "Unk"; } + void CreateDefaultBinding(int32_t slot) override {} +protected: + std::string GetControllerType() { return "Unk"; } + std::string GetConfSection() { return "Unk"; } + std::string GetBindingConfSection() { return "Unk"; } +}; diff --git a/libultraship/libultraship/GameSettings.cpp b/libultraship/libultraship/GameSettings.cpp index 0cfbbd21ac..e3f95ad76a 100644 --- a/libultraship/libultraship/GameSettings.cpp +++ b/libultraship/libultraship/GameSettings.cpp @@ -7,7 +7,6 @@ #include #include -#include "ConfigFile.h" #include "Cvar.h" #include "GlobalCtx2.h" #include "ImGuiImpl.h" @@ -33,18 +32,6 @@ namespace Game { Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); } - void LoadPadSettings() { - const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf; - - for (const auto& [i, controllers] : Ship::Window::Controllers) { - for (const auto& controller : controllers) { - if (auto padConfSection = controller->GetPadConfSection()) { - } - } - } - } - void LoadSettings() { DebugConsole_LoadCVars(); } @@ -58,6 +45,7 @@ namespace Game { ModInternal::RegisterHook([] { gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", FILTER_THREE_POINT)); SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0); + SohImGui::controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0); UpdateAudio(); }); } diff --git a/libultraship/libultraship/GlobalCtx2.cpp b/libultraship/libultraship/GlobalCtx2.cpp index 54e64e0ce5..329644192c 100644 --- a/libultraship/libultraship/GlobalCtx2.cpp +++ b/libultraship/libultraship/GlobalCtx2.cpp @@ -15,7 +15,6 @@ namespace Ship { std::weak_ptr GlobalCtx2::Context; ModManager* INSTANCE; - std::shared_ptr GlobalCtx2::GetInstance() { return Context.lock(); } @@ -49,7 +48,7 @@ namespace Ship { return GlobalCtx2::GetAppDirectoryPath() + "/" + path; } - GlobalCtx2::GlobalCtx2(const std::string& Name) : Name(Name), MainPath(""), PatchesPath("") { + GlobalCtx2::GlobalCtx2(std::string Name) : Name(std::move(Name)) { } @@ -60,22 +59,19 @@ namespace Ship { void GlobalCtx2::InitWindow() { InitLogging(); - Config = std::make_shared(GlobalCtx2::GetInstance(), GetPathRelativeToAppDirectory("shipofharkinian.ini")); - MainPath = (*Config)["ARCHIVE"]["Main Archive"]; - if (MainPath.empty()) { - MainPath = GetPathRelativeToAppDirectory("oot.otr"); - } - PatchesPath = (*Config)["ARCHIVE"]["Patches Directory"]; - if (PatchesPath.empty()) { - PatchesPath = GetAppDirectoryPath() + "/"; - } - ResMan = std::make_shared(GlobalCtx2::GetInstance(), MainPath, PatchesPath); - Win = std::make_shared(GlobalCtx2::GetInstance()); + Config = std::make_shared(GetPathRelativeToAppDirectory("shipofharkinian.json")); + Config->reload(); + + MainPath = Config->getString("Game.Main Archive", GetPathRelativeToAppDirectory("oot.otr")); + PatchesPath = Config->getString("Game.Patches Archive", GetAppDirectoryPath() + "/mods"); + + ResMan = std::make_shared(GetInstance(), MainPath, PatchesPath); + Win = std::make_shared(GetInstance()); if (!ResMan->DidLoadSuccessfully()) { #ifdef _WIN32 - MessageBox(NULL, L"Main OTR file not found!", L"Uh oh", MB_OK); + MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK); #else SPDLOG_ERROR("Main OTR file not found!"); #endif @@ -109,7 +105,7 @@ namespace Ship { } } - void GlobalCtx2::WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) { + void GlobalCtx2::WriteSaveFile(const std::filesystem::path& savePath, const uintptr_t addr, void* dramAddr, const size_t size) { std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); saveFile.seekp(addr); saveFile.write((char*)dramAddr, size); @@ -129,4 +125,4 @@ namespace Ship { saveFile.close(); } -} \ No newline at end of file +} diff --git a/libultraship/libultraship/GlobalCtx2.h b/libultraship/libultraship/GlobalCtx2.h index 5736e2b666..21402070d2 100644 --- a/libultraship/libultraship/GlobalCtx2.h +++ b/libultraship/libultraship/GlobalCtx2.h @@ -6,8 +6,9 @@ #ifdef __cplusplus #include #include +#include #include "spdlog/spdlog.h" -#include "ConfigFile.h" +#include "Lib/Mercury/Mercury.h" namespace Ship { class ResourceMgr; @@ -22,15 +23,15 @@ namespace Ship { std::shared_ptr GetWindow() { return Win; } std::shared_ptr GetResourceManager() { return ResMan; } std::shared_ptr GetLogger() { return Logger; } - std::shared_ptr GetConfig() { return Config; } + std::shared_ptr GetConfig() { return Config; } static std::string GetAppDirectoryPath(); static std::string GetPathRelativeToAppDirectory(const char* path); - void WriteSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); + void WriteSaveFile(const std::filesystem::path& savePath, uintptr_t addr, void* dramAddr, size_t size); void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size); - GlobalCtx2(const std::string& Name); + GlobalCtx2(std::string Name); ~GlobalCtx2(); protected: @@ -41,7 +42,7 @@ namespace Ship { static std::weak_ptr Context; std::shared_ptr Logger; std::shared_ptr Win; - std::shared_ptr Config; // Config needs to be after the Window because we call the Window during it's destructor. + std::shared_ptr Config; // Config needs to be after the Window because we call the Window during it's destructor. std::shared_ptr ResMan; std::string Name; std::string MainPath; diff --git a/libultraship/libultraship/Hooks.h b/libultraship/libultraship/Hooks.h index b5dec8159c..411cffe42e 100644 --- a/libultraship/libultraship/Hooks.h +++ b/libultraship/libultraship/Hooks.h @@ -5,6 +5,7 @@ #include #include "UltraController.h" +#include "Controller.h" #define DEFINE_HOOK(name, type) struct name { typedef std::function fn; } @@ -28,12 +29,11 @@ namespace ModInternal { } DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad)); - + DEFINE_HOOK(ControllerRawInput, void(Ship::Controller* backend, uint32_t raw)); DEFINE_HOOK(AudioInit, void()); - DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture)); - DEFINE_HOOK(GfxInit, void()); + DEFINE_HOOK(ExitGame, void()); } diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 69d05a74d7..dd172118d1 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -12,6 +12,7 @@ #include "GameSettings.h" #include "Console.h" #include "Hooks.h" +#define IMGUI_DEFINE_MATH_OPERATORS #include "Lib/ImGui/imgui_internal.h" #include "GlobalCtx2.h" #include "ResourceMgr.h" @@ -63,6 +64,8 @@ namespace SohImGui { ImGuiIO* io; Console* console = new Console; GameOverlay* overlay = new GameOverlay; + InputEditor* controller = new InputEditor; + static ImVector s_GroupPanelLabelStack; bool p_open = false; bool needs_save = false; @@ -326,6 +329,7 @@ namespace SohImGui { } console->Init(); overlay->Init(); + controller->Init(); ImGuiWMInit(); ImGuiBackendInit(); @@ -346,23 +350,17 @@ namespace SohImGui { LoadTexture("C-Down", "assets/ship_of_harkinian/buttons/CDown.png"); }); - for (const auto& [i, controllers] : Ship::Window::Controllers) - { - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0); - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0); - needs_save = true; - } - ModInternal::RegisterHook([](OSContPad* cont_pad) { pads = cont_pad; }); + Game::InitSettings(); CVar_SetS32("gRandoGenerating", 0); CVar_SetS32("gNewSeedGenerated", 0); CVar_SetS32("gNewFileDropped", 0); - CVar_SetString("gDroppedFile", ""); - Game::SaveSettings(); + CVar_SetString("gDroppedFile", "None"); + // Game::SaveSettings(); } void Update(EventImpl event) { @@ -511,7 +509,7 @@ namespace SohImGui { } void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue) { - + if (ImGui::BeginCombo(name.c_str(), items[static_cast(CVar_GetS32(cvarName, defaultValue))].c_str())) { for (int settingIndex = 0; settingIndex < (int) items.size(); settingIndex++) { if (ImGui::Selectable(items[settingIndex].c_str())) { @@ -691,36 +689,32 @@ namespace SohImGui { needs_save = true; GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar; ShowCursor(menu_bar, Dialogues::dMenubar); - + GlobalCtx2::GetInstance()->GetWindow()->GetControlDeck()->SaveControllerSettings(); if (CVar_GetS32("gControlNav", 0)) { if (CVar_GetS32("gOpenMenuBar", 0)) { io->ConfigFlags |=ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard; + } else { + io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; } - else - { - io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; - } - } - else - { - io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; + } else { + io->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; } } #if __APPLE__ if ((ImGui::IsKeyDown(ImGuiKey_LeftSuper) || - ImGui::IsKeyDown(ImGuiKey_RightSuper)) && + ImGui::IsKeyDown(ImGuiKey_RightSuper)) && ImGui::IsKeyPressed(ImGuiKey_R, false)) { console->Commands["reset"].handler(emptyArgs); } #else if ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || - ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && + ImGui::IsKeyDown(ImGuiKey_RightCtrl)) && ImGui::IsKeyPressed(ImGuiKey_R, false)) { console->Commands["reset"].handler(emptyArgs); } #endif - + if (ImGui::BeginMenuBar()) { if (DefaultAssets.contains("Game_Icon")) { ImGui::SetCursorPos(ImVec2(5, 2.5f)); @@ -740,7 +734,7 @@ namespace SohImGui { console->Commands["reset"].handler(emptyArgs); } ImGui::EndMenu(); - } + } if (ImGui::BeginMenu("Audio")) { EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true); @@ -758,6 +752,9 @@ namespace SohImGui { EnhancementCheckbox("Use Controller Navigation", "gControlNav"); Tooltip("Allows controller navigation of the menu bar\nD-pad to move between items, A to select, and X to grab focus on the menu bar"); + EnhancementCheckbox("Controller Configuration", "gControllerConfigurationEnabled"); + controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0); + ImGui::Separator(); // TODO mutual exclusions -- There should be some system to prevent conclifting enhancements from being selected @@ -771,41 +768,9 @@ namespace SohImGui { EnhancementCheckbox("Show Inputs", "gInputEnabled"); Tooltip("Shows currently pressed inputs on the bottom right of the screen"); - EnhancementCheckbox("Rumble Enabled", "gRumbleEnabled"); EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false); - Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); - - ImGui::Separator(); - - for (const auto& [i, controllers] : Ship::Window::Controllers) - { - bool hasPad = std::find_if(controllers.begin(), controllers.end(), [](const auto& c) { - return c->HasPadConf() && c->Connected(); - }) != controllers.end(); - - if (!hasPad) continue; - - auto menuLabel = "Controller " + std::to_string(i + 1); - if (ImGui::BeginMenu(menuLabel.c_str())) - { - EnhancementSliderFloat("Gyro Sensitivity: %d %%", "##GYROSCOPE", StringHelper::Sprintf("gCont%i_GyroSensitivity", i).c_str(), 0.0f, 1.0f, "", 1.0f, true); - - if (ImGui::Button("Recalibrate Gyro")) - { - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", i).c_str(), 0); - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", i).c_str(), 0); - needs_save = true; - } - - ImGui::Separator(); - - EnhancementSliderFloat("Rumble Strength: %d %%", "##RUMBLE", StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 0.0f, 1.0f, "", 1.0f, true); - - ImGui::EndMenu(); - } - ImGui::Separator(); - } + Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting"); ImGui::EndMenu(); } @@ -933,7 +898,7 @@ namespace SohImGui { Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses"); EnhancementCheckbox("No Heart Drops", "gNoHeartDrops"); Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series"); - + if (ImGui::BeginMenu("Potion Values")) { EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect"); @@ -942,7 +907,7 @@ namespace SohImGui { Tooltip("Changes the amount of health restored by Red Potions"); EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore"); Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health"); - + EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect"); Tooltip("Enable the following changes to the amount of mana restored by Green Potions"); EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, ""); @@ -956,7 +921,7 @@ namespace SohImGui { Tooltip("Changes the amount of health restored by Blue Potions"); EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore"); Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health"); - + EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, ""); Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96"); EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore"); @@ -1019,7 +984,7 @@ namespace SohImGui { ImGui::EndMenu(); } - + EnhancementCheckbox("Visual Stone of Agony", "gVisualAgony"); Tooltip("Displays an icon and plays a sound when Stone of Agony\nshould be activated, for those without rumble"); EnhancementCheckbox("Assignable Tunics and Boots", "gAssignableTunicsAndBoots"); @@ -1268,7 +1233,7 @@ namespace SohImGui { ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::SetNextWindowSize(ImVec2 (0,0)); ImGuiWindowFlags HiddenWndFlags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings | - ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs | + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoDecoration; ImGui::Begin(category.first.c_str(), nullptr, HiddenWndFlags); ImGui::End(); @@ -1292,6 +1257,7 @@ namespace SohImGui { } console->Draw(); + controller->DrawHud(); for (auto& windowIter : customWindows) { CustomWindow& window = windowIter.second; @@ -1457,4 +1423,124 @@ namespace SohImGui { #endif return reinterpret_cast(id); } + + void BeginGroupPanel(const char* name, const ImVec2& size) + { + ImGui::BeginGroup(); + + // auto cursorPos = ImGui::GetCursorScreenPos(); + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + ImGui::BeginGroup(); + + ImVec2 effectiveSize = size; + if (size.x < 0.0f) + effectiveSize.x = ImGui::GetContentRegionAvail().x; + else + effectiveSize.x = size.x; + ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); + + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::BeginGroup(); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::TextUnformatted(name); + auto labelMin = ImGui::GetItemRectMin(); + auto labelMax = ImGui::GetItemRectMax(); + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y)); + ImGui::BeginGroup(); + + //ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255)); + + ImGui::PopStyleVar(2); + +#if IMGUI_VERSION_NUM >= 17301 + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f; +#else + ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f; +#endif + ImGui::GetCurrentWindow()->Size.x -= frameHeight; + + auto itemWidth = ImGui::CalcItemWidth(); + ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight)); + s_GroupPanelLabelStack.push_back(ImRect(labelMin, labelMax)); + } + + void EndGroupPanel(float minHeight) { + ImGui::PopItemWidth(); + + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + + ImGui::EndGroup(); + + //ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f); + + ImGui::EndGroup(); + + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::Dummy(ImVec2(0.0, std::max(frameHeight - frameHeight * 0.5f - itemSpacing.y, minHeight))); + + ImGui::EndGroup(); + + auto itemMin = ImGui::GetItemRectMin(); + auto itemMax = ImGui::GetItemRectMax(); + //ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f); + + auto labelRect = s_GroupPanelLabelStack.back(); + s_GroupPanelLabelStack.pop_back(); + + ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f; + ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f)); + labelRect.Min.x -= itemSpacing.x; + labelRect.Max.x += itemSpacing.x; + for (int i = 0; i < 4; ++i) + { + switch (i) + { + // left half-plane + case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break; + // right half-plane + case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break; + // top + case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break; + // bottom + case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break; + } + + ImGui::GetWindowDrawList()->AddRect( + frameRect.Min, frameRect.Max, + ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)), + halfFrame.x); + + ImGui::PopClipRect(); + } + + ImGui::PopStyleVar(2); + +#if IMGUI_VERSION_NUM >= 17301 + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f; +#else + ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f; +#endif + ImGui::GetCurrentWindow()->Size.x += frameHeight; + + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + + ImGui::EndGroup(); + } } diff --git a/libultraship/libultraship/ImGuiImpl.h b/libultraship/libultraship/ImGuiImpl.h index 34bc368a68..1b2ba06c12 100644 --- a/libultraship/libultraship/ImGuiImpl.h +++ b/libultraship/libultraship/ImGuiImpl.h @@ -3,6 +3,7 @@ #include "GameOverlay.h" #include "Lib/ImGui/imgui.h" #include "Console.h" +#include "InputEditor.h" struct GameAsset { uint32_t textureId; @@ -59,12 +60,13 @@ namespace SohImGui { } CustomWindow; extern Console* console; + extern Ship::InputEditor* controller; extern Ship::GameOverlay* overlay; extern bool needs_save; void Init(WindowImpl window_impl); void Update(EventImpl event); void Tooltip(const char* text); - + void EnhancementRadioButton(const char* text, const char* cvarName, int id); void EnhancementCheckbox(const char* text, const char* cvarName); void EnhancementButton(const char* text, const char* cvarName); @@ -75,7 +77,7 @@ namespace SohImGui { void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue = 0); void DrawMainMenuAndCalculateGameSize(void); - + void DrawFramebufferAndGameInput(void); void Render(void); void CancelFrame(void); @@ -90,4 +92,6 @@ namespace SohImGui { void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha); ImTextureID GetTextureByID(int id); ImTextureID GetTextureByName(const std::string& name); + void BeginGroupPanel(const char* name, const ImVec2 & size = ImVec2(0.0f, 0.0f)); + void EndGroupPanel(float minHeight = 0.0f); } diff --git a/libultraship/libultraship/InputEditor.cpp b/libultraship/libultraship/InputEditor.cpp new file mode 100644 index 0000000000..e40990b0db --- /dev/null +++ b/libultraship/libultraship/InputEditor.cpp @@ -0,0 +1,277 @@ +#include "InputEditor.h" +#include "Controller.h" +#include "Window.h" +#include "Lib/ImGui/imgui.h" +#include "ImGuiImpl.h" +#include "Utils/StringHelper.h" +#include "Lib/ImGui/imgui_internal.h" + +namespace Ship { + + extern "C" uint8_t __enableGameInput; + #define SEPARATION() ImGui::Dummy(ImVec2(0, 5)) + + void InputEditor::Init() { + BtnReading = -1; + } + + std::shared_ptr GetControllerPerSlot(int slot) { + const std::vector vDevices = Window::ControllerApi->virtualDevices; + return Window::ControllerApi->physicalDevices[vDevices[slot]]; + } + + void InputEditor::DrawButton(const char* label, int n64Btn) { + const std::shared_ptr backend = GetControllerPerSlot(CurrentPort); + + float size = 40; + bool readingMode = BtnReading == n64Btn; + bool disabled = BtnReading != -1 && !readingMode || !backend->Connected(); + ImVec2 len = ImGui::CalcTextSize(label); + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SetCursorPosY(pos.y + len.y / 4); + ImGui::SetCursorPosX(pos.x + abs(len.x - size)); + ImGui::Text("%s", label); + ImGui::SameLine(); + ImGui::SetCursorPosY(pos.y); + + if(disabled) { + ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); + } + + if(readingMode) { + const int32_t btn = backend->ReadRawPress(); + + if(btn != -1) { + backend->SetButtonMapping(CurrentPort, n64Btn, btn); + BtnReading = -1; + } + } + + const char* BtnName = backend->GetButtonName(CurrentPort, n64Btn); + + if (ImGui::Button(StringHelper::Sprintf("%s##HBTNID_%d", readingMode ? "Press a Key..." : BtnName, n64Btn).c_str())) { + BtnReading = n64Btn; + backend->ClearRawPress(); + } + + if(disabled) { + ImGui::PopItemFlag(); + ImGui::PopStyleVar(); + } + } + + void InputEditor::DrawVirtualStick(const char* label, ImVec2 stick) { + ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5, ImGui::GetCursorPos().y)); + ImGui::BeginChild(label, ImVec2(68, 75), false); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const ImVec2 p = ImGui::GetCursorScreenPos(); + + float sz = 45.0f; + float rad = sz * 0.5f; + ImVec2 pos = ImVec2(p.x + sz * 0.5f + 12, p.y + sz * 0.5f + 11); + + float stickX = (stick.x / 83.0f) * (rad * 0.5f); + float stickY = -(stick.y / 83.0f) * (rad * 0.5f); + + ImVec4 rect = ImVec4(p.x + 2, p.y + 2, 65, 65); + draw_list->AddRect(ImVec2(rect.x, rect.y), ImVec2(rect.x + rect.z, rect.y + rect.w), ImColor(100, 100, 100, 255), 0.0f, 0, 1.5f); + draw_list->AddCircleFilled(pos, rad, ImColor(130, 130, 130, 255), 8); + draw_list->AddCircleFilled(ImVec2(pos.x + stickX, pos.y + stickY), 5, ImColor(15, 15, 15, 255), 7); + ImGui::EndChild(); + } + + void InputEditor::DrawControllerSchema() { + + const std::vector vDevices = Window::ControllerApi->virtualDevices; + const std::vector> devices = Window::ControllerApi->physicalDevices; + + std::shared_ptr Backend = devices[vDevices[CurrentPort]]; + DeviceProfile& profile =Backend->profiles[CurrentPort]; + float sensitivity = profile.Thresholds[SENSITIVITY]; + bool IsKeyboard = Backend->GetGuid() == "Keyboard" || !Backend->Connected(); + const char* ControllerName = Backend->GetControllerName(); + + if (ControllerName != nullptr && ImGui::BeginCombo("##ControllerEntries", ControllerName)) { + for (uint8_t i = 0; i < devices.size(); i++) { + if (ImGui::Selectable(devices[i]->GetControllerName(), i == vDevices[CurrentPort])) { + Window::ControllerApi->SetPhysicalDevice(CurrentPort, i); + } + } + ImGui::EndCombo(); + } + + ImGui::SameLine(); + + if(ImGui::Button("Refresh")) { + Window::ControllerApi->ScanPhysicalDevices(); + } + + SohImGui::BeginGroupPanel("Buttons", ImVec2(150, 20)); + DrawButton("A", BTN_A); + DrawButton("B", BTN_B); + DrawButton("L", BTN_L); + DrawButton("R", BTN_R); + DrawButton("Z", BTN_Z); + DrawButton("START", BTN_START); + SEPARATION(); + SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 48.0f); + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Digital Pad", ImVec2(150, 20)); + DrawButton("Up", BTN_DUP); + DrawButton("Down", BTN_DDOWN); + DrawButton("Left", BTN_DLEFT); + DrawButton("Right", BTN_DRIGHT); + SEPARATION(); + SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 94.0f); + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Analog Stick", ImVec2(150, 20)); + DrawButton("Up", BTN_STICKUP); + DrawButton("Down", BTN_STICKDOWN); + DrawButton("Left", BTN_STICKLEFT); + DrawButton("Right", BTN_STICKRIGHT); + + if (!IsKeyboard) { + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); + DrawVirtualStick("##MainVirtualStick", ImVec2(Backend->wStickX, Backend->wStickY)); + ImGui::SameLine(); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + + ImGui::BeginChild("##MSInput", ImVec2(90, 50), false); + ImGui::Text("Deadzone"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MDZone", &profile.Thresholds[LEFT_STICK]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + } else { + ImGui::Dummy(ImVec2(0, 6)); + } + SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 24.0f); + ImGui::SameLine(); + + if (!IsKeyboard) { + ImGui::SameLine(); + SohImGui::BeginGroupPanel("Camera Stick", ImVec2(150, 20)); + DrawButton("Up", BTN_VSTICKUP); + DrawButton("Down", BTN_VSTICKDOWN); + DrawButton("Left", BTN_VSTICKLEFT); + DrawButton("Right", BTN_VSTICKRIGHT); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); + DrawVirtualStick("##CameraVirtualStick", ImVec2(Backend->wCamX / sensitivity, Backend->wCamY / sensitivity)); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + ImGui::BeginChild("##CSInput", ImVec2(90, 85), false); + ImGui::Text("Deadzone"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MDZone", &profile.Thresholds[RIGHT_STICK]); + ImGui::PopItemWidth(); + ImGui::Text("Sensitivity"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##MSensitivity", &profile.Thresholds[SENSITIVITY]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + SohImGui::EndGroupPanel(14.0f); + } + + if(Backend->CanGyro()) { + ImGui::SameLine(); + + SohImGui::BeginGroupPanel("Gyro Options", ImVec2(175, 20)); + float cursorX = ImGui::GetCursorPosX() + 5; + ImGui::SetCursorPosX(cursorX); + ImGui::Checkbox("Enable Gyro", &profile.UseGyro); + ImGui::SetCursorPosX(cursorX); + ImGui::Text("Gyro Sensitivity: %d%%", profile.Thresholds[GYRO_SENSITIVITY]); + ImGui::PushItemWidth(135.0f); + ImGui::SetCursorPosX(cursorX); + ImGui::SliderInt("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0, 100, ""); + ImGui::PopItemWidth(); + ImGui::Dummy(ImVec2(0, 1)); + ImGui::SetCursorPosX(cursorX); + if (ImGui::Button("Recalibrate Gyro##RGyro")) { + profile.Thresholds[DRIFT_X] = 0; + profile.Thresholds[DRIFT_Y] = 0; + } + ImGui::SetCursorPosX(cursorX); + DrawVirtualStick("##GyroPreview", ImVec2(Backend->wGyroX, Backend->wGyroY)); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); + ImGui::BeginChild("##GyInput", ImVec2(90, 85), false); + ImGui::Text("Drift X"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##GDriftX", &profile.Thresholds[DRIFT_X]); + ImGui::PopItemWidth(); + ImGui::Text("Drift Y"); + ImGui::PushItemWidth(80); + ImGui::InputInt("##GDriftY", &profile.Thresholds[DRIFT_Y]); + ImGui::PopItemWidth(); + ImGui::EndChild(); + SohImGui::EndGroupPanel(14.0f); + } + + ImGui::SameLine(); + + const ImVec2 cursor = ImGui::GetCursorPos(); + + SohImGui::BeginGroupPanel("C-Buttons", ImVec2(158, 20)); + DrawButton("Up", BTN_CUP); + DrawButton("Down", BTN_CDOWN); + DrawButton("Left", BTN_CLEFT); + DrawButton("Right", BTN_CRIGHT); + ImGui::Dummy(ImVec2(0, 5)); + SohImGui::EndGroupPanel(); + + ImGui::SetCursorPosX(cursor.x); + ImGui::SetCursorPosY(cursor.y + 120); + SohImGui::BeginGroupPanel("Options", ImVec2(158, 20)); + float cursorX = ImGui::GetCursorPosX() + 5; + ImGui::SetCursorPosX(cursorX); + ImGui::Checkbox("Rumble Enabled", &profile.UseRumble); + if (Backend->CanRumble()) { + ImGui::SetCursorPosX(cursorX); + ImGui::Text("Rumble Force: %d%%", static_cast(100 * profile.RumbleStrength)); + ImGui::SetCursorPosX(cursorX); + ImGui::PushItemWidth(135.0f); + ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0, 1.0f, ""); + ImGui::PopItemWidth(); + } + ImGui::Dummy(ImVec2(0, 5)); + SohImGui::EndGroupPanel(IsKeyboard ? 0.0f : 2.0f); + } + + void InputEditor::DrawHud() { + + __enableGameInput = true; + + if (!this->Opened) { + BtnReading = -1; + return; + } + + ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290)); + //OTRTODO: Disable this stupid workaround ( ReadRawPress() only works when the window is on the main viewport ) + ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); + ImGui::Begin("Controller Configuration", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); + + ImGui::BeginTabBar("##Controllers"); + + for (int i = 0; i < 4; i++) { + if (ImGui::BeginTabItem(StringHelper::Sprintf("Port %d", i + 1).c_str())) { + CurrentPort = i; + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + + // Draw current cfg + + DrawControllerSchema(); + + ImGui::End(); + } +} diff --git a/libultraship/libultraship/InputEditor.h b/libultraship/libultraship/InputEditor.h new file mode 100644 index 0000000000..39bddd51d3 --- /dev/null +++ b/libultraship/libultraship/InputEditor.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +#include "Lib/ImGui/imgui.h" + +namespace Ship { + + class InputEditor { + int CurrentPort = 0; + int BtnReading = -1; + public: + bool Opened = false; + void Init(); + void DrawButton(const char* label, int n64Btn); + void DrawVirtualStick(const char* label, ImVec2 stick); + void DrawControllerSchema(); + void DrawHud(); + }; +} diff --git a/libultraship/libultraship/KeyboardController.cpp b/libultraship/libultraship/KeyboardController.cpp index 13014c6a72..0ba08f415c 100644 --- a/libultraship/libultraship/KeyboardController.cpp +++ b/libultraship/libultraship/KeyboardController.cpp @@ -1,56 +1,105 @@ #include "KeyboardController.h" + +#if __APPLE__ +#include +#else +#include +#endif + +#include "Hooks.h" #include "GlobalCtx2.h" +#include "Window.h" namespace Ship { - KeyboardController::KeyboardController(int32_t dwControllerNumber) : Controller(dwControllerNumber) { - LoadBinding(); - } - KeyboardController::~KeyboardController() { - + KeyboardController::KeyboardController() : Controller(), lastScancode(-1) { + GUID = "Keyboard"; } bool KeyboardController::PressButton(int32_t dwScancode) { - if (ButtonMapping.contains(dwScancode)) { - dwPressedButtons |= ButtonMapping[dwScancode]; - return true; + + lastKey = dwScancode; + + for (int slot = 0; slot < MAXCONTROLLERS; slot++) { + + if (profiles[slot].Mappings.contains(dwScancode)) { + dwPressedButtons[slot] |= profiles[slot].Mappings[dwScancode]; + return true; + } } return false; } bool KeyboardController::ReleaseButton(int32_t dwScancode) { - if (ButtonMapping.contains(dwScancode)) { - dwPressedButtons &= ~ButtonMapping[dwScancode]; - return true; + for (int slot = 0; slot < MAXCONTROLLERS; slot++) { + if (profiles[slot].Mappings.contains(dwScancode)) { + dwPressedButtons[slot] &= ~profiles[slot].Mappings[dwScancode]; + return true; + } } return false; } void KeyboardController::ReleaseAllButtons() { - dwPressedButtons = 0; + for(int slot = 0; slot < MAXCONTROLLERS; slot++) { + dwPressedButtons[slot] = 0; + } } - void KeyboardController::ReadFromSource() { + void KeyboardController::ReadFromSource(int32_t slot) { wStickX = 0; wStickY = 0; + wCamX = 0; + wCamY = 0; } - void KeyboardController::WriteToSource(ControllerCallback* controller) + int32_t KeyboardController::ReadRawPress() { + return lastKey; + } + + + void KeyboardController::WriteToSource(int32_t slot, ControllerCallback* controller) { } - std::string KeyboardController::GetControllerType() { - return "KEYBOARD"; + const char* KeyboardController::GetButtonName(int slot, int n64Button) { + std::map& Mappings = profiles[slot].Mappings; + const auto find = std::find_if(Mappings.begin(), Mappings.end(), [n64Button](const std::pair& pair) { + return pair.second == n64Button; + }); + + if (find == Mappings.end()) return "Unknown"; + const char* name = GlobalCtx2::GetInstance()->GetWindow()->GetKeyName(find->first); + return strlen(name) == 0 ? "Unknown" : name; } - std::string KeyboardController::GetConfSection() { - return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1); + + void KeyboardController::CreateDefaultBinding(int32_t slot) { + DeviceProfile& profile = profiles[slot]; + profile.Mappings[0x14D] = BTN_CRIGHT; + profile.Mappings[0x14B] = BTN_CLEFT; + profile.Mappings[0x150] = BTN_CDOWN; + profile.Mappings[0x148] = BTN_CUP; + profile.Mappings[0x13] = BTN_R; + profile.Mappings[0x12] = BTN_L; + profile.Mappings[0x023] = BTN_DRIGHT; + profile.Mappings[0x021] = BTN_DLEFT; + profile.Mappings[0x022] = BTN_DDOWN; + profile.Mappings[0x014] = BTN_DUP; + profile.Mappings[0x039] = BTN_START; + profile.Mappings[0x02C] = BTN_Z; + profile.Mappings[0x02E] = BTN_B; + profile.Mappings[0x02D] = BTN_A; + profile.Mappings[0x020] = BTN_STICKRIGHT; + profile.Mappings[0x01E] = BTN_STICKLEFT; + profile.Mappings[0x01F] = BTN_STICKDOWN; + profile.Mappings[0x011] = BTN_STICKUP; } - std::string KeyboardController::GetBindingConfSection() { - return GetControllerType() + " CONTROLLER BINDING " + std::to_string(GetControllerNumber() + 1); + const char* KeyboardController::GetControllerName() { + return "Keyboard"; } } diff --git a/libultraship/libultraship/KeyboardController.h b/libultraship/libultraship/KeyboardController.h index f6c109ca74..cc0aca04e7 100644 --- a/libultraship/libultraship/KeyboardController.h +++ b/libultraship/libultraship/KeyboardController.h @@ -5,24 +5,34 @@ namespace Ship { class KeyboardController : public Controller { public: - KeyboardController(int32_t dwControllerNumber); - ~KeyboardController(); - - void ReadFromSource(); - void WriteToSource(ControllerCallback* controller); - bool Connected() const { return true; } - bool CanRumble() const { return false; } + KeyboardController(); + void ReadFromSource(int32_t slot) override; + void WriteToSource(int32_t slot, ControllerCallback* controller) override; + bool Connected() const override { return true; } + bool CanRumble() const override { return false; } + bool CanGyro() const override { return false; } + const char* GetControllerName() override; + const char* GetButtonName(int slot, int n64Button) override; bool PressButton(int32_t dwScancode); bool ReleaseButton(int32_t dwScancode); + + void ClearRawPress() override { + lastKey = -1; + } + + int32_t ReadRawPress() override; void ReleaseAllButtons(); - bool HasPadConf() const { return false; } - std::optional GetPadConfSection() { return {}; } + void SetLastScancode(int32_t key) { + lastScancode = key; + } + + int32_t GetLastScancode() { return lastScancode; } + void CreateDefaultBinding(int32_t slot) override; protected: - std::string GetControllerType(); - std::string GetConfSection(); - std::string GetBindingConfSection(); + int32_t lastScancode; + int32_t lastKey = -1; }; } diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp index 06ff5f60a9..620fb52714 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp @@ -28,6 +28,7 @@ #include "gfx_pc.h" #include "../../ImGuiImpl.h" #include "../../Cvar.h" +#include "../../Hooks.h" #define DECLARE_GFX_DXGI_FUNCTIONS #include "gfx_dxgi.h" @@ -240,6 +241,7 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par dxgi.current_height = (uint32_t)(l_param >> 16); break; case WM_DESTROY: + ModInternal::ExecuteHooks(); exit(0); case WM_PAINT: if (dxgi.in_paint) { @@ -718,6 +720,12 @@ void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message) { } } +const char* gfx_dxgi_get_key_name(int scancode) { + TCHAR* Text = new TCHAR[64]; + GetKeyNameText(scancode << 16, Text, 64); + return (char*) Text; +} + extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = { gfx_dxgi_init, gfx_dxgi_set_keyboard_callbacks, @@ -734,6 +742,7 @@ extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = { gfx_dxgi_set_target_fps, gfx_dxgi_set_maximum_frame_latency, gfx_dxgi_get_detected_hz, + gfx_dxgi_get_key_name }; #endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index 44ad9ec37d..cb0d7a7f09 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -23,6 +23,7 @@ #include "../../ImGuiImpl.h" #include "../../Cvar.h" +#include "../../Hooks.h" #include "gfx_window_manager_api.h" #include "gfx_screen_config.h" @@ -108,7 +109,7 @@ static void set_fullscreen(bool on, bool call_callback) { SDL_GetDesktopDisplayMode(0, &mode); window_width = mode.w; window_height = mode.h; - //SDL_ShowCursor(false); + SDL_ShowCursor(false); } else { window_width = DESIRED_SCREEN_WIDTH; window_height = DESIRED_SCREEN_HEIGHT; @@ -229,6 +230,15 @@ static int translate_scancode(int scancode) { } } +static int untranslate_scancode(int translatedScancode) { + for (int i = 0; i < 512; i++) { + if (inverted_scancode_table[i] == translatedScancode) { + return i; + } + } + return 0; +} + static void gfx_sdl_onkeydown(int scancode) { int key = translate_scancode(scancode); if (on_key_down_callback != NULL) { @@ -270,6 +280,7 @@ static void gfx_sdl_handle_events(void) { Game::SaveSettings(); break; case SDL_QUIT: + ModInternal::ExecuteHooks(); SDL_Quit(); // bandaid fix for linux window closing issue exit(0); } @@ -339,6 +350,10 @@ static float gfx_sdl_get_detected_hz(void) { return 0; } +static const char* gfx_sdl_get_key_name(int scancode) { + return SDL_GetScancodeName((SDL_Scancode) untranslate_scancode(scancode)); +} + struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_init, gfx_sdl_set_keyboard_callbacks, @@ -354,7 +369,8 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_get_time, gfx_sdl_set_target_fps, gfx_sdl_set_maximum_frame_latency, - gfx_sdl_get_detected_hz + gfx_sdl_get_detected_hz, + gfx_sdl_get_key_name }; #endif diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h index 50618f661a..99344940e0 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h +++ b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h @@ -20,6 +20,7 @@ struct GfxWindowManagerAPI { void (*set_target_fps)(int fps); void (*set_maximum_frame_latency)(int latency); float (*get_detected_hz)(void); + const char* (*get_key_name)(int scancode); }; #endif diff --git a/libultraship/libultraship/Lib/Mercury/Mercury.cpp b/libultraship/libultraship/Lib/Mercury/Mercury.cpp new file mode 100644 index 0000000000..d6bf734ea0 --- /dev/null +++ b/libultraship/libultraship/Lib/Mercury/Mercury.cpp @@ -0,0 +1,134 @@ +#include "Mercury.h" + +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; +using json = nlohmann::json; + +std::unordered_map ramMap; + +Mercury::Mercury(std::string path) : path_(std::move(path)) { + this->reload(); +} + +std::vector split(const std::string& s, const char delimiter) { + std::vector result; + std::stringstream ss(s); + std::string item; + while (getline(ss, item, delimiter)) { + result.push_back(item); + } + return result; +} + +std::string Mercury::formatNestedKey(const std::string& key) { + const std::vector dots = split(key, '.'); + std::string tmp; + if (dots.size() > 1) + for (const auto& dot : dots) { + tmp += "/" + dot; + } + else + tmp = "/" + dots[0]; + + return tmp; +} + +json Mercury::nested(const std::string& key) { + std::vector dots = split(key, '.'); + if (!this->vjson.is_object()) + return this->vjson; + json gjson = this->vjson.unflatten(); + + if (dots.size() > 1) { + for (auto& key : dots) { + if (key == "*" || gjson.contains(key)) + gjson = gjson[key]; + } + return gjson; + } + + return gjson[key]; +} + +std::string Mercury::getString(const std::string& key, const std::string& def) { + json n = this->nested(key); + if (n.is_string() && !n.get().empty()) + return n; + return def; +} + +float Mercury::getFloat(const std::string& key, float def) { + json n = this->nested(key); + if (n.is_number_float()) + return n; + return def; +} + +bool Mercury::getBool(const std::string& key, bool def) { + json n = this->nested(key); + if (n.is_boolean()) + return n; + return def; +} + +int Mercury::getInt(const std::string& key, int def) { + json n = this->nested(key); + if (n.is_number_integer()) + return n; + return def; +} + +bool Mercury::contains(const std::string& key) { + return !this->nested(key).is_null(); +} + +void Mercury::setString(const std::string& key, const std::string& value) { + this->vjson[formatNestedKey(key)] = value; +} + +void Mercury::setFloat(const std::string& key, float value) { + this->vjson[formatNestedKey(key)] = value; +} + +void Mercury::setBool(const std::string& key, bool value) { + this->vjson[formatNestedKey(key)] = value; +} + +void Mercury::setInt(const std::string& key, int value) { + this->vjson[formatNestedKey(key)] = value; +} + +void Mercury::setUInt(const std::string& key, uint32_t value) { + this->vjson[formatNestedKey(key)] = value; +} + +void Mercury::erase(const std::string& key) { + this->vjson.erase(formatNestedKey(key)); +} + +void Mercury::reload() { + if (this->path_ == "None" || !fs::exists(this->path_) || !fs::is_regular_file(this->path_)) { + this->isNewInstance = true; + this->vjson = json::object(); + return; + } + std::ifstream ifs(this->path_); + try { + this->rjson = json::parse(ifs); + this->vjson = this->rjson.flatten(); + } + catch (...) { + this->vjson = json::object(); + } +} + +void Mercury::save() const { + std::ofstream file(this->path_); + file << this->vjson.unflatten().dump(4); +} diff --git a/libultraship/libultraship/Lib/Mercury/Mercury.h b/libultraship/libultraship/Lib/Mercury/Mercury.h new file mode 100644 index 0000000000..5c2646d362 --- /dev/null +++ b/libultraship/libultraship/Lib/Mercury/Mercury.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include +#include "../nlohmann/json.hpp" + +class Mercury { +protected: + std::string path_; +public: + explicit Mercury(std::string path); + + nlohmann::json vjson; + nlohmann::json rjson; + nlohmann::json nested(const std::string& key); + static std::string formatNestedKey(const std::string& key); + std::string getString(const std::string& key, const std::string& def = ""); + float getFloat(const std::string& key, float defValue = 0.0f); + bool getBool(const std::string& key, bool defValue = false); + int getInt(const std::string& key, int defValue = 0); + bool contains(const std::string& key); + template< typename T > std::vector getArray(const std::string& key); + void setString(const std::string& key, const std::string& value); + void setFloat(const std::string& key, float value); + void setBool(const std::string& key, bool value); + void setInt(const std::string& key, int value); + void setUInt(const std::string& key, uint32_t value); + void erase(const std::string& key); + void set(const std::string& key, std::any value); + template< typename T > void setArray(const std::string& key, std::vector array); + + void reload(); + void save() const; + bool isNewInstance = false; +}; + +template< typename T > +std::vector Mercury::getArray(const std::string& key) { + if (nlohmann::json tmp = this->nested(key); tmp.is_array()) + return tmp.get>(); + return std::vector(); +}; + +template +void Mercury::setArray(const std::string& key, std::vector array) { + this->vjson[formatNestedKey(key)] = nlohmann::json(array); +} diff --git a/soh/soh/Lib/nlohmann/LICENSE.MIT b/libultraship/libultraship/Lib/nlohmann/LICENSE.MIT similarity index 100% rename from soh/soh/Lib/nlohmann/LICENSE.MIT rename to libultraship/libultraship/Lib/nlohmann/LICENSE.MIT diff --git a/soh/soh/Lib/nlohmann/json.hpp b/libultraship/libultraship/Lib/nlohmann/json.hpp similarity index 100% rename from soh/soh/Lib/nlohmann/json.hpp rename to libultraship/libultraship/Lib/nlohmann/json.hpp diff --git a/libultraship/libultraship/SDLController.cpp b/libultraship/libultraship/SDLController.cpp index d0550e7308..fc813dd661 100644 --- a/libultraship/libultraship/SDLController.cpp +++ b/libultraship/libultraship/SDLController.cpp @@ -1,103 +1,36 @@ #include "SDLController.h" - -#include "GameSettings.h" #include "GlobalCtx2.h" #include "spdlog/spdlog.h" -#include "stox.h" #include "Window.h" -#include "Cvar.h" #include extern "C" uint8_t __osMaxControllers; namespace Ship { - SDLController::SDLController(int32_t dwControllerNumber) : Controller(dwControllerNumber), Cont(nullptr), guid(INVALID_SDL_CONTROLLER_GUID) { - - } - - SDLController::~SDLController() { - Close(); - } - - bool SDLController::IsGuidInUse(const std::string& guid) { - // Check if the GUID is loaded in any other controller; - for (size_t i = 0; i < __osMaxControllers; i++) { - for (size_t j = 0; j < Window::Controllers[i].size(); j++) { - SDLController* OtherCont = dynamic_cast(Window::Controllers[i][j].get()); - - if (OtherCont != nullptr && OtherCont->GetGuid().compare(guid) == 0) { - return true; - } - } - } - - return false; - } bool SDLController::Open() { - std::string ConfSection = GetConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); - for (int i = 0; i < SDL_NumJoysticks(); i++) { - if (SDL_IsGameController(i)) { - // Get the GUID from SDL - char GuidBuf[33]; - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), GuidBuf, sizeof(GuidBuf)); - auto NewGuid = std::string(GuidBuf); + const auto NewCont = SDL_GameControllerOpen(physicalSlot); - // Invalid GUID read. Go to next. - if (NewGuid.compare(INVALID_SDL_CONTROLLER_GUID) == 0) { - SPDLOG_ERROR("SDL Controller returned invalid guid"); - continue; - } - - // The GUID is in use, we want to use a different physical controller. Go to next. - if (IsGuidInUse(NewGuid)) { - continue; - } - - // If the GUID is blank from the config, OR if the config GUID matches, load the controller. - if (Conf[ConfSection]["GUID"].compare("") == 0 || Conf[ConfSection]["GUID"].compare(INVALID_SDL_CONTROLLER_GUID) == 0 || Conf[ConfSection]["GUID"].compare(NewGuid) == 0) { - auto NewCont = SDL_GameControllerOpen(i); - - // We failed to load the controller. Go to next. - if (NewCont == nullptr) { - SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError()); - continue; - } - - if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO)) - { - SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE); - } - - guid = NewGuid; - Cont = NewCont; - - std::string BindingConfSection = GetBindingConfSection(); - std::string PadConfSection = *GetPadConfSection(); - std::shared_ptr config = GlobalCtx2::GetInstance()->GetConfig(); - - if (!config->has(BindingConfSection)) { - CreateDefaultBinding(); - } - - if (!config->has(PadConfSection)) { - CreateDefaultPadConf(); - } - - LoadBinding(); - LoadAxisThresholds(); - // Update per-controller settings in ImGui menu after opening controller. - Game::LoadPadSettings(); - - break; - } - } + // We failed to load the controller. Go to next. + if (NewCont == nullptr) { + SPDLOG_ERROR("SDL Controller failed to open: ({})", SDL_GetError()); + return false; } - return Cont != nullptr; + if (SDL_GameControllerHasSensor(NewCont, SDL_SENSOR_GYRO)) { + SDL_GameControllerSetSensorEnabled(NewCont, SDL_SENSOR_GYRO, SDL_TRUE); + supportsGyro = true; + } + + char GuidBuf[33]; + SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(physicalSlot), GuidBuf, sizeof(GuidBuf)); + GUID = std::string(GuidBuf); + Cont = NewCont; + wCamX = 0; + wCamY = 0; + + return true; } bool SDLController::Close() { @@ -108,31 +41,14 @@ namespace Ship { SDL_GameControllerClose(Cont); } Cont = nullptr; - guid = ""; - ButtonMapping.clear(); - ThresholdMapping.clear(); - dwPressedButtons = 0; wStickX = 0; wStickY = 0; return true; } - void SDLController::LoadAxisThresholds() { - std::string ConfSection = GetBindingConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); - ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTX] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTX) + "_threshold"]); - ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTY] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTY) + "_threshold"]); - ThresholdMapping[SDL_CONTROLLER_AXIS_RIGHTX] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTX) + "_threshold"]); - ThresholdMapping[SDL_CONTROLLER_AXIS_RIGHTY] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTY) + "_threshold"]); - ThresholdMapping[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERLEFT) + "_threshold"]); - ThresholdMapping[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = Ship::stoi(Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + "_threshold"]); - } - - - void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick) { + void SDLController::NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick, float sensitivity) { //scale {-32768 ... +32767} to {-84 ... +84} auto ax = wAxisValueX * 85.0 / 32767.0; auto ay = wAxisValueY * 85.0 / 32767.0; @@ -166,18 +82,56 @@ namespace Ship { if (!isRightStick) { wStickX = +ax; wStickY = -ay; - } - else { - //SOHTODO KIRITO: Camera Sensitivity - wCamX = +ax * 15.0f; - wCamY = -ay * 15.0f; + } else { + wCamX = +ax * sensitivity; + wCamY = -ay * sensitivity; } } - void SDLController::ReadFromSource() { - std::string ConfSection = GetBindingConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); + + int32_t SDLController::ReadRawPress() { + SDL_GameControllerUpdate(); + + for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) { + if (SDL_GameControllerGetButton(Cont, static_cast(i))) { + return i; + } + } + + for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) { + const auto Axis = static_cast(i); + const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis) / 32767; + + if(AxisValue < 0) { + return -(Axis + AXIS_SCANCODE_BIT); + } + + if (AxisValue > 0) { + return (Axis + AXIS_SCANCODE_BIT); + } + } + + return -1; + } + + ControllerThresholds SDLAxisToThreshold( uint32_t axis ){ + switch(axis){ + case SDL_CONTROLLER_AXIS_LEFTX: + case SDL_CONTROLLER_AXIS_LEFTY: + return LEFT_STICK; + case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_CONTROLLER_AXIS_RIGHTY: + return RIGHT_STICK; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + return LEFT_TRIGGER; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + return RIGHT_TRIGGER; + default: return DRIFT_X; + } + } + + void SDLController::ReadFromSource(int32_t slot) { + DeviceProfile& profile = profiles[slot]; SDL_GameControllerUpdate(); @@ -194,21 +148,14 @@ namespace Ship { } } - auto cameraX = SDL_GameControllerGetAxis(Cont, SDL_CONTROLLER_AXIS_RIGHTX); - auto cameraY = SDL_GameControllerGetAxis(Cont, SDL_CONTROLLER_AXIS_RIGHTY); - NormalizeStickAxis(cameraX, cameraY, ThresholdMapping[SDL_CONTROLLER_AXIS_LEFTX], true); - - if (SDL_GameControllerHasSensor(Cont, SDL_SENSOR_GYRO)) - { - size_t contNumber = GetControllerNumber(); + if (supportsGyro && profile.UseGyro) { float gyroData[3]; SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3); - const char* contName = SDL_GameControllerName(Cont); - float gyro_drift_x = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), 0.0f); - float gyro_drift_y = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), 0.0f); - const float gyro_sensitivity = CVar_GetFloat(StringHelper::Sprintf("gCont%i_GyroSensitivity", contNumber).c_str(), 1.0f); + float gyro_drift_x = profile.GyroThresholds[DRIFT_X] / 100.0f; + float gyro_drift_y = profile.GyroThresholds[DRIFT_Y] / 100.0f; + const float gyro_sensitivity = profile.GyroThresholds[SENSITIVITY] / 100.0f; if (gyro_drift_x == 0) { gyro_drift_x = gyroData[0]; @@ -218,8 +165,8 @@ namespace Ship { gyro_drift_y = gyroData[1]; } - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftX", contNumber).c_str(), gyro_drift_x); - CVar_SetFloat(StringHelper::Sprintf("gCont%i_GyroDriftY", contNumber).c_str(), gyro_drift_y); + profile.GyroThresholds[DRIFT_X] = (int) gyro_drift_x * 100; + profile.GyroThresholds[DRIFT_Y] = (int) gyro_drift_y * 100; wGyroX = gyroData[0] - gyro_drift_x; wGyroY = gyroData[1] - gyro_drift_y; @@ -229,28 +176,32 @@ namespace Ship { } for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) { - if (ButtonMapping.contains(i)) { - if (SDL_GameControllerGetButton(Cont, (SDL_GameControllerButton)i)) { - dwPressedButtons |= ButtonMapping[i]; + if (profile.Mappings.contains(i)) { + if (SDL_GameControllerGetButton(Cont, static_cast(i))) { + dwPressedButtons[slot] |= profile.Mappings[i]; } else { - dwPressedButtons &= ~ButtonMapping[i]; + dwPressedButtons[slot] &= ~profile.Mappings[i]; } } } - SDL_GameControllerAxis StickAxisX = SDL_CONTROLLER_AXIS_INVALID; - SDL_GameControllerAxis StickAxisY = SDL_CONTROLLER_AXIS_INVALID; - int32_t StickDeadzone = 0; + SDL_GameControllerAxis LStickAxisX = SDL_CONTROLLER_AXIS_INVALID; + SDL_GameControllerAxis LStickAxisY = SDL_CONTROLLER_AXIS_INVALID; + int32_t LStickDeadzone = 0; + + SDL_GameControllerAxis RStickAxisX = SDL_CONTROLLER_AXIS_INVALID; + SDL_GameControllerAxis RStickAxisY = SDL_CONTROLLER_AXIS_INVALID; + int32_t RStickDeadzone = 0; for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) { - auto Axis = (SDL_GameControllerAxis)i; - auto PosScancode = i + AXIS_SCANCODE_BIT; - auto NegScancode = -PosScancode; - auto AxisThreshold = ThresholdMapping[i]; - auto PosButton = ButtonMapping[PosScancode]; - auto NegButton = ButtonMapping[NegScancode]; - auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis); + const auto Axis = static_cast(i); + const auto PosScancode = i + AXIS_SCANCODE_BIT; + const auto NegScancode = -PosScancode; + const auto AxisThreshold = profile.Thresholds[SDLAxisToThreshold(i)]; + const auto PosButton = profile.Mappings[PosScancode]; + const auto NegButton = profile.Mappings[NegScancode]; + const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis); #ifdef TARGET_WEB // Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562 @@ -263,94 +214,176 @@ namespace Ship { } #endif - // If the axis is NOT mapped to the control stick. if (!( PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT || PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN || NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT || NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN)) { - if (AxisValue > AxisThreshold) { - dwPressedButtons |= PosButton; - dwPressedButtons &= ~NegButton; + + if (AxisValue > 0x1E00) { + dwPressedButtons[slot] |= PosButton; + dwPressedButtons[slot] &= ~NegButton; } - else if (AxisValue < -AxisThreshold) { - dwPressedButtons &= ~PosButton; - dwPressedButtons |= NegButton; + else if (AxisValue < -0x1E00) { + dwPressedButtons[slot] &= ~PosButton; + dwPressedButtons[slot] |= NegButton; } else { - dwPressedButtons &= ~PosButton; - dwPressedButtons &= ~NegButton; + dwPressedButtons[slot] &= ~PosButton; + dwPressedButtons[slot] &= ~NegButton; } } else { if (PosButton == BTN_STICKLEFT || PosButton == BTN_STICKRIGHT) { - if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisX != Axis) { - SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", StickAxisX, Axis); + if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisX != Axis) { + SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", LStickAxisX, Axis); } - if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) { - SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", StickDeadzone, AxisThreshold); + if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", LStickDeadzone, AxisThreshold); } - StickDeadzone = AxisThreshold; - StickAxisX = Axis; + LStickDeadzone = AxisThreshold; + LStickAxisX = Axis; } if (PosButton == BTN_STICKUP || PosButton == BTN_STICKDOWN) { - if (StickAxisY != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != Axis) { - SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", StickAxisY, Axis); + if (LStickAxisY != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != Axis) { + SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", LStickAxisY, Axis); } - if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) { - SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold); + if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold); } - StickDeadzone = AxisThreshold; - StickAxisY = Axis; + LStickDeadzone = AxisThreshold; + LStickAxisY = Axis; } if (NegButton == BTN_STICKLEFT || NegButton == BTN_STICKRIGHT) { - if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisX != Axis) { - SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", StickAxisX, Axis); + if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisX != Axis) { + SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", LStickAxisX, Axis); } - if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) { - SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold); + if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold); } - StickDeadzone = AxisThreshold; - StickAxisX = Axis; + LStickDeadzone = AxisThreshold; + LStickAxisX = Axis; } if (NegButton == BTN_STICKUP || NegButton == BTN_STICKDOWN) { - if (StickAxisY != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != Axis) { - SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", StickAxisY, Axis); + if (LStickAxisY != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != Axis) { + SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", LStickAxisY, Axis); } - if (StickDeadzone != 0 && StickDeadzone != AxisThreshold) { - SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", StickDeadzone, AxisThreshold); + if (LStickDeadzone != 0 && LStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", LStickDeadzone, AxisThreshold); } - StickDeadzone = AxisThreshold; - StickAxisY = Axis; + LStickDeadzone = AxisThreshold; + LStickAxisY = Axis; } } - if (StickAxisX != SDL_CONTROLLER_AXIS_INVALID && StickAxisY != SDL_CONTROLLER_AXIS_INVALID) { - auto AxisValueX = SDL_GameControllerGetAxis(Cont, StickAxisX); - auto AxisValueY = SDL_GameControllerGetAxis(Cont, StickAxisY); - NormalizeStickAxis(AxisValueX, AxisValueY, StickDeadzone, false); + if (LStickAxisX != SDL_CONTROLLER_AXIS_INVALID && LStickAxisY != SDL_CONTROLLER_AXIS_INVALID) { + const auto AxisValueX = SDL_GameControllerGetAxis(Cont, LStickAxisX); + const auto AxisValueY = SDL_GameControllerGetAxis(Cont, LStickAxisY); + NormalizeStickAxis(AxisValueX, AxisValueY, LStickDeadzone, false, profile.Thresholds[SENSITIVITY]); + } + + // Right Stick + // If the axis is NOT mapped to the control stick. + if (!( + PosButton == BTN_VSTICKLEFT || PosButton == BTN_VSTICKRIGHT || + PosButton == BTN_VSTICKUP || PosButton == BTN_VSTICKDOWN || + NegButton == BTN_VSTICKLEFT || NegButton == BTN_VSTICKRIGHT || + NegButton == BTN_VSTICKUP || NegButton == BTN_VSTICKDOWN)) { + + if (AxisValue > 0x1E00) { + dwPressedButtons[slot] |= PosButton; + dwPressedButtons[slot] &= ~NegButton; + } + else if (AxisValue < -0x1E00) { + dwPressedButtons[slot] &= ~PosButton; + dwPressedButtons[slot] |= NegButton; + } + else { + dwPressedButtons[slot] &= ~PosButton; + dwPressedButtons[slot] &= ~NegButton; + } + + } else { + if (PosButton == BTN_VSTICKLEFT || PosButton == BTN_VSTICKRIGHT) { + if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisX != Axis) { + SPDLOG_TRACE("Invalid PosStickX configured. Neg was {} and Pos is {}", RStickAxisX, Axis); + } + + if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Up/Down was {} and Left/Right is {}", RStickDeadzone, AxisThreshold); + } + + RStickDeadzone = AxisThreshold; + RStickAxisX = Axis; + } + + if (PosButton == BTN_VSTICKUP || PosButton == BTN_VSTICKDOWN) { + if (RStickAxisY != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != Axis) { + SPDLOG_TRACE("Invalid PosStickY configured. Neg was {} and Pos is {}", RStickAxisY, Axis); + } + + if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold); + } + + RStickDeadzone = AxisThreshold; + RStickAxisY = Axis; + } + + if (NegButton == BTN_VSTICKLEFT || NegButton == BTN_VSTICKRIGHT) { + if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisX != Axis) { + SPDLOG_TRACE("Invalid NegStickX configured. Pos was {} and Neg is {}", RStickAxisX, Axis); + } + + if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone configured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold); + } + + RStickDeadzone = AxisThreshold; + RStickAxisX = Axis; + } + + if (NegButton == BTN_VSTICKUP || NegButton == BTN_VSTICKDOWN) { + if (RStickAxisY != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != Axis) { + SPDLOG_TRACE("Invalid NegStickY configured. Pos was {} and Neg is {}", RStickAxisY, Axis); + } + + if (RStickDeadzone != 0 && RStickDeadzone != AxisThreshold) { + SPDLOG_TRACE("Invalid Deadzone misconfigured. Left/Right was {} and Up/Down is {}", RStickDeadzone, AxisThreshold); + } + + RStickDeadzone = AxisThreshold; + RStickAxisY = Axis; + } + } + + if (RStickAxisX != SDL_CONTROLLER_AXIS_INVALID && RStickAxisY != SDL_CONTROLLER_AXIS_INVALID) { + const auto AxisValueX = SDL_GameControllerGetAxis(Cont, RStickAxisX); + const auto AxisValueY = SDL_GameControllerGetAxis(Cont, RStickAxisY); + NormalizeStickAxis(AxisValueX, AxisValueY, RStickDeadzone, true, profile.Thresholds[SENSITIVITY]); } } } - void SDLController::WriteToSource(ControllerCallback* controller) + void SDLController::WriteToSource(int32_t slot, ControllerCallback* controller) { - if (CanRumble()) { + if (CanRumble() && profiles[slot].UseRumble) { if (controller->rumble > 0) { - float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", GetControllerNumber()).c_str(), 1.0f); + float rumble_strength = profiles[slot].RumbleStrength; SDL_GameControllerRumble(Cont, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0); - } else { + } + else { SDL_GameControllerRumble(Cont, 0, 0, 0); } } @@ -373,74 +406,71 @@ namespace Ship { } } - void SDLController::CreateDefaultBinding() { - std::string ConfSection = GetBindingConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + const char* AxisNames[] = { + "Left Stick X", + "Left Stick Y", + "Right Stick X", + "Right Stick Y", + "Left Trigger", + "Right Trigger", + "Start Button" + }; - ConfigFile& Conf = *pConf.get(); + char buffer[50]; + const char* SDLController::GetButtonName(int slot, int n64Button) { + std::map& Mappings = profiles[slot].Mappings; + const auto find = std::find_if(Mappings.begin(), Mappings.end(), [n64Button](const std::pair& pair) { + return pair.second == n64Button; + }); - Conf[ConfSection][STR(BTN_CRIGHT)] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - Conf[ConfSection][STR(BTN_CLEFT)] = std::to_string(SDL_CONTROLLER_BUTTON_Y); - Conf[ConfSection][STR(BTN_CDOWN)] = std::to_string(SDL_CONTROLLER_BUTTON_X); - Conf[ConfSection][STR(BTN_CUP)] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSTICK); - //Conf[ConfSection][STR(BTN_CRIGHT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_X); - //Conf[ConfSection][STR(BTN_CLEFT + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_Y); - //Conf[ConfSection][STR(BTN_CDOWN + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); - //Conf[ConfSection][STR(BTN_CUP + "_2")] = std::to_string(SDL_CONTROLLER_BUTTON_RIGHTSTICK); - Conf[ConfSection][STR(BTN_R)] = std::to_string((SDL_CONTROLLER_AXIS_TRIGGERRIGHT + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_L)] = std::to_string(SDL_CONTROLLER_BUTTON_LEFTSHOULDER); - Conf[ConfSection][STR(BTN_DRIGHT)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - Conf[ConfSection][STR(BTN_DLEFT)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_LEFT); - Conf[ConfSection][STR(BTN_DDOWN)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_DOWN); - Conf[ConfSection][STR(BTN_DUP)] = std::to_string(SDL_CONTROLLER_BUTTON_DPAD_UP); - Conf[ConfSection][STR(BTN_START)] = std::to_string(SDL_CONTROLLER_BUTTON_START); - Conf[ConfSection][STR(BTN_Z)] = std::to_string((SDL_CONTROLLER_AXIS_TRIGGERLEFT + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_B)] = std::to_string(SDL_CONTROLLER_BUTTON_B); - Conf[ConfSection][STR(BTN_A)] = std::to_string(SDL_CONTROLLER_BUTTON_A); - Conf[ConfSection][STR(BTN_STICKRIGHT)] = std::to_string((SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_STICKLEFT)] = std::to_string(-(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_STICKDOWN)] = std::to_string((SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT)); - Conf[ConfSection][STR(BTN_STICKUP)] = std::to_string(-(SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT)); + if (find == Mappings.end()) return "Unknown"; - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTX) + "_threshold"] = std::to_string(16.0); - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_LEFTY) + "_threshold"] = std::to_string(16.0); - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTX) + "_threshold"] = std::to_string(0x4000); - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_RIGHTY) + "_threshold"] = std::to_string(0x4000); - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERLEFT) + "_threshold"] = std::to_string(0x1E00); - Conf[ConfSection][STR(SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + "_threshold"] = std::to_string(0x1E00); + int btn = abs(find->first); - Conf.Save(); - } + if(btn >= AXIS_SCANCODE_BIT) { + btn -= AXIS_SCANCODE_BIT; - void SDLController::CreateDefaultPadConf() { - std::string ConfSection = *GetPadConfSection(); - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); - - Conf.Save(); - } - - void SDLController::SetButtonMapping(const std::string& szButtonName, int32_t dwScancode) { - if (guid.compare(INVALID_SDL_CONTROLLER_GUID)) { - return; + snprintf(buffer, sizeof(buffer), "%s%s", AxisNames[btn], find->first > 0 ? "+" : "-"); + return buffer; } - Controller::SetButtonMapping(szButtonName, dwScancode); + snprintf(buffer, sizeof(buffer), "Button %d", btn); + return buffer; } - std::string SDLController::GetControllerType() { - return "SDL"; - } - - std::string SDLController::GetConfSection() { - return GetControllerType() + " CONTROLLER " + std::to_string(GetControllerNumber() + 1); + const char* SDLController::GetControllerName() { + return SDL_GameControllerNameForIndex(physicalSlot); } - std::string SDLController::GetBindingConfSection() { - return GetControllerType() + " CONTROLLER BINDING " + guid; - } + void SDLController::CreateDefaultBinding(int32_t slot) { + DeviceProfile& profile = profiles[slot]; + profile.Mappings.clear(); - std::optional SDLController::GetPadConfSection() { - return GetControllerType() + " CONTROLLER PAD " + guid; + profile.UseRumble = true; + profile.RumbleStrength = 1.0f; + profile.UseGyro = false; + profile.Mappings[ SDL_CONTROLLER_AXIS_RIGHTX | AXIS_SCANCODE_BIT] = BTN_CRIGHT; + profile.Mappings[-(SDL_CONTROLLER_AXIS_RIGHTX | AXIS_SCANCODE_BIT)] = BTN_CLEFT; + profile.Mappings[ SDL_CONTROLLER_AXIS_RIGHTY | AXIS_SCANCODE_BIT] = BTN_CDOWN; + profile.Mappings[-(SDL_CONTROLLER_AXIS_RIGHTY | AXIS_SCANCODE_BIT)] = BTN_CUP; + profile.Mappings[SDL_CONTROLLER_AXIS_TRIGGERRIGHT + AXIS_SCANCODE_BIT] = BTN_R; + profile.Mappings[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = BTN_L; + profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_RIGHT] = BTN_DRIGHT; + profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_LEFT] = BTN_DLEFT; + profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_DOWN] = BTN_DDOWN; + profile.Mappings[SDL_CONTROLLER_BUTTON_DPAD_UP] = BTN_DUP; + profile.Mappings[SDL_CONTROLLER_BUTTON_START] = BTN_START; + profile.Mappings[SDL_CONTROLLER_AXIS_TRIGGERLEFT + AXIS_SCANCODE_BIT] = BTN_Z; + profile.Mappings[SDL_CONTROLLER_BUTTON_B] = BTN_B; + profile.Mappings[SDL_CONTROLLER_BUTTON_A] = BTN_A; + profile.Mappings[(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)] = BTN_STICKRIGHT; + profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)] = BTN_STICKLEFT; + profile.Mappings[SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT] = BTN_STICKDOWN; + profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT)] = BTN_STICKUP; + profile.Thresholds[LEFT_STICK] = 16.0; + profile.Thresholds[RIGHT_STICK] = 16.0; + profile.Thresholds[LEFT_TRIGGER] = 0x1E00; + profile.Thresholds[RIGHT_TRIGGER] = 0x1E00; + profile.Thresholds[SENSITIVITY] = 16.0; } } diff --git a/libultraship/libultraship/SDLController.h b/libultraship/libultraship/SDLController.h index d1d671bb99..ae239a2f1d 100644 --- a/libultraship/libultraship/SDLController.h +++ b/libultraship/libultraship/SDLController.h @@ -6,46 +6,35 @@ #include #endif -#define INVALID_SDL_CONTROLLER_GUID (std::string("00000000000000000000000000000000")) - namespace Ship { class SDLController : public Controller { public: - SDLController(int32_t dwControllerNumber); - ~SDLController(); - - void ReadFromSource(); - void WriteToSource(ControllerCallback* controller); - bool Connected() const { return Cont != nullptr; } - bool CanRumble() const { + SDLController(int slot) : Controller(), Cont(nullptr), physicalSlot(slot) { } + void ReadFromSource(int32_t slot) override; + const char* GetControllerName() override; + const char* GetButtonName(int slot, int n64Button) override; + void WriteToSource(int32_t slot, ControllerCallback* controller) override; + bool Connected() const override { return Cont != nullptr; } + bool CanGyro() const override { return supportsGyro; } + bool CanRumble() const override { #if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(2,0,18) return SDL_GameControllerHasRumble(Cont); #endif return true; } - std::string GetGuid() { return guid; }; - - bool HasPadConf() const { return true; } - std::optional GetPadConfSection(); + bool Open(); + void ClearRawPress() override {} + int32_t ReadRawPress() override; protected: - std::string GetControllerType(); - void SetButtonMapping(const std::string& szButtonName, int32_t dwScancode); - std::string GetConfSection(); - std::string GetBindingConfSection(); - void CreateDefaultBinding(); - void CreateDefaultPadConf(); - static bool IsGuidInUse(const std::string& guid); + void CreateDefaultBinding(int32_t slot) override; private: SDL_GameController* Cont; - std::string guid; - std::map ThresholdMapping; - - void LoadAxisThresholds(); - void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick); - bool Open(); + int physicalSlot; + bool supportsGyro; + void NormalizeStickAxis(int16_t wAxisValueX, int16_t wAxisValueY, int16_t wAxisThreshold, bool isRightStick, float sensitivity); bool Close(); }; } diff --git a/libultraship/libultraship/UltraController.h b/libultraship/libultraship/UltraController.h index e08212b979..41ea7f082a 100644 --- a/libultraship/libultraship/UltraController.h +++ b/libultraship/libultraship/UltraController.h @@ -101,6 +101,10 @@ #define BTN_STICKRIGHT 0x20000 #define BTN_STICKDOWN 0x40000 #define BTN_STICKUP 0x80000 +#define BTN_VSTICKUP 0x100000 +#define BTN_VSTICKDOWN 0x200000 +#define BTN_VSTICKLEFT 0x400000 +#define BTN_VSTICKRIGHT 0x800000 typedef struct { /* 0x00 */ int32_t ram[15]; diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index 91878b8903..b8f8957c40 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -38,8 +38,7 @@ extern "C" { uint8_t __enableGameInput = 1; int32_t osContInit(OSMesgQueue* mq, uint8_t* controllerBits, OSContStatus* status) { - std::shared_ptr pConf = Ship::GlobalCtx2::GetInstance()->GetConfig(); - Ship::ConfigFile& Conf = *pConf.get(); + *controllerBits = 0; if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) { SPDLOG_ERROR("Failed to initialize SDL game controllers ({})", SDL_GetError()); @@ -54,43 +53,7 @@ extern "C" { SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError()); } - // TODO: This for loop is debug. Burn it with fire. - for (int i = 0; i < SDL_NumJoysticks(); i++) { - if (SDL_IsGameController(i)) { - // Get the GUID from SDL - char buf[33]; - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), buf, sizeof(buf)); - auto guid = std::string(buf); - auto name = std::string(SDL_GameControllerNameForIndex(i)); - - SPDLOG_INFO("Found Controller \"{}\" with ID \"{}\"", name, guid); - } - } - - for (int32_t i = 0; i < __osMaxControllers; i++) { - std::string ControllerType = Conf["CONTROLLERS"]["CONTROLLER " + std::to_string(i+1)]; - mINI::INIStringUtil::toLower(ControllerType); - - if (ControllerType == "auto") { - Ship::Window::Controllers[i].push_back(std::make_shared(i)); - Ship::Window::Controllers[i].push_back(std::make_shared(i)); - } else if (ControllerType == "keyboard") { - Ship::Window::Controllers[i].push_back(std::make_shared(i)); - } else if (ControllerType == "usb") { - Ship::Window::Controllers[i].push_back(std::make_shared(i)); - } else if (ControllerType == "unplugged") { - // Do nothing for unplugged controllers - } else { - SPDLOG_ERROR("Invalid Controller Type: {}", ControllerType); - } - } - - *controllerBits = 0; - for (size_t i = 0; i < __osMaxControllers; i++) { - if (Ship::Window::Controllers[i].size() > 0) { - *controllerBits |= 1 << i; - } - } + Ship::Window::ControllerApi->Init(controllerBits); return 0; } @@ -103,17 +66,14 @@ extern "C" { pad->button = 0; pad->stick_x = 0; pad->stick_y = 0; + pad->cam_x = 0; + pad->cam_y = 0; pad->err_no = 0; pad->gyro_x = 0; pad->gyro_y = 0; - if (__enableGameInput) - { - for (size_t i = 0; i < __osMaxControllers; i++) { - for (size_t j = 0; j < Ship::Window::Controllers[i].size(); j++) { - Ship::Window::Controllers[i][j]->Read(&pad[i]); - } - } + if (__enableGameInput) { + Ship::Window::ControllerApi->WriteToPad(pad); } ModInternal::ExecuteHooks(pad); @@ -129,15 +89,10 @@ extern "C" { if (hashStr != nullptr) { auto res = std::static_pointer_cast(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str())); + return (Vtx*)res->vertices.data(); + } - //if (res != nullptr) - return (Vtx*)res->vertices.data(); - //else - //return (Vtx*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadFile(hashStr)->buffer.get(); - } - else { - return nullptr; - } + return nullptr; } int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) { @@ -146,9 +101,9 @@ extern "C" { if (hashStr != nullptr) { auto res = std::static_pointer_cast(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str())); return (int32_t*)res->mtx.data(); - } else { - return nullptr; } + + return nullptr; } Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) { @@ -233,7 +188,7 @@ extern GfxWindowManagerAPI gfx_sdl; void SetWindowManager(GfxWindowManagerAPI** WmApi, GfxRenderingAPI** RenderingApi, const std::string& gfx_backend); namespace Ship { - std::map>> Window::Controllers; + int32_t Window::lastScancode; Window::Window(std::shared_ptr Context) : Context(Context), APlayer(nullptr) { @@ -248,26 +203,49 @@ namespace Ship { SPDLOG_INFO("destruct window"); } + void Window::CreateDefaults() { + const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + if (pConf->isNewInstance) { + pConf->setInt("Window.Width", 640); + pConf->setInt("Window.Height", 480); + pConf->setBool("Window.Options", false); + pConf->setString("Window.GfxBackend", ""); + + pConf->setBool("Window.Fullscreen.Enabled", false); + pConf->setInt("Window.Fullscreen.Width", 640); + pConf->setInt("Window.Fullscreen.Height", 480); + + pConf->setString("Game.SaveName", ""); + pConf->setString("Game.Main Archive", ""); + pConf->setString("Game.Patches Archive", ""); + + pConf->setInt("Shortcuts.Fullscreen", 0x044); + pConf->setInt("Shortcuts.Console", 0x029); + pConf->save(); + } + } + void Window::Init() { - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); + std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + + CreateDefaults(); SetAudioPlayer(); - bIsFullscreen = Ship::stob(Conf["WINDOW"]["FULLSCREEN"]); - if (bIsFullscreen) { - dwWidth = Ship::stoi(Conf["WINDOW"]["FULLSCREEN WIDTH"], 1920); - dwHeight = Ship::stoi(Conf["WINDOW"]["FULLSCREEN HEIGHT"], 1080); - } else { - dwWidth = Ship::stoi(Conf["WINDOW"]["WINDOW WIDTH"], 640); - dwHeight = Ship::stoi(Conf["WINDOW"]["WINDOW HEIGHT"], 480); - } - dwMenubar = Ship::stoi(Conf["WINDOW"]["menubar"], 0); - const std::string& gfx_backend = Conf["WINDOW"]["GFX BACKEND"]; + bIsFullscreen = pConf->getBool("Window.Fullscreen.Enabled", false); + + dwWidth = pConf->getInt("Window.Fullscreen.Width", bIsFullscreen ? 1920 : 640); + dwHeight = pConf->getInt("Window.Fullscreen.Height", bIsFullscreen ? 1080 : 480); + dwMenubar = pConf->getBool("Window.Options", false); + const std::string& gfx_backend = pConf->getString("Window.GfxBackend"); SetWindowManager(&WmApi, &RenderingApi, gfx_backend); gfx_init(WmApi, RenderingApi, GetContext()->GetName().c_str(), bIsFullscreen, dwWidth, dwHeight); - WmApi->set_fullscreen_changed_callback(Window::OnFullscreenChanged); - WmApi->set_keyboard_callbacks(Window::KeyDown, Window::KeyUp, Window::AllKeysUp); + WmApi->set_fullscreen_changed_callback(OnFullscreenChanged); + WmApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp); + + ModInternal::RegisterHook([]() { + ControllerApi->SaveControllerSettings(); + }); } void Window::StartFrame() { @@ -318,30 +296,26 @@ namespace Ship { void Window::MainLoop(void (*MainFunction)(void)) { WmApi->main_loop(MainFunction); } + bool Window::KeyUp(int32_t dwScancode) { - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); + std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_FULLSCREEN"])) { + if (dwScancode == pConf->getInt("Shortcuts.Fullscreen", 0x044)) { GlobalCtx2::GetInstance()->GetWindow()->ToggleFullscreen(); } - - // OTRTODO: Rig with Kirito's console? //if (dwScancode == Ship::stoi(Conf["KEYBOARD SHORTCUTS"]["KEY_CONSOLE"])) { // ToggleConsole(); //} + + lastScancode = -1; bool bIsProcessed = false; - for (size_t i = 0; i < __osMaxControllers; i++) { - for (size_t j = 0; j < Controllers[i].size(); j++) { - KeyboardController* pad = dynamic_cast(Ship::Window::Controllers[i][j].get()); - if (pad != nullptr) { - if (pad->ReleaseButton(dwScancode)) { - bIsProcessed = true; - } - } + const auto pad = dynamic_cast(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get()); + if (pad != nullptr) { + if (pad->ReleaseButton(dwScancode)) { + bIsProcessed = true; } } @@ -350,14 +324,11 @@ namespace Ship { bool Window::KeyDown(int32_t dwScancode) { bool bIsProcessed = false; - for (size_t i = 0; i < __osMaxControllers; i++) { - for (size_t j = 0; j < Controllers[i].size(); j++) { - KeyboardController* pad = dynamic_cast(Ship::Window::Controllers[i][j].get()); - if (pad != nullptr) { - if (pad->PressButton(dwScancode)) { - bIsProcessed = true; - } - } + + const auto pad = dynamic_cast(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get()); + if (pad != nullptr) { + if (pad->PressButton(dwScancode)) { + bIsProcessed = true; } } @@ -368,21 +339,17 @@ namespace Ship { void Window::AllKeysUp(void) { - for (size_t i = 0; i < __osMaxControllers; i++) { - for (size_t j = 0; j < Controllers[i].size(); j++) { - KeyboardController* pad = dynamic_cast(Ship::Window::Controllers[i][j].get()); - if (pad != nullptr) { - pad->ReleaseAllButtons(); - } - } + const auto pad = dynamic_cast(ControllerApi->physicalDevices[ControllerApi->physicalDevices.size() - 2].get()); + if (pad != nullptr) { + pad->ReleaseAllButtons(); } } void Window::OnFullscreenChanged(bool bIsFullscreen) { - std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); - ConfigFile& Conf = *pConf.get(); + std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + GlobalCtx2::GetInstance()->GetWindow()->bIsFullscreen = bIsFullscreen; - Conf["WINDOW"]["FULLSCREEN"] = std::to_string(bIsFullscreen); + pConf->setBool("Window.Fullscreen.Enabled", bIsFullscreen); GlobalCtx2::GetInstance()->GetWindow()->ShowCursor(!bIsFullscreen); } diff --git a/libultraship/libultraship/Window.h b/libultraship/libultraship/Window.h index a3087bf0cb..1fa43abeb2 100644 --- a/libultraship/libultraship/Window.h +++ b/libultraship/libultraship/Window.h @@ -5,17 +5,22 @@ #include "UltraController.h" #include "Controller.h" #include "GlobalCtx2.h" +#include "ControlDeck.h" +#include + +#include "Lib/Fast3D/gfx_window_manager_api.h" namespace Ship { class AudioPlayer; class Window { public: - static std::map>> Controllers; static int32_t lastScancode; + inline static ControlDeck* ControllerApi = new ControlDeck; Window(std::shared_ptr Context); ~Window(); + void CreateDefaults(); void MainLoop(void (*MainFunction)(void)); void Init(); void StartFrame(); @@ -31,9 +36,11 @@ namespace Ship { bool IsFullscreen() { return bIsFullscreen; } uint32_t GetCurrentWidth(); uint32_t GetCurrentHeight(); + ControlDeck* GetControlDeck() { return ControllerApi; }; uint32_t dwMenubar; std::shared_ptr GetContext() { return Context.lock(); } std::shared_ptr GetAudioPlayer() { return APlayer; } + const char* GetKeyName(int scancode) { return WmApi->get_key_name(scancode); } protected: private: @@ -46,11 +53,10 @@ namespace Ship { std::weak_ptr Context; std::shared_ptr APlayer; - GfxWindowManagerAPI* WmApi; GfxRenderingAPI* RenderingApi; + GfxWindowManagerAPI* WmApi; bool bIsFullscreen; uint32_t dwWidth; uint32_t dwHeight; }; } - diff --git a/libultraship/libultraship/libultraship.vcxproj b/libultraship/libultraship/libultraship.vcxproj index d379154828..964f51f512 100644 --- a/libultraship/libultraship/libultraship.vcxproj +++ b/libultraship/libultraship/libultraship.vcxproj @@ -38,38 +38,38 @@ StaticLibrary true - v142 + v143 Unicode StaticLibrary true - v142 + v143 Unicode StaticLibrary false - v142 + v143 true Unicode StaticLibrary true - v142 + v143 Unicode StaticLibrary true - v142 + v143 Unicode StaticLibrary false - v142 + v143 true Unicode @@ -256,13 +256,16 @@ + + + @@ -279,7 +282,6 @@ - @@ -342,13 +344,18 @@ + + + + + @@ -404,7 +411,6 @@ - diff --git a/libultraship/libultraship/libultraship.vcxproj.filters b/libultraship/libultraship/libultraship.vcxproj.filters index d1682c86fa..ec1c6f8701 100644 --- a/libultraship/libultraship/libultraship.vcxproj.filters +++ b/libultraship/libultraship/libultraship.vcxproj.filters @@ -31,9 +31,6 @@ {c0f07350-c627-444e-9f66-23e19407ad9a} - - {9cf4833f-e90c-4a9d-8747-d47cde657beb} - {2aa34c3b-6148-480f-a4fc-19c4e0f8c822} @@ -94,6 +91,15 @@ {db6e02cc-fc4c-4138-8219-1d281ad93ec2} + + {2be7c90f-ba21-455d-8a11-6f99452be15c} + + + {7e415dd2-403b-4d4d-b4f2-3e311f91db19} + + + {010dc29b-d1f6-4793-a4e7-4156aa4fcdd6} + @@ -165,9 +171,6 @@ Source Files\Controller\Attachment - - Source Files\Config - Source Files\Resources\Files @@ -354,6 +357,15 @@ Source Files\Resources\Factories + + Source Files\Controller\InputEditor + + + Source Files\Controller + + + Source Files\Lib\Mercury + @@ -386,9 +398,6 @@ Source Files\Controller\Attachment - - Source Files\Config - Source Files\Resources @@ -659,5 +668,20 @@ Source Files\Lib\dr_libs + + Source Files\Controller\InputEditor + + + Source Files\Controller + + + Source Files\Controller + + + Source Files\Lib\nlohmann + + + Source Files\Lib\Mercury + \ No newline at end of file diff --git a/soh/include/functions.h b/soh/include/functions.h index 73f366bb57..72fd6e98cb 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -559,6 +559,7 @@ void ActorOverlayTable_Cleanup(void); u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*); void func_80038A28(CollisionPoly* poly, f32 tx, f32 ty, f32 tz, MtxF* dest); f32 CollisionPoly_GetPointDistanceFromPlane(CollisionPoly* poly, Vec3f* point); +CollisionHeader* BgCheck_GetCollisionHeader(CollisionContext* colCtx, s32 bgId); void CollisionPoly_GetVerticesByBgId(CollisionPoly* poly, s32 bgId, CollisionContext* colCtx, Vec3f* dest); s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight, CollisionPoly** outPoly); diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj index 5f7ea818f1..c305b03b1c 100644 --- a/soh/soh.vcxproj +++ b/soh/soh.vcxproj @@ -143,7 +143,7 @@ TurnOffAllWarnings false - INCLUDE_GAME_PRINTF;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;ENABLE_DX11;%(PreprocessorDefinitions)GLEW_STATIC + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;ENABLE_DX11;%(PreprocessorDefinitions) true stdcpp20 MultiThreadedDebug @@ -1038,7 +1038,6 @@ - diff --git a/soh/soh.vcxproj.filters b/soh/soh.vcxproj.filters index bbe6578f26..457e23ed16 100644 --- a/soh/soh.vcxproj.filters +++ b/soh/soh.vcxproj.filters @@ -82,12 +82,6 @@ {04fc1c52-49ff-48e2-ae23-2c00867374f8} - - {dbcf07c4-80b1-4c88-ac54-2bbdd8f53ee4} - - - {9c880c8e-492b-48f6-b230-1fd269ea74b1} - @@ -3947,9 +3941,6 @@ Source Files\soh - - Source Files\soh\Lib\nlohmann - Source Files\soh diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index 0b789b4451..4f20155d4a 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -20,7 +20,7 @@ extern BootCommandFunc BootCommands_Command_LoadFileSelect(char** argv, s32 argc static BootCommand sCommands[] = { { "--skiplogo", BootCommands_Command_SkipLogo }, { "--loadfileselect", BootCommands_Command_LoadFileSelect } }; -void BootCommands_Init() +void BootCommands_Init() { CVar_RegisterS32("gDisableLOD", 0); CVar_RegisterS32("gDebugEnabled", 0); @@ -30,7 +30,6 @@ void BootCommands_Init() CVar_RegisterS32("gHoverFishing", 0); CVar_RegisterS32("gN64WeirdFrames", 0); CVar_RegisterS32("gBombchusOOB", 0); - CVar_RegisterS32("gRumbleEnabled", 0); CVar_RegisterS32("gUniformLR", 0); CVar_RegisterS32("gTwoHandedIdle", 0); CVar_RegisterS32("gDekuNutUpgradeFix", 0); diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index b2981d3615..4bb4efd19e 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -16,6 +16,7 @@ #include #include +#include "Window.h" #include "Lib/ImGui/imgui_internal.h" #undef PATH_HACK #undef Path @@ -315,7 +316,7 @@ static bool SaveStateHandler(const std::vector& args) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE }); - switch (rtn) { + switch (rtn) { case SaveStateReturn::SUCCESS: INFO("[SOH] Saved state to slot %u", slot); return CMD_SUCCESS; @@ -329,7 +330,7 @@ static bool SaveStateHandler(const std::vector& args) { static bool LoadStateHandler(const std::vector& args) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD }); - + switch (rtn) { case SaveStateReturn::SUCCESS: INFO("[SOH] Loaded state from slot %u", slot); @@ -342,7 +343,7 @@ static bool LoadStateHandler(const std::vector& args) { return CMD_FAILED; case SaveStateReturn::FAIL_WRONG_GAMESTATE: ERROR("[SOH] Can not load a state outside of \"GamePlay\""); - return CMD_FAILED; + return CMD_FAILED; } } @@ -360,7 +361,7 @@ static bool StateSlotSelectHandler(const std::vector& args) { ERROR("[SOH] SaveState slot value must be a number."); return CMD_FAILED; } - + if (slot < 0) { ERROR("[SOH] Invalid slot passed. Slot must be between 0 and 2"); return CMD_FAILED; @@ -498,8 +499,7 @@ template bool is_number(const std::string& s) { return ((std::istringstream(s) >> n >> std::ws).eof()); } -void DebugConsole_LoadCVars() -{ +void DebugConsole_LoadLegacyCVars() { auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); if (File::Exists(cvarsConfig)) { const auto lines = File::ReadAllLines(cvarsConfig); @@ -520,23 +520,58 @@ void DebugConsole_LoadCVars() CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1])); } } + + fs::remove("cvars.cfg"); } } +void DebugConsole_LoadCVars() { + + std::shared_ptr pConf = Ship::GlobalCtx2::GetInstance()->GetConfig(); + pConf->reload(); + + for (const auto& item : pConf->rjson["CVars"].items()) { + auto value = item.value(); + switch (value.type()) { + case nlohmann::detail::value_t::array: + break; + case nlohmann::detail::value_t::string: + CVar_SetString(item.key().c_str(), value.get().c_str()); + break; + case nlohmann::detail::value_t::boolean: + CVar_SetS32(item.key().c_str(), value.get()); + break; + case nlohmann::detail::value_t::number_unsigned: + case nlohmann::detail::value_t::number_integer: + CVar_SetS32(item.key().c_str(), value.get()); + break; + case nlohmann::detail::value_t::number_float: + CVar_SetFloat(item.key().c_str(), value.get()); + break; + default: ; + } + if (item.key() == "gOpenMenuBar") { + int bp = 0; + } + } + + DebugConsole_LoadLegacyCVars(); +} + void DebugConsole_SaveCVars() { - std::string output; + std::shared_ptr pConf = Ship::GlobalCtx2::GetInstance()->GetConfig(); for (const auto &cvar : cvars) { - if (cvar.second->type == CVAR_TYPE_STRING) - output += StringHelper::Sprintf("%s = \"%s\"\n", cvar.first.c_str(), cvar.second->value.valueStr); + const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str()); + + if (cvar.second->type == CVAR_TYPE_STRING && cvar.second->value.valueStr != nullptr) + pConf->setString(key, std::string(cvar.second->value.valueStr)); else if (cvar.second->type == CVAR_TYPE_S32) - output += StringHelper::Sprintf("%s = %i\n", cvar.first.c_str(), cvar.second->value.valueS32); + pConf->setInt(key, cvar.second->value.valueS32); else if (cvar.second->type == CVAR_TYPE_FLOAT) - output += StringHelper::Sprintf("%s = %f\n", cvar.first.c_str(), cvar.second->value.valueFloat); + pConf->setFloat(key, cvar.second->value.valueFloat); } - - auto cvarsConfig = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("cvars.cfg"); - File::WriteAllText(cvarsConfig, output); + pConf->save(); } diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 3ed486a44d..24662f1d7b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -11,7 +11,7 @@ #include "utils.hpp" #include "shops.hpp" #include "hints.hpp" -#include "soh/Lib/nlohmann/json.hpp" +#include "Lib/nlohmann/json.hpp" #include #include diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 43e278ab5f..09704e8671 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1,5 +1,5 @@ #include "randomizer.h" -#include "soh/Lib/nlohmann/json.hpp" +#include "Lib/nlohmann/json.hpp" #include #include #include diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 5fe2e0ae4c..7f4d16031c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -1,5 +1,4 @@ -#ifndef RANDOMIZER_H -#define RANDOMIZER_H +#pragma once #include #include @@ -54,5 +53,3 @@ void Rando_Init(void); } #endif - -#endif diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 3a862d58ab..514edc563e 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1153,34 +1153,27 @@ extern "C" s32* ResourceMgr_LoadCSByName(const char* path) return (s32*)res->commands.data(); } -std::filesystem::path GetSaveFile(Ship::ConfigFile& Conf) { - std::string fileName = Conf.get("SAVE").get("Save Filename"); - - if (fileName.empty()) { - Conf["SAVE"]["Save Filename"] = Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav"); - Conf.Save(); - } +std::filesystem::path GetSaveFile(std::shared_ptr Conf) { + const std::string fileName = Conf->getString("Game.SaveName", Ship::GlobalCtx2::GetPathRelativeToAppDirectory("oot_save.sav")); std::filesystem::path saveFile = std::filesystem::absolute(fileName); - if (!std::filesystem::exists(saveFile.parent_path())) { - std::filesystem::create_directories(saveFile.parent_path()); + if (!exists(saveFile.parent_path())) { + create_directories(saveFile.parent_path()); } return saveFile; } std::filesystem::path GetSaveFile() { - std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); - Ship::ConfigFile& Conf = *pConf.get(); + const std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); - return GetSaveFile(Conf); + return GetSaveFile(pConf); } -void OTRGlobals::CheckSaveFile(size_t sramSize) { - std::shared_ptr pConf = context->GetConfig(); - Ship::ConfigFile& Conf = *pConf.get(); +void OTRGlobals::CheckSaveFile(size_t sramSize) const { + const std::shared_ptr pConf = Instance->context->GetConfig(); - std::filesystem::path savePath = GetSaveFile(Conf); + std::filesystem::path savePath = GetSaveFile(pConf); std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary); if (saveFile.fail()) { saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app); @@ -1199,25 +1192,6 @@ extern "C" void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size) { OTRGlobals::Instance->context->WriteSaveFile(GetSaveFile(), addr, dramAddr, size); } -/* Remember to free after use of value */ -extern "C" char* Config_getValue(char* category, char* key) { - std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); - Ship::ConfigFile& Conf = *pConf.get(); - - std::string data = Conf.get(std::string(category)).get(std::string(key)); - char* retval = (char*)malloc(data.length()+1); - strcpy(retval, data.c_str()); - - return retval; -} - -extern "C" bool Config_setValue(char* category, char* key, char* value) { - std::shared_ptr pConf = OTRGlobals::Instance->context->GetConfig(); - Ship::ConfigFile& Conf = *pConf.get(); - Conf[std::string(category)][std::string(key)] = std::string(value); - return Conf.Save(); -} - std::wstring StringToU16(const std::string& s) { std::vector result; size_t i = 0; @@ -1319,11 +1293,10 @@ extern "C" uint32_t OTRGetCurrentHeight() { } extern "C" void OTRControllerCallback(ControllerCallback* controller) { - auto controllers = OTRGlobals::Instance->context->GetWindow()->Controllers; - for (size_t i = 0; i < controllers.size(); i++) { - for (int j = 0; j < controllers[i].size(); j++) { - OTRGlobals::Instance->context->GetWindow()->Controllers[i][j]->WriteToSource(controller); - } + const auto controllers = Ship::Window::ControllerApi->virtualDevices; + + for (int i = 0; i < controllers.size(); ++i) { + Ship::Window::ControllerApi->physicalDevices[controllers[i]]->WriteToSource(i, controller); } } @@ -1377,11 +1350,11 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) { } extern "C" int Controller_ShouldRumble(size_t i) { - for (const auto& controller : Ship::Window::Controllers.at(i)) - { - float rumble_strength = CVar_GetFloat(StringHelper::Sprintf("gCont%i_RumbleStrength", i).c_str(), 1.0f); - if (controller->CanRumble() && rumble_strength > 0.001f) { + const auto controllers = Ship::Window::ControllerApi->virtualDevices; + + for (const auto virtual_entry : controllers) { + if (Ship::Window::ControllerApi->physicalDevices[virtual_entry]->CanRumble()) { return 1; } } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 7c56e54c11..7c42da3709 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -23,7 +23,7 @@ public: ~OTRGlobals(); private: - void CheckSaveFile(size_t sramSize); + void CheckSaveFile(size_t sramSize) const; }; #endif @@ -61,8 +61,6 @@ SoundFontSample* ResourceMgr_LoadAudioSample(const char* path); CollisionHeader* ResourceMgr_LoadColByName(const char* path); void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size); void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); -char* Config_getValue(char* category, char* key); -bool Config_setValue(char* category, char* key, char* value); uint64_t GetPerfCounter(); struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path); diff --git a/soh/src/code/padmgr.c b/soh/src/code/padmgr.c index d89207e6fe..9bd9d53e7c 100644 --- a/soh/src/code/padmgr.c +++ b/soh/src/code/padmgr.c @@ -269,7 +269,7 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) { input->press.stick_y += (s8)(input->cur.stick_y - input->prev.stick_y); } - controllerCallback.rumble = CVar_GetS32("gRumbleEnabled", 0) && (padMgr->rumbleEnable[0] > 0); + controllerCallback.rumble = (padMgr->rumbleEnable[0] > 0); if (HealthMeter_IsCritical()) { controllerCallback.ledColor = 0; diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 704062b1b3..287edeb606 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -1481,7 +1481,7 @@ s32 Camera_Free(Camera* camera) { camBgChk.pos = camera->eye; - float maxRadius = 160.0f; + float maxRadius = 150.0f; if (Camera_BGCheckInfo(camera, &at, &camBgChk)) { VecSph collSphere; OLib_Vec3fDiffToVecSphGeo(&collSphere, &at, &camBgChk.pos); diff --git a/soh/src/code/z_fbdemo_wipe1.c b/soh/src/code/z_fbdemo_wipe1.c index 1dfb0a501d..d4502f8e72 100644 --- a/soh/src/code/z_fbdemo_wipe1.c +++ b/soh/src/code/z_fbdemo_wipe1.c @@ -89,6 +89,7 @@ void TransitionWipe_Draw(void* thisx, Gfx** gfxP) { TransitionWipe* this = (TransitionWipe*)thisx; s32 pad[4]; Gfx* tex; + Gfx* wipeDl = sWipeDList; modelView = this->modelView[this->frame]; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index d07222768a..576f550c75 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -419,7 +419,7 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { (!fileSelectSpoilerFileLoaded && SpoilerFileExists(CVar_GetString("gSpoilerLog", "")))) { if (CVar_GetS32("gNewFileDropped", 0) != 0) { - CVar_SetString("gSpoilerLog", CVar_GetString("gDroppedFile", "")); + CVar_SetString("gSpoilerLog", CVar_GetString("gDroppedFile", "None")); } bool silent = true; if ((CVar_GetS32("gNewFileDropped", 0) != 0) || @@ -1894,7 +1894,7 @@ void FileChoose_Main(GameState* thisx) { }; FileChooseContext* this = (FileChooseContext*)thisx; Input* input = &this->state.input[0]; - + if (CVar_GetS32("gTimeFlowFileSelect", 0) != 0) { gSaveContext.skyboxTime += 0x10; } From 31511af130fefb9b63357c0b6204ec2be0aa727c Mon Sep 17 00:00:00 2001 From: Kenix3 Date: Wed, 13 Jul 2022 23:41:22 -0400 Subject: [PATCH 16/38] Enough! My ship sails in the morning. --- libultraship/libultraship/Resource.h | 3 +-- soh/src/boot/build.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libultraship/libultraship/Resource.h b/libultraship/libultraship/Resource.h index 4e4d73b29d..6bdae983eb 100644 --- a/libultraship/libultraship/Resource.h +++ b/libultraship/libultraship/Resource.h @@ -63,8 +63,7 @@ namespace Ship Deckard = 0, Roy = 1, Rachael = 2, - Leon = 3, - Zhora = 4, + Zhora = 3, // ... }; diff --git a/soh/src/boot/build.c b/soh/src/boot/build.c index 94d142020e..84a73076d3 100644 --- a/soh/src/boot/build.c +++ b/soh/src/boot/build.c @@ -1,4 +1,4 @@ -const char gBuildVersion[] = "ROY ALFA (2.0.0)"; +const char gBuildVersion[] = "RACHAEL ALFA (3.0.0)"; const char gBuildTeam[] = "github.com/harbourmasters"; const char gBuildDate[] = __DATE__ " " __TIME__; const char gBuildMakeOption[] = ""; From b2b7cf23747bc78d9e791fdda1946f0879e5e60c Mon Sep 17 00:00:00 2001 From: KiritoDev <36680385+KiritoDv@users.noreply.github.com> Date: Wed, 13 Jul 2022 23:42:15 -0500 Subject: [PATCH 17/38] Fixed menubar items position (#763) * Fixed menubar items position * Reverted tooltip tab position --- libultraship/libultraship/ImGuiImpl.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index dd172118d1..153a193e8d 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -736,6 +736,10 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::Separator(); + + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Audio")) { EnhancementSliderFloat("Master Volume: %d %%", "##Master_Vol", "gGameMasterVolume", 0.0f, 1.0f, "", 1.0f, true); @@ -747,6 +751,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Controller")) { EnhancementCheckbox("Use Controller Navigation", "gControlNav"); @@ -775,6 +781,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Graphics")) { EnhancementSliderFloat("Internal Resolution: %d %%", "##IMul", "gInternalResolution", 0.5f, 2.0f, "", 1.0f, true); @@ -823,6 +831,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Languages")) { EnhancementRadioButton("English", "gLanguages", 0); EnhancementRadioButton("German", "gLanguages", 1); @@ -830,6 +840,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Enhancements")) { if (ImGui::BeginMenu("Gameplay")) @@ -1154,6 +1166,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Cheats")) { if (ImGui::BeginMenu("Infinite...")) { @@ -1191,6 +1205,8 @@ namespace SohImGui { ImGui::EndMenu(); } + ImGui::SetCursorPosY(0.0f); + if (ImGui::BeginMenu("Developer Tools")) { EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled"); @@ -1211,6 +1227,7 @@ namespace SohImGui { } for (const auto& category : windowCategories) { + ImGui::SetCursorPosY(0.0f); if (ImGui::BeginMenu(category.first.c_str())) { for (const std::string& name : category.second) { std::string varName(name); From 06338d864f15f6c923f0ed9ee2b8259a8b8b5a2d Mon Sep 17 00:00:00 2001 From: agamache Date: Thu, 14 Jul 2022 00:56:29 -0400 Subject: [PATCH 18/38] Fixes macOS randomizer functionality with App Directory (#761) * Fixes macOS randomizer functionality with App Directory * Fix windows build * Update soh/soh/Enhancements/randomizer/3drando/rando_main.cpp * Update soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp * Revert band-aid fix Co-authored-by: Kenix3 --- soh/soh.vcxproj | 1 + .../Enhancements/randomizer/3drando/rando_main.cpp | 5 ++++- .../Enhancements/randomizer/3drando/spoiler_log.cpp | 11 ++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj index c305b03b1c..5a293d3f02 100644 --- a/soh/soh.vcxproj +++ b/soh/soh.vcxproj @@ -941,6 +941,7 @@ + diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index a936b65671..e14cf502dd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -7,6 +7,9 @@ // #include #include #include +#define NOGDI +#define WIN32_LEAN_AND_MEAN +#include #define TICKS_PER_SEC 268123480.0 @@ -18,7 +21,7 @@ void RandoMain::GenerateRando(std::unordered_map cvarS // std::string settingsFileName = "./randomizer/latest_settings.json"; // CVar_SetString("gLoadedPreset", settingsFileName.c_str()); - std::string fileName = GenerateRandomizer(cvarSettings); + std::string fileName = Ship::GlobalCtx2::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings).c_str()); CVar_SetString("gSpoilerLog", fileName.c_str()); Game::SaveSettings(); diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 24662f1d7b..5deea40882 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -26,6 +26,10 @@ #include #include +#define NOGDI +#define WIN32_LEAN_AND_MEAN +#include "GlobalCtx2.h" + using json = nlohmann::json; json jsonData; @@ -721,12 +725,13 @@ const char* SpoilerLog_Write(int language) { //WriteShuffledEntrances(spoilerLog); WriteAllLocations(language); - if (!std::filesystem::exists("./Randomizer")) { - std::filesystem::create_directory("./Randomizer"); + if (!std::filesystem::exists(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer"))) { + std::filesystem::create_directory(Ship::GlobalCtx2::GetPathRelativeToAppDirectory("Randomizer")); } std::string jsonString = jsonData.dump(4); - std::ofstream jsonFile("./Randomizer/" + Settings::seed + ".json"); + std::ofstream jsonFile(Ship::GlobalCtx2::GetPathRelativeToAppDirectory( + (std::string("Randomizer/") + std::string(Settings::seed) + std::string(".json")).c_str())); jsonFile << std::setw(4) << jsonString << std::endl; jsonFile.close(); From 1ed58c4a99cbeecebdb213e3d30223495038a1ef Mon Sep 17 00:00:00 2001 From: David Chavez Date: Thu, 14 Jul 2022 07:19:40 +0200 Subject: [PATCH 19/38] Fix migration cvar deletion path (#765) --- soh/soh/Enhancements/debugconsole.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 4bb4efd19e..eb2b02b115 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -521,7 +521,7 @@ void DebugConsole_LoadLegacyCVars() { } } - fs::remove("cvars.cfg"); + fs::remove(cvarsConfig); } } From 8417db65c73cb3d117f2a0f9040105022a45480c Mon Sep 17 00:00:00 2001 From: Sirius902 <10891979+Sirius902@users.noreply.github.com> Date: Thu, 14 Jul 2022 06:05:36 -0700 Subject: [PATCH 20/38] Various controller fixes (#771) * Fix controller * Also fix rumble strength being a bool * Remove ControllerHud.cpp * Downgrade platform toolset back to previous version * Fix gyro * Fix bug that makes binding axes difficult and clear buttons before reading * Exaggerate gyro display and adjust stick binding threshold * Initialize drift thresholds --- libultraship/libultraship/ControlDeck.cpp | 15 +- libultraship/libultraship/Controller.cpp | 41 ++- libultraship/libultraship/Controller.h | 3 +- libultraship/libultraship/ControllerHud.cpp | 277 ------------------ libultraship/libultraship/InputEditor.cpp | 24 +- libultraship/libultraship/SDLController.cpp | 29 +- .../libultraship/libultraship.vcxproj | 12 +- 7 files changed, 56 insertions(+), 345 deletions(-) delete mode 100644 libultraship/libultraship/ControllerHud.cpp diff --git a/libultraship/libultraship/ControlDeck.cpp b/libultraship/libultraship/ControlDeck.cpp index 2fbf3d2254..ff7a1d243e 100644 --- a/libultraship/libultraship/ControlDeck.cpp +++ b/libultraship/libultraship/ControlDeck.cpp @@ -89,15 +89,10 @@ void Ship::ControlDeck::LoadControllerSettings() { profile.Mappings.clear(); profile.Thresholds.clear(); - profile.GyroThresholds.clear(); profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", "")); - profile.RumbleStrength = Config->getBool(NESTED("Rumble.Strength", "")); + profile.RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", "")); profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", "")); - for (auto const& val : rawProfile["Gyro"]["Thresholds"].items()) { - profile.GyroThresholds[std::stoi(val.key())] = val.value(); - } - for (auto const& val : rawProfile["Thresholds"].items()) { profile.Thresholds[static_cast(std::stoi(val.key()))] = val.value(); } @@ -135,12 +130,8 @@ void Ship::ControlDeck::SaveControllerSettings() { Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1); } - for (auto const& [key, val] : profile.GyroThresholds) { - Config->setInt(NESTED("Gyro.Thresholds.%d", key), val); - } - for (auto const& [key, val] : profile.Thresholds) { - Config->setInt(NESTED("Thresholds.%d", key), val); + Config->setFloat(NESTED("Thresholds.%d", key), val); } for (auto const& [key, val] : profile.Mappings) { @@ -152,4 +143,4 @@ void Ship::ControlDeck::SaveControllerSettings() { } Config->save(); -} \ No newline at end of file +} diff --git a/libultraship/libultraship/Controller.cpp b/libultraship/libultraship/Controller.cpp index 8c0994a854..6fc99c5c2c 100644 --- a/libultraship/libultraship/Controller.cpp +++ b/libultraship/libultraship/Controller.cpp @@ -26,52 +26,45 @@ namespace Ship { pad->button |= dwPressedButtons[slot] & 0xFFFF; // Stick Inputs - if (pad->stick_x == 0) { + if (wStickX == 0) { if (dwPressedButtons[slot] & BTN_STICKLEFT) { pad->stick_x = -128; - } - else if (dwPressedButtons[slot] & BTN_STICKRIGHT) { + } else if (dwPressedButtons[slot] & BTN_STICKRIGHT) { pad->stick_x = 127; } - else { - pad->stick_x = wStickX; - } + } else { + pad->stick_x = wStickX; } - if (pad->stick_y == 0) { + if (wStickY == 0) { if (dwPressedButtons[slot] & BTN_STICKDOWN) { pad->stick_y = -128; - } - else if (dwPressedButtons[slot] & BTN_STICKUP) { + } else if (dwPressedButtons[slot] & BTN_STICKUP) { pad->stick_y = 127; } - else { - pad->stick_y = wStickY; - } + } else { + pad->stick_y = wStickY; } // Stick Inputs - if (pad->cam_x == 0) { + if (wCamX == 0) { if (dwPressedButtons[slot] & BTN_VSTICKLEFT) { pad->cam_x = -128 * 10.0f; - } - else if (dwPressedButtons[slot] & BTN_VSTICKRIGHT) { + } else if (dwPressedButtons[slot] & BTN_VSTICKRIGHT) { pad->cam_x = 127 * 10.0f; } - else { - pad->cam_x = wCamX; - } + } else { + pad->cam_x = wCamX; } - if (pad->cam_y == 0) { + + if (wCamY == 0) { if (dwPressedButtons[slot] & BTN_VSTICKDOWN) { pad->cam_y = -128 * 10.0f; - } - else if (dwPressedButtons[slot] & BTN_VSTICKUP) { + } else if (dwPressedButtons[slot] & BTN_VSTICKUP) { pad->cam_y = 127 * 10.0f; } - else { - pad->cam_y = wCamY; - } + } else { + pad->cam_y = wCamY; } // Gyro diff --git a/libultraship/libultraship/Controller.h b/libultraship/libultraship/Controller.h index ffbeeaabff..70c339d25a 100644 --- a/libultraship/libultraship/Controller.h +++ b/libultraship/libultraship/Controller.h @@ -29,8 +29,7 @@ namespace Ship { bool UseRumble = false; bool UseGyro = false; float RumbleStrength = 1.0f; - std::unordered_map Thresholds; - std::unordered_map GyroThresholds; + std::unordered_map Thresholds; std::map Mappings; }; diff --git a/libultraship/libultraship/ControllerHud.cpp b/libultraship/libultraship/ControllerHud.cpp deleted file mode 100644 index e40990b0db..0000000000 --- a/libultraship/libultraship/ControllerHud.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include "InputEditor.h" -#include "Controller.h" -#include "Window.h" -#include "Lib/ImGui/imgui.h" -#include "ImGuiImpl.h" -#include "Utils/StringHelper.h" -#include "Lib/ImGui/imgui_internal.h" - -namespace Ship { - - extern "C" uint8_t __enableGameInput; - #define SEPARATION() ImGui::Dummy(ImVec2(0, 5)) - - void InputEditor::Init() { - BtnReading = -1; - } - - std::shared_ptr GetControllerPerSlot(int slot) { - const std::vector vDevices = Window::ControllerApi->virtualDevices; - return Window::ControllerApi->physicalDevices[vDevices[slot]]; - } - - void InputEditor::DrawButton(const char* label, int n64Btn) { - const std::shared_ptr backend = GetControllerPerSlot(CurrentPort); - - float size = 40; - bool readingMode = BtnReading == n64Btn; - bool disabled = BtnReading != -1 && !readingMode || !backend->Connected(); - ImVec2 len = ImGui::CalcTextSize(label); - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SetCursorPosY(pos.y + len.y / 4); - ImGui::SetCursorPosX(pos.x + abs(len.x - size)); - ImGui::Text("%s", label); - ImGui::SameLine(); - ImGui::SetCursorPosY(pos.y); - - if(disabled) { - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); - } - - if(readingMode) { - const int32_t btn = backend->ReadRawPress(); - - if(btn != -1) { - backend->SetButtonMapping(CurrentPort, n64Btn, btn); - BtnReading = -1; - } - } - - const char* BtnName = backend->GetButtonName(CurrentPort, n64Btn); - - if (ImGui::Button(StringHelper::Sprintf("%s##HBTNID_%d", readingMode ? "Press a Key..." : BtnName, n64Btn).c_str())) { - BtnReading = n64Btn; - backend->ClearRawPress(); - } - - if(disabled) { - ImGui::PopItemFlag(); - ImGui::PopStyleVar(); - } - } - - void InputEditor::DrawVirtualStick(const char* label, ImVec2 stick) { - ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5, ImGui::GetCursorPos().y)); - ImGui::BeginChild(label, ImVec2(68, 75), false); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - const ImVec2 p = ImGui::GetCursorScreenPos(); - - float sz = 45.0f; - float rad = sz * 0.5f; - ImVec2 pos = ImVec2(p.x + sz * 0.5f + 12, p.y + sz * 0.5f + 11); - - float stickX = (stick.x / 83.0f) * (rad * 0.5f); - float stickY = -(stick.y / 83.0f) * (rad * 0.5f); - - ImVec4 rect = ImVec4(p.x + 2, p.y + 2, 65, 65); - draw_list->AddRect(ImVec2(rect.x, rect.y), ImVec2(rect.x + rect.z, rect.y + rect.w), ImColor(100, 100, 100, 255), 0.0f, 0, 1.5f); - draw_list->AddCircleFilled(pos, rad, ImColor(130, 130, 130, 255), 8); - draw_list->AddCircleFilled(ImVec2(pos.x + stickX, pos.y + stickY), 5, ImColor(15, 15, 15, 255), 7); - ImGui::EndChild(); - } - - void InputEditor::DrawControllerSchema() { - - const std::vector vDevices = Window::ControllerApi->virtualDevices; - const std::vector> devices = Window::ControllerApi->physicalDevices; - - std::shared_ptr Backend = devices[vDevices[CurrentPort]]; - DeviceProfile& profile =Backend->profiles[CurrentPort]; - float sensitivity = profile.Thresholds[SENSITIVITY]; - bool IsKeyboard = Backend->GetGuid() == "Keyboard" || !Backend->Connected(); - const char* ControllerName = Backend->GetControllerName(); - - if (ControllerName != nullptr && ImGui::BeginCombo("##ControllerEntries", ControllerName)) { - for (uint8_t i = 0; i < devices.size(); i++) { - if (ImGui::Selectable(devices[i]->GetControllerName(), i == vDevices[CurrentPort])) { - Window::ControllerApi->SetPhysicalDevice(CurrentPort, i); - } - } - ImGui::EndCombo(); - } - - ImGui::SameLine(); - - if(ImGui::Button("Refresh")) { - Window::ControllerApi->ScanPhysicalDevices(); - } - - SohImGui::BeginGroupPanel("Buttons", ImVec2(150, 20)); - DrawButton("A", BTN_A); - DrawButton("B", BTN_B); - DrawButton("L", BTN_L); - DrawButton("R", BTN_R); - DrawButton("Z", BTN_Z); - DrawButton("START", BTN_START); - SEPARATION(); - SohImGui::EndGroupPanel(IsKeyboard ? 7.0f : 48.0f); - ImGui::SameLine(); - SohImGui::BeginGroupPanel("Digital Pad", ImVec2(150, 20)); - DrawButton("Up", BTN_DUP); - DrawButton("Down", BTN_DDOWN); - DrawButton("Left", BTN_DLEFT); - DrawButton("Right", BTN_DRIGHT); - SEPARATION(); - SohImGui::EndGroupPanel(IsKeyboard ? 53.0f : 94.0f); - ImGui::SameLine(); - SohImGui::BeginGroupPanel("Analog Stick", ImVec2(150, 20)); - DrawButton("Up", BTN_STICKUP); - DrawButton("Down", BTN_STICKDOWN); - DrawButton("Left", BTN_STICKLEFT); - DrawButton("Right", BTN_STICKRIGHT); - - if (!IsKeyboard) { - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); - DrawVirtualStick("##MainVirtualStick", ImVec2(Backend->wStickX, Backend->wStickY)); - ImGui::SameLine(); - - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - - ImGui::BeginChild("##MSInput", ImVec2(90, 50), false); - ImGui::Text("Deadzone"); - ImGui::PushItemWidth(80); - ImGui::InputInt("##MDZone", &profile.Thresholds[LEFT_STICK]); - ImGui::PopItemWidth(); - ImGui::EndChild(); - } else { - ImGui::Dummy(ImVec2(0, 6)); - } - SohImGui::EndGroupPanel(IsKeyboard ? 52.0f : 24.0f); - ImGui::SameLine(); - - if (!IsKeyboard) { - ImGui::SameLine(); - SohImGui::BeginGroupPanel("Camera Stick", ImVec2(150, 20)); - DrawButton("Up", BTN_VSTICKUP); - DrawButton("Down", BTN_VSTICKDOWN); - DrawButton("Left", BTN_VSTICKLEFT); - DrawButton("Right", BTN_VSTICKRIGHT); - - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8); - DrawVirtualStick("##CameraVirtualStick", ImVec2(Backend->wCamX / sensitivity, Backend->wCamY / sensitivity)); - - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - ImGui::BeginChild("##CSInput", ImVec2(90, 85), false); - ImGui::Text("Deadzone"); - ImGui::PushItemWidth(80); - ImGui::InputInt("##MDZone", &profile.Thresholds[RIGHT_STICK]); - ImGui::PopItemWidth(); - ImGui::Text("Sensitivity"); - ImGui::PushItemWidth(80); - ImGui::InputInt("##MSensitivity", &profile.Thresholds[SENSITIVITY]); - ImGui::PopItemWidth(); - ImGui::EndChild(); - SohImGui::EndGroupPanel(14.0f); - } - - if(Backend->CanGyro()) { - ImGui::SameLine(); - - SohImGui::BeginGroupPanel("Gyro Options", ImVec2(175, 20)); - float cursorX = ImGui::GetCursorPosX() + 5; - ImGui::SetCursorPosX(cursorX); - ImGui::Checkbox("Enable Gyro", &profile.UseGyro); - ImGui::SetCursorPosX(cursorX); - ImGui::Text("Gyro Sensitivity: %d%%", profile.Thresholds[GYRO_SENSITIVITY]); - ImGui::PushItemWidth(135.0f); - ImGui::SetCursorPosX(cursorX); - ImGui::SliderInt("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0, 100, ""); - ImGui::PopItemWidth(); - ImGui::Dummy(ImVec2(0, 1)); - ImGui::SetCursorPosX(cursorX); - if (ImGui::Button("Recalibrate Gyro##RGyro")) { - profile.Thresholds[DRIFT_X] = 0; - profile.Thresholds[DRIFT_Y] = 0; - } - ImGui::SetCursorPosX(cursorX); - DrawVirtualStick("##GyroPreview", ImVec2(Backend->wGyroX, Backend->wGyroY)); - - ImGui::SameLine(); - ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); - ImGui::BeginChild("##GyInput", ImVec2(90, 85), false); - ImGui::Text("Drift X"); - ImGui::PushItemWidth(80); - ImGui::InputInt("##GDriftX", &profile.Thresholds[DRIFT_X]); - ImGui::PopItemWidth(); - ImGui::Text("Drift Y"); - ImGui::PushItemWidth(80); - ImGui::InputInt("##GDriftY", &profile.Thresholds[DRIFT_Y]); - ImGui::PopItemWidth(); - ImGui::EndChild(); - SohImGui::EndGroupPanel(14.0f); - } - - ImGui::SameLine(); - - const ImVec2 cursor = ImGui::GetCursorPos(); - - SohImGui::BeginGroupPanel("C-Buttons", ImVec2(158, 20)); - DrawButton("Up", BTN_CUP); - DrawButton("Down", BTN_CDOWN); - DrawButton("Left", BTN_CLEFT); - DrawButton("Right", BTN_CRIGHT); - ImGui::Dummy(ImVec2(0, 5)); - SohImGui::EndGroupPanel(); - - ImGui::SetCursorPosX(cursor.x); - ImGui::SetCursorPosY(cursor.y + 120); - SohImGui::BeginGroupPanel("Options", ImVec2(158, 20)); - float cursorX = ImGui::GetCursorPosX() + 5; - ImGui::SetCursorPosX(cursorX); - ImGui::Checkbox("Rumble Enabled", &profile.UseRumble); - if (Backend->CanRumble()) { - ImGui::SetCursorPosX(cursorX); - ImGui::Text("Rumble Force: %d%%", static_cast(100 * profile.RumbleStrength)); - ImGui::SetCursorPosX(cursorX); - ImGui::PushItemWidth(135.0f); - ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0, 1.0f, ""); - ImGui::PopItemWidth(); - } - ImGui::Dummy(ImVec2(0, 5)); - SohImGui::EndGroupPanel(IsKeyboard ? 0.0f : 2.0f); - } - - void InputEditor::DrawHud() { - - __enableGameInput = true; - - if (!this->Opened) { - BtnReading = -1; - return; - } - - ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290)); - //OTRTODO: Disable this stupid workaround ( ReadRawPress() only works when the window is on the main viewport ) - ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); - ImGui::Begin("Controller Configuration", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); - - ImGui::BeginTabBar("##Controllers"); - - for (int i = 0; i < 4; i++) { - if (ImGui::BeginTabItem(StringHelper::Sprintf("Port %d", i + 1).c_str())) { - CurrentPort = i; - ImGui::EndTabItem(); - } - } - - ImGui::EndTabBar(); - - // Draw current cfg - - DrawControllerSchema(); - - ImGui::End(); - } -} diff --git a/libultraship/libultraship/InputEditor.cpp b/libultraship/libultraship/InputEditor.cpp index e40990b0db..0d170e305e 100644 --- a/libultraship/libultraship/InputEditor.cpp +++ b/libultraship/libultraship/InputEditor.cpp @@ -141,7 +141,7 @@ namespace Ship { ImGui::BeginChild("##MSInput", ImVec2(90, 50), false); ImGui::Text("Deadzone"); ImGui::PushItemWidth(80); - ImGui::InputInt("##MDZone", &profile.Thresholds[LEFT_STICK]); + ImGui::InputFloat("##MDZone", &profile.Thresholds[LEFT_STICK], 1.0f, 0.0f, "%.0f"); ImGui::PopItemWidth(); ImGui::EndChild(); } else { @@ -166,11 +166,11 @@ namespace Ship { ImGui::BeginChild("##CSInput", ImVec2(90, 85), false); ImGui::Text("Deadzone"); ImGui::PushItemWidth(80); - ImGui::InputInt("##MDZone", &profile.Thresholds[RIGHT_STICK]); + ImGui::InputFloat("##MDZone", &profile.Thresholds[RIGHT_STICK], 1.0f, 0.0f, "%.0f"); ImGui::PopItemWidth(); ImGui::Text("Sensitivity"); ImGui::PushItemWidth(80); - ImGui::InputInt("##MSensitivity", &profile.Thresholds[SENSITIVITY]); + ImGui::InputFloat("##MSensitivity", &profile.Thresholds[SENSITIVITY], 1.0f, 0.0f, "%.0f"); ImGui::PopItemWidth(); ImGui::EndChild(); SohImGui::EndGroupPanel(14.0f); @@ -184,30 +184,30 @@ namespace Ship { ImGui::SetCursorPosX(cursorX); ImGui::Checkbox("Enable Gyro", &profile.UseGyro); ImGui::SetCursorPosX(cursorX); - ImGui::Text("Gyro Sensitivity: %d%%", profile.Thresholds[GYRO_SENSITIVITY]); + ImGui::Text("Gyro Sensitivity: %d%%", static_cast(100.0f * profile.Thresholds[GYRO_SENSITIVITY])); ImGui::PushItemWidth(135.0f); ImGui::SetCursorPosX(cursorX); - ImGui::SliderInt("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0, 100, ""); + ImGui::SliderFloat("##GSensitivity", &profile.Thresholds[GYRO_SENSITIVITY], 0.0f, 1.0f, ""); ImGui::PopItemWidth(); ImGui::Dummy(ImVec2(0, 1)); ImGui::SetCursorPosX(cursorX); if (ImGui::Button("Recalibrate Gyro##RGyro")) { - profile.Thresholds[DRIFT_X] = 0; - profile.Thresholds[DRIFT_Y] = 0; + profile.Thresholds[DRIFT_X] = 0.0f; + profile.Thresholds[DRIFT_Y] = 0.0f; } ImGui::SetCursorPosX(cursorX); - DrawVirtualStick("##GyroPreview", ImVec2(Backend->wGyroX, Backend->wGyroY)); + DrawVirtualStick("##GyroPreview", ImVec2(-10.0f * Backend->wGyroY, 10.0f * Backend->wGyroX)); ImGui::SameLine(); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5); ImGui::BeginChild("##GyInput", ImVec2(90, 85), false); ImGui::Text("Drift X"); ImGui::PushItemWidth(80); - ImGui::InputInt("##GDriftX", &profile.Thresholds[DRIFT_X]); + ImGui::InputFloat("##GDriftX", &profile.Thresholds[DRIFT_X], 1.0f, 0.0f, "%.1f"); ImGui::PopItemWidth(); ImGui::Text("Drift Y"); ImGui::PushItemWidth(80); - ImGui::InputInt("##GDriftY", &profile.Thresholds[DRIFT_Y]); + ImGui::InputFloat("##GDriftY", &profile.Thresholds[DRIFT_Y], 1.0f, 0.0f, "%.1f"); ImGui::PopItemWidth(); ImGui::EndChild(); SohImGui::EndGroupPanel(14.0f); @@ -233,10 +233,10 @@ namespace Ship { ImGui::Checkbox("Rumble Enabled", &profile.UseRumble); if (Backend->CanRumble()) { ImGui::SetCursorPosX(cursorX); - ImGui::Text("Rumble Force: %d%%", static_cast(100 * profile.RumbleStrength)); + ImGui::Text("Rumble Force: %d%%", static_cast(100.0f * profile.RumbleStrength)); ImGui::SetCursorPosX(cursorX); ImGui::PushItemWidth(135.0f); - ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0, 1.0f, ""); + ImGui::SliderFloat("##RStrength", &profile.RumbleStrength, 0.0f, 1.0f, ""); ImGui::PopItemWidth(); } ImGui::Dummy(ImVec2(0, 5)); diff --git a/libultraship/libultraship/SDLController.cpp b/libultraship/libultraship/SDLController.cpp index fc813dd661..3d02a86143 100644 --- a/libultraship/libultraship/SDLController.cpp +++ b/libultraship/libultraship/SDLController.cpp @@ -100,13 +100,13 @@ namespace Ship { for (int32_t i = SDL_CONTROLLER_AXIS_LEFTX; i < SDL_CONTROLLER_AXIS_MAX; i++) { const auto Axis = static_cast(i); - const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis) / 32767; + const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis) / 32767.0f; - if(AxisValue < 0) { + if (AxisValue < -0.7f) { return -(Axis + AXIS_SCANCODE_BIT); } - if (AxisValue > 0) { + if (AxisValue > 0.7f) { return (Axis + AXIS_SCANCODE_BIT); } } @@ -153,9 +153,9 @@ namespace Ship { float gyroData[3]; SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3); - float gyro_drift_x = profile.GyroThresholds[DRIFT_X] / 100.0f; - float gyro_drift_y = profile.GyroThresholds[DRIFT_Y] / 100.0f; - const float gyro_sensitivity = profile.GyroThresholds[SENSITIVITY] / 100.0f; + float gyro_drift_x = profile.Thresholds[DRIFT_X] / 100.0f; + float gyro_drift_y = profile.Thresholds[DRIFT_Y] / 100.0f; + const float gyro_sensitivity = profile.Thresholds[GYRO_SENSITIVITY]; if (gyro_drift_x == 0) { gyro_drift_x = gyroData[0]; @@ -165,8 +165,8 @@ namespace Ship { gyro_drift_y = gyroData[1]; } - profile.GyroThresholds[DRIFT_X] = (int) gyro_drift_x * 100; - profile.GyroThresholds[DRIFT_Y] = (int) gyro_drift_y * 100; + profile.Thresholds[DRIFT_X] = gyro_drift_x * 100.0f; + profile.Thresholds[DRIFT_Y] = gyro_drift_y * 100.0f; wGyroX = gyroData[0] - gyro_drift_x; wGyroY = gyroData[1] - gyro_drift_y; @@ -175,6 +175,8 @@ namespace Ship { wGyroY *= gyro_sensitivity; } + dwPressedButtons[slot] = 0; + for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) { if (profile.Mappings.contains(i)) { if (SDL_GameControllerGetButton(Cont, static_cast(i))) { @@ -198,7 +200,7 @@ namespace Ship { const auto Axis = static_cast(i); const auto PosScancode = i + AXIS_SCANCODE_BIT; const auto NegScancode = -PosScancode; - const auto AxisThreshold = profile.Thresholds[SDLAxisToThreshold(i)]; + const auto AxisThreshold = static_cast(profile.Thresholds[SDLAxisToThreshold(i)]); const auto PosButton = profile.Mappings[PosScancode]; const auto NegButton = profile.Mappings[NegScancode]; const auto AxisValue = SDL_GameControllerGetAxis(Cont, Axis); @@ -467,10 +469,13 @@ namespace Ship { profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTX + AXIS_SCANCODE_BIT)] = BTN_STICKLEFT; profile.Mappings[SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT] = BTN_STICKDOWN; profile.Mappings[-(SDL_CONTROLLER_AXIS_LEFTY + AXIS_SCANCODE_BIT)] = BTN_STICKUP; - profile.Thresholds[LEFT_STICK] = 16.0; - profile.Thresholds[RIGHT_STICK] = 16.0; + profile.Thresholds[LEFT_STICK] = 16.0f; + profile.Thresholds[RIGHT_STICK] = 16.0f; profile.Thresholds[LEFT_TRIGGER] = 0x1E00; profile.Thresholds[RIGHT_TRIGGER] = 0x1E00; - profile.Thresholds[SENSITIVITY] = 16.0; + profile.Thresholds[DRIFT_X] = 0.0f; + profile.Thresholds[DRIFT_Y] = 0.0f; + profile.Thresholds[SENSITIVITY] = 16.0f; + profile.Thresholds[GYRO_SENSITIVITY] = 1.0f; } } diff --git a/libultraship/libultraship/libultraship.vcxproj b/libultraship/libultraship/libultraship.vcxproj index 964f51f512..27e868afaa 100644 --- a/libultraship/libultraship/libultraship.vcxproj +++ b/libultraship/libultraship/libultraship.vcxproj @@ -38,38 +38,38 @@ StaticLibrary true - v143 + v142 Unicode StaticLibrary true - v143 + v142 Unicode StaticLibrary false - v143 + v142 true Unicode StaticLibrary true - v143 + v142 Unicode StaticLibrary true - v143 + v142 Unicode StaticLibrary false - v143 + v142 true Unicode From 93bea4c151b779e3c304f81d5f81c2e6ed715fe6 Mon Sep 17 00:00:00 2001 From: M4xw Date: Fri, 15 Jul 2022 01:40:02 +0200 Subject: [PATCH 21/38] git subrepo push soh subrepo: subdir: "soh" merged: "75ccbade8" upstream: origin: "https://github.com/HarbourMasters/soh.git" branch: "master" commit: "75ccbade8" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- soh/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/.gitrepo b/soh/.gitrepo index 1186c7e01b..06ac43f778 100644 --- a/soh/.gitrepo +++ b/soh/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/HarbourMasters/soh.git branch = master - commit = ba904bbd0d724784f8f37ff4bea378f6fe26151b - parent = 0bb0e7b53bd80bdc7f78e08c441691737e039b2b + commit = 75ccbade8ba26485266a8c8aa7d81e495d0ca4dd + parent = 8417db65c73cb3d117f2a0f9040105022a45480c method = rebase cmdver = 0.4.1 From d45968270a6fc11aa99f6e9c96e7ad655b3edd63 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:20:07 -0400 Subject: [PATCH 22/38] Address rando pr comments (#742) * prefix randomizer methods with Randomizer_ * make filename a local var * remove unused file, update malon to use new names * move randomizertypes to randomizer directory * rename to Randomizer_GetSettingValue Co-authored-by: briaguya --- .../libultraship/Lib/Fast3D/gfx_dxgi.cpp | 3 +- soh/include/z64save.h | 2 +- soh/randomizer_generation.cpp | 19 ---------- soh/soh.vcxproj | 2 +- soh/soh.vcxproj.filters | 2 +- .../Enhancements/randomizer/3drando/menu.cpp | 2 +- .../Enhancements/randomizer/3drando/menu.hpp | 2 +- .../randomizer/3drando/playthrough.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.h | 2 +- .../randomizer}/randomizerTypes.h | 0 soh/soh/OTRGlobals.cpp | 26 ++++++------- soh/soh/OTRGlobals.h | 26 ++++++------- soh/src/code/z_actor.c | 16 ++++---- soh/src/code/z_demo.c | 2 +- soh/src/code/z_en_item00.c | 14 +++---- soh/src/code/z_message_PAL.c | 18 ++++----- soh/src/code/z_parameter.c | 4 +- soh/src/code/z_play.c | 12 +++--- soh/src/code/z_sram.c | 38 +++++++++---------- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 2 +- .../ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c | 2 +- .../ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c | 14 +++---- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 2 +- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 4 +- .../actors/ovl_Demo_Kekkai/z_demo_kekkai.c | 2 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 2 +- soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 4 +- .../ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c | 6 +-- soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 8 ++-- .../ovl_En_Diving_Game/z_en_diving_game.c | 4 +- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 6 +-- .../actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c | 4 +- soh/src/overlays/actors/ovl_En_Du/z_en_du.c | 2 +- .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 22 +++++------ soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 4 +- soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 2 +- soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c | 4 +- soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 8 ++-- soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c | 4 +- soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c | 4 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 2 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 6 +-- soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 2 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 6 +-- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 4 +- soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 2 +- soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 4 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 8 ++-- .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 6 +-- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 2 +- soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 8 ++-- soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 10 ++--- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 4 +- soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 2 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 2 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 4 +- .../overlays/actors/ovl_Fishing/z_fishing.c | 6 +-- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 4 +- .../ovl_Item_Etcetera/z_item_etcetera.c | 12 +++--- .../actors/ovl_Item_Ocarina/z_item_ocarina.c | 6 +-- .../ovl_file_choose/z_file_choose.c | 12 +++--- 61 files changed, 197 insertions(+), 217 deletions(-) delete mode 100644 soh/randomizer_generation.cpp rename soh/{ => soh/Enhancements/randomizer}/randomizerTypes.h (100%) diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp index 620fb52714..6e0c2e4d6d 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp @@ -229,9 +229,8 @@ static void onkeyup(WPARAM w_param, LPARAM l_param) { } } -char fileName[256]; - static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_param, LPARAM l_param) { + char fileName[256]; SohImGui::EventImpl event_impl; event_impl.win32 = { h_wnd, static_cast(message), static_cast(w_param), static_cast(l_param) }; SohImGui::Update(event_impl); diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 86e9627999..e58d7a9250 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -3,7 +3,7 @@ #include "ultra64.h" #include "z64math.h" -#include +#include "soh/Enhancements/randomizer/randomizerTypes.h" typedef struct { /* 0x00 */ u8 buttonItems[8]; diff --git a/soh/randomizer_generation.cpp b/soh/randomizer_generation.cpp deleted file mode 100644 index a55d5fcf0a..0000000000 --- a/soh/randomizer_generation.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include - -void GenerateRandomizer() { - int ret = Playthrough::Playthrough_Init(std::hash{}(Settings::seed)); - - if (ret < 0) { - if (ret == -1) { // Failed to generate after 5 tries - SPDLOG_ERROR( - "\n\nFailed to generate after 5 tries.\nPress B to go back to the menu.\nA different seed might be " - "successful."); - return; - } else { - SPDLOG_ERROR("\n\nError %d with fill.\nPress Select to exit or B to go back to the menu.\n", ret); - return; - } - } - - const auto& randomizerHash = GetRandomizerHash(); -} \ No newline at end of file diff --git a/soh/soh.vcxproj b/soh/soh.vcxproj index 5a293d3f02..6275e82fd6 100644 --- a/soh/soh.vcxproj +++ b/soh/soh.vcxproj @@ -983,7 +983,7 @@ - + diff --git a/soh/soh.vcxproj.filters b/soh/soh.vcxproj.filters index 457e23ed16..5f48ff0425 100644 --- a/soh/soh.vcxproj.filters +++ b/soh/soh.vcxproj.filters @@ -4052,7 +4052,7 @@ Header Files - + Header Files diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 80e5d63b2e..7a0c16def9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -14,7 +14,7 @@ #include "location_access.hpp" #include "debug.hpp" #include -#include "randomizerTypes.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" namespace { bool seedChanged; diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index 2f39331359..737c1d3cfa 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -2,7 +2,7 @@ #include #include -#include "randomizerTypes.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" #define MAIN_MENU 0 #define OPTION_SUB_MENU 1 diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp index 772cd4a5f0..cfcbdfa917 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -6,7 +6,7 @@ #include "logic.hpp" #include "random.hpp" #include "spoiler_log.hpp" -#include "randomizerTypes.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" namespace Playthrough { diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 7f4d16031c..f4101e8fd3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -4,7 +4,7 @@ #include #include "../../../include/ultra64.h" #include "../../../include/z64item.h" -#include +#include "soh/Enhancements/randomizer/randomizerTypes.h" class Randomizer { private: diff --git a/soh/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h similarity index 100% rename from soh/randomizerTypes.h rename to soh/soh/Enhancements/randomizer/randomizerTypes.h diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 514edc563e..6a1ecc1980 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1367,23 +1367,23 @@ extern "C" void* getN64WeirdFrame(s32 i) { return &weirdFrameBytes[i + sizeof(n64WeirdFrames)]; } -extern "C" s16 GetItemModelFromId(s16 itemId) { +extern "C" s16 Randomizer_GetItemModelFromId(s16 itemId) { return OTRGlobals::Instance->gRandomizer->GetItemModelFromId(itemId); } -extern "C" s32 GetItemIDFromGetItemID(s32 getItemId) { +extern "C" s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId) { return OTRGlobals::Instance->gRandomizer->GetItemIDFromGetItemID(getItemId); } -extern "C" void LoadRandomizerSettings(const char* spoilerFileName) { +extern "C" void Randomizer_LoadSettings(const char* spoilerFileName) { OTRGlobals::Instance->gRandomizer->LoadRandomizerSettings(spoilerFileName); } -extern "C" void LoadHintLocations(const char* spoilerFileName) { +extern "C" void Randomizer_LoadHintLocations(const char* spoilerFileName) { OTRGlobals::Instance->gRandomizer->LoadHintLocations(spoilerFileName); } -extern "C" void LoadItemLocations(const char* spoilerFileName, bool silent) { +extern "C" void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent) { OTRGlobals::Instance->gRandomizer->LoadItemLocations(spoilerFileName, silent); } @@ -1391,11 +1391,11 @@ extern "C" bool SpoilerFileExists(const char* spoilerFileName) { return OTRGlobals::Instance->gRandomizer->SpoilerFileExists(spoilerFileName); } -extern "C" u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { +extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey) { return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(randoSettingKey); } -extern "C" RandomizerCheck GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams) { +extern "C" RandomizerCheck Randomizer_GetCheckFromActor(s16 sceneNum, s16 actorId, s16 actorParams) { return OTRGlobals::Instance->gRandomizer->GetCheckFromActor(sceneNum, actorId, actorParams); } @@ -1471,33 +1471,33 @@ extern "C" int CopyScrubMessage(u16 scrubTextId, char* buffer, const int maxBuff return CopyStringToCharBuffer(scrubText, buffer, maxBufferSize); } -extern "C" int CopyAltarMessage(char* buffer, const int maxBufferSize) { +extern "C" int Randomizer_CopyAltarMessage(char* buffer, const int maxBufferSize) { const std::string& altarText = (LINK_IS_ADULT) ? OTRGlobals::Instance->gRandomizer->GetAdultAltarText() : OTRGlobals::Instance->gRandomizer->GetChildAltarText(); return CopyStringToCharBuffer(altarText, buffer, maxBufferSize); } -extern "C" int CopyGanonText(char* buffer, const int maxBufferSize) { +extern "C" int Randomizer_CopyGanonText(char* buffer, const int maxBufferSize) { const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonText(); return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize); } -extern "C" int CopyGanonHintText(char* buffer, const int maxBufferSize) { +extern "C" int Randomizer_CopyGanonHintText(char* buffer, const int maxBufferSize) { const std::string& ganonText = OTRGlobals::Instance->gRandomizer->GetGanonHintText(); return CopyStringToCharBuffer(ganonText, buffer, maxBufferSize); } -extern "C" int CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize) { +extern "C" int Randomizer_CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize) { // we don't want to make a copy of the std::string returned from GetHintFromCheck // so we're just going to let RVO take care of it const std::string& hintText = OTRGlobals::Instance->gRandomizer->GetHintFromCheck(check); return CopyStringToCharBuffer(hintText, buffer, maxBufferSize); } -extern "C" s32 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { +extern "C" s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum) { return OTRGlobals::Instance->gRandomizer->GetRandomizedItemId(ogId, actorId, actorParams, sceneNum); } -extern "C" s32 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { +extern "C" s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId) { return OTRGlobals::Instance->gRandomizer->GetRandomizedItemIdFromKnownCheck(randomizerCheck, ogId); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 7c42da3709..2bee6819de 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -84,19 +84,19 @@ void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); int Controller_ShouldRumble(size_t i); void* getN64WeirdFrame(s32 i); Sprite* GetSeedTexture(uint8_t index); -void LoadRandomizerSettings(const char* spoilerFileName); -u8 GetRandoSettingValue(RandomizerSettingKey randoSettingKey); -RandomizerCheck GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum); -int CopyAltarMessage(char* buffer, const int maxBufferSize); -int CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize); -int CopyGanonText(char* buffer, const int maxBufferSize); -int CopyGanonHintText(char* buffer, const int maxBufferSize); -void LoadHintLocations(const char* spoilerFileName); -void LoadItemLocations(const char* spoilerFileName, bool silent); -s16 GetItemModelFromId(s16 itemId); -s32 GetItemIDFromGetItemID(s32 getItemId); -s32 GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); -s32 GetRandomizedItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); +void Randomizer_LoadSettings(const char* spoilerFileName); +u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); +RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 actorParams, s16 sceneNum); +int Randomizer_CopyAltarMessage(char* buffer, const int maxBufferSize); +int Randomizer_CopyHintFromCheck(RandomizerCheck check, char* buffer, const int maxBufferSize); +int Randomizer_CopyGanonText(char* buffer, const int maxBufferSize); +int Randomizer_CopyGanonHintText(char* buffer, const int maxBufferSize); +void Randomizer_LoadHintLocations(const char* spoilerFileName); +void Randomizer_LoadItemLocations(const char* spoilerFileName, bool silent); +s16 Randomizer_GetItemModelFromId(s16 itemId); +s32 Randomizer_GetItemIDFromGetItemID(s32 getItemId); +s32 Randomizer_GetRandomizedItemId(GetItemID ogId, s16 actorId, s16 actorParams, s16 sceneNum); +s32 Randomizer_GetItemIdFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); #endif #endif diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 42ab8064c8..70771880c3 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -5983,7 +5983,7 @@ s32 func_80038290(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, Vec3s* ar } s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) { - if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { // RANDOTODO update this logic when we implement keysanity // because 3drando replaces the keys not the rupees if (ogDrawId == GID_RUPEE_GREEN || @@ -5993,27 +5993,27 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) switch(room) { case 1: if(!Flags_GetCollectible(globalCtx, 0x1B)) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, GI_RUPEE_GREEN); } break; case 2: if(!Flags_GetCollectible(globalCtx, 0x1C)) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, GI_RUPEE_GREEN); } break; case 3: if(!Flags_GetCollectible(globalCtx, 0x1D)) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, GI_RUPEE_BLUE); } break; case 4: if(!Flags_GetCollectible(globalCtx, 0x1E)) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, GI_RUPEE_BLUE); } break; case 5: if(!Flags_GetCollectible(globalCtx, 0x1F)) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, GI_RUPEE_RED); } break; } @@ -6021,7 +6021,7 @@ s32 GetChestGameRandoGetItemId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) } if(ogDrawId == GID_HEART_PIECE) { - return GetRandomizedItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE); + return Randomizer_GetItemIdFromKnownCheck(RC_MARKET_TREASURE_CHEST_GAME_REWARD, GI_HEART_PIECE); } return GI_NONE; @@ -6031,7 +6031,7 @@ s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, GlobalContext* globalCtx) { s32 randoGetItemId = GetChestGameRandoGetItemId(room, ogDrawId, globalCtx); if(randoGetItemId != GI_NONE) { - return GetItemModelFromId(randoGetItemId); + return Randomizer_GetItemModelFromId(randoGetItemId); } return ogDrawId; diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 7b55150eee..46b5fd9cf3 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -2124,7 +2124,7 @@ void Cutscene_HandleConditionalTriggers(GlobalContext* globalCtx) { // If we are rando and tower escape skip is on, then set the flag to say we saw the towers fall // and exit. - if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_TOWER_ESCAPE)) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)) { return; } gSaveContext.cutsceneIndex = 0xFFF0; diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 0c26f8be91..baa49020a1 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -509,7 +509,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { } if ((gSaveContext.n64ddFlag || getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) { - getItemId = GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); func_8002F554(&this->actor, globalCtx, getItemId); } @@ -548,7 +548,7 @@ void func_8001DFC8(EnItem00* this, GlobalContext* globalCtx) { } if (this->actor.params == ITEM00_HEART_PIECE) { - if ((CVar_GetS32("gNewDrops", 0) !=0) && !gSaveContext.n64ddFlag) { + if (CVar_GetS32("gNewDrops", 0) && !gSaveContext.n64ddFlag) { this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 20.0f + 50.0f; } else { this->actor.shape.yOffset = Math_SinS(this->actor.shape.rot.y) * 150.0f + 850.0f; @@ -881,7 +881,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, globalCtx)) { if (gSaveContext.n64ddFlag) { - getItemId = GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + getItemId = Randomizer_GetRandomizedItemId(getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); } func_8002F554(&this->actor, globalCtx, getItemId); } @@ -1300,11 +1300,11 @@ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) { if ((gSaveContext.n64ddFlag && this->getItemId != GI_NONE) || this->actor.params == ITEM00_SMALL_KEY) { f32 mtxScale = 16.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - s32 randoGetItemId = GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); + s32 randoGetItemId = Randomizer_GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); } - GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId)); + GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); } else { s32 texIndex = this->actor.params - 3; @@ -1360,11 +1360,11 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { f32 mtxScale = 16.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - s32 randoGetItemId = GetRandomizedItemId(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); + s32 randoGetItemId = Randomizer_GetRandomizedItemId(GI_HEART_PIECE, this->actor.id, this->ogParams, globalCtx->sceneNum); if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); } - GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId)); + GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); } else { s32 pad; diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 9cf592e4fb..9631c5a123 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -1676,11 +1676,11 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { // if we're rando'd and talking to a gossip stone if (gSaveContext.n64ddFlag && textId == 0x2053 && - GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) != 0 && - (GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 1 || - (GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 2 && + Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) != 0 && + (Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 1 || + (Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 2 && Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) || - (GetRandoSettingValue(RSK_GOSSIP_STONE_HINTS) == 3 && + (Randomizer_GetSettingValue(RSK_GOSSIP_STONE_HINTS) == 3 && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { s16 actorParams = msgCtx->talkActor->params; @@ -1700,14 +1700,14 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { } } - RandomizerCheck hintCheck = GetCheckFromActor(globalCtx->sceneNum, msgCtx->talkActor->id, actorParams); + RandomizerCheck hintCheck = Randomizer_GetCheckFromActor(globalCtx->sceneNum, msgCtx->talkActor->id, actorParams); // Pass the sizeof the message buffer so we don't hardcode any sizes and can rely on globals. // If no hint can be found, this just returns 0 size and doesn't modify the buffer, so no worries. - msgCtx->msgLength = font->msgLength = CopyHintFromCheck(hintCheck, font->msgBuf, sizeof(font->msgBuf)); + msgCtx->msgLength = font->msgLength = Randomizer_CopyHintFromCheck(hintCheck, font->msgBuf, sizeof(font->msgBuf)); } else if (gSaveContext.n64ddFlag && (textId == 0x7040 || textId == 0x7088)) { // rando hints at altar - msgCtx->msgLength = font->msgLength = CopyAltarMessage(font->msgBuf, sizeof(font->msgBuf)); + msgCtx->msgLength = font->msgLength = Randomizer_CopyAltarMessage(font->msgBuf, sizeof(font->msgBuf)); } else if (textId == 0x00b4 && CVar_GetS32("gInjectSkulltulaCount", 0) != 0) { switch (gSaveContext.language) { case LANGUAGE_FRA: @@ -1731,9 +1731,9 @@ void Message_OpenText(GlobalContext* globalCtx, u16 textId) { msgCtx->msgLength = font->msgLength = CopyScrubMessage(textId, font->msgBuf, sizeof(font->msgBuf)); } else if (gSaveContext.n64ddFlag && textId == 0x70CC) { if (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) { - msgCtx->msgLength = font->msgLength = CopyGanonText(font->msgBuf, sizeof(font->msgBuf)); + msgCtx->msgLength = font->msgLength = Randomizer_CopyGanonText(font->msgBuf, sizeof(font->msgBuf)); } else { - msgCtx->msgLength = font->msgLength = CopyGanonHintText(font->msgBuf, sizeof(font->msgBuf)); + msgCtx->msgLength = font->msgLength = Randomizer_CopyGanonHintText(font->msgBuf, sizeof(font->msgBuf)); } } else { msgCtx->msgLength = font->msgLength; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 0ac1e1048c..4a79bd3bc5 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -1810,13 +1810,13 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) { return ITEM_NONE; } else if (item == ITEM_WALLET_ADULT) { Inventory_ChangeUpgrade(UPG_WALLET, 1); - if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_FULL_WALLETS)) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { Rupees_ChangeBy(200); } return ITEM_NONE; } else if (item == ITEM_WALLET_GIANT) { Inventory_ChangeUpgrade(UPG_WALLET, 2); - if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_FULL_WALLETS)) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { Rupees_ChangeBy(500); } return ITEM_NONE; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index c6938718fc..5656f4c07e 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -198,7 +198,7 @@ void GivePlayerRandoRewardSongOfTime(GlobalContext* globalCtx, RandomizerCheck c if (gSaveContext.entranceIndex == 0x050F && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && !Flags_GetTreasure(globalCtx, 0x1F) && gSaveContext.nextTransition == 0xFF) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_SONG_OF_TIME); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME); GiveItemWithoutActor(globalCtx, getItemId); Flags_SetTreasure(globalCtx, 0x1F); } @@ -212,7 +212,7 @@ void GivePlayerRandoRewardNocturne(GlobalContext* globalCtx, RandomizerCheck che gSaveContext.entranceIndex == 0x0195) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && !Flags_GetEventChkInf(0xAA)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_NOCTURNE_OF_SHADOW); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_NOCTURNE_OF_SHADOW); GiveItemWithoutActor(globalCtx, getItemId); Flags_SetEventChkInf(0xAA); } @@ -224,7 +224,7 @@ void GivePlayerRandoRewardRequiem(GlobalContext* globalCtx, RandomizerCheck chec if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(0xAC) && player != NULL && !Player_InBlockingCsMode(globalCtx, player)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_SONG_OF_TIME); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_TIME); GiveItemWithoutActor(globalCtx, getItemId); Flags_SetEventChkInf(0xAC); } @@ -238,7 +238,7 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TOKINOMA) && !Flags_GetTreasure(globalCtx, 0x1E) && player != NULL && !Player_InBlockingCsMode(globalCtx, player) && globalCtx->sceneLoadFlag == 0 && player->getItemId == GI_NONE) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ARROW_LIGHT); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ARROW_LIGHT); GiveItemWithoutActor(globalCtx, getItemId); Flags_SetTreasure(globalCtx, 0x1E); } @@ -247,7 +247,7 @@ void GivePlayerRandoRewardZeldaLightArrowsGift(GlobalContext* globalCtx, Randomi void GivePlayerRandoRewardSariaGift(GlobalContext* globalCtx, RandomizerCheck check) { Player* player = GET_PLAYER(globalCtx); if (gSaveContext.entranceIndex == 0x05E0) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); if ((!Flags_GetEventChkInf(0xC1) || (player->getItemId == getItemId && getItemId != GI_ICE_TRAP)) && player != NULL && !Player_InBlockingCsMode(globalCtx, player)) { @@ -271,7 +271,7 @@ void Gameplay_Init(GameState* thisx) { u8 tempSetupIndex; s32 pad[2]; - if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_CHILD_STEALTH)) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH)) { if (gSaveContext.entranceIndex == 0x7A) { gSaveContext.entranceIndex = 0x400; } else if (gSaveContext.entranceIndex == 0x296) { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index c88fc9ba1e..7670762c59 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -416,7 +416,7 @@ void GiveLinkDungeonReward(GetItemID getItemId) { } void GiveLinksPocketMedallion() { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LINKS_POCKET, RG_NONE); GiveLinkDungeonReward(getItemId); } @@ -644,7 +644,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { // Give Link's pocket item GiveLinksPocketMedallion(); - int openForest = GetRandoSettingValue(RSK_FOREST); + int openForest = Randomizer_GetSettingValue(RSK_FOREST); switch (openForest) { case 0: // closed break; @@ -657,28 +657,28 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { break; } - int doorOfTime = GetRandoSettingValue(RSK_DOOR_OF_TIME); + int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); switch (doorOfTime) { case 0: // open gSaveContext.eventChkInf[4] |= 0x800; break; } - int kakGate = GetRandoSettingValue(RSK_KAK_GATE); + int kakGate = Randomizer_GetSettingValue(RSK_KAK_GATE); switch (kakGate) { case 1: // open gSaveContext.infTable[7] |= 0x40; break; } - if(GetRandoSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword(); - if(GetRandoSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield(); + if(Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) GiveLinkKokiriSword(); + if(Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD)) GiveLinkDekuShield(); - if(GetRandoSettingValue(RSK_STARTING_OCARINA)) { + if(Randomizer_GetSettingValue(RSK_STARTING_OCARINA)) { INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY; } - if(GetRandoSettingValue(RSK_STARTING_MAPS_COMPASSES)) { + if(Randomizer_GetSettingValue(RSK_STARTING_MAPS_COMPASSES)) { uint32_t mapBitMask = 1 << 1; uint32_t compassBitMask = 1 << 2; uint32_t startingDungeonItemsBitMask = mapBitMask | compassBitMask; @@ -687,13 +687,13 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } } - if (GetRandoSettingValue(RSK_STARTING_CONSUMABLES)) { + if (Randomizer_GetSettingValue(RSK_STARTING_CONSUMABLES)) { GiveLinkDekuSticks(10); GiveLinkDekuNuts(20); } - if(GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA)) { - s32 giid = GetRandomizedItemIdFromKnownCheck(RC_SONG_FROM_IMPA, GI_ZELDAS_LULLABY); + if(Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { + s32 giid = Randomizer_GetItemIdFromKnownCheck(RC_SONG_FROM_IMPA, GI_ZELDAS_LULLABY); if(giid >= GI_ZELDAS_LULLABY && giid <= GI_PRELUDE_OF_LIGHT) { GiveLinkSong(giid); @@ -780,7 +780,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } else if (giid == GI_DOUBLE_DEFENSE) { GiveLinkDoubleDefense(); } else { - s32 iid = GetItemIDFromGetItemID(giid); + s32 iid = Randomizer_GetItemIDFromGetItemID(giid); if (iid != -1) INV_CONTENT(iid) = iid; } @@ -801,18 +801,18 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; } - if (GetRandoSettingValue(RSK_FULL_WALLETS)) { + if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { GiveLinkRupees(9001); } // For Ganon's boss key "Start With" is 0 - if(GetRandoSettingValue(RSK_GANONS_BOSS_KEY) == 0) { + if(Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == 0) { gSaveContext.inventory.dungeonItems[10] |= 1; } - HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * GetRandoSettingValue(RSK_BIG_POE_COUNT)); + HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); - if(GetRandoSettingValue(RSK_SKIP_EPONA_RACE)) { + if(Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { gSaveContext.eventChkInf[1] |= (1 << 8); } @@ -839,7 +839,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.infTable[25] |= 0x20; // fast gerudo fortress - if (GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 1 || GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 2) { + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 1 || Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 2) { gSaveContext.eventChkInf[9] |= 2; gSaveContext.eventChkInf[9] |= 4; gSaveContext.eventChkInf[9] |= 8; @@ -858,14 +858,14 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { } // open gerudo fortress - if (GetRandoSettingValue(RSK_GERUDO_FORTRESS) == 2) { + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == 2) { gSaveContext.eventChkInf[9] |= 1; gSaveContext.sceneFlags[12].swch |= (1 << 0x01); gSaveContext.sceneFlags[12].swch |= (1 << 0x05); gSaveContext.sceneFlags[12].swch |= (1 << 0x11); gSaveContext.sceneFlags[12].collect |= (1 << 0x0C); - if (!GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { GiveLinkGerudoCard(); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index a31d488555..7be483bd9a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -69,7 +69,7 @@ const ActorInit Bg_Dy_Yoseizo_InitVars = { void GivePlayerRandoRewardGreatFairy(BgDyYoseizo* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - GetItemID getItemId = GetRandomizedItemId(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum); + GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->fountainType + 1, globalCtx->sceneNum); if (this->actor.parent == GET_PLAYER(globalCtx) && !Flags_GetTreasure(globalCtx, this->fountainType + 1) && !Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { diff --git a/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c b/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c index b2d8367f52..ec4dc030e5 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c +++ b/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c @@ -46,7 +46,7 @@ void BgGateShutter_Init(Actor* thisx, GlobalContext* globalCtx) { this->somePos.z = thisx->world.pos.z; if (((gSaveContext.infTable[7] & 0x40) || (!gSaveContext.n64ddFlag && (gSaveContext.eventChkInf[4] & 0x20)) || - (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_KAK_GATE))) && + (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_KAK_GATE))) && (globalCtx->sceneNum == SCENE_SPOT01)) { thisx->world.pos.x = -89.0f; thisx->world.pos.z = -1375.0f; diff --git a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c index ddb3f99cf9..9e46c39ef1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c +++ b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c @@ -50,7 +50,7 @@ void BgGjyoBridge_Init(Actor* thisx, GlobalContext* globalCtx) { this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader); - int bridge = GetRandoSettingValue(RSK_RAINBOW_BRIDGE); + int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE); if (gSaveContext.eventChkInf[4] & 0x2000 || (gSaveContext.n64ddFlag && bridge == 0)) { this->actionFunc = func_808787A4; } else { @@ -176,12 +176,12 @@ void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, GlobalContext* globalCtx) LaunchBridgeCutscene(this, globalCtx); } } else { - int bridge = GetRandoSettingValue(RSK_RAINBOW_BRIDGE); - int bridgeStoneCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT); - int bridgeMedallionCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT); - int bridgeRewardCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT); - int bridgeDungeonCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT); - int bridgeTokenCount = GetRandoSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT); + int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE); + int bridgeStoneCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT); + int bridgeMedallionCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT); + int bridgeRewardCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT); + int bridgeDungeonCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT); + int bridgeTokenCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT); if (CheckPlayerPosition(player, globalCtx)) { switch (bridge) { diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index db57554362..f7a85fc26d 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -1504,7 +1504,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, GlobalContext* globalCtx) if (this->csTimer == 180) { globalCtx->sceneLoadFlag = 0x14; - if (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_SKIP_TOWER_ESCAPE)) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)) { Flags_SetEventChkInf(0xC7); globalCtx->nextEntranceIndex = 0x517; } diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index a59e8fa68f..cd49f75586 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -899,12 +899,12 @@ void func_80986BF8(DemoIm* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardImpa(Actor* impa, GlobalContext* globalCtx, RandomizerCheck check) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_ZELDAS_LULLABY); if (impa->parent != NULL && impa->parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); - } else if (!Flags_GetTreasure(globalCtx, 0x1F) && !GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA)) { + } else if (!Flags_GetTreasure(globalCtx, 0x1F) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { func_8002F434(impa, globalCtx, getItemId, 75.0f, 50.0f); } else if (!Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { gSaveContext.eventChkInf[5] |= 0x200; diff --git a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c index 04b5b72476..46ecf59792 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c +++ b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c @@ -128,7 +128,7 @@ void DemoKekkai_Init(Actor* thisx, GlobalContext* globalCtx) { this->collider2.dim.yShift = 300; if (gSaveContext.n64ddFlag) { - int trialsToComplete = GetRandoSettingValue(RSK_TRIAL_COUNT); + int trialsToComplete = Randomizer_GetSettingValue(RSK_TRIAL_COUNT); if (trialsToComplete <= TrialsDoneCount()) { Actor_Kill(thisx); return; diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 20fc6355d7..291208752f 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -462,7 +462,7 @@ s32 DoorWarp1_PlayerInRange(DoorWarp1* this, GlobalContext* globalCtx) { } void GivePlayerRandoReward(DoorWarp1* this, Player* player, GlobalContext* globalCtx, u8 ruto, u8 adult) { - GetItemID getItemId = GetRandomizedItemId(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum); + GetItemID getItemId = Randomizer_GetRandomizedItemId(GI_NONE, this->actor.id, this->actor.params, globalCtx->sceneNum); if (this->actor.parent != NULL && this->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index ed6eef1a96..b5c7d8a4a6 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -127,7 +127,7 @@ void func_809B0558(EnAni* this, GlobalContext* globalCtx) { gSaveContext.itemGetInf[1] |= 0x20; } else { if (gSaveContext.n64ddFlag) { - s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); + s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f); } else { func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f); @@ -141,7 +141,7 @@ void func_809B05F0(EnAni* this, GlobalContext* globalCtx) { } if (gSaveContext.n64ddFlag) { - s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); + s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_MAN_ON_ROOF, GI_HEART_PIECE); func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 200.0f); } else { func_8002F434(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 200.0f); diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 5d86e72fb4..ee9ce13293 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -186,14 +186,14 @@ void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) { switch (this->prizeIndex) { case EXITEM_BOMB_BAG_BOWLING: this->getItemId = - GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); + Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); break; case EXITEM_HEART_PIECE_BOWLING: this->getItemId = - GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); + Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); break; case EXITEM_BOMBCHUS_BOWLING: - this->getItemId = GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); + this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); break; } } diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 617e7ff00b..533ba593ac 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -421,7 +421,7 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) { Flags_SetTreasure(globalCtx, this->dyna.actor.params & 0x1F); // treasure chest game rando - if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) { if((this->dyna.actor.params & 0xF) < 2) { Flags_SetCollectible(globalCtx, 0x1B); @@ -445,10 +445,10 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) { func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos); if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f && Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) { - int32_t item = GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum); + int32_t item = Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum); // RANDOTODO treasure chest game rando - if (GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { if (gSaveContext.n64ddFlag && globalCtx->sceneNum == 16 && (this->dyna.actor.params & 0x60) != 0x20) { if((this->dyna.actor.params & 0xF) < 2) { if(Flags_GetCollectible(globalCtx, 0x1B)) { @@ -590,7 +590,7 @@ void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) { } if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) || - (gSaveContext.n64ddFlag && GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, + (gSaveContext.n64ddFlag && Randomizer_GetRandomizedItemId(this->dyna.actor.params >> 5 & 0x7F, this->dyna.actor.id, this->dyna.actor.params, globalCtx->sceneNum) == GI_ICE_TRAP)) && this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 6760542cfa..9f43a5f54c 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -453,7 +453,7 @@ void func_809EEA00(EnDivingGame* this, GlobalContext* globalCtx) { if ((this->unk_292 == Message_GetState(&globalCtx->msgCtx) && Message_ShouldAdvance(globalCtx))) { Message_CloseTextbox(globalCtx); this->actor.parent = NULL; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); this->actionFunc = func_809EEA90; } } @@ -463,7 +463,7 @@ void func_809EEA90(EnDivingGame* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = func_809EEAF8; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_ZD_DIVING_MINIGAME, GI_SCALE_SILVER) : GI_SCALE_SILVER, 90.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index 0d0a31f520..a89d583ae5 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -371,7 +371,7 @@ void EnDns_Talk(EnDns* this, GlobalContext* globalCtx) { void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) { if (this->actor.params == 0x9) { if (gSaveContext.n64ddFlag) { - func_8002F434(&this->actor, globalCtx, GetRandomizedItemId(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_STICK_UPGRADE_30, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); } else if (CUR_UPG_VALUE(UPG_STICKS) < 2) { func_8002F434(&this->actor, globalCtx, GI_STICK_UPGRADE_20, 130.0f, 100.0f); } else { @@ -379,14 +379,14 @@ void func_809EFDD0(EnDns* this, GlobalContext* globalCtx) { } } else if (this->actor.params == 0xA) { if (gSaveContext.n64ddFlag) { - func_8002F434(&this->actor, globalCtx, GetRandomizedItemId(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, Randomizer_GetRandomizedItemId(GI_NUT_UPGRADE_40, this->actor.id, this->actor.params, globalCtx->sceneNum), 130.0f, 100.0f); } else if (CUR_UPG_VALUE(UPG_NUTS) < 2) { func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_30, 130.0f, 100.0f); } else { func_8002F434(&this->actor, globalCtx, GI_NUT_UPGRADE_40, 130.0f, 100.0f); } } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemId(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum) : this->dnsItemEntry->getItemId, 130.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetRandomizedItemId(this->dnsItemEntry->getItemId, this->actor.id, this->actor.params, globalCtx->sceneNum) : this->dnsItemEntry->getItemId, 130.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c index b500efea52..6d3a4accd9 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c @@ -139,13 +139,13 @@ void EnDntDemo_Judge(EnDntDemo* this, GlobalContext* globalCtx) { switch (Player_GetMask(globalCtx)) { case PLAYER_MASK_SKULL: if (!Flags_GetTreasure(globalCtx, 0x1F)) { - GiveItemWithoutActor(globalCtx, GetRandomizedItemIdFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30)); + GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_SKULL_MASK, GI_STICK_UPGRADE_30)); Flags_SetTreasure(globalCtx, 0x1F); } break; case PLAYER_MASK_TRUTH: if (!Flags_GetTreasure(globalCtx, 0x1E)) { - GiveItemWithoutActor(globalCtx, GetRandomizedItemIdFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40)); + GiveItemWithoutActor(globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DEKU_THEATER_MASK_OF_TRUTH, GI_NUT_UPGRADE_40)); Flags_SetTreasure(globalCtx, 0x1E); } break; diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index f90092d2f3..e7f9b51aab 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -548,7 +548,7 @@ void func_809FEC70(EnDu* this, GlobalContext* globalCtx) { EnDu_SetupAction(this, func_809FECE4); } else { f32 xzRange = this->actor.xzDistToPlayer + 1.0f; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET) : GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GC_DARUNIAS_JOY, GI_BRACELET) : GI_BRACELET, xzRange, fabsf(this->actor.yDistToPlayer) + 1.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 1b76ceaa98..b42ad6cbf2 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -138,8 +138,8 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { case EXITEM_BOMB_BAG_BOWLING: this->unk_17C = func_8002EBCC; if (gSaveContext.n64ddFlag) { - this->giDrawId = GetItemModelFromId( - GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20)); + this->giDrawId = Randomizer_GetItemModelFromId( + Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20)); } else { this->giDrawId = GID_BOMB_BAG_30; } @@ -173,8 +173,8 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { case EXITEM_BOMBCHUS_BOWLING: this->unk_17C = func_8002EBCC; if (gSaveContext.n64ddFlag) { - this->giDrawId = GetItemModelFromId( - GetRandomizedItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10)); + this->giDrawId = Randomizer_GetItemModelFromId( + Randomizer_GetItemIdFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10)); } else { this->giDrawId = GID_BOMBCHU; } @@ -229,7 +229,7 @@ void EnExItem_WaitForObject(EnExItem* this, GlobalContext* globalCtx) { this->scale = 0.5f; this->unkFloat = 0.5f; this->actor.velocity.y = 10.0f; - if (!gSaveContext.n64ddFlag || !GetRandoSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { + if (!gSaveContext.n64ddFlag || !Randomizer_GetSettingValue(RSK_SHUFFLE_CHEST_MINIGAME)) { switch (this->type) { case EXITEM_GREEN_RUPEE_CHEST: this->giDrawId = GID_RUPEE_GREEN; @@ -404,7 +404,7 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (gSaveContext.n64ddFlag) { GET_PLAYER(globalCtx)->stateFlags1 &= ~(PLAYER_STATE1_10 | PLAYER_STATE1_11); - getItemId = GetRandomizedItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); } else { if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) { getItemId = GI_BULLET_BAG_40; @@ -424,7 +424,7 @@ void EnExItem_TargetPrizeGive(EnExItem* this, GlobalContext* globalCtx) { this->actionFunc = EnExItem_TargetPrizeFinish; } else { if (gSaveContext.n64ddFlag) { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50); } else { getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40; } @@ -510,12 +510,12 @@ void EnExItem_DrawItems(EnExItem* this, GlobalContext* globalCtx) { switch (this->type) { case EXITEM_BOMB_BAG_BOWLING: case EXITEM_BOMB_BAG_COUNTER: - randoGetItemId = GetRandomizedItemIdFromKnownCheck( + randoGetItemId = Randomizer_GetItemIdFromKnownCheck( RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20); break; case EXITEM_BOMBCHUS_BOWLING: case EXITEM_BOMBCHUS_COUNTER: - randoGetItemId = GetRandomizedItemIdFromKnownCheck( + randoGetItemId = Randomizer_GetItemIdFromKnownCheck( RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10); break; } @@ -532,12 +532,12 @@ void EnExItem_DrawHeartPiece(EnExItem* this, GlobalContext* globalCtx) { func_8002ED80(&this->actor, globalCtx, 0); if (gSaveContext.n64ddFlag) { - s32 randoGetItemId = GetRandomizedItemIdFromKnownCheck( + s32 randoGetItemId = Randomizer_GetItemIdFromKnownCheck( RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE); if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); } - GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId)); + GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); } else { GetItem_Draw(globalCtx, GID_HEART_PIECE); } diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index e31f316a60..e6a85b3318 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -940,7 +940,7 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { - this->reward = GetRandomizedItemIdFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); + this->reward = Randomizer_GetItemIdFromKnownCheck(RC_ZR_FROGS_IN_THE_RAIN, GI_HEART_PIECE); } } else { this->reward = GI_RUPEE_BLUE; @@ -951,7 +951,7 @@ void EnFr_SetReward(EnFr* this, GlobalContext* globalCtx) { if (!gSaveContext.n64ddFlag) { this->reward = GI_HEART_PIECE; } else { - this->reward = GetRandomizedItemIdFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); + this->reward = Randomizer_GetItemIdFromKnownCheck(RC_ZR_FROGS_OCARINA_GAME, GI_HEART_PIECE); } } else { this->reward = GI_RUPEE_PURPLE; diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index e08424d38a..24676a5776 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -154,7 +154,7 @@ void GivePlayerRandoRewardSongOfStorms(EnFu* windmillGuy, GlobalContext* globalC Flags_SetTreasure(globalCtx, 0x1F); windmillGuy->actionFunc = func_80A1DBD4; } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_SONG_OF_STORMS); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_SONG_OF_STORMS); func_8002F434(&windmillGuy->actor, globalCtx, getItemId, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c index c41c067c22..a92ef3d6d3 100644 --- a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c +++ b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c @@ -351,7 +351,7 @@ void func_80A2FA50(EnGb* this, GlobalContext* globalCtx) { void func_80A2FB40(EnGb* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE && Message_ShouldAdvance(globalCtx)) { - func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); + func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); this->actionFunc = func_80A2FBB0; } } @@ -361,7 +361,7 @@ void func_80A2FBB0(EnGb* this, GlobalContext* globalCtx) { this->dyna.actor.parent = NULL; this->actionFunc = func_80A2FC0C; } else { - func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); + func_8002F434(&this->dyna.actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_10_BIG_POES, GI_BOTTLE) : GI_BOTTLE, 100.0f, 10.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index e9cae8032c..d34fb977be 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -533,14 +533,14 @@ void EnGe1_WaitTillItemGiven_Archery(EnGe1* this, GlobalContext* globalCtx) { break; } } else { - getItemId = GetRandomizedItemIdFromKnownCheck( + getItemId = Randomizer_GetItemIdFromKnownCheck( RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); } } else { if (!gSaveContext.n64ddFlag) { getItemId = GI_HEART_PIECE; } else { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); } } func_8002F434(&this->actor, globalCtx, getItemId, 10000.0f, 50.0f); @@ -567,14 +567,14 @@ void EnGe1_BeginGiveItem_Archery(EnGe1* this, GlobalContext* globalCtx) { break; } } else { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_GF_HBA_1500_POINTS, + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1500_POINTS, CUR_UPG_VALUE(UPG_QUIVER) == 1 ? GI_QUIVER_40 : GI_QUIVER_50); } } else { if (!gSaveContext.n64ddFlag) { getItemId = GI_HEART_PIECE; } else { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_GF_HBA_1000_POINTS, GI_HEART_PIECE); } } diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 2fc6ef1dff..5310fc65e9 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -457,7 +457,7 @@ void EnGe2_WaitTillCardGiven(EnGe2* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnGe2_SetActionAfterTalk; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); } } @@ -466,7 +466,7 @@ void EnGe2_GiveCard(EnGe2* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->actor.flags &= ~ACTOR_FLAG_16; this->actionFunc = EnGe2_WaitTillCardGiven; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index 3a2c50fab2..556e7c203a 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -142,7 +142,7 @@ void EnGe3_WaitTillCardGiven(EnGe3* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnGe3_Wait; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); } } @@ -151,7 +151,7 @@ void EnGe3_GiveCard(EnGe3* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->actor.flags &= ~ACTOR_FLAG_16; this->actionFunc = EnGe3_WaitTillCardGiven; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_GF_GERUDO_MEMBERSHIP_CARD, GI_GERUDO_CARD) : GI_GERUDO_CARD, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index c1e6bd290f..050bfc4d10 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -955,7 +955,7 @@ void EnGo_GetItem(EnGo* this, GlobalContext* globalCtx) { this->unk_20C = 0; if ((this->actor.params & 0xF0) == 0x90) { if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_CLAIM_CHECK) { - getItemId = gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS) : GI_SWORD_BGS; + getItemId = gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS) : GI_SWORD_BGS; this->unk_20C = 1; } if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_EYEDROPS) { diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index 21d375d387..97f8fb5e04 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -342,7 +342,7 @@ s16 EnGo2_GetStateGoronCityRollingBig(GlobalContext* globalCtx, EnGo2* this) { if(!gSaveContext.n64ddFlag) { bombBagUpgrade = CUR_CAPACITY(UPG_BOMB_BAG) == 30 ? GI_BOMB_BAG_40 : GI_BOMB_BAG_30; } else { - bombBagUpgrade = GetRandomizedItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40); + bombBagUpgrade = Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_CHILD, GI_BOMB_BAG_40); } EnGo2_GetItem(this, globalCtx, bombBagUpgrade); Message_CloseTextbox(globalCtx); @@ -538,7 +538,7 @@ s16 EnGo2_GetStateGoronCityLink(GlobalContext* globalCtx, EnGo2* this) { } gSaveContext.infTable[16] |= 0x200; - EnGo2_GetItem(this, globalCtx, GetRandomizedItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); + EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_GC_ROLLING_GORON_AS_ADULT, GI_TUNIC_GORON)); this->actionFunc = EnGo2_SetupGetItem; Flags_SetTreasure(globalCtx, 0x1F); return 2; @@ -617,7 +617,7 @@ s16 EnGo2_GetStateGoronDmtBiggoron(GlobalContext* globalCtx, EnGo2* this) { return 0; } - EnGo2_GetItem(this, globalCtx, GetRandomizedItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); + EnGo2_GetItem(this, globalCtx, Randomizer_GetItemIdFromKnownCheck(RC_DMT_TRADE_CLAIM_CHECK, GI_SWORD_BGS)); Flags_SetTreasure(globalCtx, 0x1F); } else { EnGo2_GetItem(this, globalCtx, GI_SWORD_BGS); diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index 92fc1f022b..af4eb8ef4f 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -659,7 +659,7 @@ s16 func_80A70058(GlobalContext* globalCtx, Actor* thisx) { gSaveContext.dogParams = 0; break; case 0x709F: - func_80A6F7CC(this, globalCtx, (gSaveContext.infTable[25] & 2) ? GI_RUPEE_BLUE : gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_MARKET_LOST_DOG, GI_HEART_PIECE) : GI_HEART_PIECE); + func_80A6F7CC(this, globalCtx, (gSaveContext.infTable[25] & 2) ? GI_RUPEE_BLUE : gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_MARKET_LOST_DOG, GI_HEART_PIECE) : GI_HEART_PIECE); this->actionFunc = func_80A714C4; break; } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 97544bce67..cda6e476df 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -344,7 +344,7 @@ void EnKz_Init(Actor* thisx, GlobalContext* globalCtx) { EnKz_SetMovedPos(this, globalCtx); } } else { - int zorasFountain = GetRandoSettingValue(RSK_ZORAS_FOUNTAIN); + int zorasFountain = Randomizer_GetSettingValue(RSK_ZORAS_FOUNTAIN); switch (zorasFountain) { case 0: if (gSaveContext.eventChkInf[3] & 8) { @@ -464,10 +464,10 @@ void EnKz_SetupGetItem(EnKz* this, GlobalContext* globalCtx) { } else { if (gSaveContext.n64ddFlag) { if (this->isTrading) { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_TRADE_PRESCRIPTION, GI_FROG); Flags_SetTreasure(globalCtx, 0x1F); } else { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_ZD_KING_ZORA_THAWED, GI_TUNIC_ZORA); } } else { getItemId = this->isTrading ? GI_FROG : GI_TUNIC_ZORA; diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index 33e2bad213..15b0b84552 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -338,7 +338,7 @@ void func_80AA0EA0(EnMa1* this, GlobalContext* globalCtx) { this->actionFunc = func_80AA0EFC; } else { if (gSaveContext.n64ddFlag) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(RC_HC_MALON_EGG, GI_WEIRD_EGG); func_8002F434(&this->actor, globalCtx, getItemId, 120.0f, 10.0f); } else { func_8002F434(&this->actor, globalCtx, GI_WEIRD_EGG, 120.0f, 10.0f); @@ -356,7 +356,7 @@ void func_80AA0EFC(EnMa1* this, GlobalContext* globalCtx) { } void GivePlayerRandoRewardMalon(EnMa1* malon, GlobalContext* globalCtx, RandomizerCheck check) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_EPONAS_SONG); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_EPONAS_SONG); // Prevents flag from getting set if we weren't able to get the item (i.e. Player is holding shield // when closing the textbox). if (malon->actor.parent != NULL && malon->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 3bf4fcbb08..ffb02e8d23 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -487,7 +487,7 @@ u8 EnMd_ShouldSpawn(EnMd* this, GlobalContext* globalCtx) { // if we have beaten deku tree or have open forest turned on // or have already shown mido we have an equipped sword/shield if (gSaveContext.dungeonsDone[1] || - GetRandoSettingValue(RSK_FOREST) == 1 || + Randomizer_GetSettingValue(RSK_FOREST) == 1 || gSaveContext.eventChkInf[0] & 0x10) { return 0; } diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index 8f4c512e3c..f42e095223 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -198,14 +198,14 @@ void func_80AACFA0(EnMk* this, GlobalContext* globalCtx) { gSaveContext.itemGetInf[1] |= 1; } else { // not sure when/how/if this is getting called - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); } } void func_80AAD014(EnMk* this, GlobalContext* globalCtx) { if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = func_80AACFA0; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LH_LAB_DIVE, GI_HEART_PIECE) : GI_HEART_PIECE, 10000.0f, 50.0f); } this->flags |= 1; diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 47a1e5e0d2..c31f2b923f 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -200,7 +200,7 @@ void func_80ABA244(EnNiwLady* this, GlobalContext* globalCtx) { EnNiw* currentCucco; s32 phi_s1; - this->cuccosInPen = gSaveContext.n64ddFlag ? (7 - GetRandoSettingValue(RSK_CUCCO_COUNT)) : 0; + this->cuccosInPen = gSaveContext.n64ddFlag ? (7 - Randomizer_GetSettingValue(RSK_CUCCO_COUNT)) : 0; currentCucco = (EnNiw*)globalCtx->actorCtx.actorLists[ACTORCAT_PROP].head; while (currentCucco != NULL) { if (currentCucco->actor.id == ACTOR_EN_NIW) { @@ -305,7 +305,7 @@ void func_80ABA654(EnNiwLady* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (gSaveContext.n64ddFlag) { - s32 itemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); + s32 itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_CHILD, GI_BOTTLE); func_8002F434(&this->actor, globalCtx, itemId, 100.0f, 50.0f); } else { this->getItemId = GI_BOTTLE; @@ -395,7 +395,7 @@ void func_80ABA9B8(EnNiwLady* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (gSaveContext.n64ddFlag) { - s32 itemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); + s32 itemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); func_8002F434(&this->actor, globalCtx, itemId, 200.0f, 100.0f); } else { func_8002F434(&this->actor, globalCtx, GI_POCKET_EGG, 200.0f, 100.0f); @@ -455,7 +455,7 @@ void func_80ABAC00(EnNiwLady* this, GlobalContext* globalCtx) { getItemId = !(gSaveContext.itemGetInf[2] & 0x1000) ? GI_POCKET_EGG : GI_COJIRO; if (gSaveContext.n64ddFlag && getItemId == GI_POCKET_EGG) { - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_ANJU_AS_ADULT, GI_POCKET_EGG); } } func_8002F434(&this->actor, globalCtx, getItemId, 200.0f, 100.0f); diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index b36a07dd53..cc7360c0a0 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -234,7 +234,7 @@ void func_80ABF4C8(EnOkarinaTag* this, GlobalContext* globalCtx) { if (globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_04) { this->actionFunc = func_80ABF28C; } else if (globalCtx->msgCtx.ocarinaMode == OCARINA_MODE_03) { - if (!gSaveContext.n64ddFlag || (gSaveContext.n64ddFlag && GetRandoSettingValue(RSK_DOOR_OF_TIME) != 2)) { + if (!gSaveContext.n64ddFlag || (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_DOOR_OF_TIME) != 2)) { func_80078884(NA_SE_SY_CORRECT_CHIME); } if (this->switchFlag >= 0) { @@ -257,7 +257,7 @@ void func_80ABF4C8(EnOkarinaTag* this, GlobalContext* globalCtx) { break; case 4: if (gSaveContext.n64ddFlag) { - int doorOfTime = GetRandoSettingValue(RSK_DOOR_OF_TIME); + int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); if (doorOfTime == 2 && (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_OCARINA_TIME || !CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) || !CHECK_QUEST_ITEM(QUEST_GORON_RUBY) || @@ -327,7 +327,7 @@ void GivePlayerRandoRewardSunSong(EnOkarinaTag* song, GlobalContext* globalCtx, !Flags_GetTreasure(globalCtx, 0x1F)) { Flags_SetTreasure(globalCtx, 0x1F); } else if (!Flags_GetTreasure(globalCtx, 0x1F)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_LETTER_ZELDA); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_LETTER_ZELDA); func_8002F434(&song->actor, globalCtx, getItemId, 10000.0f, 100.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index 15cae19d05..c6dd38accf 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -619,7 +619,7 @@ void func_80AF67D0(EnSa* this, GlobalContext* globalCtx) { void GivePlayerRandoRewardSaria(EnSa* saria, GlobalContext* globalCtx, RandomizerCheck check) { GetItemID getItemId = - GetRandomizedItemIdFromKnownCheck(check, GI_SARIAS_SONG); + Randomizer_GetItemIdFromKnownCheck(check, GI_SARIAS_SONG); if (saria->actor.parent != NULL && saria->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1F)) { diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index 332aefc0ba..859afb4063 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -1035,7 +1035,7 @@ void EnSkj_SariaSongTalk(EnSkj* this, GlobalContext* globalCtx) { EnSkj_SetupWaitInRange(this); } else { func_80AFFE24(this); - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } @@ -1050,7 +1050,7 @@ void func_80AFFE44(EnSkj* this, GlobalContext* globalCtx) { this->actor.parent = NULL; EnSkj_SetupPostSariasSong(this); } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LW_SKULL_KID, GI_HEART_PIECE) : GI_HEART_PIECE, EnSkj_GetItemXzRange(this), EnSkj_GetItemYRange(this)); } } @@ -1529,7 +1529,7 @@ void EnSkj_WaitToGiveReward(EnSkj* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(globalCtx)) { func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3 - ? GetRandomizedItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) + ? Randomizer_GetItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) : sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); @@ -1544,7 +1544,7 @@ void EnSkj_GiveOcarinaGameReward(EnSkj* this, GlobalContext* globalCtx) { } else { func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag && gSaveContext.ocarinaGameRoundNum != 3 - ? GetRandomizedItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) + ? Randomizer_GetItemIdFromKnownCheck(RC_LW_OCARINA_MEMORY_GAME, GI_HEART_PIECE) : sOcarinaGameRewards[gSaveContext.ocarinaGameRoundNum], 26.0f, 26.0f); } diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index d48aedc77b..b01c6b8c42 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -245,19 +245,19 @@ void EnSth_GivePlayerItem(EnSth* this, GlobalContext* globalCtx) { case GI_RUPEE_GOLD: break; case GI_WALLET_ADULT: - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_10_GOLD_SKULLTULA_REWARD, GI_WALLET_ADULT); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_10_GOLD_SKULLTULA_REWARD, GI_WALLET_ADULT); break; case GI_STONE_OF_AGONY: - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_20_GOLD_SKULLTULA_REWARD, GI_STONE_OF_AGONY); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_20_GOLD_SKULLTULA_REWARD, GI_STONE_OF_AGONY); break; case GI_WALLET_GIANT: - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_30_GOLD_SKULLTULA_REWARD, GI_WALLET_GIANT); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_30_GOLD_SKULLTULA_REWARD, GI_WALLET_GIANT); break; case GI_BOMBCHUS_10: - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_40_GOLD_SKULLTULA_REWARD, GI_BOMBCHUS_10); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_40_GOLD_SKULLTULA_REWARD, GI_BOMBCHUS_10); break; case GI_HEART_PIECE: - getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_50_GOLD_SKULLTULA_REWARD, GI_HEART_PIECE); + getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_50_GOLD_SKULLTULA_REWARD, GI_HEART_PIECE); break; } } else { diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 4f779cd0a1..7b57bea89a 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -336,7 +336,7 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) { this->actor.parent = NULL; if (!LINK_IS_ADULT) { if(gSaveContext.n64ddFlag && !Flags_GetTreasure(globalCtx, 0x1E)) { - this->getItemId = GetRandomizedItemIdFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50); + this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_MARKET_SHOOTING_GALLERY_REWARD, GI_BULLET_BAG_50); Flags_SetTreasure(globalCtx, 0x1E); } else if (!gSaveContext.n64ddFlag && !(gSaveContext.itemGetInf[0] & 0x2000)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Pachinko ☆☆☆☆☆ %d\n" VT_RST, @@ -351,7 +351,7 @@ void EnSyatekiMan_EndGame(EnSyatekiMan* this, GlobalContext* globalCtx) { } } else { if(gSaveContext.n64ddFlag && !Flags_GetTreasure(globalCtx, 0x1F)) { - this->getItemId = GetRandomizedItemIdFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50); + this->getItemId = Randomizer_GetItemIdFromKnownCheck(RC_KAK_SHOOTING_GALLERY_REWARD, GI_QUIVER_50); Flags_SetTreasure(globalCtx, 0x1F); } else if (!gSaveContext.n64ddFlag && !(gSaveContext.itemGetInf[0] & 0x4000)) { osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ Equip_Bow ☆☆☆☆☆ %d\n" VT_RST, diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index e9f23176c0..dad7d25e5f 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -883,7 +883,7 @@ void func_80B15F54(EnTa* this, GlobalContext* globalCtx) { Message_CloseTextbox(globalCtx); this->unk_2E0 &= ~0x2; func_80B13AA0(this, func_80B15E80, func_80B16938); - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? GetRandomizedItemIdFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE) : GI_MILK_BOTTLE, 10000.0f, 50.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? Randomizer_GetItemIdFromKnownCheck(RC_LLR_TALONS_CHICKENS, GI_MILK_BOTTLE) : GI_MILK_BOTTLE, 10000.0f, 50.0f); } } diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index e4ccbf4a35..88ce05819f 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -292,7 +292,7 @@ void GivePlayerRandoRewardSheikSong(EnXc* sheik, GlobalContext* globalCtx, Rando !(gSaveContext.eventChkInf[5] & sheikType)) { gSaveContext.eventChkInf[5] |= sheikType; } else if (!(gSaveContext.eventChkInf[5] & sheikType)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, ogSongId); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, ogSongId); if (check == RC_SHEIK_AT_TEMPLE && !Flags_GetTreasure(globalCtx, 0x1F)) { if (func_8002F434(&sheik->actor, globalCtx, getItemId, 10000.0f, 100.0f)) { Flags_SetTreasure(globalCtx, 0x1F); diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index 87574aa56d..d4250fca21 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -231,9 +231,9 @@ void GivePlayerRandoRewardZeldaChild(EnZl4* zelda, GlobalContext* globalCtx, Ran if (zelda->actor.parent != NULL && zelda->actor.parent->id == GET_PLAYER(globalCtx)->actor.id && !Flags_GetTreasure(globalCtx, 0x1E)) { Flags_SetTreasure(globalCtx, 0x1E); - } else if (!Flags_GetTreasure(globalCtx, 0x1E) && !GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA) && Actor_TextboxIsClosing(&zelda->actor, globalCtx) && + } else if (!Flags_GetTreasure(globalCtx, 0x1E) && !Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA) && Actor_TextboxIsClosing(&zelda->actor, globalCtx) && (globalCtx->msgCtx.textId == 0x703C || globalCtx->msgCtx.textId == 0x703D)) { - GetItemID getItemId = GetRandomizedItemIdFromKnownCheck(check, GI_LETTER_ZELDA); + GetItemID getItemId = Randomizer_GetItemIdFromKnownCheck(check, GI_LETTER_ZELDA); func_8002F434(&zelda->actor, globalCtx, getItemId, 10000.0f, 100.0f); } else if (Flags_GetTreasure(globalCtx, 0x1E) && !Player_InBlockingCsMode(globalCtx, GET_PLAYER(globalCtx))) { gSaveContext.unk_13EE = 0x32; diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 8666ca3028..eb7c0a20a5 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -5044,7 +5044,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { HIGH_SCORE(HS_FISHING) |= 0x400; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; getItemId = gSaveContext.n64ddFlag ? - GetRandomizedItemIdFromKnownCheck(RC_LH_CHILD_FISHING, GI_HEART_PIECE) : + Randomizer_GetItemIdFromKnownCheck(RC_LH_CHILD_FISHING, GI_HEART_PIECE) : GI_HEART_PIECE; } } @@ -5054,7 +5054,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { HIGH_SCORE(HS_FISHING) |= 0x800; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; getItemId = gSaveContext.n64ddFlag ? - GetRandomizedItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD) : + Randomizer_GetItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD) : GI_SCALE_GOLD; } } @@ -5130,7 +5130,7 @@ void Fishing_HandleOwnerDialog(Fishing* this, GlobalContext* globalCtx) { func_8002F434(&this->actor, globalCtx, GI_SCALE_GOLD, 2000.0f, 1000.0f); } else { func_8002F434(&this->actor, globalCtx, - GetRandomizedItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD), 2000.0f, + Randomizer_GetItemIdFromKnownCheck(RC_LH_ADULT_FISHING, GI_SCALE_GOLD), 2000.0f, 1000.0f); } } diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index 17404ab77f..e32ab216f3 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -60,7 +60,7 @@ void ItemBHeart_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_Kill(&this->actor); } else { if (gSaveContext.n64ddFlag) { - s32 getItemId = GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum); + s32 getItemId = Randomizer_GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum); func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 40.0f); } else { func_8002F434(&this->actor, globalCtx, GI_HEART_CONTAINER_2, 30.0f, 40.0f); @@ -100,7 +100,7 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { GetItem_Draw(globalCtx, - GetItemModelFromId(GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum))); + Randomizer_GetItemModelFromId(Randomizer_GetRandomizedItemId(GI_HEART_CONTAINER_2, this->actor.id, this->actor.params, globalCtx->sceneNum))); } else { if (flag) { func_80093D84(globalCtx->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index f1575306bf..cfa115dafc 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -133,7 +133,7 @@ void func_80B85824(ItemEtcetera* this, GlobalContext* globalCtx) { Actor_Kill(&this->actor); } else { if (gSaveContext.n64ddFlag) { - s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); + s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 50.0f); } else { func_8002F434(&this->actor, globalCtx, this->getItemId, 30.0f, 50.0f); @@ -156,7 +156,7 @@ void func_80B858B4(ItemEtcetera* this, GlobalContext* globalCtx) { if (0) {} // Necessary to match if (gSaveContext.n64ddFlag) { - s32 getItemId = GetRandomizedItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); + s32 getItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); func_8002F434(&this->actor, globalCtx, getItemId, 30.0f, 50.0f); } else { func_8002F434(&this->actor, globalCtx, this->getItemId, 30.0f, 50.0f); @@ -234,7 +234,7 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, GlobalContext* globalCtx) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); } if (randoGetItemId != GI_NONE) { - GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId)); + GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); return; } } @@ -250,9 +250,9 @@ void ItemEtcetera_Draw(Actor* thisx, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { s32 randoGetItemId = GI_NONE; if (type == ITEM_ETC_ARROW_FIRE) { - randoGetItemId = GetRandomizedItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); + randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE); } else if (type == ITEM_ETC_LETTER) { - randoGetItemId = GetRandomizedItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); + randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO); } if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) { @@ -260,7 +260,7 @@ void ItemEtcetera_Draw(Actor* thisx, GlobalContext* globalCtx) { } if (randoGetItemId != GI_NONE) { - this->giDrawId = GetItemModelFromId(randoGetItemId); + this->giDrawId = Randomizer_GetItemModelFromId(randoGetItemId); } } diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index 0b3d9382c2..9992d08b3e 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -191,7 +191,7 @@ void ItemOcarina_WaitInWater(ItemOcarina* this, GlobalContext* globalCtx) { } else { func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag - ? GetRandomizedItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT) + ? Randomizer_GetItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT) : GI_OCARINA_OOT, 30.0f, 50.0f); @@ -214,11 +214,11 @@ void ItemOcarina_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8002ED80(thisx, globalCtx, 0); if (gSaveContext.n64ddFlag) { - s32 randoGetItemId = GetRandomizedItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); + s32 randoGetItemId = Randomizer_GetItemIdFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT); if (randoGetItemId >= GI_MINUET_OF_FOREST && randoGetItemId <= GI_DOUBLE_DEFENSE) { EnItem00_CustomItemsParticles(&this->actor, globalCtx, randoGetItemId); } - GetItem_Draw(globalCtx, GetItemModelFromId(randoGetItemId)); + GetItem_Draw(globalCtx, Randomizer_GetItemModelFromId(randoGetItemId)); return; } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 576f550c75..2aef4bc64f 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -431,9 +431,9 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { CVar_SetString("gDroppedFile", ""); fileSelectSpoilerFileLoaded = false; const char* fileLoc = CVar_GetString("gSpoilerLog", ""); - LoadRandomizerSettings(fileLoc); - LoadHintLocations(fileLoc); - LoadItemLocations(fileLoc, silent); + Randomizer_LoadSettings(fileLoc); + Randomizer_LoadHintLocations(fileLoc); + Randomizer_LoadItemLocations(fileLoc, silent); fileSelectSpoilerFileLoaded = true; } @@ -1740,9 +1740,9 @@ void FileChoose_LoadGame(GameState* thisx) { this->state.running = false; } - LoadRandomizerSettings(""); - LoadHintLocations(""); - LoadItemLocations("", true); + Randomizer_LoadSettings(""); + Randomizer_LoadHintLocations(""); + Randomizer_LoadItemLocations("", true); gSaveContext.respawn[0].entranceIndex = -1; gSaveContext.respawnFlag = 0; From 2daddd8a5a568dd37f6af8cac81bcbd34c53da30 Mon Sep 17 00:00:00 2001 From: KiritoDev <36680385+KiritoDv@users.noreply.github.com> Date: Mon, 18 Jul 2022 18:21:31 -0500 Subject: [PATCH 23/38] Added renderer api switch dropdown (#775) * Added renderer api switch * Joined backend api and names into a pair * Added close button on input editor --- libultraship/libultraship/ImGuiImpl.cpp | 40 +++++++++++++++++++++++ libultraship/libultraship/InputEditor.cpp | 4 ++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index 153a193e8d..ff04133cef 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -68,6 +68,7 @@ namespace SohImGui { static ImVector s_GroupPanelLabelStack; bool p_open = false; bool needs_save = false; + int lastBackendID = 0; const char* filters[3] = { "Three-Point", @@ -75,6 +76,14 @@ namespace SohImGui { "None" }; + std::pair backends[] = { +#ifdef _WIN32 + { "dx11", "DirectX" }, +#endif + { "sdl", "OpenGL" } + }; + + const char* powers[9] = { "Vanilla (1x)", "Double (2x)", @@ -91,6 +100,21 @@ namespace SohImGui { std::map> windowCategories; std::map customWindows; + int GetBackendID(std::shared_ptr cfg) { + std::string backend = cfg->getString("Window.GfxBackend"); + if (backend.empty()) { + return 0; + } + + for (size_t i = 0; i < (sizeof(backends) / sizeof(backends[0])); i++) { + if(backend == backends[i].first) { + return i; + } + } + + return 0; + } + int ClampFloatToInt(float value, int min, int max) { return fmin(fmax(value, min), max); } @@ -315,6 +339,8 @@ namespace SohImGui { io = &ImGui::GetIO(); io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; io->Fonts->AddFontDefault(); + + lastBackendID = GetBackendID(GlobalCtx2::GetInstance()->GetConfig()); if (CVar_GetS32("gOpenMenuBar", 0) != 1) { SohImGui::overlay->TextDrawNotification(30.0f, true, "Press F1 to access enhancements menu"); } @@ -653,6 +679,8 @@ namespace SohImGui { ImGui::NewFrame(); const std::shared_ptr wnd = GlobalCtx2::GetInstance()->GetWindow(); + const std::shared_ptr pConf = GlobalCtx2::GetInstance()->GetConfig(); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize; @@ -822,6 +850,18 @@ namespace SohImGui { "to do CPU + GPU work in time."); } + + ImGui::Text("Renderer API (Needs reload)"); + if (ImGui::BeginCombo("##RApi", backends[lastBackendID].second)) { + for (uint8_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) { + if (ImGui::Selectable(backends[i].second, i == lastBackendID)) { + pConf->setString("Window.GfxBackend", backends[i].first); + lastBackendID = i; + } + } + ImGui::EndCombo(); + } + EXPERIMENTAL(); ImGui::Text("Texture Filter (Needs reload)"); EnhancementCombobox("gTextureFilter", filters, 3, 0); diff --git a/libultraship/libultraship/InputEditor.cpp b/libultraship/libultraship/InputEditor.cpp index 0d170e305e..f03e94d57a 100644 --- a/libultraship/libultraship/InputEditor.cpp +++ b/libultraship/libultraship/InputEditor.cpp @@ -5,6 +5,7 @@ #include "ImGuiImpl.h" #include "Utils/StringHelper.h" #include "Lib/ImGui/imgui_internal.h" +#include "Cvar.h" namespace Ship { @@ -249,13 +250,14 @@ namespace Ship { if (!this->Opened) { BtnReading = -1; + CVar_SetS32("gControllerConfigurationEnabled", 0); return; } ImGui::SetNextWindowSizeConstraints(ImVec2(641, 250), ImVec2(1200, 290)); //OTRTODO: Disable this stupid workaround ( ReadRawPress() only works when the window is on the main viewport ) ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); - ImGui::Begin("Controller Configuration", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); + ImGui::Begin("Controller Configuration", &this->Opened, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); ImGui::BeginTabBar("##Controllers"); From 10cb23ad74251907de9830dc626763af143fd81f Mon Sep 17 00:00:00 2001 From: qurious-pixel <62252937+qurious-pixel@users.noreply.github.com> Date: Mon, 18 Jul 2022 16:21:47 -0700 Subject: [PATCH 24/38] [APPIMAGE] LibFuse removal fix (#780) * [APPIMAGE] LibFuse removal fix * [APPIMAGE] LibFuse 2 fix Keep Original App name --- appimage/appimage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appimage/appimage.sh b/appimage/appimage.sh index 2914d0ae64..7ac03934e7 100755 --- a/appimage/appimage.sh +++ b/appimage/appimage.sh @@ -2,8 +2,8 @@ curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" chmod a+x linuxdeploy*.AppImage -curl -sSfLO "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage" -chmod a+x appimagetool*.AppImage +curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/releases | grep "mkappimage-.*-x86_64.AppImage" | head -n 1 | cut -d '"' -f 2) -o mkappimage.AppImage +chmod a+x mkappimage.AppImage mkdir -p AppDir/usr/bin cp appimage/{soh.desktop,soh.sh} AppDir/ @@ -30,5 +30,5 @@ export UPD_INFO="gh-releases-zsync|HarbourMasters|Shipwright-linux|develop|SOH-L cd /soh -./appimagetool-x86_64.AppImage --appimage-extract-and-run ./AppDir "SOH-Linux.AppImage" - +VERSION=Linux ./mkappimage.AppImage --appimage-extract-and-run ./AppDir # "SOH-Linux-x86_64.AppImage" +mv SOH-Linux-x86_64.AppImage SOH-Linux.AppImage # Keep Original Name From 9e8335c1f03eb25e8cc58a45f8e2d8d84552ca40 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:22:12 -0400 Subject: [PATCH 25/38] fix non-rando non-3d-drops small key crash (#789) Co-authored-by: briaguya --- soh/src/code/z_en_item00.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index baa49020a1..51870bc17d 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -1297,7 +1297,7 @@ void EnItem00_DrawRupee(EnItem00* this, GlobalContext* globalCtx) { * Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...). */ void EnItem00_DrawCollectible(EnItem00* this, GlobalContext* globalCtx) { - if ((gSaveContext.n64ddFlag && this->getItemId != GI_NONE) || this->actor.params == ITEM00_SMALL_KEY) { + if (gSaveContext.n64ddFlag && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { f32 mtxScale = 16.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); s32 randoGetItemId = Randomizer_GetRandomizedItemId(this->getItemId, this->actor.id, this->ogParams, globalCtx->sceneNum); From c65a40f432d8de9e34d8d65cd579257ef4dfec9c Mon Sep 17 00:00:00 2001 From: Ada <60364512+GreatArgorath@users.noreply.github.com> Date: Tue, 19 Jul 2022 00:23:28 +0100 Subject: [PATCH 26/38] Adds tooltip to free camera (#795) --- libultraship/libultraship/ImGuiImpl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index ff04133cef..aa74685d4d 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -1202,6 +1202,7 @@ namespace SohImGui { Tooltip("Holding down B skips text\nKnown to cause a cutscene softlock in Water Temple\nSoftlock can be fixed by pressing D-Right in Debug mode"); EnhancementCheckbox("Free Camera", "gFreeCamera"); + Tooltip("Enables camera control\nNote: You must remap C buttons off of\nthe right stick in the controller\nconfig menu, and map the camera stick\nto the right stick."); ImGui::EndMenu(); } From cc28a1444deba8ad341df7c9fefdd7c373647a03 Mon Sep 17 00:00:00 2001 From: Ada <60364512+GreatArgorath@users.noreply.github.com> Date: Tue, 19 Jul 2022 00:24:20 +0100 Subject: [PATCH 27/38] Update README.md (#796) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f07f45e38..8546d6ea75 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Other shortcuts: | Alt+Enter | Fullscreen (DirectX) | | Ctrl+R | Reset | -Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX. +Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.json` configuration file in notepad and add `sdl` to the quotes in `"GfxBackend": ""` for OpenGL or leave blank for DirectX. ## Take The Survey Want to use cartridge readers in tandem with the OTRGui? From 9118788149ba6001393ddacedf9fc5098c06c578 Mon Sep 17 00:00:00 2001 From: PurpleHato Date: Tue, 19 Jul 2022 01:24:56 +0200 Subject: [PATCH 28/38] ADD: SaveEditor Edit current D-Pad Item (#799) * ADD: Dapd on "current Dpad equip * TWEAK: Spelling * TWEAK: Shows it only if gDpadEquips is enable * TWEAK: Forgot one "D-pad" * TWEAK: Spacing --- soh/soh/Enhancements/debugger/debugSaveEditor.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 60c3e6c4e3..f31a5e42ad 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1561,6 +1561,18 @@ void DrawPlayerTab() { ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL); ImGui::SameLine(); ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL); + + if (CVar_GetS32("gDpadEquips", 0)) { + ImGui::NewLine(); + ImGui::Text("Current D-pad Equips"); + ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); // Two spaces at the end for aligning, not elegant but it's working + ImGui::SameLine(); + ImGui::InputScalar("D-pad Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[5], &one, NULL); + // Intentionnal to not put everything on the same line, else it's taking too much for lower resolution. + ImGui::InputScalar("D-pad Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[6], &one, NULL); + ImGui::SameLine(); + ImGui::InputScalar("D-pad Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[7], &one, NULL); + } }); } else { From 5e5e57ea8feb8f8535d8612d10678cc5d1601fbb Mon Sep 17 00:00:00 2001 From: Josh Bodner <30329717+jbodner09@users.noreply.github.com> Date: Mon, 18 Jul 2022 16:25:11 -0700 Subject: [PATCH 29/38] Add Windows x64 build instruction (#800) --- BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index 5999f1eb9d..1821f2bc30 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -12,7 +12,7 @@ 8. Build the solution. 9. Launching `OTRExporter/extract_assets.py` will generate an `oot.otr` archive file in `OTRExporter/oot.otr`. 10. Run `soh/soh.sln` - 11. Switch the solution to `Release x86`. + 11. Switch the solution to `Release x86` or `Release x64`. 12. Build the solution. 13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`. 14. Launch `soh.exe`. From 9679075cbaf05e680bcca3688186cc167dc68647 Mon Sep 17 00:00:00 2001 From: Baoulettes Date: Tue, 19 Jul 2022 01:26:01 +0200 Subject: [PATCH 30/38] - + button optionnal for Int and float sliders (#803) --- libultraship/libultraship/ImGuiImpl.cpp | 106 +++++++++++++++++++++--- libultraship/libultraship/ImGuiImpl.h | 4 +- 2 files changed, 96 insertions(+), 14 deletions(-) diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index aa74685d4d..b9ce62aee9 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -477,11 +477,21 @@ namespace SohImGui { } } - void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue) + void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue, bool PlusMinusButton) { int val = CVar_GetS32(cvarName, defaultValue); - ImGui::Text(text, val); + if(PlusMinusButton) { + std::string MinusBTNName = " - ##"; + MinusBTNName += cvarName; + if (ImGui::Button(MinusBTNName.c_str())) { + val--; + CVar_SetS32(cvarName, val); + needs_save = true; + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + } if (ImGui::SliderInt(id, &val, min, max, format)) { @@ -489,6 +499,18 @@ namespace SohImGui { needs_save = true; } + if(PlusMinusButton) { + std::string PlusBTNName = " + ##"; + PlusBTNName += cvarName; + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNName.c_str())) { + val++; + CVar_SetS32(cvarName, val); + needs_save = true; + } + } + if (val < min) { val = min; @@ -504,7 +526,7 @@ namespace SohImGui { } } - void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage) + void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton) { float val = CVar_GetFloat(cvarName, defaultValue); @@ -513,12 +535,36 @@ namespace SohImGui { else ImGui::Text(text, static_cast(100 * val)); + if(PlusMinusButton) { + std::string MinusBTNName = " - ##"; + MinusBTNName += cvarName; + if (ImGui::Button(MinusBTNName.c_str())) { + val -= 0.1f; + CVar_SetFloat(cvarName, val); + needs_save = true; + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + } + if (ImGui::SliderFloat(id, &val, min, max, format)) { CVar_SetFloat(cvarName, val); needs_save = true; } + if(PlusMinusButton) { + std::string PlusBTNName = " + ##"; + PlusBTNName += cvarName; + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNName.c_str())) { + val += 0.1f; + CVar_SetFloat(cvarName, val); + needs_save = true; + } + } + if (val < min) { val = min; @@ -836,6 +882,16 @@ namespace SohImGui { ImGui::Text("Jitter fix: >= %d FPS", fps); } + std::string MinusBTNELT = " - ##ExtraLatencyThreshold"; + std::string PlusBTNELT = " + ##ExtraLatencyThreshold"; + if (ImGui::Button(MinusBTNELT.c_str())) { + val--; + CVar_SetS32(cvar, val); + needs_save = true; + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::SliderInt("##ExtraLatencyThreshold", &val, 0, 250, "", ImGuiSliderFlags_AlwaysClamp)) { CVar_SetS32(cvar, val); @@ -848,6 +904,14 @@ namespace SohImGui { "to work on one frame while GPU works on the previous frame.\n" "This setting should be used when your computer is too slow\n" "to do CPU + GPU work in time."); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNELT.c_str())) { + val++; + CVar_SetS32(cvar, val); + needs_save = true; + } } @@ -955,54 +1019,54 @@ namespace SohImGui { { EnhancementCheckbox("Change Red Potion Effect", "gRedPotionEffect"); Tooltip("Enable the following changes to the amount of health restored by Red Potions"); - EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, ""); + EnhancementSliderInt("Red Potion Health: %d", "##REDPOTIONHEALTH", "gRedPotionHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Red Potions"); EnhancementCheckbox("Red Potion Percent Restore", "gRedPercentRestore"); Tooltip("Toggles from Red Potions restoring a fixed amount of health to a percent of the player's current max health"); EnhancementCheckbox("Change Green Potion Effect", "gGreenPotionEffect"); Tooltip("Enable the following changes to the amount of mana restored by Green Potions"); - EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, ""); + EnhancementSliderInt("Green Potion Mana: %d", "##GREENPOTIONMANA", "gGreenPotionMana", 1, 100, "", 0, true); Tooltip("Changes the amount of mana restored by Green Potions, base max mana is 48, max upgraded mana is 96"); EnhancementCheckbox("Green Potion Percent Restore", "gGreenPercentRestore"); Tooltip("Toggles from Green Potions restoring a fixed amount of mana to a percent of the player's current max mana"); EnhancementCheckbox("Change Blue Potion Effects", "gBluePotionEffects"); Tooltip("Enable the following changes to the amount of health and mana restored by Blue Potions"); - EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, ""); + EnhancementSliderInt("Blue Potion Health: %d", "##BLUEPOTIONHEALTH", "gBluePotionHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Blue Potions"); EnhancementCheckbox("Blue Potion Health Percent Restore", "gBlueHealthPercentRestore"); Tooltip("Toggles from Blue Potions restoring a fixed amount of health to a percent of the player's current max health"); - EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, ""); + EnhancementSliderInt("Blue Potion Mana: %d", "##BLUEPOTIONMANA", "gBluePotionMana", 1, 100, "", 0, true); Tooltip("Changes the amount of mana restored by Blue Potions, base max mana is 48, max upgraded mana is 96"); EnhancementCheckbox("Blue Potion Mana Percent Restore", "gBlueManaPercentRestore"); Tooltip("Toggles from Blue Potions restoring a fixed amount of mana to a percent of the player's current max mana"); EnhancementCheckbox("Change Milk Effect", "gMilkEffect"); Tooltip("Enable the following changes to the amount of health restored by Milk"); - EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, ""); + EnhancementSliderInt("Milk Health: %d", "##MILKHEALTH", "gMilkHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Milk"); EnhancementCheckbox("Milk Percent Restore", "gMilkPercentRestore"); Tooltip("Toggles from Milk restoring a fixed amount of health to a percent of the player's current max health"); EnhancementCheckbox("Separate Half Milk Effect", "gSeparateHalfMilkEffect"); Tooltip("Enable the following changes to the amount of health restored by Half Milk\nIf this is disabled, Half Milk will behave the same as Full Milk."); - EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, ""); + EnhancementSliderInt("Half Milk Health: %d", "##HALFMILKHEALTH", "gHalfMilkHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Half Milk"); EnhancementCheckbox("Half Milk Percent Restore", "gHalfMilkPercentRestore"); Tooltip("Toggles from Half Milk restoring a fixed amount of health to a percent of the player's current max health"); EnhancementCheckbox("Change Fairy Effect", "gFairyEffect"); Tooltip("Enable the following changes to the amount of health restored by Fairies"); - EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, ""); + EnhancementSliderInt("Fairy: %d", "##FAIRYHEALTH", "gFairyHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Fairies"); EnhancementCheckbox("Fairy Percent Restore", "gFairyPercentRestore"); Tooltip("Toggles from Fairies restoring a fixed amount of health to a percent of the player's current max health"); EnhancementCheckbox("Change Fairy Revive Effect", "gFairyReviveEffect"); Tooltip("Enable the following changes to the amount of health restored by Fairy Revivals"); - EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, ""); + EnhancementSliderInt("Fairy Revival: %d", "##FAIRYREVIVEHEALTH", "gFairyReviveHealth", 1, 100, "", 0, true); Tooltip("Changes the amount of health restored by Fairy Revivals"); EnhancementCheckbox("Fairy Revive Percent Restore", "gFairyRevivePercentRestore"); Tooltip("Toggles from Fairy Revivals restoring a fixed amount of health to a percent of the player's current max health"); @@ -1091,7 +1155,7 @@ namespace SohImGui { EnhancementRadioButton("Random cycle", "gPauseLiveLink", 16); Tooltip("Randomize the animation played on the menu after a certain time"); if (CVar_GetS32("gPauseLiveLink", 0) >= 16) { - EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, ""); + EnhancementSliderInt("Frame to wait: %d", "##MinFrameCount", "gMinFrameCount", 1, 1000, "", 0, true); } ImGui::EndMenu(); @@ -1163,6 +1227,16 @@ namespace SohImGui { ImGui::Text("Frame interpolation: %d FPS", fps); } + std::string MinusBTNFPSI = " - ##FPSInterpolation"; + std::string PlusBTNFPSI = " + ##FPSInterpolation"; + if (ImGui::Button(MinusBTNFPSI.c_str())) { + val--; + CVar_SetS32(fps_cvar, val); + needs_save = true; + } + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::SliderInt("##FPSInterpolation", &val, 20, 250, "", ImGuiSliderFlags_AlwaysClamp)) { CVar_SetS32(fps_cvar, val); @@ -1175,6 +1249,14 @@ namespace SohImGui { "and might give a worse result.\n" "For consistent input lag, set this value and your monitor's refresh rate to a multiple of 20\n" "Ctrl+Click for keyboard input"); + + ImGui::SameLine(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + if (ImGui::Button(PlusBTNFPSI.c_str())) { + val++; + CVar_SetS32(fps_cvar, val); + needs_save = true; + } } if (impl.backend == Backend::DX11) { diff --git a/libultraship/libultraship/ImGuiImpl.h b/libultraship/libultraship/ImGuiImpl.h index 1b2ba06c12..580d5cdb61 100644 --- a/libultraship/libultraship/ImGuiImpl.h +++ b/libultraship/libultraship/ImGuiImpl.h @@ -70,8 +70,8 @@ namespace SohImGui { void EnhancementRadioButton(const char* text, const char* cvarName, int id); void EnhancementCheckbox(const char* text, const char* cvarName); void EnhancementButton(const char* text, const char* cvarName); - void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0); - void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage); + void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format, int defaultValue = 0, bool PlusMinusButton = false); + void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage, bool PlusMinusButton = false); void EnhancementCombobox(const char* name, const char* ComboArray[], size_t arraySize, uint8_t FirstTimeValue); void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false); void EnhancementCombo(const std::string& name, const char* cvarName, const std::vector& items, int defaultValue = 0); From 37afdbd84c51c9dd1f6742f414c617640a9958c8 Mon Sep 17 00:00:00 2001 From: David Chavez Date: Tue, 19 Jul 2022 01:28:12 +0200 Subject: [PATCH 31/38] Fix: Respect Config Window Resolution (#807) * Fix regression witn using config window res * Fix fullscreen presets --- libultraship/libultraship/Window.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index b8f8957c40..9d28ecf5eb 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -212,8 +212,8 @@ namespace Ship { pConf->setString("Window.GfxBackend", ""); pConf->setBool("Window.Fullscreen.Enabled", false); - pConf->setInt("Window.Fullscreen.Width", 640); - pConf->setInt("Window.Fullscreen.Height", 480); + pConf->setInt("Window.Fullscreen.Width", 1920); + pConf->setInt("Window.Fullscreen.Height", 1080); pConf->setString("Game.SaveName", ""); pConf->setString("Game.Main Archive", ""); @@ -233,8 +233,14 @@ namespace Ship { SetAudioPlayer(); bIsFullscreen = pConf->getBool("Window.Fullscreen.Enabled", false); - dwWidth = pConf->getInt("Window.Fullscreen.Width", bIsFullscreen ? 1920 : 640); - dwHeight = pConf->getInt("Window.Fullscreen.Height", bIsFullscreen ? 1080 : 480); + if (bIsFullscreen) { + dwWidth = pConf->getInt("Window.Fullscreen.Width", 1920); + dwHeight = pConf->getInt("Window.Fullscreen.Height", 1080); + } else { + dwWidth = pConf->getInt("Window.Width", 640); + dwHeight = pConf->getInt("Window.Height", 480); + } + dwMenubar = pConf->getBool("Window.Options", false); const std::string& gfx_backend = pConf->getString("Window.GfxBackend"); SetWindowManager(&WmApi, &RenderingApi, gfx_backend); From 660897ff63eed203d7759d3fa4b8039f9730e8d3 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 19 Jul 2022 01:29:24 +0200 Subject: [PATCH 32/38] Avoid UB on ocarinaAction shifts (#809) --- soh/src/code/z_message_PAL.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 9631c5a123..79326ee81b 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2237,14 +2237,14 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) { } } else { osSyncPrintf("Na_StartOcarinaSinglePlayCheck2( message->ocarina_no );\n"); - func_800ECC04((1 << msgCtx->ocarinaAction) + 0x8000); + func_800ECC04((1 << (msgCtx->ocarinaAction % 32)) + 0x8000); } msgCtx->msgMode = MSGMODE_OCARINA_PLAYING; } else if (msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION_STARTING) { msgCtx->stateTimer = 20; msgCtx->msgMode = MSGMODE_SONG_DEMONSTRATION_SELECT_INSTRUMENT; } else { - func_800ECC04((1 << (msgCtx->ocarinaAction + 0x11)) + 0x8000); + func_800ECC04((1 << ((msgCtx->ocarinaAction + 0x11) % 32)) + 0x8000); // "Performance Check" osSyncPrintf("演奏チェック=%d\n", msgCtx->ocarinaAction - OCARINA_ACTION_PLAYBACK_MINUET); msgCtx->msgMode = MSGMODE_SONG_PLAYBACK; From 4745f73655a42ce53f889c091808bbba1eacc142 Mon Sep 17 00:00:00 2001 From: David Chavez Date: Tue, 19 Jul 2022 01:30:29 +0200 Subject: [PATCH 33/38] [macOS] Bring support down to macOS 10.15 (#816) * Pull out CC and CXX flags * Set minimum deployment target * Update version to 3.0.0 --- Jenkinsfile | 9 +++++++-- soh/macosx/Info.plist | 8 ++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8ea6317a45..7f3589ec84 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -125,6 +125,11 @@ pipeline { agent { label "SoH-Mac-Builders" } + environment { + CC = 'clang -arch arm64 -arch x86_64' + CXX = 'clang++ -arch arm64 -arch x86_64' + MACOSX_DEPLOYMENT_TARGET = 10.15 + } steps { checkout([ $class: 'GitSCM', @@ -137,8 +142,8 @@ pipeline { sh ''' cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64 cd soh - export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld" - export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld" + make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld" + make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld" make -j4 appbundle mv ../README.md readme.txt 7z a soh-mac.7z soh.app readme.txt diff --git a/soh/macosx/Info.plist b/soh/macosx/Info.plist index f657ef6578..d42198f02f 100644 --- a/soh/macosx/Info.plist +++ b/soh/macosx/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable soh CFBundleGetInfoString - 2.0.0 + 3.0.0 CFBundleIconFile soh.icns CFBundleIdentifier @@ -22,14 +22,14 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.0 + 3.0.0 CFBundleSignature ZOoT CFBundleVersion - 2.0.0 + 3.0.0 NSHumanReadableCopyright Copyright 2022 HarbourMasters. LSMinimumSystemVersion - 10.3 + 10.15 From 169f757954bcfe788ee72b64b03b9650cd3dec17 Mon Sep 17 00:00:00 2001 From: Christopher Leggett Date: Mon, 18 Jul 2022 19:31:04 -0400 Subject: [PATCH 34/38] Fixes ice trap chests to have short chest animations (#817) --- soh/src/overlays/actors/ovl_player_actor/z_player.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 1973a09a44..1f1d09a8db 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -620,7 +620,7 @@ static GetItemEntry sGetItemTable[] = { GET_ITEM(ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT), GET_ITEM(ITEM_BULLET_BAG_50, OBJECT_GI_DEKUPOUCH, GID_BULLET_BAG_50, 0x6C, 0x80, CHEST_ANIM_LONG), - GET_ITEM(ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x3C, 0x80, CHEST_ANIM_LONG), // Ice Traps + GET_ITEM(ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x3C, 0x80, CHEST_ANIM_SHORT), // Ice Traps GET_ITEM_NONE, GET_ITEM(ITEM_MEDALLION_LIGHT, OBJECT_GI_MEDAL, GID_MEDALLION_LIGHT, 0x40, 0x80, CHEST_ANIM_LONG), From edfa369639593ae48afa25d838cbdb4f972ea2bf Mon Sep 17 00:00:00 2001 From: Andrew Van Caem Date: Tue, 19 Jul 2022 09:31:52 +1000 Subject: [PATCH 35/38] Add yShift position when displaying the positions of cylinders (#823) --- soh/soh/Enhancements/debugger/colViewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 1cab6ef649..e98ff03995 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -529,7 +529,7 @@ void DrawColCheckList(std::vector& dl, Collider** objects, int32_t count) { Mtx m; MtxF mt; - SkinMatrix_SetTranslate(&mt, cyl->dim.pos.x, cyl->dim.pos.y, cyl->dim.pos.z); + SkinMatrix_SetTranslate(&mt, cyl->dim.pos.x, cyl->dim.pos.y + cyl->dim.yShift, cyl->dim.pos.z); MtxF ms; int32_t radius = cyl->dim.radius == 0 ? 1 : cyl->dim.radius; SkinMatrix_SetScale(&ms, radius / 128.0f, cyl->dim.height / 128.0f, radius / 128.0f); From 97d1f0e46c5f67af1d9b8f8dad60e1c9bdfc607a Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 19 Jul 2022 01:32:15 +0200 Subject: [PATCH 36/38] Fix ZAPDTR linking order for linux builds (#825) * Fix ZAPDTR linking order for linux builds * Fix linking on macos --- ZAPDTR/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ZAPDTR/Makefile b/ZAPDTR/Makefile index 755fd931aa..6d8ba354d4 100644 --- a/ZAPDTR/Makefile +++ b/ZAPDTR/Makefile @@ -45,8 +45,8 @@ ifneq ($(DEPRECATION_ON),0) endif # CXXFLAGS += -DTEXTURE_DEBUG -LDFLAGS := -lm -ldl \ - -L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm +LDFLAGS := -Llib/libgfxd -L../libultraship -L../StormLib/build \ + -pthread -lgfxd -lultraship ZAPDUtils/ZAPDUtils.a -lstorm -lbz2 -lm -ldl ifeq ($(UNAME), Darwin) LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation @@ -137,4 +137,4 @@ ZAPDUtils: # Linking ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils StormLib - $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a ../StormLib/build/libstorm.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION) + $(CXX) $(CXXFLAGS) $(O_FILES) $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION) From 046b7e8949ada491054d38a63d4e28c444b9dbf7 Mon Sep 17 00:00:00 2001 From: GaryOderNichts <12049776+GaryOderNichts@users.noreply.github.com> Date: Tue, 19 Jul 2022 01:33:36 +0200 Subject: [PATCH 37/38] Include game version in linux otr builds (#826) --- OTRExporter/extract_assets.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OTRExporter/extract_assets.py b/OTRExporter/extract_assets.py index 67b4ca6e45..6862fb0744 100755 --- a/OTRExporter/extract_assets.py +++ b/OTRExporter/extract_assets.py @@ -4,10 +4,15 @@ import os, sys, shutil import shutil from rom_info import Z64Rom import rom_chooser +import struct def BuildOTR(xmlPath, rom): shutil.copytree("assets", "Extract/assets") + checksum = int(Z64Rom(rom).checksum.value, 16) + with open("Extract/version", "wb") as f: + f.write(struct.pack(' Date: Mon, 18 Jul 2022 16:34:08 -0700 Subject: [PATCH 38/38] [APPIMAGE] Use GUI dialog boxes (#829) * [APPIMAGE] Use GUI dialog boxes * [APPIMAGE] Adjust timing --- appimage/soh.sh | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/appimage/soh.sh b/appimage/soh.sh index 21ddcd5aab..f3b563cc7a 100644 --- a/appimage/soh.sh +++ b/appimage/soh.sh @@ -3,6 +3,7 @@ HERE="$(dirname "$(readlink -f "${0}")")"/../.. export PATH="$HERE"/bin:"$HERE"/usr/bin:"$PATH" export LD_LIBRARY_PATH="$HERE"/usr/lib:"$LD_LIBRARY_PATH" +export ZENITY=$(command -v zenity) while [[ ! -e "$PWD"/oot.otr ]]; do export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)" @@ -14,16 +15,26 @@ while [[ ! -e "$PWD"/oot.otr ]]; do ln -s "$OLDPWD"/*.*64 "$ASSETDIR"/tmp/rom.z64 cp -r "$ASSETDIR"/assets/game/ship_of_harkinian "$ASSETDIR"/Extract/assets/ cd "$ASSETDIR" - case $(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') in + ROMHASH=$(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') + case "$ROMHASH" in cee6bc3c2a634b41728f2af8da54d9bf8cc14099) ROM=GC_NMQ_D;; 0227d7c0074f2d0ac935631990da8ec5914597b4) ROM=GC_NMQ_PAL_F;; *) - echo -e "\nrom hash does not match\n" + if [ -n "$ZENITY" ]; then + zenity --error --timeout=10 --text="ROM hash $ROMHASH does not match" --title="Incorrect ROM file" --width=500 --width=200 + else + echo -e "\nrom hash does not match\n" + fi exit;; esac - echo "Processing..." + if [ -n "$ZENITY" ]; then + (echo "# 25%"; echo "25"; sleep 2; echo "# 50%"; echo "50"; sleep 3; echo "# 75%"; echo "75"; sleep 2; echo "# 100%"; echo "100"; sleep 3) | + zenity --progress --title="OTR Generating..." --timeout=10 --percentage=0 --icon-name=soh --window-icon=soh.png --height=80 --width=400 & + else + echo "Processing..." + fi assets/extractor/ZAPD.out ed -eh -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR > /dev/null 2>&1 cp "$ASSETDIR"/oot.otr "$OLDPWD" echo "Restart $APPIMAGE to play!" @@ -31,7 +42,11 @@ while [[ ! -e "$PWD"/oot.otr ]]; do rm -r "$ASSETDIR" break else - echo -e "\nPlace ROM in this folder\n" + if [ -n "$ZENITY" ]; then + zenity --error --timeout=5 --text="Place ROM in $OWD" --title="Missing ROM file" --width=500 --width=200 + else + echo -e "\nPlace ROM in this folder\n" + fi exit fi done