Merge branch 'develop' into pausedpadnav

This commit is contained in:
Josh Bodner 2022-03-30 21:08:21 -07:00
commit bc1861a569
18 changed files with 371 additions and 119 deletions

View File

@ -18,6 +18,7 @@ Shader shader = { 0 };
Light light = { 0 }; Light light = { 0 };
Vector3 lightPos = { -5.0f, 10.0f, 10.0f }; Vector3 lightPos = { -5.0f, 10.0f, 10.0f };
Vector2 dragOffset; Vector2 dragOffset;
bool isDragging = false;
std::string sohFolder = NULLSTR; std::string sohFolder = NULLSTR;
bool extracting = false; bool extracting = false;
bool rom_ready = false; bool rom_ready = false;
@ -95,69 +96,101 @@ void OTRGame::update(){
} }
void OTRGame::draw() { void OTRGame::draw() {
Vector2 windowSize(GetScreenWidth(), GetScreenHeight());
Rectangle titlebar = Rectangle(0, 0, windowSize.x - 50, 35);
Vector2 mousePos = GetMousePosition();
Vector2 mouseDelta = GetMouseDelta();
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && !isDragging &&
mousePos.x >= titlebar.x && mousePos.y >= titlebar.y && mousePos.x <= titlebar.x + titlebar.width && mousePos.y <= titlebar.y + titlebar.height) {
isDragging = true;
dragOffset = mousePos;
}
else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && isDragging) {
isDragging = false;
dragOffset = Vector2(0, 0);
}
if (isDragging && (mouseDelta.x != 0.0f || mouseDelta.y != 0.0f)) {
Vector2 wndPos = GetWindowPosition();
wndPos = Vector2(wndPos.x + (mousePos.x - dragOffset.x), wndPos.y + (mousePos.y - dragOffset.y));
// Calculate virtual screen total size in case there are multiple monitors
int vsX1 = 0, vsY1 = 0, vsX2 = 0, vsY2 = 0;
int monitorCount = GetMonitorCount();
for (int m = 0; m < monitorCount; m++) {
Vector2 monitorPos = GetMonitorPosition(m);
Vector2 monitorSize = Vector2(GetMonitorWidth(m), GetMonitorHeight(m));
if (monitorPos.x < vsX1) vsX1 = monitorPos.x;
if (monitorPos.y < vsY1) vsY1 = monitorPos.y;
if (monitorPos.x + monitorSize.x > vsX2) vsX2 = monitorPos.x + monitorSize.x;
if (monitorPos.y + monitorSize.y > vsY2) vsY2 = monitorPos.y + monitorSize.y;
}
// Clamp the window to the borders of the monitors
if (wndPos.x < vsX1) wndPos.x = vsX1;
if (wndPos.y < vsY1) wndPos.y = vsY1;
if (wndPos.x + windowSize.x > vsX2) wndPos.x = vsX2 - windowSize.x;
if (wndPos.y + windowSize.y > vsY2) wndPos.y = vsY2 - windowSize.y;
SetWindowPosition(wndPos.x, wndPos.y);
}
BeginDrawing(); BeginDrawing();
ClearBackground(Color(40, 40, 40, 255)); ClearBackground(Color(40, 40, 40, 255));
Vector3 windowSize(GetScreenWidth(), GetScreenHeight());
Rectangle titlebar = Rectangle(0, 0, windowSize.x - 50, 35);
Vector2 mousePos = Vector2(GetMouseX(), GetMouseY());
bool hoveredTitlebar = mousePos.x >= titlebar.x && mousePos.y >= titlebar.y && mousePos.x <= titlebar.x + titlebar.width && mousePos.y <= titlebar.y + titlebar.height;
if (hoveredTitlebar && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { DrawTexture(Textures["Frame"], 0, 0, WHITE);
if (dragOffset.x == 0 && dragOffset.y == 0) dragOffset = mousePos;
Vector2 wndPos = GetWindowPosition();
SetWindowPosition(wndPos.x + (mousePos.x - dragOffset.x), wndPos.y + (mousePos.y - dragOffset.y)); Texture2D titleTex = Textures["Title"];
} DrawTexture(titleTex, windowSize.x / 2 - titleTex.width / 2, titlebar.height / 2 - titleTex.height / 2, WHITE);
else dragOffset = Vector2(0, 0);
DrawTexture(Textures["Frame"], 0, 0, WHITE); if (UIUtils::GuiIcon("Exit", windowSize.x - 36, titlebar.height / 2 - 10) && (extracting && currentStep.find("Done") != std::string::npos || !extracting)) {
closeRequested = true;
}
Texture2D titleTex = Textures["Title"]; BeginMode3D(camera);
DrawTexture(titleTex, windowSize.x / 2 - titleTex.width / 2, titlebar.height / 2 - titleTex.height / 2, WHITE); DrawModelEx(Models["Ship"], Vector3Zero(), Vector3(.0f, 1.0f, .0f), this->ModelRotation, SCALE(1.0f), WHITE);
EndMode3D();
if (UIUtils::GuiIcon("Exit", windowSize.x - 36, titlebar.height / 2 - 10) && (extracting && currentStep.find("Done") != std::string::npos || !extracting)) { constexpr float text_y = 125.f;
CloseWindow(); UIUtils::GuiShadowText(("Rom Type: " + version.version).c_str(), 32, text_y, 10, WHITE, BLACK);
} UIUtils::GuiShadowText("Tool Version: 1.0", 32, text_y + 15, 10, WHITE, BLACK);
UIUtils::GuiShadowText("OTR Version: 1.0", 32, text_y + 30, 10, WHITE, BLACK);
UIUtils::GuiToggle(&single_thread, "Single Thread", 32, text_y + 40, currentStep != NULLSTR);
BeginMode3D(camera); if (!hide_second_btn && UIUtils::GuiIconButton("Folder", "Open\nShip Folder", 109, 50, currentStep != NULLSTR, "Select your Ship of Harkinian Folder\n\nYou could use another folder\nfor development purposes")) {
DrawModelEx(Models["Ship"] ,Vector3Zero(), Vector3(.0f, 1.0f, .0f), this->ModelRotation, SCALE(1.0f), WHITE); const std::string path = NativeFS->LaunchFileExplorer(LaunchType::FOLDER);
EndMode3D(); sohFolder = path;
}
constexpr float text_y = 125.f; if (UIUtils::GuiIconButton("Cartridge", "Open\nOoT Rom", 32, 50, currentStep != NULLSTR, "Select an Ocarina of Time\nMaster Quest or Vanilla Debug Rom\n\nYou can dump it or lend one from Nintendo")) {
UIUtils::GuiShadowText(("Rom Type: " + version.version).c_str(), 32, text_y, 10, WHITE, BLACK); const std::string path = NativeFS->LaunchFileExplorer(LaunchType::FILE);
UIUtils::GuiShadowText("Tool Version: 1.0", 32, text_y + 15, 10, WHITE, BLACK); if (path != NULLSTR) {
UIUtils::GuiShadowText("OTR Version: 1.0", 32, text_y + 30, 10, WHITE, BLACK); const std::string patched_n64 = std::string(patched_rom);
UIUtils::GuiToggle(&single_thread, "Single Thread", 32, text_y + 40, currentStep != NULLSTR); MoonUtils::rm(patched_n64);
version = GetVersion(fopen(path.c_str(), "r"));
if(!hide_second_btn && UIUtils::GuiIconButton("Folder", "Open\nShip Folder", 109, 50, currentStep != NULLSTR, "Select your Ship of Harkinian Folder\n\nYou could use another folder\nfor development purposes")) { if (version.version != NULLSTR) {
const std::string path = NativeFS->LaunchFileExplorer(LaunchType::FOLDER); MoonUtils::copy(path, patched_n64);
sohFolder = path; rom_ready = true;
} return;
if (UIUtils::GuiIconButton("Cartridge", "Open\nOoT Rom", 32, 50, currentStep != NULLSTR, "Select an Ocarina of Time\nMaster Quest or Vanilla Debug Rom\n\nYou can dump it or lend one from Nintendo")) {
const std::string path = NativeFS->LaunchFileExplorer(LaunchType::FILE);
if (path != NULLSTR) {
const std::string patched_n64 = std::string(patched_rom);
MoonUtils::rm(patched_n64);
version = GetVersion(fopen(path.c_str(), "r"));
if (version.version != NULLSTR) {
MoonUtils::copy(path, patched_n64);
rom_ready = true;
return;
}
fix_baserom(path.c_str(), patched_rom);
version = GetVersion(fopen(patched_rom, "r"));
if (version.version != NULLSTR) rom_ready = true;
} }
fix_baserom(path.c_str(), patched_rom);
version = GetVersion(fopen(patched_rom, "r"));
if (version.version != NULLSTR) rom_ready = true;
} }
}
if(currentStep != NULLSTR) { if (currentStep != NULLSTR) {
DrawRectangle(0, 0, windowSize.x, windowSize.y, Color(0, 0, 0, 160)); DrawRectangle(0, 0, windowSize.x, windowSize.y, Color(0, 0, 0, 160));
DrawTexture(Textures["Modal"], windowSize.x / 2 - Textures["Modal"].width / 2, windowSize.y / 2 - Textures["Modal"].height / 2, WHITE); DrawTexture(Textures["Modal"], windowSize.x / 2 - Textures["Modal"].width / 2, windowSize.y / 2 - Textures["Modal"].height / 2, WHITE);
UIUtils::GuiShadowText(currentStep.c_str(), 0, windowSize.y / 2, 10, WHITE, BLACK, windowSize.x, true); UIUtils::GuiShadowText(currentStep.c_str(), 0, windowSize.y / 2, 10, WHITE, BLACK, windowSize.x, true);
} }
EndDrawing(); EndDrawing();
} }
void setCurrentStep(const std::string& step) { void setCurrentStep(const std::string& step) {

View File

@ -19,6 +19,8 @@ public:
void update(); void update();
void draw(); void draw();
void exit(); void exit();
inline bool CloseRequested() { return closeRequested; }
protected: protected:
void LoadTexture(const std::string& name, const std::string& path) { void LoadTexture(const std::string& name, const std::string& path) {
const Image tmp = LoadImage(path.c_str()); const Image tmp = LoadImage(path.c_str());
@ -32,6 +34,9 @@ protected:
SetTextureFilter(font.texture, TEXTURE_FILTER_POINT); SetTextureFilter(font.texture, TEXTURE_FILTER_POINT);
Fonts[name] = font; Fonts[name] = font;
} }
private:
bool closeRequested = false;
}; };
extern OTRGame* Game; extern OTRGame* Game;

