Skip to content

Commit 7a41bd3

Browse files
Mirrored world enhancement (HarbourMasters#1569)
* Mirrored world PoC * invert culling for health meter and A button action * A few more fixes * Fix for item equip animations * Fix for pause triforce * Mirror scenes with static backgrounds * mirror minimap for mirror world * mirror dungeon maps and icons on the pause menu * mirror overworld map and icons on the pause menu * mirror debug world movement * mirror shops cursor and movement * use flip flag * Reverse crouch stab x axis for mirror mode * use invert culling command and clean up culling logic * Move mirror mode handler to mods and support random modes * Small cvar tweaks * mirror billboard score numbers and fix gyro horse mirrored inputs --------- Co-authored-by: Adam Bird <archez39@me.com>
1 parent 90d45d4 commit 7a41bd3

File tree

22 files changed

+363
-84
lines changed

22 files changed

+363
-84
lines changed

soh/include/z64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ typedef struct {
203203
/* 0x0060 */ Mtx projection;
204204
/* 0x00A0 */ Mtx viewing;
205205
/* 0x00E0 */ Mtx* projectionPtr;
206+
/* 0x00E0 */ Mtx* projectionFlippedPtr;
206207
/* 0x00E4 */ Mtx* viewingPtr;
207208
/* 0x00E8 */ Vec3f distortionOrientation;
208209
/* 0x00F4 */ Vec3f distortionScale;

soh/soh/Enhancements/enhancementTypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ typedef enum {
1111
BUNNY_HOOD_FAST
1212
} BunnyHoodMode;
1313

14+
typedef enum {
15+
MIRRORED_WORLD_OFF,
16+
MIRRORED_WORLD_ALWAYS,
17+
MIRRORED_WORLD_RANDOM,
18+
MIRRORED_WORLD_RANDOM_SEEDED,
19+
} MirroredWorldMode;
20+
1421
typedef enum {
1522
FASTFILE_1,
1623
FASTFILE_2,

soh/soh/Enhancements/mods.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "tts/tts.h"
55
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
66
#include "soh/Enhancements/enhancementTypes.h"
7+
#include "soh/Enhancements/randomizer/3drando/random.hpp"
78

89
extern "C" {
910
#include <z64.h>
@@ -550,6 +551,29 @@ void RegisterMenuPathFix() {
550551
});
551552
}
552553

554+
void UpdateMirrorModeState(int32_t sceneNum) {
555+
if (CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) == MIRRORED_WORLD_RANDOM_SEEDED) {
556+
uint32_t seed = sceneNum + (gSaveContext.n64ddFlag ? (gSaveContext.seedIcons[0] + gSaveContext.seedIcons[1] + gSaveContext.seedIcons[2] + gSaveContext.seedIcons[3] + gSaveContext.seedIcons[4]) : gSaveContext.sohStats.fileCreatedAt);
557+
Random_Init(seed);
558+
}
559+
560+
uint8_t randomNumber = Random(0, 2);
561+
if (
562+
CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) == MIRRORED_WORLD_ALWAYS ||
563+
CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) > MIRRORED_WORLD_ALWAYS && randomNumber == 1
564+
) {
565+
CVarSetInteger("gMirroredWorld", 1);
566+
} else {
567+
CVarClear("gMirroredWorld");
568+
}
569+
}
570+
571+
void RegisterMirrorModeHandler() {
572+
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int32_t sceneNum) {
573+
UpdateMirrorModeState(sceneNum);
574+
});
575+
}
576+
553577
void InitMods() {
554578
RegisterTTS();
555579
RegisterInfiniteMoney();
@@ -571,4 +595,5 @@ void InitMods() {
571595
RegisterHyperEnemies();
572596
RegisterBonkDamage();
573597
RegisterMenuPathFix();
598+
RegisterMirrorModeHandler();
574599
}

soh/soh/Enhancements/mods.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extern "C" {
88
#endif
99

1010
void UpdateDirtPathFixState(int32_t sceneNum);
11+
void UpdateMirrorModeState(int32_t sceneNum);
1112
void InitMods();
1213

1314
#ifdef __cplusplus

soh/soh/SohMenuBar.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ std::string GetWindowButtonText(const char* text, bool menuOpen) {
6262

6363
static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" };
6464
static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" };
65+
static const char* mirroredWorldModes[4] = { "Disabled", "Always", "Random", "Random (Seeded)" };
6566
static const char* allPowers[9] = {
6667
"Vanilla (1x)",
6768
"Double (2x)",
@@ -1015,6 +1016,19 @@ void DrawEnhancementsMenu() {
10151016
UIWidgets::Spacer(0);
10161017

10171018
if (ImGui::BeginMenu("Extra Modes")) {
1019+
UIWidgets::PaddedText("Mirrored World Mode", true, false);
1020+
if (UIWidgets::EnhancementCombobox("gMirroredWorldMode", mirroredWorldModes, MIRRORED_WORLD_OFF) && gPlayState != NULL) {
1021+
UpdateMirrorModeState(gPlayState->sceneNum);
1022+
}
1023+
UIWidgets::Tooltip(
1024+
"Mirrors the world horizontally\n\n"
1025+
"- Always: Always mirror the world\n"
1026+
"- Random: Randomly decide to mirror the world on each scene change\n"
1027+
"- Random (Seeded): Scenes are mirrored based on the current randomizer seed/file\n"
1028+
);
1029+
1030+
UIWidgets::Spacer(0);
1031+
10181032
UIWidgets::PaddedEnhancementCheckbox("Ivan the Fairy (Coop Mode)", "gIvanCoopModeEnabled", true, false);
10191033
UIWidgets::Tooltip("Enables Ivan the Fairy upon the next map change. Player 2 can control Ivan and "
10201034
"press the C-Buttons to use items and mess with Player 1!");

soh/src/code/audio_synthesis.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,11 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
653653
}
654654

655655
updateIndex = aiBufLen * 2;
656-
aInterleave(cmd++, DMEM_TEMP, DMEM_LEFT_CH, DMEM_RIGHT_CH, updateIndex);
656+
if (CVarGetInteger("gMirroredWorld", 0)) {
657+
aInterleave(cmd++, DMEM_TEMP, DMEM_RIGHT_CH, DMEM_LEFT_CH, updateIndex);
658+
} else {
659+
aInterleave(cmd++, DMEM_TEMP, DMEM_LEFT_CH, DMEM_RIGHT_CH, updateIndex);
660+
}
657661
aSaveBuffer(cmd++, DMEM_TEMP, aiBuf, updateIndex * 2);
658662

659663
return cmd;

soh/src/code/z_camera.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,8 +1487,9 @@ s32 Camera_Free(Camera* camera) {
14871487

14881488
f32 newCamX = -D_8015BD7C->state.input[0].cur.right_stick_x * 10.0f * (CVarGetFloat("gThirdPersonCameraSensitivityX", 1.0f));
14891489
f32 newCamY = D_8015BD7C->state.input[0].cur.right_stick_y * 10.0f * (CVarGetFloat("gThirdPersonCameraSensitivityY", 1.0f));
1490+
bool invertXAxis = (CVarGetInteger("gInvertXAxis", 0) && !CVarGetInteger("gMirroredWorld", 0)) || (!CVarGetInteger("gInvertXAxis", 0) && CVarGetInteger("gMirroredWorld", 0));
14901491

1491-
camera->play->camX += newCamX * (CVarGetInteger("gInvertXAxis", 0) ? -1 : 1);
1492+
camera->play->camX += newCamX * (invertXAxis ? -1 : 1);
14921493
camera->play->camY += newCamY * (CVarGetInteger("gInvertYAxis", 1) ? 1 : -1);
14931494

14941495
if (camera->play->camY > 0x32A4) {

soh/src/code/z_lib.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ void func_80077D10(f32* arg0, s16* arg1, Input* input) {
201201
f32 relX = input->rel.stick_x;
202202
f32 relY = input->rel.stick_y;
203203

204+
if (CVarGetInteger("gMirroredWorld", 0)) {
205+
relX = -input->rel.stick_x;
206+
}
207+
204208
*arg0 = sqrtf(SQ(relX) + SQ(relY));
205209
*arg0 = (60.0f < *arg0) ? 60.0f : *arg0;
206210

0 commit comments

Comments
 (0)