mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-02-12 05:10:26 -05:00
Add Mirror World gfx patches and patch Royal Grave Sun Song etching (#3005)
* add mirror world gfx patches and patch royal grave sun song * simplify nonmq vs mq
This commit is contained in:
parent
ef6227d8be
commit
a842894d0d
@ -8,6 +8,8 @@ extern "C" {
|
|||||||
#include "objects/object_ik/object_ik.h"
|
#include "objects/object_ik/object_ik.h"
|
||||||
#include "objects/object_link_child/object_link_child.h"
|
#include "objects/object_link_child/object_link_child.h"
|
||||||
|
|
||||||
|
uint32_t ResourceMgr_GameHasMasterQuest();
|
||||||
|
uint32_t ResourceMgr_GameHasOriginal();
|
||||||
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
|
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
|
||||||
void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
|
void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
|
||||||
}
|
}
|
||||||
@ -189,3 +191,67 @@ void ApplyAuthenticGfxPatches() {
|
|||||||
PatchFreezardTextureOverflow();
|
PatchFreezardTextureOverflow();
|
||||||
PatchIronKnuckleTextureOverflow();
|
PatchIronKnuckleTextureOverflow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Patches the Sun Song Etching in the Royal Grave to be mirrored in mirror mode
|
||||||
|
// This is achieved by mirroring the texture at the boundary and overriding the vertex texture coordinates
|
||||||
|
void PatchMirroredSunSongEtching() {
|
||||||
|
static const char gMqRoyalGraveBackRoomDL[] = "__OTR__scenes/mq/hakaana_ouke_scene/hakaana_ouke_room_2DL_005040";
|
||||||
|
static const char gNonMqRoyalGraveBackRoomDL[] = "__OTR__scenes/nonmq/hakaana_ouke_scene/hakaana_ouke_room_2DL_005040";
|
||||||
|
static const char gMqRoyalGraveBackRoomSongVtx[] = "__OTR__scenes/mq/hakaana_ouke_scene/hakaana_ouke_room_2Vtx_004F80";
|
||||||
|
static const char gNonMqRoyalGraveBackRoomSongVtx[] = "__OTR__scenes/nonmq/hakaana_ouke_scene/hakaana_ouke_room_2Vtx_004F80";
|
||||||
|
|
||||||
|
static Vtx* mirroredVtx;
|
||||||
|
|
||||||
|
// Using a dummy texture here, but will be ignoring the texture command itself
|
||||||
|
// Only need to patch over the two SetTile commands to get the MIRROR effect
|
||||||
|
Gfx mirroredSunSongTex[] = {
|
||||||
|
gsDPLoadTextureBlock("", G_IM_FMT_IA, G_IM_SIZ_8b, 128, 32, 0, G_TX_MIRROR | G_TX_WRAP,
|
||||||
|
G_TX_NOMIRROR | G_TX_CLAMP, 7, 5, G_TX_NOLOD, G_TX_NOLOD)
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* royalGraveBackRoomDL;
|
||||||
|
const char* royalGraveBackRoomSongVtx;
|
||||||
|
|
||||||
|
// If we have the original game, then always prefer the nonmq paths as that is what will be used in game
|
||||||
|
if (ResourceMgr_GameHasOriginal()) {
|
||||||
|
royalGraveBackRoomDL = gNonMqRoyalGraveBackRoomDL;
|
||||||
|
royalGraveBackRoomSongVtx = gNonMqRoyalGraveBackRoomSongVtx;
|
||||||
|
} else {
|
||||||
|
royalGraveBackRoomDL = gMqRoyalGraveBackRoomDL;
|
||||||
|
royalGraveBackRoomSongVtx = gMqRoyalGraveBackRoomSongVtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CVarGetInteger("gMirroredWorld", 0)) {
|
||||||
|
if (mirroredVtx == nullptr) {
|
||||||
|
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
|
||||||
|
mirroredVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
|
||||||
|
Vtx* origVtx = (Vtx*)ResourceGetDataByName(royalGraveBackRoomSongVtx);
|
||||||
|
memcpy(mirroredVtx, origVtx, sizeof(Vtx) * 4);
|
||||||
|
|
||||||
|
// Offset the vertex U coordinate values by the width of the texture
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
mirroredVtx[i].v.tc[0] += 128 << 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceMgr_PatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTexture_1", 13, mirroredSunSongTex[1]);
|
||||||
|
ResourceMgr_PatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTexture_2", 17, mirroredSunSongTex[5]);
|
||||||
|
ResourceMgr_PatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_1", 24, gsSPVertex(mirroredVtx, 4, 0));
|
||||||
|
// noop as the original vertex command is 128 bit wide
|
||||||
|
ResourceMgr_PatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_2", 25, gsSPNoOp());
|
||||||
|
} else {
|
||||||
|
if (mirroredVtx != nullptr) {
|
||||||
|
free(mirroredVtx);
|
||||||
|
mirroredVtx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceMgr_UnpatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTexture_1");
|
||||||
|
ResourceMgr_UnpatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTexture_2");
|
||||||
|
ResourceMgr_UnpatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_1");
|
||||||
|
ResourceMgr_UnpatchGfxByName(royalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyMirrorWorldGfxPatches() {
|
||||||
|
PatchMirroredSunSongEtching();
|
||||||
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void ApplyAuthenticGfxPatches();
|
void ApplyAuthenticGfxPatches();
|
||||||
|
void ApplyMirrorWorldGfxPatches();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
||||||
#include "soh/Enhancements/enhancementTypes.h"
|
#include "soh/Enhancements/enhancementTypes.h"
|
||||||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||||
|
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <z64.h>
|
#include <z64.h>
|
||||||
@ -552,20 +553,32 @@ void RegisterMenuPathFix() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdateMirrorModeState(int32_t sceneNum) {
|
void UpdateMirrorModeState(int32_t sceneNum) {
|
||||||
if (CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) == MIRRORED_WORLD_RANDOM_SEEDED) {
|
static bool prevMirroredWorld = false;
|
||||||
|
bool nextMirroredWorld = false;
|
||||||
|
|
||||||
|
int16_t mirroredMode = CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF);
|
||||||
|
|
||||||
|
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED) {
|
||||||
uint32_t seed = sceneNum + (gSaveContext.n64ddFlag ? (gSaveContext.seedIcons[0] + gSaveContext.seedIcons[1] + gSaveContext.seedIcons[2] + gSaveContext.seedIcons[3] + gSaveContext.seedIcons[4]) : gSaveContext.sohStats.fileCreatedAt);
|
uint32_t seed = sceneNum + (gSaveContext.n64ddFlag ? (gSaveContext.seedIcons[0] + gSaveContext.seedIcons[1] + gSaveContext.seedIcons[2] + gSaveContext.seedIcons[3] + gSaveContext.seedIcons[4]) : gSaveContext.sohStats.fileCreatedAt);
|
||||||
Random_Init(seed);
|
Random_Init(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t randomNumber = Random(0, 2);
|
uint8_t randomNumber = Random(0, 2);
|
||||||
if (
|
if (
|
||||||
CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) == MIRRORED_WORLD_ALWAYS ||
|
mirroredMode == MIRRORED_WORLD_ALWAYS ||
|
||||||
CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF) > MIRRORED_WORLD_ALWAYS && randomNumber == 1
|
(mirroredMode > MIRRORED_WORLD_ALWAYS && randomNumber == 1)
|
||||||
) {
|
) {
|
||||||
|
nextMirroredWorld = true;
|
||||||
CVarSetInteger("gMirroredWorld", 1);
|
CVarSetInteger("gMirroredWorld", 1);
|
||||||
} else {
|
} else {
|
||||||
|
nextMirroredWorld = false;
|
||||||
CVarClear("gMirroredWorld");
|
CVarClear("gMirroredWorld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prevMirroredWorld != nextMirroredWorld) {
|
||||||
|
prevMirroredWorld = nextMirroredWorld;
|
||||||
|
ApplyMirrorWorldGfxPatches();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterMirrorModeHandler() {
|
void RegisterMirrorModeHandler() {
|
||||||
|
Loading…
Reference in New Issue
Block a user