View File

@ -17,8 +17,8 @@ void UpdateDrawFrame(void) {
} }
int main() { int main() {
constexpr Vector2 windowSize = Vector2(400, 200); constexpr Vector2 windowSize = Vector2(400, 200);
SetTargetFPS(144); SetConfigFlags(FLAG_VSYNC_HINT);
SetConfigFlags(FLAG_WINDOW_HIGHDPI); SetConfigFlags(FLAG_WINDOW_HIGHDPI);
SetConfigFlags(FLAG_WINDOW_UNDECORATED); SetConfigFlags(FLAG_WINDOW_UNDECORATED);
SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_MSAA_4X_HINT);
@ -32,7 +32,7 @@ int main() {
Game = new OTRGame(); Game = new OTRGame();
Game->preload(); Game->preload();
Game->init(); Game->init();
while(!WindowShouldClose()) { while(!WindowShouldClose() && !Game->CloseRequested()) {
UpdateDrawFrame(); UpdateDrawFrame();
} }
CloseWindow(); CloseWindow();

View File

@ -188,14 +188,16 @@ int main(int argc, char* argv[])
} }
else if (arg == "-eh") // Enable Error Handler else if (arg == "-eh") // Enable Error Handler
{ {
#if !defined(_MSC_VER) && !defined(__CYGWIN__) #if !defined(_MSC_VER) && !defined(__CYGWIN__)
signal(SIGSEGV, ErrorHandler); signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler); signal(SIGABRT, ErrorHandler);
#else #else
HANDLE_WARNING(WarningType::Always, // HANDLE_WARNING(WarningType::Always,
"tried to set error handler, but this ZAPD build lacks support for one", // "tried to set error handler, but this ZAPD build lacks support for one",
""); // "");
#endif #endif
} }
else if (arg == "-v") // Verbose else if (arg == "-v") // Verbose
{ {

View File

@ -27,6 +27,7 @@ namespace Game {
const std::string AudioSection = AUDIO_SECTION; const std::string AudioSection = AUDIO_SECTION;
const std::string ControllerSection = CONTROLLER_SECTION; const std::string ControllerSection = CONTROLLER_SECTION;
const std::string EnhancementSection = ENHANCEMENTS_SECTION; const std::string EnhancementSection = ENHANCEMENTS_SECTION;
const std::string CheatSection = CHEATS_SECTION;
void UpdateAudio() { void UpdateAudio() {
Audio_SetGameVolume(SEQ_BGM_MAIN, Settings.audio.music_main); Audio_SetGameVolume(SEQ_BGM_MAIN, Settings.audio.music_main);
@ -57,9 +58,7 @@ namespace Game {
Settings.enhancements.animated_pause_menu = stob(Conf[EnhancementSection]["animated_pause_menu"]); Settings.enhancements.animated_pause_menu = stob(Conf[EnhancementSection]["animated_pause_menu"]);
CVar_SetS32(const_cast<char*>("gPauseLiveLink"), Settings.enhancements.animated_pause_menu); CVar_SetS32(const_cast<char*>("gPauseLiveLink"), Settings.enhancements.animated_pause_menu);
Settings.enhancements.debug_mode = stob(Conf[EnhancementSection]["debug_mode"]); // Audio
CVar_SetS32(const_cast<char*>("gDebugEnabled"), Settings.enhancements.debug_mode);
Settings.audio.master = Ship::stof(Conf[AudioSection]["master"]); Settings.audio.master = Ship::stof(Conf[AudioSection]["master"]);
CVar_SetFloat(const_cast<char*>("gGameMasterVolume"), Settings.audio.master); CVar_SetFloat(const_cast<char*>("gGameMasterVolume"), Settings.audio.master);
@ -75,6 +74,7 @@ namespace Game {
Settings.audio.fanfare = Ship::stof(Conf[AudioSection]["fanfare"]); Settings.audio.fanfare = Ship::stof(Conf[AudioSection]["fanfare"]);
CVar_SetFloat(const_cast<char*>("gFanfareVolume"), Settings.audio.fanfare); CVar_SetFloat(const_cast<char*>("gFanfareVolume"), Settings.audio.fanfare);
// Controllers
Settings.controller.gyro_sensitivity = Ship::stof(Conf[ControllerSection]["gyro_sensitivity"]); Settings.controller.gyro_sensitivity = Ship::stof(Conf[ControllerSection]["gyro_sensitivity"]);
CVar_SetFloat(const_cast<char*>("gGyroSensitivity"), Settings.controller.gyro_sensitivity); CVar_SetFloat(const_cast<char*>("gGyroSensitivity"), Settings.controller.gyro_sensitivity);
@ -87,6 +87,34 @@ namespace Game {
Settings.controller.input_enabled = stob(Conf[ControllerSection]["input_enabled"]); Settings.controller.input_enabled = stob(Conf[ControllerSection]["input_enabled"]);
CVar_SetS32(const_cast<char*>("gInputEnabled"), Settings.controller.input_enabled); CVar_SetS32(const_cast<char*>("gInputEnabled"), Settings.controller.input_enabled);
// Cheats
Settings.cheats.debug_mode = stob(Conf[CheatSection]["debug_mode"]);
CVar_SetS32(const_cast<char*>("gDebugEnabled"), Settings.cheats.debug_mode);
Settings.cheats.infinite_money = stob(Conf[CheatSection]["infinite_money"]);
CVar_SetS32(const_cast<char*>("gInfiniteMoney"), Settings.cheats.infinite_money);
Settings.cheats.infinite_health = stob(Conf[CheatSection]["infinite_health"]);
CVar_SetS32(const_cast<char*>("gInfiniteHealth"), Settings.cheats.infinite_health);
Settings.cheats.infinite_ammo = stob(Conf[CheatSection]["infinite_ammo"]);
CVar_SetS32(const_cast<char*>("gInfiniteAmmo"), Settings.cheats.infinite_ammo);
Settings.cheats.infinite_magic = stob(Conf[CheatSection]["infinite_magic"]);
CVar_SetS32(const_cast<char*>("gInfiniteMagic"), Settings.cheats.infinite_magic);
Settings.cheats.no_clip = stob(Conf[CheatSection]["no_clip"]);
CVar_SetS32(const_cast<char*>("gNoClip"), Settings.cheats.no_clip);
Settings.cheats.climb_everything = stob(Conf[CheatSection]["climb_everything"]);
CVar_SetS32(const_cast<char*>("gClimbEverything"), Settings.cheats.climb_everything);
Settings.cheats.moon_jump_on_l = stob(Conf[CheatSection]["moon_jump_on_l"]);
CVar_SetS32(const_cast<char*>("gMoonJumpOnL"), Settings.cheats.moon_jump_on_l);
Settings.cheats.super_tunic = stob(Conf[CheatSection]["super_tunic"]);
CVar_SetS32(const_cast<char*>("gSuperTunic"), Settings.cheats.super_tunic);
UpdateAudio(); UpdateAudio();
} }
@ -111,13 +139,25 @@ namespace Game {
Conf[EnhancementSection]["fast_text"] = std::to_string(Settings.enhancements.fast_text); Conf[EnhancementSection]["fast_text"] = std::to_string(Settings.enhancements.fast_text);
Conf[EnhancementSection]["disable_lod"] = std::to_string(Settings.enhancements.disable_lod); Conf[EnhancementSection]["disable_lod"] = std::to_string(Settings.enhancements.disable_lod);
Conf[EnhancementSection]["animated_pause_menu"] = std::to_string(Settings.enhancements.animated_pause_menu); Conf[EnhancementSection]["animated_pause_menu"] = std::to_string(Settings.enhancements.animated_pause_menu);
Conf[EnhancementSection]["debug_mode"] = std::to_string(Settings.enhancements.debug_mode);
// Controllers
Conf[ControllerSection]["gyro_sensitivity"] = std::to_string(Settings.controller.gyro_sensitivity); Conf[ControllerSection]["gyro_sensitivity"] = std::to_string(Settings.controller.gyro_sensitivity);
Conf[ControllerSection]["rumble_strength"] = std::to_string(Settings.controller.rumble_strength); Conf[ControllerSection]["rumble_strength"] = std::to_string(Settings.controller.rumble_strength);
Conf[ControllerSection]["input_scale"] = std::to_string(Settings.controller.input_scale); Conf[ControllerSection]["input_scale"] = std::to_string(Settings.controller.input_scale);
Conf[ControllerSection]["input_enabled"] = std::to_string(Settings.controller.input_enabled); Conf[ControllerSection]["input_enabled"] = std::to_string(Settings.controller.input_enabled);
// Cheats
Conf[CheatSection]["debug_mode"] = std::to_string(Settings.cheats.debug_mode);
Conf[CheatSection]["infinite_money"] = std::to_string(Settings.cheats.infinite_money);
Conf[CheatSection]["infinite_health"] = std::to_string(Settings.cheats.infinite_health);
Conf[CheatSection]["infinite_ammo"] = std::to_string(Settings.cheats.infinite_ammo);
Conf[CheatSection]["infinite_magic"] = std::to_string(Settings.cheats.infinite_magic);
Conf[CheatSection]["no_clip"] = std::to_string(Settings.cheats.no_clip);
Conf[CheatSection]["climb_everything"] = std::to_string(Settings.cheats.climb_everything);
Conf[CheatSection]["moon_jump_on_l"] = std::to_string(Settings.cheats.moon_jump_on_l);
Conf[CheatSection]["super_tunic"] = std::to_string(Settings.cheats.super_tunic);
Conf.Save(); Conf.Save();
} }

View File

@ -23,15 +23,30 @@ struct SoHConfigType {
bool fast_text = false; bool fast_text = false;
bool disable_lod = false; bool disable_lod = false;
bool animated_pause_menu = false; bool animated_pause_menu = false;
bool debug_mode = false;
} enhancements; } enhancements;
// Controller
struct { struct {
float gyro_sensitivity = 1.0f; float gyro_sensitivity = 1.0f;
float rumble_strength = 1.0f; float rumble_strength = 1.0f;
float input_scale = 1.0f; float input_scale = 1.0f;
bool input_enabled = false; float gyroDriftX = 0.0f;
float gyroDriftY = 0.0f;
bool input_enabled = false;
} controller; } controller;
// Cheats
struct {
bool debug_mode = false;
bool infinite_money = false;
bool infinite_health = false;
bool infinite_ammo = false;
bool infinite_magic = false;
bool no_clip = false;
bool climb_everything = false;
bool moon_jump_on_l = false;
bool super_tunic = false;
} cheats;
}; };
enum SeqPlayers { enum SeqPlayers {
@ -46,6 +61,7 @@ enum SeqPlayers {
#define AUDIO_SECTION "AUDIO SETTINGS" #define AUDIO_SECTION "AUDIO SETTINGS"
#define CONTROLLER_SECTION "CONTROLLER SECTION" #define CONTROLLER_SECTION "CONTROLLER SECTION"
#define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS" #define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS"
#define CHEATS_SECTION "CHEATS SETTINGS"
namespace Game { namespace Game {
extern SoHConfigType Settings; extern SoHConfigType Settings;

View File

@ -673,7 +673,11 @@ static void gfx_opengl_resize_framebuffer(int fb, uint32_t width, uint32_t heigh
void gfx_opengl_set_framebuffer(int fb) void gfx_opengl_set_framebuffer(int fb)
{ {
glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE); // Set origin to upper left corner, to match N64 and DX11 if (GLEW_ARB_clip_control || GLEW_VERSION_4_5) {
// Set origin to upper left corner, to match N64 and DX11
// If this function is not supported, the texture will be upside down :(
glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
}
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb); glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
@ -687,7 +691,9 @@ void gfx_opengl_reset_framebuffer(void)
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); glBindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer);
glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE); if (GLEW_ARB_clip_control || GLEW_VERSION_4_5) {
glClipControl(GL_LOWER_LEFT, GL_NEGATIVE_ONE_TO_ONE);
}
} }
void gfx_opengl_select_texture_fb(int fbID) void gfx_opengl_select_texture_fb(int fbID)

View File

@ -7,12 +7,8 @@
#include "Window.h" #include "Window.h"
extern "C" uint8_t __osMaxControllers; extern "C" uint8_t __osMaxControllers;
float gyroDriftX;
float gyroDriftY;
namespace Ship { namespace Ship {
SDLController::SDLController(int32_t dwControllerNumber) : Controller(dwControllerNumber), Cont(nullptr), guid(INVALID_SDL_CONTROLLER_GUID) { SDLController::SDLController(int32_t dwControllerNumber) : Controller(dwControllerNumber), Cont(nullptr), guid(INVALID_SDL_CONTROLLER_GUID) {
} }
@ -147,8 +143,8 @@ namespace Ship {
//bound diagonals to an octagonal range {-68 ... +68} //bound diagonals to an octagonal range {-68 ... +68}
if (ax != 0.0 && ay != 0.0) { if (ax != 0.0 && ay != 0.0) {
auto slope = ay / ax; auto slope = ay / ax;
auto edgex = copysign(85.0 / (abs(slope) + wAxisThreshold / 69.0), ax); auto edgex = copysign(85.0 / (abs(slope) + 16.0 / 69.0), ax);
auto edgey = copysign(std::min(abs(edgex * slope), 85.0 / (1.0 / abs(slope) + wAxisThreshold / 69.0)), ay); auto edgey = copysign(std::min(abs(edgex * slope), 85.0 / (1.0 / abs(slope) + 16.0 / 69.0)), ay);
edgex = edgey / slope; edgex = edgey / slope;
auto scale = sqrt(edgex * edgex + edgey * edgey) / 85.0; auto scale = sqrt(edgex * edgex + edgey * edgey) / 85.0;
@ -186,31 +182,31 @@ namespace Ship {
SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3); SDL_GameControllerGetSensorData(Cont, SDL_SENSOR_GYRO, gyroData, 3);
const char* contName = SDL_GameControllerName(Cont); const char* contName = SDL_GameControllerName(Cont);
const int isSpecialController = strcmp("PS5 Controller", contName); const int isSpecialController = !strcmp("PS5 Controller", contName);
const float gyroSensitivity = Game::Settings.controller.gyro_sensitivity; const float gyroSensitivity = Game::Settings.controller.gyro_sensitivity;
if (gyroDriftX == 0) { if (Game::Settings.controller.gyroDriftX == 0) {
if (isSpecialController == 0) { Game::Settings.controller.gyroDriftX = gyroData[0];
gyroDriftX = gyroData[2]; }
if (Game::Settings.controller.gyroDriftY == 0) {
if (isSpecialController == 1) {
Game::Settings.controller.gyroDriftY = gyroData[2];
} }
else { else {
gyroDriftX = gyroData[0]; Game::Settings.controller.gyroDriftY = gyroData[1];
} }
} }
if (gyroDriftY == 0) { if (isSpecialController == 1) {
gyroDriftY = gyroData[1]; wGyroX = gyroData[0] - Game::Settings.controller.gyroDriftX;
} wGyroY = -gyroData[2] - Game::Settings.controller.gyroDriftY;
if (isSpecialController == 0) {
wGyroX = gyroData[2] - gyroDriftX;
} }
else { else {
wGyroX = gyroData[0] - gyroDriftX; wGyroX = gyroData[0] - Game::Settings.controller.gyroDriftX;
wGyroY = gyroData[1] - Game::Settings.controller.gyroDriftY;
} }
wGyroY = gyroData[1] - gyroDriftY;
wGyroX *= gyroSensitivity; wGyroX *= gyroSensitivity;
wGyroY *= gyroSensitivity; wGyroY *= gyroSensitivity;
} }
@ -340,11 +336,19 @@ namespace Ship {
} }
if (SDL_GameControllerHasLED(Cont)) { if (SDL_GameControllerHasLED(Cont)) {
if (controller->ledColor == 1) { switch (controller->ledColor) {
case 0:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 255, 0, 0); SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 255, 0, 0);
} break;
else { case 1:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 0, 255, 0); SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 0x1E, 0x69, 0x1B);
break;
case 2:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 0x64, 0x14, 0x00);
break;
case 3:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(Cont), 0x00, 0x3C, 0x64);
break;
} }
} }
} }

