summaryrefslogtreecommitdiff
path: root/soh/src/code
diff options
context:
space:
mode:
authorAdam Bird <Archez@users.noreply.github.com>2023-06-12 17:10:53 -0400
committerGitHub <noreply@github.com>2023-06-12 17:10:53 -0400
commitca9b1614af5b5613f1cd54413d0e180b69d3c796 (patch)
tree0f9c0486effc3d8e7350386b4cdae11772847f7c /soh/src/code
parent21560ecf65866c2f1caad337cd6db263c5786dae (diff)
Fix: Minimap dungeon entrance placement (#2958)
* use correct minimaps in randomizer * fix minimap dungeon entrance placement * rework topLeft0 check to be more readable * who needs topLeft0 anyways * move minimap hidden checks up higher
Diffstat (limited to 'soh/src/code')
-rw-r--r--soh/src/code/z_map_exp.c123
1 files changed, 49 insertions, 74 deletions
diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c
index 5b23d6ed1..990f1b695 100644
--- a/soh/src/code/z_map_exp.c
+++ b/soh/src/code/z_map_exp.c
@@ -392,7 +392,9 @@ void Map_InitData(PlayState* play, s16 room) {
extendedMapIndex = 0x14;
}
} else if (play->sceneNum == SCENE_SPOT06) {
- if ((LINK_AGE_IN_YEARS == YEARS_ADULT) && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) {
+ if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
+ ((!gSaveContext.n64ddFlag && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
+ (gSaveContext.n64ddFlag && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) {
extendedMapIndex = 0x15;
}
} else if (play->sceneNum == SCENE_SPOT09) {
@@ -400,7 +402,8 @@ void Map_InitData(PlayState* play, s16 room) {
extendedMapIndex = 0x16;
}
} else if (play->sceneNum == SCENE_SPOT12) {
- if ((gSaveContext.eventChkInf[9] & 0xF) == 0xF) {
+ if ((!gSaveContext.n64ddFlag && ((gSaveContext.eventChkInf[9] & 0xF) == 0xF)) ||
+ (gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
extendedMapIndex = 0x17;
}
}
@@ -651,10 +654,6 @@ void Minimap_DrawCompassIcons(PlayState* play) {
Matrix_Translate(
(R_COMPASS_OFFSET_X + tempX + (CVarGetInteger("gMinimapPosX", 0)*10) / 10.0f),
(R_COMPASS_OFFSET_Y + ((Y_Margins_Minimap*10)*-1) - tempZ + ((CVarGetInteger("gMinimapPosY", 0)*10)*-1)) / 10.0f, 0.0f, MTXMODE_NEW);
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- Matrix_Translate(
- (R_COMPASS_OFFSET_X+(9999*10) + tempX / 10.0f),
- (R_COMPASS_OFFSET_Y+(9999*10) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
}
} else {
Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X+(X_Margins_Minimap*10) + tempX) / 10.0f), (R_COMPASS_OFFSET_Y+((Y_Margins_Minimap*10)*-1) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
@@ -689,10 +688,6 @@ void Minimap_DrawCompassIcons(PlayState* play) {
Matrix_Translate(
(R_COMPASS_OFFSET_X + tempX + (CVarGetInteger("gMinimapPosX", 0)*10) / 10.0f),
(R_COMPASS_OFFSET_Y - tempZ + ((CVarGetInteger("gMinimapPosY", 0)*10)*-1)) / 10.0f, 0.0f, MTXMODE_NEW);
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- Matrix_Translate(
- (R_COMPASS_OFFSET_X+(9999*10) + tempX / 10.0f),
- (R_COMPASS_OFFSET_Y+(9999*10) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
}
} else {
Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X+(X_Margins_Minimap*10) + tempX) / 10.0f), (R_COMPASS_OFFSET_Y+((Y_Margins_Minimap*10)*-1) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
@@ -749,7 +744,7 @@ void Minimap_Draw(PlayState* play) {
case SCENE_HAKADAN:
case SCENE_HAKADANCH:
case SCENE_ICE_DOUKUTO:
- if (!R_MINIMAP_DISABLED) {
+ if (!R_MINIMAP_DISABLED && CVarGetInteger("gMinimapPosType", 0) != 4) { // Not Hidden
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
gDPSetCombineLERP(OVERLAY_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0,
TEXEL0, 0, PRIMITIVE, 0);
@@ -773,8 +768,6 @@ void Minimap_Draw(PlayState* play) {
dgnMiniMapX = OTRGetDimensionFromRightEdge(R_DGN_MINIMAP_X+CVarGetInteger("gMinimapPosX", 0)+X_Margins_Minimap);
} else if (CVarGetInteger("gMinimapPosType", 0) == 3) {//Anchor None
dgnMiniMapX = CVarGetInteger("gMinimapPosX", 0);
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- dgnMiniMapX = -9999;
}
}
gSPWideTextureRectangle(OVERLAY_DISP++, dgnMiniMapX << 2, dgnMiniMapY << 2,
@@ -821,7 +814,7 @@ void Minimap_Draw(PlayState* play) {
case SCENE_SPOT18:
case SCENE_SPOT20:
case SCENE_GANON_TOU:
- if (!R_MINIMAP_DISABLED) {
+ if (!R_MINIMAP_DISABLED && CVarGetInteger("gMinimapPosType", 0) != 4) { // Not Hidden
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
@@ -844,8 +837,6 @@ void Minimap_Draw(PlayState* play) {
oWMiniMapX = OTRGetDimensionFromRightEdge(R_OW_MINIMAP_X+CVarGetInteger("gMinimapPosX", 0)+X_Margins_Minimap);
} else if (CVarGetInteger("gMinimapPosType", 0) == 3) {//Anchor None
oWMiniMapX = CVarGetInteger("gMinimapPosX", 0);
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- oWMiniMapX = -9999;
}
}
gSPWideTextureRectangle(OVERLAY_DISP++, oWMiniMapX << 2, oWMiniMapY << 2,
@@ -855,59 +846,51 @@ void Minimap_Draw(PlayState* play) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b, interfaceCtx->minimapAlpha);
+ s16 iconSize = 8;
+
if (((play->sceneNum != SCENE_SPOT01) && (play->sceneNum != SCENE_SPOT04) &&
(play->sceneNum != SCENE_SPOT08)) ||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) {
- bool Map0 = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 == 0;
- s16 IconSize = 8;
- s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + (Map0 ? 0 : X_Margins_Minimap);
- s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + (Map0 ? 0 : Y_Margins_Minimap);
- //gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed.
-
- s16 TopLeftX = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX) : OTRGetRectDimensionFromRightEdge(PosX)) << 2;
- s16 TopLeftY = PosY << 2;
- s16 TopLeftW = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX + IconSize) : OTRGetRectDimensionFromRightEdge(PosX + IconSize)) << 2;
- s16 TopLeftH = (PosY + IconSize) << 2;
+ // The game authentically uses larger negative values for the entrance icon Y pos value. Normally only the first 12 bits
+ // would be read when the final value is passed into `gSPTextureRectangle`, but our cosmetic hud placements requires using
+ // `gSPWideTextureRectangle` which reads the first 24 bits instead. This caused the icon to be placed off screen.
+ // To address this, we take only the first 10 bits (which are later left-shifted by 2 to get our final 12 bits)
+ // to fix the entrance icon position when used with `gSPWideTextureRectangle`
+ s16 newY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] & 0x3FF;
+ s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + X_Margins_Minimap;
+
+ s16 entranceX = OTRGetRectDimensionFromRightEdge(PosX);
+ s16 entranceY = newY + Y_Margins_Minimap;
if (CVarGetInteger("gMinimapPosType", 0) != 0) {
- PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + CVarGetInteger("gMinimapPosX", 0) + X_Margins_Minimap;
- PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + CVarGetInteger("gMinimapPosY", 0) + Y_Margins_Minimap;
- if (CVarGetInteger("gMinimapPosType", 0) == 1) {//Anchor Left
+ entranceY = newY + CVarGetInteger("gMinimapPosY", 0) + Y_Margins_Minimap;
+ if (CVarGetInteger("gMinimapPosType", 0) == 1) { // Anchor Left
if (CVarGetInteger("gMinimapUseMargins", 0) != 0) {X_Margins_Minimap = Left_MM_Margin;};
- TopLeftX = OTRGetRectDimensionFromLeftEdge(PosX) << 2;
- TopLeftW = OTRGetRectDimensionFromLeftEdge(PosX + IconSize) << 2;
- } else if (CVarGetInteger("gMinimapPosType", 0) == 2) {//Anchor Right
+ entranceX = OTRGetRectDimensionFromLeftEdge(PosX + CVarGetInteger("gMinimapPosX", 0));
+ } else if (CVarGetInteger("gMinimapPosType", 0) == 2) { // Anchor Right
if (CVarGetInteger("gMinimapUseMargins", 0) != 0) {X_Margins_Minimap = Right_MM_Margin;};
- TopLeftX = OTRGetRectDimensionFromRightEdge(PosX) << 2;
- TopLeftW = OTRGetRectDimensionFromRightEdge(PosX + IconSize) << 2;
- } else if (CVarGetInteger("gMinimapPosType", 0) == 3) {//Anchor None
- TopLeftX = PosX << 2;
- TopLeftW = PosX + IconSize << 2;
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- TopLeftX = -9999 << 2;
- TopLeftW = -9999 + IconSize << 2;
- }
- if (!CVarGetInteger("gMinimapPosType", 0) != 4 && Map0 && !CVarGetInteger("gFixDungeonMinimapIcon", 0)) { //Force top left icon if fix not applied.
- TopLeftX = OTRGetRectDimensionFromLeftEdge(gMapData->owEntranceIconPosX[sEntranceIconMapIndex]) << 2;
- TopLeftY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2;
- TopLeftW = OTRGetRectDimensionFromLeftEdge(gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + IconSize) << 2;
- TopLeftH = (gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + IconSize) << 2;
+ entranceX = OTRGetRectDimensionFromRightEdge(PosX + CVarGetInteger("gMinimapPosX", 0));
+ } else if (CVarGetInteger("gMinimapPosType", 0) == 3) { // Anchor None
+ entranceX = PosX + CVarGetInteger("gMinimapPosX", 0);
}
}
- if (CVarGetInteger("gFixDungeonMinimapIcon", 0) != 0){
- //No idea why and how Original value work but this does actually fix them all.
- PosY = PosY+1024;
+
+ // For icons that normally would be placed in 0,0 leave them there based on the left edge dimension
+ // or hide them entirely if the fix is applied
+ if (gMapData->owEntranceIconPosY[sEntranceIconMapIndex] == 0) {
+ entranceY = 0;
+ entranceX = CVarGetInteger("gFixDungeonMinimapIcon", 0) ? -9999 : OTRGetRectDimensionFromLeftEdge(0);
}
- if (((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
- ((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
- (gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]])
- )) || CVarGetInteger("gAlwaysShowDungeonMinimapIcon", 0)) {
- if (!Map0 || !CVarGetInteger("gFixDungeonMinimapIcon", 0)) {
- gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
- IconSize, IconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
- G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
- gSPWideTextureRectangle(OVERLAY_DISP++, TopLeftX, TopLeftY, TopLeftW, TopLeftH, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
- }
+ //! @bug UB: sEntranceIconMapIndex can be up to 23 and is accessing owEntranceFlag which is size 20
+ if ((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
+ ((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
+ ((gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]]) ||
+ CVarGetInteger("gAlwaysShowDungeonMinimapIcon", 0)))) {
+ gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
+ iconSize, iconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
+ G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
+ gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + iconSize) << 2,
+ (entranceY + iconSize) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
}
@@ -923,25 +906,17 @@ void Minimap_Draw(PlayState* play) {
entranceX = OTRGetRectDimensionFromRightEdge(270 + X_Margins_Minimap + CVarGetInteger("gMinimapPosX", 0));
} else if (CVarGetInteger("gMinimapPosType", 0) == 3) {//Anchor None
entranceX = 270 + X_Margins_Minimap + CVarGetInteger("gMinimapPosX", 0);
- } else if (CVarGetInteger("gMinimapPosType", 0) == 4) {//Hidden
- entranceX = -9999;
}
}
- if ((play->sceneNum == SCENE_SPOT08) && (gSaveContext.infTable[26] & gBitFlags[9])) {
- gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8,
- 8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
+ // Ice Cavern entrance icon
+ if ((play->sceneNum == SCENE_SPOT08) && ((gSaveContext.infTable[26] & gBitFlags[9]) ||
+ CVarGetInteger("gAlwaysShowDungeonMinimapIcon", 0))) {
+ gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, iconSize,
+ iconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
- gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + 32) << 2, (entranceY + 8) << 2,
- G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
- } else if ((play->sceneNum == SCENE_SPOT08) && CVarGetInteger("gAlwaysShowDungeonMinimapIcon", 0) != 0){
-
- gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8,
- 8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
- G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
-
- gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + 32) << 2, (entranceY + 8) << 2,
- G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
+ gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + iconSize) << 2,
+ (entranceY + iconSize) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
Minimap_DrawCompassIcons(play); // Draw icons for the player spawn and current position