View File

@ -306,6 +306,14 @@ namespace SohImGui {
if (ImGui::SliderFloat("##GYROSCOPE", &Game::Settings.controller.gyro_sensitivity, 0.0f, 1.0f, "")) { if (ImGui::SliderFloat("##GYROSCOPE", &Game::Settings.controller.gyro_sensitivity, 0.0f, 1.0f, "")) {
needs_save = true; needs_save = true;
} }
if (ImGui::Button("Recalibrate Gyro")) {
Game::Settings.controller.gyroDriftX = 0;
Game::Settings.controller.gyroDriftY = 0;
}
ImGui::Separator();
ImGui::Text("Rumble Strength: %d %%", static_cast<int>(100 * Game::Settings.controller.rumble_strength)); ImGui::Text("Rumble Strength: %d %%", static_cast<int>(100 * Game::Settings.controller.rumble_strength));
if (ImGui::SliderFloat("##RUMBLE", &Game::Settings.controller.rumble_strength, 0.0f, 1.0f, "")) { if (ImGui::SliderFloat("##RUMBLE", &Game::Settings.controller.rumble_strength, 0.0f, 1.0f, "")) {
needs_save = true; needs_save = true;
@ -350,20 +358,65 @@ namespace SohImGui {
needs_save = true; needs_save = true;
} }
ImGui::Text("Debugging");
ImGui::Separator();
if (ImGui::Checkbox("Debug Mode", &Game::Settings.enhancements.debug_mode)) {
CVar_SetS32(const_cast<char*>("gDebugEnabled"), Game::Settings.enhancements.debug_mode);
needs_save = true;
}
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Developer Tools")) { if (ImGui::BeginMenu("Developer Tools")) {
HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh)); HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh));
HOOK(ImGui::MenuItem("Console", nullptr, &console->opened)); HOOK(ImGui::MenuItem("Console", nullptr, &console->opened));
ImGui::Text("Debug");
ImGui::Separator();
if (ImGui::Checkbox("Debug Mode", &Game::Settings.cheats.debug_mode)) {
CVar_SetS32(const_cast<char*>("gDebugEnabled"), Game::Settings.cheats.debug_mode);
needs_save = true;
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Cheats")) {
if (ImGui::Checkbox("Infinite Money", &Game::Settings.cheats.infinite_money)) {
CVar_SetS32(const_cast<char*>("gInfiniteMoney"), Game::Settings.cheats.infinite_money);
needs_save = true;
}
if (ImGui::Checkbox("Infinite Health", &Game::Settings.cheats.infinite_health)) {
CVar_SetS32(const_cast<char*>("gInfiniteHealth"), Game::Settings.cheats.infinite_health);
needs_save = true;
}
if (ImGui::Checkbox("Infinite Ammo", &Game::Settings.cheats.infinite_ammo)) {
CVar_SetS32(const_cast<char*>("gInfiniteAmmo"), Game::Settings.cheats.infinite_ammo);
needs_save = true;
}
if (ImGui::Checkbox("Infinite Magic", &Game::Settings.cheats.infinite_magic)) {
CVar_SetS32(const_cast<char*>("gInfiniteMagic"), Game::Settings.cheats.infinite_magic);
needs_save = true;
}
if (ImGui::Checkbox("No Clip", &Game::Settings.cheats.no_clip)) {
CVar_SetS32(const_cast<char*>("gNoClip"), Game::Settings.cheats.no_clip);
needs_save = true;
}
if (ImGui::Checkbox("Climb Everything", &Game::Settings.cheats.climb_everything)) {
CVar_SetS32(const_cast<char*>("gClimbEverything"), Game::Settings.cheats.climb_everything);
needs_save = true;
}
if (ImGui::Checkbox("Moon Jump on L", &Game::Settings.cheats.moon_jump_on_l)) {
CVar_SetS32(const_cast<char*>("gMoonJumpOnL"), Game::Settings.cheats.moon_jump_on_l);
needs_save = true;
}
if (ImGui::Checkbox("Super Tunic", &Game::Settings.cheats.super_tunic)) {
CVar_SetS32(const_cast<char*>("gSuperTunic"), Game::Settings.cheats.super_tunic);
needs_save = true;
}
ImGui::EndMenu(); ImGui::EndMenu();
} }

View File

@ -39,6 +39,14 @@ extern "C" {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
const char* controllerDb = "gamecontrollerdb.txt";
int mappingsAdded = SDL_GameControllerAddMappingsFromFile(controllerDb);
if (mappingsAdded >= 0) {
SPDLOG_INFO("Added SDL game controllers from \"{}\" ({})", controllerDb, mappingsAdded);
} else {
SPDLOG_ERROR("Failed add SDL game controller mappings from \"{}\" ({})", controllerDb, SDL_GetError());
}
// TODO: This for loop is debug. Burn it with fire. // TODO: This for loop is debug. Burn it with fire.
for (size_t i = 0; i < SDL_NumJoysticks(); i++) { for (size_t i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) { if (SDL_IsGameController(i)) {

View File

@ -1,6 +1,6 @@
<Root> <Root>
<File Name="object_triforce_spot" Segment="6"> <File Name="object_triforce_spot" Segment="6">
<Array Name="gTriforceVtx" Count="32" Offset="0x0000"> <Array Name="gTriforceVtx" Count="96" Offset="0x0000">
<Vtx/> <Vtx/>
</Array> </Array>

View File

@ -324,6 +324,75 @@ void GameState_Update(GameState* gameState) {
func_800C49F4(gfxCtx); func_800C49F4(gfxCtx);
} }
// -----------------------
// Cheats hooks
// -----------------------
// Inf Money
if (CVar_GetS32("gInfiniteMoney", 0) != 0) {
if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) {
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
}
}
// Inf Health
if (CVar_GetS32("gInfiniteHealth", 0) != 0) {
if (gSaveContext.health < gSaveContext.healthCapacity) {
gSaveContext.health = gSaveContext.healthCapacity;
}
}
// Inf Ammo
if (CVar_GetS32("gInfiniteAmmo", 0) != 0) {
// Deku Sticks
if (AMMO(ITEM_STICK) < CUR_CAPACITY(UPG_STICKS)) {
AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS);
}
// Deku Nuts
if (AMMO(ITEM_NUT) < CUR_CAPACITY(UPG_NUTS)) {
AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS);
}
// Bombs
if (AMMO(ITEM_BOMB) < CUR_CAPACITY(UPG_BOMB_BAG)) {
AMMO(ITEM_BOMB) = CUR_CAPACITY(UPG_BOMB_BAG);
}
// Fairy Bow (Ammo)
if (AMMO(ITEM_BOW) < CUR_CAPACITY(UPG_QUIVER)) {
AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER);
}
// Fairy Slingshot (Ammo)
if (AMMO(ITEM_SLINGSHOT) < CUR_CAPACITY(UPG_BULLET_BAG)) {
AMMO(ITEM_SLINGSHOT) = CUR_CAPACITY(UPG_BULLET_BAG);
}
// Bombchus (max: 50, no upgrades)
if (AMMO(ITEM_BOMBCHU) < 50) {
AMMO(ITEM_BOMBCHU) = 50;
}
}
// Inf Magic
if (CVar_GetS32("gInfiniteMagic", 0) != 0) {
if (gSaveContext.magicAcquired && gSaveContext.magic != (gSaveContext.doubleMagic + 1) * 0x30) {
gSaveContext.magic = (gSaveContext.doubleMagic + 1) * 0x30;
}
}
// Moon Jump On L
if (CVar_GetS32("gMoonJumpOnL", 0) != 0) {
if (gGlobalCtx) {
Player* player = GET_PLAYER(gGlobalCtx);
if (CHECK_BTN_ANY(gGlobalCtx->state.input[0].cur.button, BTN_L)) {
player->actor.velocity.y = 6.34375f;
}
}
}
gameState->frames++; gameState->frames++;
} }

View File

@ -272,9 +272,19 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) {
controllerCallback.rumble = padMgr->rumbleEnable[0] > 0 ? 1 : 0; controllerCallback.rumble = padMgr->rumbleEnable[0] > 0 ? 1 : 0;
if (HealthMeter_IsCritical()) { if (HealthMeter_IsCritical()) {
controllerCallback.ledColor = 1;
} else {
controllerCallback.ledColor = 0; controllerCallback.ledColor = 0;
} else if (gGlobalCtx) {
switch (CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1) {
case PLAYER_TUNIC_KOKIRI:
controllerCallback.ledColor = 1;
break;
case PLAYER_TUNIC_GORON:
controllerCallback.ledColor = 2;
break;
case PLAYER_TUNIC_ZORA:
controllerCallback.ledColor = 3;
break;
}
} }
OTRControllerCallback(&controllerCallback); OTRControllerCallback(&controllerCallback);

View File

@ -1874,6 +1874,10 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
s32 bgId2; s32 bgId2;
f32 nx, ny, nz; // unit normal of polygon f32 nx, ny, nz; // unit normal of polygon
if (CVar_GetS32("gNoClip", 0) != 0) {
return false;
}
result = false; result = false;
*outBgId = BGCHECK_SCENE; *outBgId = BGCHECK_SCENE;
*outPoly = NULL; *outPoly = NULL;
@ -3996,7 +4000,11 @@ u32 func_80041D94(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) {
* SurfaceType Get Wall Flags * SurfaceType Get Wall Flags
*/ */
s32 func_80041DB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { s32 func_80041DB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) {
return D_80119D90[func_80041D94(colCtx, poly, bgId)]; if (CVar_GetS32("gClimbEverything", 0) != 0) {
return (1 << 3) | D_80119D90[func_80041D94(colCtx, poly, bgId)];
} else {
return D_80119D90[func_80041D94(colCtx, poly, bgId)];
}
} }
/** /**

View File

@ -4078,11 +4078,11 @@ void Interface_Update(GlobalContext* globalCtx) {
D_80125A58 = func_8008F2F8(globalCtx); D_80125A58 = func_8008F2F8(globalCtx);
if (D_80125A58 == 1) { if (D_80125A58 == 1) {
if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 2) { if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 2 || CVar_GetS32("gSuperTunic", 0) != 0) {
D_80125A58 = 0; D_80125A58 = 0;
} }
} else if ((func_8008F2F8(globalCtx) >= 2) && (func_8008F2F8(globalCtx) < 5)) { } else if ((func_8008F2F8(globalCtx) >= 2) && (func_8008F2F8(globalCtx) < 5)) {
if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 3) { if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == 3 || CVar_GetS32("gSuperTunic", 0) != 0) {
D_80125A58 = 0; D_80125A58 = 0;
} }
} }

View File

@ -631,9 +631,9 @@ s32 func_8008F2F8(GlobalContext* globalCtx) {
if (0) {} if (0) {}
if ((triggerEntry->flag != 0) && !(gSaveContext.textTriggerFlags & triggerEntry->flag) && if ((triggerEntry->flag != 0) && !(gSaveContext.textTriggerFlags & triggerEntry->flag) &&
(((var == 0) && (this->currentTunic != PLAYER_TUNIC_GORON)) || (((var == 0) && (this->currentTunic != PLAYER_TUNIC_GORON && CVar_GetS32("gSuperTunic", 0) == 0)) ||
(((var == 1) || (var == 3)) && (this->currentBoots == PLAYER_BOOTS_IRON) && (((var == 1) || (var == 3)) && (this->currentBoots == PLAYER_BOOTS_IRON) &&
(this->currentTunic != PLAYER_TUNIC_ZORA)))) { (this->currentTunic != PLAYER_TUNIC_ZORA && CVar_GetS32("gSuperTunic", 0) == 0)))) {
Message_StartTextbox(globalCtx, triggerEntry->textId, NULL); Message_StartTextbox(globalCtx, triggerEntry->textId, NULL);
gSaveContext.textTriggerFlags |= triggerEntry->flag; gSaveContext.textTriggerFlags |= triggerEntry->flag;
} }
@ -1590,7 +1590,7 @@ void func_80091A24(GlobalContext* globalCtx, void* seg04, void* seg06, SkelAnime
sp12C[0] = sword; sp12C[0] = sword;
sp12C[1] = shield; sp12C[1] = shield;
Matrix_SetTranslateRotateYXZ(pos->x - (LINK_AGE_IN_YEARS == YEARS_ADULT ? 25 : 0), Matrix_SetTranslateRotateYXZ(pos->x - ((CVar_GetS32("gPauseLiveLink", 0) && LINK_AGE_IN_YEARS == YEARS_ADULT) ? 25 : 0),
pos->y - (CVar_GetS32("gPauseTriforce", 0) ? 16 : 0), pos->z, rot); pos->y - (CVar_GetS32("gPauseTriforce", 0) ? 16 : 0), pos->z, rot);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);

View File

@ -300,7 +300,7 @@ void EnKusa_Main(EnKusa* this, GlobalContext* globalCtx) {
if (Actor_HasParent(&this->actor, globalCtx)) { if (Actor_HasParent(&this->actor, globalCtx)) {
EnKusa_SetupLiftedUp(this); EnKusa_SetupLiftedUp(this);
SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT); SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT);
} else if (this->collider.base.acFlags & AC_HIT) { } else if (this->collider.base.acFlags & AC_HIT && gGlobalCtx->csCtx.state == 0) {
this->collider.base.acFlags &= ~AC_HIT; this->collider.base.acFlags &= ~AC_HIT;
EnKusa_SpawnFragments(this, globalCtx); EnKusa_SpawnFragments(this, globalCtx);
EnKusa_DropCollectible(this, globalCtx); EnKusa_DropCollectible(this, globalCtx);

View File

@ -2321,9 +2321,7 @@ s32 func_8083501C(Player* this, GlobalContext* globalCtx) {
if ((!Player_HoldsHookshot(this) || func_80834FBC(this)) && !func_80834758(globalCtx, this) && if ((!Player_HoldsHookshot(this) || func_80834FBC(this)) && !func_80834758(globalCtx, this) &&
!func_80834F2C(this, globalCtx)) { !func_80834F2C(this, globalCtx)) {
return 0; return 0;
} } else if (this->rideActor != NULL) {
else
{
this->unk_6AD = 2; // OTRTODO: THIS IS A BAD IDEA BUT IT FIXES THE HORSE FIRST PERSON? this->unk_6AD = 2; // OTRTODO: THIS IS A BAD IDEA BUT IT FIXES THE HORSE FIRST PERSON?
} }
@ -3842,12 +3840,12 @@ s32 func_808382DC(Player* this, GlobalContext* globalCtx) {
s32 sp48 = func_80838144(D_808535E4); s32 sp48 = func_80838144(D_808535E4);
if (((this->actor.wallPoly != NULL) && if (((this->actor.wallPoly != NULL) &&
SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.wallPoly, this->actor.wallBgId)) || SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.wallPoly, this->actor.wallBgId)) ||
((sp48 >= 0) && ((sp48 >= 0) &&
SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) && SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) &&
(this->unk_A79 >= D_808544F4[sp48])) || (this->unk_A79 >= D_808544F4[sp48])) ||
((sp48 >= 0) && ((sp48 >= 0) &&
((this->currentTunic != PLAYER_TUNIC_GORON) || (this->unk_A79 >= D_808544F4[sp48])))) { ((this->currentTunic != PLAYER_TUNIC_GORON && CVar_GetS32("gSuperTunic", 0) == 0) || (this->unk_A79 >= D_808544F4[sp48])))) {
this->unk_A79 = 0; this->unk_A79 = 0;
this->actor.colChkInfo.damage = 4; this->actor.colChkInfo.damage = 4;
func_80837C0C(globalCtx, this, 0, 4.0f, 5.0f, this->actor.shape.rot.y, 20); func_80837C0C(globalCtx, this, 0, 4.0f, 5.0f, this->actor.shape.rot.y, 20);
@ -4632,7 +4630,7 @@ s32 func_8083A6AC(Player* this, GlobalContext* globalCtx) {
if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp74, &sp68, &sp84, true, false, false, if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp74, &sp68, &sp84, true, false, false,
true, &sp80) && true, &sp80) &&
(ABS(sp84->normal.y) < 600)) { ((ABS(sp84->normal.y) < 600) || (CVar_GetS32("gClimbEverything", 0) != 0))) {
f32 nx = COLPOLY_GET_NORMAL(sp84->normal.x); f32 nx = COLPOLY_GET_NORMAL(sp84->normal.x);
f32 ny = COLPOLY_GET_NORMAL(sp84->normal.y); f32 ny = COLPOLY_GET_NORMAL(sp84->normal.y);
f32 nz = COLPOLY_GET_NORMAL(sp84->normal.z); f32 nz = COLPOLY_GET_NORMAL(sp84->normal.z);
@ -8152,7 +8150,7 @@ static struct_80832924 D_808545F0[] = {
}; };
void func_80843CEC(Player* this, GlobalContext* globalCtx) { void func_80843CEC(Player* this, GlobalContext* globalCtx) {
if (this->currentTunic != PLAYER_TUNIC_GORON) { if (this->currentTunic != PLAYER_TUNIC_GORON && CVar_GetS32("gSuperTunic", 0) == 0) {
if ((globalCtx->roomCtx.curRoom.unk_02 == 3) || (D_808535E4 == 9) || if ((globalCtx->roomCtx.curRoom.unk_02 == 3) || (D_808535E4 == 9) ||
((func_80838144(D_808535E4) >= 0) && ((func_80838144(D_808535E4) >= 0) &&
!SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId))) { !SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId))) {
@ -9888,7 +9886,7 @@ void func_80847BA0(GlobalContext* globalCtx, Player* this) {
if ((this->actor.bgCheckFlags & 0x200) && (D_80853608 < 0x3000)) { if ((this->actor.bgCheckFlags & 0x200) && (D_80853608 < 0x3000)) {
CollisionPoly* wallPoly = this->actor.wallPoly; CollisionPoly* wallPoly = this->actor.wallPoly;
if (ABS(wallPoly->normal.y) < 600) { if ((ABS(wallPoly->normal.y) < 600) || (CVar_GetS32("gClimbEverything", 0) != 0)) {
f32 sp8C = COLPOLY_GET_NORMAL(wallPoly->normal.x); f32 sp8C = COLPOLY_GET_NORMAL(wallPoly->normal.x);
f32 sp88 = COLPOLY_GET_NORMAL(wallPoly->normal.y); f32 sp88 = COLPOLY_GET_NORMAL(wallPoly->normal.y);
f32 sp84 = COLPOLY_GET_NORMAL(wallPoly->normal.z); f32 sp84 = COLPOLY_GET_NORMAL(wallPoly->normal.z);
@ -10188,7 +10186,7 @@ void func_80848C74(GlobalContext* globalCtx, Player* this) {
s32 sp58; s32 sp58;
s32 sp54; s32 sp54;
if (this->currentTunic == PLAYER_TUNIC_GORON) { if (this->currentTunic == PLAYER_TUNIC_GORON || CVar_GetS32("gSuperTunic", 0) != 0) {
sp54 = 20; sp54 = 20;
} }
else { else {