mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 06:13:45 -07:00
Merge b55d6f4b76
into 330e64180c
This commit is contained in:
commit
826aa2371c
34 changed files with 5957 additions and 1053 deletions
|
@ -1687,7 +1687,8 @@ typedef struct PreNMIContext {
|
|||
} PreNMIContext; // size = 0xAC
|
||||
|
||||
typedef enum {
|
||||
/* 1 */ F_8F = 1,
|
||||
/* 0 */ F_NA,
|
||||
/* 1 */ F_8F,
|
||||
/* 2 */ F_7F,
|
||||
/* 3 */ F_6F,
|
||||
/* 4 */ F_5F,
|
||||
|
|
|
@ -47,8 +47,8 @@ typedef struct {
|
|||
/* 0x28 */ u16 equipment; // a mask where each nibble corresponds to a type of equipment `EquipmentType`, and each bit to an owned piece `EquipInv*`
|
||||
/* 0x2C */ u32 upgrades;
|
||||
/* 0x30 */ u32 questItems;
|
||||
/* 0x34 */ u8 dungeonItems[20];
|
||||
/* 0x48 */ s8 dungeonKeys[19];
|
||||
/* 0x34 */ u8* dungeonItems;
|
||||
/* 0x48 */ s8* dungeonKeys;
|
||||
/* 0x5B */ s8 defenseHearts;
|
||||
/* 0x5C */ s16 gsTokens;
|
||||
} Inventory; // size = 0x5E
|
||||
|
@ -224,7 +224,7 @@ typedef struct {
|
|||
/* 0x0066 */ s16 savedSceneNum; // Upstream TODO: sceneId
|
||||
/* 0x0068 */ ItemEquips equips;
|
||||
/* 0x0074 */ Inventory inventory;
|
||||
/* 0x00D4 */ SavedSceneFlags sceneFlags[124];
|
||||
/* 0x00D4 */ SavedSceneFlags* sceneFlags;
|
||||
/* 0x0E64 */ FaroresWindData fw;
|
||||
/* 0x0E8C */ char unk_E8C[0x10];
|
||||
/* 0x0E9C */ s32 gsFlags[6];
|
||||
|
|
|
@ -514,7 +514,7 @@ ActorDB::Entry& ActorDB::AddEntry(const std::string& name, const std::string& de
|
|||
return entry;
|
||||
}
|
||||
|
||||
// Adds an actor with the new ActorDBInit struct. The id assigned to the actor is dynamic. Use the return Entry or
|
||||
// Adds an actor with the new ActorDBInit struct. The id assigned to the actor is dynamic. Use the returned Entry or
|
||||
// RetrieveId to get it.
|
||||
ActorDB::Entry& ActorDB::AddEntry(const ActorDBInit& init) {
|
||||
Entry& entry = AddEntry(init.name, init.desc, nextFreeId);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
|
||||
#include "soh/Enhancements/item-tables/ItemTableManager.h"
|
||||
|
@ -857,13 +858,16 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
*should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY);
|
||||
break;
|
||||
case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS:
|
||||
*should = LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
*should = LINK_IS_ADULT &&
|
||||
(EntranceDB::Instance->RetrieveEntry(gSaveContext.entranceIndex).entry.sceneId ==
|
||||
SCENE_TEMPLE_OF_TIME) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
|
||||
MeetsLACSRequirements();
|
||||
break;
|
||||
case VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW:
|
||||
*should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT &&
|
||||
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE &&
|
||||
(EntranceDB::Instance->RetrieveEntry(gSaveContext.entranceIndex).entry.sceneId ==
|
||||
SCENE_KAKARIKO_VILLAGE) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER);
|
||||
break;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "dungeon.h"
|
||||
#include "context.h"
|
||||
#include "macros.h"
|
||||
|
@ -2025,6 +2026,7 @@ void Logic::InitSaveContext() {
|
|||
mSaveContext->equips.equipment = 0;
|
||||
|
||||
// Inventory
|
||||
size_t numScenes = SceneDB::Instance->GetNumEntries();
|
||||
for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) {
|
||||
mSaveContext->inventory.items[item] = ITEM_NONE;
|
||||
}
|
||||
|
@ -2034,15 +2036,15 @@ void Logic::InitSaveContext() {
|
|||
mSaveContext->inventory.equipment = 0;
|
||||
mSaveContext->inventory.upgrades = 0;
|
||||
mSaveContext->inventory.questItems = 0;
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) {
|
||||
for (int dungeon = 0; dungeon < numScenes; dungeon++) {
|
||||
mSaveContext->inventory.dungeonItems[dungeon] = 0;
|
||||
}
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) {
|
||||
for (int dungeon = 0; dungeon < numScenes; dungeon++) {
|
||||
mSaveContext->inventory.dungeonKeys[dungeon] = 0x0;
|
||||
}
|
||||
mSaveContext->inventory.defenseHearts = 0;
|
||||
mSaveContext->inventory.gsTokens = 0;
|
||||
for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) {
|
||||
for (int scene = 0; scene < numScenes; scene++) {
|
||||
mSaveContext->sceneFlags[scene].chest = 0;
|
||||
mSaveContext->sceneFlags[scene].swch = 0;
|
||||
mSaveContext->sceneFlags[scene].clear = 0;
|
||||
|
@ -2121,9 +2123,16 @@ void Logic::InitSaveContext() {
|
|||
|
||||
void Logic::NewSaveContext() {
|
||||
if (mSaveContext != nullptr && mSaveContext != &gSaveContext) {
|
||||
free(mSaveContext);
|
||||
delete[] mSaveContext->inventory.dungeonItems;
|
||||
delete[] mSaveContext->inventory.dungeonKeys;
|
||||
delete[] mSaveContext->sceneFlags;
|
||||
delete mSaveContext;
|
||||
}
|
||||
size_t numScenes = SceneDB::Instance->GetNumEntries();
|
||||
mSaveContext = new SaveContext();
|
||||
mSaveContext->inventory.dungeonItems = new u8[numScenes];
|
||||
mSaveContext->inventory.dungeonKeys = new s8[numScenes];
|
||||
mSaveContext->sceneFlags = new SavedSceneFlags[numScenes];
|
||||
InitSaveContext();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "randomizer_grotto.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "global.h"
|
||||
|
@ -92,7 +93,7 @@ static void Entrance_SeparateOGCFairyFountainExit(void) {
|
|||
// Overwrite unused entrance 0x03E8 (ENTR_POTION_SHOP_KAKARIKO_1) with values from 0x0340
|
||||
// (ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT) to use it as the exit from OGC Great Fairy Fountain -> Castle Grounds
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
gEntranceTable[ENTR_POTION_SHOP_KAKARIKO_1 + i] = gEntranceTable[ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT + i];
|
||||
EntranceDB_Copy(ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT + i, ENTR_POTION_SHOP_KAKARIKO_1 + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +101,7 @@ static void Entrance_SeparateAdultSpawnAndPrelude() {
|
|||
// Overwrite unused entrance 0x0282 (ENTR_HYRULE_FIELD_10) with values from 0x05F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD) to
|
||||
// use it as the Adult Spawn index and separate it from Prelude of Light
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
gEntranceTable[ENTR_HYRULE_FIELD_10 + i] = gEntranceTable[ENTR_TEMPLE_OF_TIME_WARP_PAD + i];
|
||||
EntranceDB_Copy(ENTR_TEMPLE_OF_TIME_WARP_PAD + i, ENTR_HYRULE_FIELD_10 + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,56 +110,45 @@ static void Entrance_ReplaceChildTempleWarps() {
|
|||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) {
|
||||
// Forest Temple
|
||||
gEntranceTable[ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP] =
|
||||
gEntranceTable[ENTR_SACRED_FOREST_MEADOW_WARP_PAD];
|
||||
gEntranceTable[ENTR_SACRED_FOREST_MEADOW_3_1] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_2_1];
|
||||
EntranceDB_Copy(ENTR_SACRED_FOREST_MEADOW_WARP_PAD, ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP);
|
||||
EntranceDB_Copy(ENTR_SACRED_FOREST_MEADOW_2_1, ENTR_SACRED_FOREST_MEADOW_3_1);
|
||||
// Fire Temple
|
||||
gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP] =
|
||||
gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD];
|
||||
gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_5_1] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_4_1];
|
||||
EntranceDB_Copy(ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP);
|
||||
EntranceDB_Copy(ENTR_DEATH_MOUNTAIN_CRATER_4_1, ENTR_DEATH_MOUNTAIN_CRATER_5_1);
|
||||
// Water Temple
|
||||
gEntranceTable[ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_LAKE_HYLIA_WARP_PAD];
|
||||
gEntranceTable[ENTR_LAKE_HYLIA_9_1] = gEntranceTable[ENTR_LAKE_HYLIA_8_1];
|
||||
EntranceDB_Copy(ENTR_LAKE_HYLIA_WARP_PAD, ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP);
|
||||
EntranceDB_Copy(ENTR_LAKE_HYLIA_8_1, ENTR_LAKE_HYLIA_9_1);
|
||||
// Shadow Temple
|
||||
gEntranceTable[ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_GRAVEYARD_WARP_PAD];
|
||||
gEntranceTable[ENTR_GRAVEYARD_8_1] = gEntranceTable[ENTR_GRAVEYARD_7_1];
|
||||
EntranceDB_Copy(ENTR_GRAVEYARD_WARP_PAD, ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP);
|
||||
EntranceDB_Copy(ENTR_GRAVEYARD_7_1, ENTR_GRAVEYARD_8_1);
|
||||
// Spirit Temple
|
||||
gEntranceTable[ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_DESERT_COLOSSUS_WARP_PAD];
|
||||
gEntranceTable[ENTR_DESERT_COLOSSUS_8_1] = gEntranceTable[ENTR_DESERT_COLOSSUS_5_1];
|
||||
}
|
||||
}
|
||||
|
||||
void Entrance_CopyOriginalEntranceTable(void) {
|
||||
if (!hasCopiedEntranceTable) {
|
||||
memcpy(originalEntranceTable, gEntranceTable, sizeof(EntranceInfo) * ENTRANCE_TABLE_SIZE);
|
||||
hasCopiedEntranceTable = 1;
|
||||
EntranceDB_Copy(ENTR_DESERT_COLOSSUS_WARP_PAD, ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP);
|
||||
EntranceDB_Copy(ENTR_DESERT_COLOSSUS_5_1, ENTR_DESERT_COLOSSUS_8_1);
|
||||
}
|
||||
}
|
||||
|
||||
void Entrance_ResetEntranceTable(void) {
|
||||
if (hasCopiedEntranceTable && hasModifiedEntranceTable) {
|
||||
memcpy(gEntranceTable, originalEntranceTable, sizeof(EntranceInfo) * ENTRANCE_TABLE_SIZE);
|
||||
hasModifiedEntranceTable = 0;
|
||||
}
|
||||
EntranceDB_ResetVanillaEntrances();
|
||||
}
|
||||
|
||||
void Entrance_Init(void) {
|
||||
EntranceOverride* entranceOverrides = Randomizer_GetEntranceOverrides();
|
||||
s32 index;
|
||||
|
||||
Entrance_CopyOriginalEntranceTable();
|
||||
|
||||
// Skip Child Stealth if given by settings
|
||||
if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH)) {
|
||||
gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].scene = SCENE_CASTLE_COURTYARD_ZELDA;
|
||||
gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].spawn = 0;
|
||||
gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].field =
|
||||
ENTRANCE_INFO_FIELD(false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE);
|
||||
EntranceDB_Copy(ENTR_CASTLE_COURTYARD_ZELDA_0, ENTR_CASTLE_COURTYARD_GUARDS_DAY_0);
|
||||
}
|
||||
|
||||
// Delete the title card and add a fade in for Hyrule Field from Ocarina of Time cutscene
|
||||
for (index = ENTR_HYRULE_FIELD_16; index <= ENTR_HYRULE_FIELD_16_3; ++index) {
|
||||
gEntranceTable[index].field = ENTRANCE_INFO_FIELD(false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_INSTANT);
|
||||
// Normally modifying a EntranceDBEntry is not safe since it can mess up the internal tables,
|
||||
// but since we are just changing the cosmetic stuff, it is fine
|
||||
EntranceDBEntry* entry = EntranceDB_Retrieve(index);
|
||||
entry->continueBgm = false;
|
||||
entry->displayTitleCard = false;
|
||||
entry->endTransition = TRANS_TYPE_FADE_BLACK;
|
||||
entry->startTransition = TRANS_TYPE_INSTANT;
|
||||
}
|
||||
|
||||
Entrance_SeparateOGCFairyFountainExit();
|
||||
|
@ -251,9 +241,7 @@ void Entrance_Init(void) {
|
|||
|
||||
s16 override = indicesToSilenceBackgroundMusic[j];
|
||||
for (s16 i = 0; i < 4; i++) {
|
||||
// Zero out the bit in the field which tells the game to keep playing
|
||||
// background music for all four scene setups at each index
|
||||
gEntranceTable[override + i].field &= ~ENTRANCE_INFO_CONTINUE_BGM_FLAG;
|
||||
EntranceDB_Retrieve(override + i)->continueBgm = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -316,8 +304,8 @@ u32 Entrance_SceneAndSpawnAre(u8 scene, u8 spawn) {
|
|||
}
|
||||
}
|
||||
|
||||
EntranceInfo currentEntrance = gEntranceTable[entranceIndex];
|
||||
return currentEntrance.scene == scene && currentEntrance.spawn == spawn;
|
||||
EntranceDBEntry* entry = EntranceDB_Retrieve(entranceIndex);
|
||||
return entry->sceneId == scene && entry->spawn == spawn;
|
||||
}
|
||||
|
||||
// Properly respawn the player after a game over, accounting for dungeon entrance randomizer
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
@ -180,7 +181,8 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
|||
// LACS
|
||||
u8 meetsLACSRequirements =
|
||||
LINK_IS_ADULT &&
|
||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
|
||||
(EntranceDB::Instance->RetrieveEntry(gSaveContext.entranceIndex).entry.sceneId ==
|
||||
SCENE_TEMPLE_OF_TIME) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
|
||||
if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, meetsLACSRequirements)) {
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "message_data_static.h"
|
||||
#include "overlays/gamestates/ovl_file_choose/file_choose.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRush.h"
|
||||
#include "soh/resource/type/SohResourceType.h"
|
||||
|
||||
extern "C" {
|
||||
extern MapData* gMapData;
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
@ -206,6 +206,7 @@ void RegisterOnKaleidoscopeUpdateHook() {
|
|||
|
||||
PauseContext* pauseCtx = &gPlayState->pauseCtx;
|
||||
Input* input = &gPlayState->state.input[0];
|
||||
SceneDB::Entry& scene = SceneDB::Instance->RetrieveEntry(gSaveContext.mapIndex);
|
||||
|
||||
// Save game prompt
|
||||
if (pauseCtx->state == 7) {
|
||||
|
@ -454,8 +455,7 @@ void RegisterOnKaleidoscopeUpdateHook() {
|
|||
|
||||
// Cursor is on a dungeon floor position
|
||||
if (cursorPoint >= 3 && cursorPoint < 11) {
|
||||
int floorID =
|
||||
gMapData->floorID[gPlayState->interfaceCtx.unk_25A][pauseCtx->dungeonMapSlot - 3];
|
||||
int floorID = scene.entry.dungeonData.floors[pauseCtx->dungeonMapSlot - 3].id;
|
||||
// Normalize so F1 == 0, and negative numbers are basement levels
|
||||
int normalizedFloor = (floorID * -1) + 8;
|
||||
if (normalizedFloor >= 0) {
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "soh/SohGui/ImGuiUtils.h"
|
||||
#include "ActorDB.h"
|
||||
#include "SaveManager.h"
|
||||
#include "SceneDB.h"
|
||||
|
||||
#ifdef ENABLE_REMOTE_CONTROL
|
||||
#include "soh/Network/CrowdControl/CrowdControl.h"
|
||||
|
@ -1228,6 +1229,8 @@ extern "C" void InitOTR() {
|
|||
OTRGlobals::Instance->gRandoContext->AddExcludedOptions();
|
||||
AudioCollection::Instance = new AudioCollection();
|
||||
ActorDB::Instance = new ActorDB();
|
||||
SceneDB::Instance = new SceneDB();
|
||||
EntranceDB::Instance = new EntranceDB();
|
||||
#ifdef __APPLE__
|
||||
SpeechSynthesizer::Instance = new DarwinSpeechSynthesizer();
|
||||
SpeechSynthesizer::Instance->Init();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "macros.h"
|
||||
#include <variables.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "soh/SceneDB.h"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
|
||||
#define NOGDI // avoid various windows defines that conflict with things in z64.h
|
||||
|
@ -24,6 +25,7 @@
|
|||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
|
||||
extern "C" SaveContext gSaveContext;
|
||||
|
@ -117,7 +119,8 @@ SaveManager::SaveManager() {
|
|||
AddLoadFunction("base", 2, LoadBaseVersion2);
|
||||
AddLoadFunction("base", 3, LoadBaseVersion3);
|
||||
AddLoadFunction("base", 4, LoadBaseVersion4);
|
||||
AddSaveFunction("base", 4, SaveBase, true, SECTION_PARENT_NONE);
|
||||
AddLoadFunction("base", 5, LoadBaseVersion5);
|
||||
AddSaveFunction("base", 5, SaveBase, true, SECTION_PARENT_NONE);
|
||||
|
||||
AddLoadFunction("randomizer", 1, LoadRandomizerVersion1);
|
||||
AddLoadFunction("randomizer", 2, LoadRandomizerVersion2);
|
||||
|
@ -736,6 +739,7 @@ void SaveManager::InitFile(bool isDebug) {
|
|||
}
|
||||
|
||||
void SaveManager::InitFileImpl(bool isDebug) {
|
||||
AllocateSceneData();
|
||||
if (isDebug) {
|
||||
InitFileDebug();
|
||||
} else {
|
||||
|
@ -809,23 +813,11 @@ void SaveManager::InitFileNormal() {
|
|||
gSaveContext.inventory.equipment = 0x1100;
|
||||
gSaveContext.inventory.upgrades = 0;
|
||||
gSaveContext.inventory.questItems = 0;
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonItems); dungeon++) {
|
||||
gSaveContext.inventory.dungeonItems[dungeon] = 0;
|
||||
}
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonKeys); dungeon++) {
|
||||
gSaveContext.inventory.dungeonKeys[dungeon] = 0xFF;
|
||||
}
|
||||
std::fill_n(gSaveContext.inventory.dungeonItems, SceneDB::Instance->GetNumEntries(), 0);
|
||||
std::fill_n(gSaveContext.inventory.dungeonKeys, SceneDB::Instance->GetNumEntries(), -1);
|
||||
gSaveContext.inventory.defenseHearts = 0;
|
||||
gSaveContext.inventory.gsTokens = 0;
|
||||
for (int scene = 0; scene < ARRAY_COUNT(gSaveContext.sceneFlags); scene++) {
|
||||
gSaveContext.sceneFlags[scene].chest = 0;
|
||||
gSaveContext.sceneFlags[scene].swch = 0;
|
||||
gSaveContext.sceneFlags[scene].clear = 0;
|
||||
gSaveContext.sceneFlags[scene].collect = 0;
|
||||
gSaveContext.sceneFlags[scene].unk = 0;
|
||||
gSaveContext.sceneFlags[scene].rooms = 0;
|
||||
gSaveContext.sceneFlags[scene].floors = 0;
|
||||
}
|
||||
std::fill_n(gSaveContext.sceneFlags, SceneDB::Instance->GetNumEntries(), SavedSceneFlags{ 0, 0, 0, 0, 0, 0, 0 });
|
||||
gSaveContext.fw.pos.x = 0;
|
||||
gSaveContext.fw.pos.y = 0;
|
||||
gSaveContext.fw.pos.z = 0;
|
||||
|
@ -996,13 +988,12 @@ void SaveManager::InitFileDebug() {
|
|||
gSaveContext.inventory.equipment = 0x7777;
|
||||
gSaveContext.inventory.upgrades = 0x125249;
|
||||
gSaveContext.inventory.questItems = 0x1E3FFFF;
|
||||
static std::array<u8, 20> sDungeonItems = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonItems); dungeon++) {
|
||||
gSaveContext.inventory.dungeonItems[dungeon] = sDungeonItems[dungeon];
|
||||
}
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonKeys); dungeon++) {
|
||||
gSaveContext.inventory.dungeonKeys[dungeon] = 8;
|
||||
std::fill_n(gSaveContext.inventory.dungeonItems, SceneDB::Instance->GetNumEntries(), 0);
|
||||
for (int dungeon = 0; dungeon <= SCENE_ICE_CAVERN; dungeon++) {
|
||||
gSaveContext.inventory.dungeonItems[dungeon] = 0b111;
|
||||
}
|
||||
std::fill_n(gSaveContext.inventory.dungeonKeys, SceneDB::Instance->GetNumEntries(), 8);
|
||||
|
||||
gSaveContext.inventory.defenseHearts = 0;
|
||||
gSaveContext.inventory.gsTokens = 0;
|
||||
|
||||
|
@ -1117,13 +1108,8 @@ void SaveManager::InitFileMaxed() {
|
|||
gSaveContext.inventory.equipment = 0x7777;
|
||||
gSaveContext.inventory.upgrades = 3597531;
|
||||
gSaveContext.inventory.questItems = 33554431;
|
||||
static std::array<u8, 20> sDungeonItems = { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 };
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonItems); dungeon++) {
|
||||
gSaveContext.inventory.dungeonItems[dungeon] = sDungeonItems[dungeon];
|
||||
}
|
||||
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.inventory.dungeonKeys); dungeon++) {
|
||||
gSaveContext.inventory.dungeonKeys[dungeon] = 9;
|
||||
}
|
||||
std::fill_n(gSaveContext.inventory.dungeonItems, SceneDB::Instance->GetNumEntries(), 0b111);
|
||||
std::fill_n(gSaveContext.inventory.dungeonKeys, SceneDB::Instance->GetNumEntries(), 9);
|
||||
gSaveContext.inventory.defenseHearts = 20;
|
||||
gSaveContext.inventory.gsTokens = 100;
|
||||
|
||||
|
@ -1192,6 +1178,22 @@ void SaveManager::InitFileMaxed() {
|
|||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
}
|
||||
|
||||
void SaveManager::AllocateSceneData() {
|
||||
delete[] gSaveContext.inventory.dungeonItems;
|
||||
delete[] gSaveContext.inventory.dungeonKeys;
|
||||
delete[] gSaveContext.sceneFlags;
|
||||
|
||||
size_t numScenes = SceneDB::Instance->GetNumEntries();
|
||||
|
||||
gSaveContext.inventory.dungeonItems = new u8[numScenes];
|
||||
gSaveContext.inventory.dungeonKeys = new s8[numScenes];
|
||||
gSaveContext.sceneFlags = new SavedSceneFlags[numScenes];
|
||||
|
||||
std::fill_n(gSaveContext.inventory.dungeonItems, numScenes, 0);
|
||||
std::fill_n(gSaveContext.inventory.dungeonKeys, numScenes, -1);
|
||||
std::fill_n(gSaveContext.sceneFlags, numScenes, SavedSceneFlags{ 0, 0, 0, 0, 0, 0, 0 });
|
||||
}
|
||||
|
||||
#if defined(__WIIU__) || defined(__SWITCH__)
|
||||
// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
|
||||
int copy_file(const char* src, const char* dst) {
|
||||
|
@ -1568,16 +1570,16 @@ void SaveManager::LoadBaseVersion1() {
|
|||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadArray(
|
||||
"dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]); });
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("dungeonItems", 20, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", 19, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneFlags", SCENE_ID_MAX, [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
|
@ -1712,10 +1714,10 @@ void SaveManager::LoadBaseVersion2() {
|
|||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadArray(
|
||||
"dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]); });
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("dungeonItems", 20, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", 19, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
|
@ -1744,7 +1746,7 @@ void SaveManager::LoadBaseVersion2() {
|
|||
"entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]); });
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneFlags", SCENE_ID_MAX, [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
|
@ -1928,10 +1930,10 @@ void SaveManager::LoadBaseVersion3() {
|
|||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadArray(
|
||||
"dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]); });
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("dungeonItems", 20, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", 19, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
|
@ -1977,7 +1979,7 @@ void SaveManager::LoadBaseVersion3() {
|
|||
"entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]); });
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneFlags", SCENE_ID_MAX, [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
|
@ -2148,16 +2150,16 @@ void SaveManager::LoadBaseVersion4() {
|
|||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadArray(
|
||||
"dungeonItems", ARRAY_COUNT(gSaveContext.inventory.dungeonItems),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]); });
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", ARRAY_COUNT(gSaveContext.inventory.dungeonKeys), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("dungeonItems", 20, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("dungeonKeys", 19, [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("sceneFlags", ARRAY_COUNT(gSaveContext.sceneFlags), [](size_t i) {
|
||||
SaveManager::Instance->LoadArray("sceneFlags", SCENE_ID_MAX, [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
|
@ -2255,6 +2257,187 @@ void SaveManager::LoadBaseVersion4() {
|
|||
SaveManager::Instance->LoadData("maskMemory", gSaveContext.ship.maskMemory);
|
||||
}
|
||||
|
||||
void SaveManager::LoadBaseVersion5() {
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.entranceIndex);
|
||||
SaveManager::Instance->LoadData("linkAge", gSaveContext.linkAge);
|
||||
SaveManager::Instance->LoadData("cutsceneIndex", gSaveContext.cutsceneIndex);
|
||||
SaveManager::Instance->LoadData("dayTime", gSaveContext.dayTime);
|
||||
SaveManager::Instance->LoadData("nightFlag", gSaveContext.nightFlag);
|
||||
SaveManager::Instance->LoadData("totalDays", gSaveContext.totalDays);
|
||||
SaveManager::Instance->LoadData("bgsDayCount", gSaveContext.bgsDayCount);
|
||||
SaveManager::Instance->LoadData("deaths", gSaveContext.deaths);
|
||||
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.playerName[i]); });
|
||||
int isRando = 0;
|
||||
SaveManager::Instance->LoadData("n64ddFlag", isRando);
|
||||
if (isRando) {
|
||||
gSaveContext.ship.quest.id = QUEST_RANDOMIZER;
|
||||
}
|
||||
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
|
||||
SaveManager::Instance->LoadData("health", gSaveContext.health);
|
||||
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
|
||||
SaveManager::Instance->LoadData("magic", gSaveContext.magic);
|
||||
SaveManager::Instance->LoadData("rupees", gSaveContext.rupees);
|
||||
SaveManager::Instance->LoadData("swordHealth", gSaveContext.swordHealth);
|
||||
SaveManager::Instance->LoadData("naviTimer", gSaveContext.naviTimer);
|
||||
SaveManager::Instance->LoadData("isMagicAcquired", gSaveContext.isMagicAcquired);
|
||||
SaveManager::Instance->LoadData("isDoubleMagicAcquired", gSaveContext.isDoubleMagicAcquired);
|
||||
SaveManager::Instance->LoadData("isDoubleDefenseAcquired", gSaveContext.isDoubleDefenseAcquired);
|
||||
SaveManager::Instance->LoadData("bgsFlag", gSaveContext.bgsFlag);
|
||||
SaveManager::Instance->LoadData("ocarinaGameRoundNum", gSaveContext.ocarinaGameRoundNum);
|
||||
SaveManager::Instance->LoadStruct("childEquips", []() {
|
||||
SaveManager::Instance->LoadArray(
|
||||
"buttonItems", ARRAY_COUNT(gSaveContext.childEquips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.childEquips.buttonItems[i],
|
||||
static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray(
|
||||
"cButtonSlots", ARRAY_COUNT(gSaveContext.childEquips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.childEquips.cButtonSlots[i],
|
||||
static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.childEquips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("adultEquips", []() {
|
||||
SaveManager::Instance->LoadArray(
|
||||
"buttonItems", ARRAY_COUNT(gSaveContext.adultEquips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.buttonItems[i],
|
||||
static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray(
|
||||
"cButtonSlots", ARRAY_COUNT(gSaveContext.adultEquips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.adultEquips.cButtonSlots[i],
|
||||
static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.adultEquips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadData("unk_54", gSaveContext.unk_54);
|
||||
SaveManager::Instance->LoadData("savedSceneNum", gSaveContext.savedSceneNum);
|
||||
SaveManager::Instance->LoadStruct("equips", []() {
|
||||
SaveManager::Instance->LoadArray("buttonItems", ARRAY_COUNT(gSaveContext.equips.buttonItems), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.equips.buttonItems[i], static_cast<uint8_t>(ITEM_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadArray("cButtonSlots", ARRAY_COUNT(gSaveContext.equips.cButtonSlots), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.equips.cButtonSlots[i], static_cast<uint8_t>(SLOT_NONE));
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.equips.equipment);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("inventory", []() {
|
||||
SaveManager::Instance->LoadArray("items", ARRAY_COUNT(gSaveContext.inventory.items), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.items[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("ammo", ARRAY_COUNT(gSaveContext.inventory.ammo), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.inventory.ammo[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("equipment", gSaveContext.inventory.equipment);
|
||||
SaveManager::Instance->LoadData("upgrades", gSaveContext.inventory.upgrades);
|
||||
SaveManager::Instance->LoadData("questItems", gSaveContext.inventory.questItems);
|
||||
SaveManager::Instance->LoadData("defenseHearts", gSaveContext.inventory.defenseHearts);
|
||||
SaveManager::Instance->LoadData("gsTokens", gSaveContext.inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("sceneData", []() {
|
||||
for (size_t i = 0; i < SceneDB::Instance->GetNumEntries(); i++) {
|
||||
const SceneDB::Entry& entry = SceneDB::Instance->RetrieveEntry(static_cast<int>(i));
|
||||
SaveManager::Instance->LoadStruct(entry.name, [&i]() {
|
||||
SaveManager::Instance->LoadData("chest", gSaveContext.sceneFlags[i].chest);
|
||||
SaveManager::Instance->LoadData("swch", gSaveContext.sceneFlags[i].swch);
|
||||
SaveManager::Instance->LoadData("clear", gSaveContext.sceneFlags[i].clear);
|
||||
SaveManager::Instance->LoadData("collect", gSaveContext.sceneFlags[i].collect);
|
||||
SaveManager::Instance->LoadData("unk", gSaveContext.sceneFlags[i].unk);
|
||||
SaveManager::Instance->LoadData("rooms", gSaveContext.sceneFlags[i].rooms);
|
||||
SaveManager::Instance->LoadData("floors", gSaveContext.sceneFlags[i].floors);
|
||||
SaveManager::Instance->LoadData("dungeonKeys", gSaveContext.inventory.dungeonKeys[i]);
|
||||
SaveManager::Instance->LoadData("dungeonItems", gSaveContext.inventory.dungeonItems[i]);
|
||||
});
|
||||
}
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("fw", []() {
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.fw.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.fw.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.fw.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.fw.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.fw.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.fw.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.fw.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.fw.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.fw.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.fw.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("gsFlags", ARRAY_COUNT(gSaveContext.gsFlags),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.gsFlags[i]); });
|
||||
SaveManager::Instance->LoadArray("highScores", ARRAY_COUNT(gSaveContext.highScores),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.highScores[i]); });
|
||||
SaveManager::Instance->LoadArray("eventChkInf", ARRAY_COUNT(gSaveContext.eventChkInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.eventChkInf[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadArray("itemGetInf", ARRAY_COUNT(gSaveContext.itemGetInf),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.itemGetInf[i]); });
|
||||
SaveManager::Instance->LoadArray("infTable", ARRAY_COUNT(gSaveContext.infTable),
|
||||
[](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.infTable[i]); });
|
||||
SaveManager::Instance->LoadData("worldMapAreaData", gSaveContext.worldMapAreaData);
|
||||
SaveManager::Instance->LoadData("scarecrowLongSongSet", gSaveContext.scarecrowLongSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowLongSong", ARRAY_COUNT(gSaveContext.scarecrowLongSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowLongSong[i].noteIdx);
|
||||
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowLongSong[i].unk_01);
|
||||
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowLongSong[i].unk_02);
|
||||
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowLongSong[i].volume);
|
||||
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowLongSong[i].vibrato);
|
||||
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowLongSong[i].tone);
|
||||
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowLongSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadData("scarecrowSpawnSongSet", gSaveContext.scarecrowSpawnSongSet);
|
||||
SaveManager::Instance->LoadArray("scarecrowSpawnSong", ARRAY_COUNT(gSaveContext.scarecrowSpawnSong), [](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&i]() {
|
||||
SaveManager::Instance->LoadData("noteIdx", gSaveContext.scarecrowSpawnSong[i].noteIdx);
|
||||
SaveManager::Instance->LoadData("unk_01", gSaveContext.scarecrowSpawnSong[i].unk_01);
|
||||
SaveManager::Instance->LoadData("unk_02", gSaveContext.scarecrowSpawnSong[i].unk_02);
|
||||
SaveManager::Instance->LoadData("volume", gSaveContext.scarecrowSpawnSong[i].volume);
|
||||
SaveManager::Instance->LoadData("vibrato", gSaveContext.scarecrowSpawnSong[i].vibrato);
|
||||
SaveManager::Instance->LoadData("tone", gSaveContext.scarecrowSpawnSong[i].tone);
|
||||
SaveManager::Instance->LoadData("semitone", gSaveContext.scarecrowSpawnSong[i].semitone);
|
||||
});
|
||||
});
|
||||
SaveManager::Instance->LoadStruct("horseData", []() {
|
||||
SaveManager::Instance->LoadData("scene", gSaveContext.horseData.scene);
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.horseData.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.horseData.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.horseData.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("angle", gSaveContext.horseData.angle);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.ship.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.ship.randomizerInf[i]);
|
||||
});
|
||||
int isMQ = 0;
|
||||
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
|
||||
if (isMQ) {
|
||||
gSaveContext.ship.quest.id = QUEST_MASTER;
|
||||
}
|
||||
SaveManager::Instance->LoadStruct("backupFW", []() {
|
||||
SaveManager::Instance->LoadStruct("pos", []() {
|
||||
SaveManager::Instance->LoadData("x", gSaveContext.ship.backupFW.pos.x);
|
||||
SaveManager::Instance->LoadData("y", gSaveContext.ship.backupFW.pos.y);
|
||||
SaveManager::Instance->LoadData("z", gSaveContext.ship.backupFW.pos.z);
|
||||
});
|
||||
SaveManager::Instance->LoadData("yaw", gSaveContext.ship.backupFW.yaw);
|
||||
SaveManager::Instance->LoadData("playerParams", gSaveContext.ship.backupFW.playerParams);
|
||||
SaveManager::Instance->LoadData("entranceIndex", gSaveContext.ship.backupFW.entranceIndex);
|
||||
SaveManager::Instance->LoadData("roomIndex", gSaveContext.ship.backupFW.roomIndex);
|
||||
SaveManager::Instance->LoadData("set", gSaveContext.ship.backupFW.set);
|
||||
SaveManager::Instance->LoadData("tempSwchFlags", gSaveContext.ship.backupFW.tempSwchFlags);
|
||||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.ship.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
|
||||
SaveManager::Instance->LoadData("filenameLanguage", gSaveContext.ship.filenameLanguage);
|
||||
SaveManager::Instance->LoadData("maskMemory", gSaveContext.ship.maskMemory);
|
||||
}
|
||||
|
||||
void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
SaveManager::Instance->SaveData("entranceIndex", saveContext->entranceIndex);
|
||||
SaveManager::Instance->SaveData("linkAge", saveContext->linkAge);
|
||||
|
@ -2319,25 +2502,24 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
|
|||
SaveManager::Instance->SaveData("equipment", saveContext->inventory.equipment);
|
||||
SaveManager::Instance->SaveData("upgrades", saveContext->inventory.upgrades);
|
||||
SaveManager::Instance->SaveData("questItems", saveContext->inventory.questItems);
|
||||
SaveManager::Instance->SaveArray(
|
||||
"dungeonItems", ARRAY_COUNT(saveContext->inventory.dungeonItems),
|
||||
[&](size_t i) { SaveManager::Instance->SaveData("", saveContext->inventory.dungeonItems[i]); });
|
||||
SaveManager::Instance->SaveArray("dungeonKeys", ARRAY_COUNT(saveContext->inventory.dungeonKeys), [&](size_t i) {
|
||||
SaveManager::Instance->SaveData("", saveContext->inventory.dungeonKeys[i]);
|
||||
});
|
||||
SaveManager::Instance->SaveData("defenseHearts", saveContext->inventory.defenseHearts);
|
||||
SaveManager::Instance->SaveData("gsTokens", saveContext->inventory.gsTokens);
|
||||
});
|
||||
SaveManager::Instance->SaveArray("sceneFlags", ARRAY_COUNT(saveContext->sceneFlags), [&](size_t i) {
|
||||
SaveManager::Instance->SaveStruct("", [&]() {
|
||||
SaveManager::Instance->SaveData("chest", saveContext->sceneFlags[i].chest);
|
||||
SaveManager::Instance->SaveData("swch", saveContext->sceneFlags[i].swch);
|
||||
SaveManager::Instance->SaveData("clear", saveContext->sceneFlags[i].clear);
|
||||
SaveManager::Instance->SaveData("collect", saveContext->sceneFlags[i].collect);
|
||||
SaveManager::Instance->SaveData("unk", saveContext->sceneFlags[i].unk);
|
||||
SaveManager::Instance->SaveData("rooms", saveContext->sceneFlags[i].rooms);
|
||||
SaveManager::Instance->SaveData("floors", saveContext->sceneFlags[i].floors);
|
||||
});
|
||||
SaveManager::Instance->SaveStruct("sceneData", [&]() {
|
||||
for (size_t i = 0; i < SceneDB::Instance->GetNumEntries(); i++) {
|
||||
const SceneDB::Entry& entry = SceneDB::Instance->RetrieveEntry(static_cast<int>(i));
|
||||
SaveManager::Instance->SaveStruct(entry.name, [&]() {
|
||||
SaveManager::Instance->SaveData("chest", saveContext->sceneFlags[i].chest);
|
||||
SaveManager::Instance->SaveData("swch", saveContext->sceneFlags[i].swch);
|
||||
SaveManager::Instance->SaveData("clear", saveContext->sceneFlags[i].clear);
|
||||
SaveManager::Instance->SaveData("collect", saveContext->sceneFlags[i].collect);
|
||||
SaveManager::Instance->SaveData("unk", saveContext->sceneFlags[i].unk);
|
||||
SaveManager::Instance->SaveData("rooms", saveContext->sceneFlags[i].rooms);
|
||||
SaveManager::Instance->SaveData("floors", saveContext->sceneFlags[i].floors);
|
||||
SaveManager::Instance->SaveData("dungeonKeys", saveContext->inventory.dungeonKeys[i]);
|
||||
SaveManager::Instance->SaveData("dungeonItems", saveContext->inventory.dungeonItems[i]);
|
||||
});
|
||||
}
|
||||
});
|
||||
SaveManager::Instance->SaveStruct("fw", [&]() {
|
||||
SaveManager::Instance->SaveStruct("pos", [&]() {
|
||||
|
@ -2800,7 +2982,7 @@ void CopyV0Save(SaveContext_v0& src, SaveContext& dst) {
|
|||
}
|
||||
dst.inventory.defenseHearts = src.inventory.defenseHearts;
|
||||
dst.inventory.gsTokens = src.inventory.gsTokens;
|
||||
for (size_t i = 0; i < ARRAY_COUNT(src.sceneFlags); i++) {
|
||||
for (size_t i = 0; i < SCENE_ID_MAX; i++) {
|
||||
dst.sceneFlags[i].chest = src.sceneFlags[i].chest;
|
||||
dst.sceneFlags[i].swch = src.sceneFlags[i].swch;
|
||||
dst.sceneFlags[i].clear = src.sceneFlags[i].clear;
|
||||
|
|
|
@ -166,6 +166,8 @@ class SaveManager {
|
|||
static void InitFileDebug();
|
||||
static void InitFileMaxed();
|
||||
|
||||
static void AllocateSceneData();
|
||||
|
||||
static void LoadRandomizerVersion1();
|
||||
static void LoadRandomizerVersion2();
|
||||
static void LoadRandomizerVersion3();
|
||||
|
@ -177,6 +179,7 @@ class SaveManager {
|
|||
static void LoadBaseVersion2();
|
||||
static void LoadBaseVersion3();
|
||||
static void LoadBaseVersion4();
|
||||
static void LoadBaseVersion5();
|
||||
static void SaveBase(SaveContext* saveContext, int sectionID, bool fullSave);
|
||||
|
||||
std::vector<InitFunc> initFuncs;
|
||||
|
|
1190
soh/soh/SceneDB.cpp
Normal file
1190
soh/soh/SceneDB.cpp
Normal file
File diff suppressed because it is too large
Load diff
374
soh/soh/SceneDB.h
Normal file
374
soh/soh/SceneDB.h
Normal file
|
@ -0,0 +1,374 @@
|
|||
#pragma once
|
||||
#include <libultraship/libultra.h>
|
||||
#include "z64scene.h"
|
||||
#include "z64.h"
|
||||
|
||||
typedef struct {
|
||||
FloorID id;
|
||||
f32 height;
|
||||
s8* rooms;
|
||||
u32 numRooms;
|
||||
const char* mapLeftTexture;
|
||||
const char* mapRightTexture;
|
||||
PauseMapMarkPoint* chestMarks;
|
||||
u32 numChestMarks;
|
||||
PauseMapMarkPoint* bossMarks;
|
||||
u32 numBossMarks;
|
||||
} SceneDBFloor;
|
||||
|
||||
typedef struct {
|
||||
s16 compassOffsetX;
|
||||
s16 compassOffsetY;
|
||||
const char* minimapTexture;
|
||||
MapMarkPoint* chestMarks;
|
||||
u32 numChestMarks;
|
||||
MapMarkPoint* bossMarks;
|
||||
u32 numBossMarks;
|
||||
} SceneDBRoom;
|
||||
|
||||
typedef struct {
|
||||
u8 fromRoom;
|
||||
u8 toRoom;
|
||||
u8 toFloor;
|
||||
} SceneDBIntraRoomTransition;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* desc;
|
||||
u32 valid;
|
||||
s32 id;
|
||||
const char* titleCard;
|
||||
SceneDrawConfig sceneDrawConfig;
|
||||
struct {
|
||||
u8 hGauge;
|
||||
u8 bButton;
|
||||
u8 aButton;
|
||||
u8 bottles;
|
||||
u8 tradeItems;
|
||||
u8 hookshot;
|
||||
u8 ocarina;
|
||||
u8 warpSongs;
|
||||
u8 sunsSong;
|
||||
u8 farores;
|
||||
u8 dinsNayrus;
|
||||
u8 all;
|
||||
} restrictions;
|
||||
struct {
|
||||
u32 allowed;
|
||||
Vec3s startingPos;
|
||||
s16 angle;
|
||||
Vec3s* spawnPos;
|
||||
u32 numSpawns;
|
||||
} epona;
|
||||
struct {
|
||||
s16 scaleX;
|
||||
s16 scaleY;
|
||||
s16 x;
|
||||
s16 y;
|
||||
} compassInfo;
|
||||
struct {
|
||||
s32 mapScene;
|
||||
} bossData;
|
||||
struct {
|
||||
s32 bossFloor;
|
||||
s16* palettes;
|
||||
u32 numPalettes;
|
||||
const char* nameEngTexture;
|
||||
const char* nameGerTexture;
|
||||
const char* nameFraTexture;
|
||||
SceneDBFloor floors[8];
|
||||
SceneDBRoom* rooms;
|
||||
u32 numRooms;
|
||||
SceneDBIntraRoomTransition* intraRoomTransitions;
|
||||
u32 numIntraRoomTransitions;
|
||||
} dungeonData;
|
||||
struct {
|
||||
s16 minimapX;
|
||||
s16 minimapY;
|
||||
s16 minimapWidth;
|
||||
s16 minimapHeight;
|
||||
s16 iconX;
|
||||
s16 iconY;
|
||||
s16 entranceFlag;
|
||||
const char* minimapTexture;
|
||||
} worldData;
|
||||
} SceneDBEntry;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* desc;
|
||||
u32 valid;
|
||||
s32 id;
|
||||
s32 sceneId;
|
||||
s32 spawn;
|
||||
s32 layer;
|
||||
u8 continueBgm;
|
||||
u8 displayTitleCard;
|
||||
u8 endTransition;
|
||||
u8 startTransition;
|
||||
} EntranceDBEntry;
|
||||
|
||||
#define SCENEDB_ISBOSS(entry) ((entry)->bossData.mapScene != -1)
|
||||
#define SCENEDB_ISDUNGEON(entry) ((entry)->dungeonData.numRooms != 0)
|
||||
#define SCENEDB_ISOVERWORLD(entry) ((entry)->worldData.minimapTexture != NULL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SceneDB {
|
||||
public:
|
||||
static SceneDB* Instance;
|
||||
|
||||
struct Init {
|
||||
struct FloorInit {
|
||||
FloorID id = F_NA;
|
||||
f32 height = 9999.0f;
|
||||
std::vector<s8> palettes;
|
||||
std::string mapLeftTexture;
|
||||
std::string mapRightTexture;
|
||||
std::vector<PauseMapMarkPoint> chestMarks;
|
||||
std::vector<PauseMapMarkPoint> bossMarks;
|
||||
};
|
||||
|
||||
struct RoomInit {
|
||||
s16 compassOffsetX = 0;
|
||||
s16 compassOffsetY = 0;
|
||||
std::string minimapTexture;
|
||||
std::vector<MapMarkPoint> chestMarks;
|
||||
std::vector<MapMarkPoint> bossMarks;
|
||||
};
|
||||
|
||||
struct IntraRoomTransitionInit {
|
||||
u8 fromRoom = 0xFF;
|
||||
u8 toRoom = 0xFF;
|
||||
u8 toFloor = 0xFF;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::string desc;
|
||||
std::string titleCard;
|
||||
SceneDrawConfig sceneDrawConfig = SDC_DEFAULT;
|
||||
struct {
|
||||
bool hGauge = false;
|
||||
bool bButton = false;
|
||||
bool aButton = false;
|
||||
bool bottles = false;
|
||||
bool tradeItems = false;
|
||||
bool hookshot = false;
|
||||
bool ocarina = false;
|
||||
bool warpSongs = false;
|
||||
bool sunsSong = false;
|
||||
bool farores = false;
|
||||
bool dinsNayrus = false;
|
||||
bool all = false;
|
||||
} restrictions;
|
||||
struct {
|
||||
bool allowed = false;
|
||||
Vec3s startingPos = { 0, 0, 0 };
|
||||
s16 angle = 0;
|
||||
std::vector<Vec3s> spawnPos;
|
||||
} epona;
|
||||
struct {
|
||||
s16 scaleX = 0;
|
||||
s16 scaleY = 0;
|
||||
s16 x = 0;
|
||||
s16 y = 0;
|
||||
} compassInfo;
|
||||
struct {
|
||||
std::string mapScene;
|
||||
} bossData;
|
||||
struct {
|
||||
s32 bossFloor = -1;
|
||||
std::vector<s16> palettes;
|
||||
std::string nameEngTexture;
|
||||
std::string nameGerTexture;
|
||||
std::string nameFraTexture;
|
||||
std::vector<FloorInit> floors;
|
||||
std::vector<RoomInit> rooms;
|
||||
std::vector<IntraRoomTransitionInit> intraRoomTransitions;
|
||||
} dungeonData;
|
||||
struct {
|
||||
s16 minimapX = 0;
|
||||
s16 minimapY = 0;
|
||||
s16 minimapWidth = 0;
|
||||
s16 minimapHeight = 0;
|
||||
s16 iconX = 0;
|
||||
s16 iconY = 0;
|
||||
s16 entranceFlag = -1;
|
||||
std::string minimapTexture;
|
||||
} worldData;
|
||||
};
|
||||
|
||||
SceneDB();
|
||||
|
||||
// Wrapper around SceneDBEntry so we get C++isms for the entries
|
||||
struct Entry {
|
||||
Entry();
|
||||
Entry(const Entry& other);
|
||||
Entry& operator=(const Entry& other);
|
||||
|
||||
struct FloorInfo {
|
||||
std::vector<s8> rooms;
|
||||
std::string mapLeftTexture;
|
||||
std::string mapRightTexture;
|
||||
std::vector<PauseMapMarkPoint> chestMarks;
|
||||
std::vector<PauseMapMarkPoint> bossMarks;
|
||||
};
|
||||
|
||||
struct RoomInfo {
|
||||
std::string minimapTexture;
|
||||
std::vector<MapMarkPoint> chestMarks;
|
||||
std::vector<MapMarkPoint> bossMarks;
|
||||
};
|
||||
|
||||
void SetName(const std::string& newName);
|
||||
void SetDesc(const std::string& newDesc);
|
||||
void SetTitleCard(const std::string& newTitleCard);
|
||||
void SetEponaSpawnPos(const std::vector<Vec3s>& newSpawnPos);
|
||||
void SetDungeonPalettes(const std::vector<s16>& newDungeonPalettes);
|
||||
void SetDungeonNameTextures(const std::string& newNameEngTexture, const std::string& newNameGerTexture,
|
||||
const std::string& newNameFraTexture);
|
||||
void SetDungeonFloors(const std::vector<Init::FloorInit>& newDungeonFloors);
|
||||
void SetDungeonFloors(const std::vector<SceneDBFloor>& newDungeonFloors,
|
||||
const std::vector<FloorInfo>& newDungeonFloorInfo);
|
||||
void SetDungeonRooms(const std::vector<Init::RoomInit>& newDungeonRooms);
|
||||
void SetDungeonRooms(const std::vector<SceneDBRoom>& newDungeonRooms,
|
||||
const std::vector<RoomInfo>& newDungeonRoomInfo);
|
||||
void SetDungeonIntraRoomTransitions(
|
||||
const std::vector<Init::IntraRoomTransitionInit>& newDungeonIntraRoomTransitions);
|
||||
void
|
||||
SetDungeonIntraRoomTransitions(const std::vector<SceneDBIntraRoomTransition>& newDungeonIntraRoomTransitions);
|
||||
void SetWorldMinimapTexture(const std::string& newWorldMinimapTexture);
|
||||
void SetMapMarkData(const bool isMQ);
|
||||
void SetPauseMapMarkData(const bool isMQ);
|
||||
|
||||
bool isBoss();
|
||||
bool isDungeon();
|
||||
bool isOverworld();
|
||||
|
||||
std::string name;
|
||||
std::string desc;
|
||||
std::string titleCard;
|
||||
std::vector<Vec3s> eponaSpawnPos;
|
||||
std::vector<s16> dungeonPalettes;
|
||||
std::string nameEngTexture;
|
||||
std::string nameGerTexture;
|
||||
std::string nameFraTexture;
|
||||
std::vector<FloorInfo> dungeonFloorInfo;
|
||||
std::vector<SceneDBFloor> dungeonFloors;
|
||||
std::vector<RoomInfo> dungeonRoomInfo;
|
||||
std::vector<SceneDBRoom> dungeonRooms;
|
||||
std::vector<SceneDBIntraRoomTransition> dungeonIntraRoomTransitions;
|
||||
std::string worldMinimapTexture;
|
||||
SceneDBEntry entry;
|
||||
};
|
||||
Entry& AddEntry(const Init& init);
|
||||
|
||||
Entry& RetrieveEntry(const int id);
|
||||
int RetrieveId(const std::string& name);
|
||||
|
||||
size_t GetNumEntries();
|
||||
|
||||
private:
|
||||
Entry& AddEntry(const std::string& name, const std::string& desc, size_t index);
|
||||
|
||||
std::vector<Entry> db;
|
||||
std::unordered_map<std::string, int> nameTable;
|
||||
size_t nextFreeId = 0;
|
||||
};
|
||||
|
||||
class EntranceDB {
|
||||
public:
|
||||
static EntranceDB* Instance;
|
||||
|
||||
struct Init {
|
||||
std::string name;
|
||||
std::string desc;
|
||||
std::string scene;
|
||||
s32 spawn;
|
||||
bool continueBgm;
|
||||
bool displayTitleCard;
|
||||
u8 endTransition;
|
||||
u8 startTransition;
|
||||
};
|
||||
|
||||
EntranceDB();
|
||||
|
||||
// Wrapper around EntranceDBEntry so we get C++isms for the entries
|
||||
struct Entry {
|
||||
Entry();
|
||||
Entry(const Entry& other);
|
||||
Entry& operator=(const Entry& other);
|
||||
|
||||
void SetName(const std::string& newName);
|
||||
void SetDesc(const std::string& newDesc);
|
||||
|
||||
std::string name;
|
||||
std::string desc;
|
||||
EntranceDBEntry entry;
|
||||
};
|
||||
Entry& AddEntry(const Init& init);
|
||||
|
||||
void ResetVanillaEntrances();
|
||||
|
||||
Entry& RetrieveEntry(const int id);
|
||||
Entry& RetrieveEntry(const int id, const int layer);
|
||||
int RetrieveId(const std::string& name);
|
||||
|
||||
size_t GetNumEntries();
|
||||
|
||||
s32 CalcId(s32 sceneId, s32 spawn, s32 layer);
|
||||
s32 CalcId(s32 entrance, s32 newLayer);
|
||||
|
||||
void Copy(s32 from, s32 to);
|
||||
|
||||
private:
|
||||
Entry& AddEntry(const std::string& name, const std::string& desc, size_t index);
|
||||
|
||||
std::vector<Entry> db;
|
||||
std::unordered_map<std::string, int> nameTable;
|
||||
size_t nextFreeId = 0;
|
||||
|
||||
// This keeps a mapping of a scene, spawn, and layer to the resulting entrance ID, since we can assume no order
|
||||
// about them
|
||||
struct IdLookupKey {
|
||||
s32 sceneId;
|
||||
s32 spawn;
|
||||
s32 layer;
|
||||
auto operator<=>(const IdLookupKey&) const = default;
|
||||
};
|
||||
std::map<IdLookupKey, s32> idLookupTable;
|
||||
|
||||
// This keeps a mapping of a scene and spawn to the next avaliable layer
|
||||
// When loading mods that add cutscenes, this will tell us the layer that cutscene's entrance is assigned
|
||||
struct NextLayerLookupKey {
|
||||
s32 sceneId;
|
||||
s32 spawn;
|
||||
auto operator<=>(const NextLayerLookupKey&) const = default;
|
||||
};
|
||||
std::map<NextLayerLookupKey, s32> nextLayerLookupTable;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
SceneDBEntry* SceneDB_Retrieve(const int id);
|
||||
int SceneDB_RetrieveId(const char* name);
|
||||
int SceneDB_IsBoss(const int id);
|
||||
int SceneDB_IsDungeon(const int id);
|
||||
int SceneDB_IsOverworld(const int id);
|
||||
void SceneDB_SetMapMarkData(const int id, const int isMQ);
|
||||
void SceneDB_SetPauseMapMarkData(const int id, const int isMQ);
|
||||
|
||||
EntranceDBEntry* EntranceDB_Retrieve(const int id);
|
||||
EntranceDBEntry* EntranceDB_RetrieveLayer(const int id, const int layer);
|
||||
int EntranceDB_RetrieveId(const char* name);
|
||||
int EntranceDB_CalcId(const int sceneId, const int spawn, const int layer);
|
||||
int EntranceDB_CalcIdWithEntrance(const int entrance, const int newLayer);
|
||||
void EntranceDB_ResetVanillaEntrances(void);
|
||||
void EntranceDB_Copy(const int from, const int to);
|
||||
|
||||
#endif
|
3288
soh/soh/SceneDB_Table.cpp
Normal file
3288
soh/soh/SceneDB_Table.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@
|
|||
#include "soh/resource/type/Scene.h"
|
||||
#include <utils/StringHelper.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "global.h"
|
||||
#include "vt.h"
|
||||
#include <Vertex.h>
|
||||
|
@ -20,14 +21,10 @@ Ship::IResource* OTRPlay_LoadFile(PlayState* play, const char* fileName) {
|
|||
}
|
||||
|
||||
extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) {
|
||||
SceneTableEntry* scene = &gSceneTable[sceneId];
|
||||
SceneDB::Entry& entry = SceneDB::Instance->RetrieveEntry(sceneId);
|
||||
|
||||
scene->unk_13 = 0;
|
||||
play->loadedScene = scene;
|
||||
play->sceneNum = sceneId;
|
||||
play->sceneConfig = scene->config;
|
||||
|
||||
// osSyncPrintf("\nSCENE SIZE %fK\n", (scene->sceneFile.vromEnd - scene->sceneFile.vromStart) / 1024.0f);
|
||||
play->sceneConfig = entry.entry.sceneDrawConfig;
|
||||
|
||||
// Scenes considered "dungeon" with a MQ variant
|
||||
int16_t inNonSharedScene = (sceneId >= SCENE_DEKU_TREE && sceneId <= SCENE_ICE_CAVERN) ||
|
||||
|
@ -37,8 +34,8 @@ extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) {
|
|||
if (inNonSharedScene) {
|
||||
sceneVersion = ResourceMgr_IsGameMasterQuest() ? "mq" : "nonmq";
|
||||
}
|
||||
std::string scenePath = StringHelper::Sprintf("scenes/%s/%s/%s", sceneVersion.c_str(), scene->sceneFile.fileName,
|
||||
scene->sceneFile.fileName);
|
||||
std::string scenePath =
|
||||
StringHelper::Sprintf("scenes/%s/%s/%s", sceneVersion.c_str(), entry.name.c_str(), entry.name.c_str());
|
||||
|
||||
play->sceneSegment = OTRPlay_LoadFile(play, scenePath.c_str());
|
||||
|
||||
|
@ -50,12 +47,8 @@ extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) {
|
|||
return;
|
||||
}
|
||||
|
||||
scene->unk_13 = 0;
|
||||
|
||||
// gSegments[2] = VIRTUAL_TO_PHYSICAL(play->sceneSegment);
|
||||
|
||||
OTRPlay_InitScene(play, spawn);
|
||||
auto roomSize = func_80096FE8(play, &play->roomCtx);
|
||||
uint32_t roomSize = func_80096FE8(play, &play->roomCtx);
|
||||
|
||||
osSyncPrintf("ROOM SIZE=%fK\n", roomSize / 1024.0f);
|
||||
|
||||
|
|
|
@ -875,6 +875,7 @@ void TitleCard_InitBossName(PlayState* play, TitleCardContext* titleCtx, void* t
|
|||
titleCtx->delayTimer = 0;
|
||||
}
|
||||
|
||||
// SceneDB TODO: this needs to be parameterized with a good multi-language solution for the textures
|
||||
void TitleCard_InitPlaceName(PlayState* play, TitleCardContext* titleCtx, void* texture, s32 x, s32 y, s32 width,
|
||||
s32 height, s32 delay) {
|
||||
SceneTableEntry* loadedScene = play->loadedScene;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
u16 D_8011E1C0 = 0;
|
||||
u16 D_8011E1C4 = 0;
|
||||
|
@ -2218,6 +2219,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
|
|||
return;
|
||||
}
|
||||
|
||||
s32 scene = EntranceDB_Retrieve(gSaveContext.entranceIndex)->sceneId;
|
||||
if ((gSaveContext.gameMode == GAMEMODE_NORMAL) && (gSaveContext.respawnFlag <= 0) &&
|
||||
(gSaveContext.cutsceneIndex < 0xFFF0)) {
|
||||
if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) &&
|
||||
|
@ -2247,12 +2249,12 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
|
|||
(CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
||||
LINK_IS_ADULT &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
|
||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)))) {
|
||||
(scene == SCENE_TEMPLE_OF_TIME)))) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
|
||||
gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE;
|
||||
gSaveContext.cutsceneIndex = 0xFFF8;
|
||||
} else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) &&
|
||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) {
|
||||
(scene == SCENE_GANON_BOSS)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
|
||||
gSaveContext.entranceIndex = ENTR_GANON_BOSS_0;
|
||||
gSaveContext.cutsceneIndex = 0xFFF0;
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
#include <assert.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
s32 func_8006CFC0(s32 scene) {
|
||||
s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS,
|
||||
SCENE_LON_LON_RANCH };
|
||||
#if 0
|
||||
s32 validScenes[] = { SCENE_HYRULE_FIELD, SCENE_LAKE_HYLIA, SCENE_GERUDO_VALLEY, SCENE_GERUDOS_FORTRESS, SCENE_LON_LON_RANCH };
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(validScenes); i++) {
|
||||
|
@ -16,6 +17,8 @@ s32 func_8006CFC0(s32 scene) {
|
|||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
return SceneDB_Retrieve(scene)->epona.allowed;
|
||||
}
|
||||
|
||||
void func_8006D074(PlayState* play) {
|
||||
|
@ -108,19 +111,13 @@ void func_8006D0EC(PlayState* play, Player* player) {
|
|||
Actor* horseActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, 0.0f, 0.0f, -500.0f, 0, 0, 0, 1, true);
|
||||
assert(horseActor != NULL);
|
||||
} else if (Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) || (DREG(1) != 0)) {
|
||||
for (i = 0; i < ARRAY_COUNT(horseSpawns); i++) {
|
||||
HorseSpawn* horseSpawn = &horseSpawns[i];
|
||||
if (horseSpawn->scene == play->sceneNum) {
|
||||
Actor* horseActor =
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, horseSpawn->pos.x, horseSpawn->pos.y,
|
||||
horseSpawn->pos.z, 0, horseSpawn->angle, 0, horseSpawn->type, true);
|
||||
assert(horseActor != NULL);
|
||||
if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
|
||||
horseActor->room = -1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
Actor* horseActor =
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, entry->epona.startingPos.x, entry->epona.startingPos.y,
|
||||
entry->epona.startingPos.z, 0, entry->epona.angle, 0, 2, true);
|
||||
assert(horseActor != NULL);
|
||||
if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
|
||||
horseActor->room = -1;
|
||||
}
|
||||
} else if (!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)) {
|
||||
if ((DREG(1) == 0) && (play->sceneNum == SCENE_LON_LON_BUILDINGS) && !IS_DAY) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "global.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
s16 sKaleidoSetupKscpPos0[] = { PAUSE_QUEST, PAUSE_EQUIP, PAUSE_ITEM, PAUSE_MAP };
|
||||
f32 sKaleidoSetupEyeX0[] = { 0.0f, 64.0f, 0.0f, -64.0f };
|
||||
|
@ -124,6 +126,10 @@ void KaleidoSetup_Init(PlayState* play) {
|
|||
pauseCtx->randoQuestMode = 0;
|
||||
|
||||
View_Init(&pauseCtx->view, play->state.gfxCtx);
|
||||
|
||||
if (SceneDB_IsDungeon(play->sceneNum)) {
|
||||
SceneDB_SetPauseMapMarkData(play->sceneNum, ResourceMgr_IsGameMasterQuest());
|
||||
}
|
||||
}
|
||||
|
||||
void KaleidoSetup_Destroy(PlayState* play) {
|
||||
|
|
|
@ -132,25 +132,32 @@ static s16 sPaletteRoom[10][8][14] = {
|
|||
},
|
||||
};
|
||||
|
||||
static s16 sRoomCompassOffsetX[10][44] = {
|
||||
{ 1090, 1390, 1560, 1220, 1200, 1390, 1770, 1610, 2000, 1290, 1420,
|
||||
1110, 1040, 470, 790, 1570, 720, 1000, 1580, 70, 0 },
|
||||
{ 940, 320, 1500, 240, 580, 1510, 720, 1030, 800, 660, 180, 520, 310, 550, 790, 1650, 1000, 1570, 80, 70 },
|
||||
{ 1130, 1070, 1090, 1160, 1500, 690, 1540, 920, 1160, 700, 1650, 950, 1380, 1460, 830, 1170, 1620 },
|
||||
{ 1130, 1170, 965, 890, 1170, 1460, 1170, 800, 1320, 880, 1130, 1590, 1390, 830, 610, 580, 710,
|
||||
980, 1640, 1510, 590, 1610, 1130, 1130, 820, 1320, 1620, 0, 0, 0, 0, 1300, 1270 },
|
||||
{ 1160, 620, 1330, 1280, 440, 600, 810, 830, 720, 1170, 1490, 1640, 1870, 1800, 1610, 1130, 860, 1310, 1140,
|
||||
850, 760, 380, 800, 800, 1930, 1410, 640, 845, 810, 810, 850, 1390, 1540, 1650, 1880, 1530, 420, 1950 },
|
||||
{ 1120, 1290, 1120, 1380, 930, 1520, 1980, 2010, 1590, 1510, 1500, 1300, 1240, 1800, 1290,
|
||||
1450, 1560, 880, 820, 820, 1060, 1670, 1120, 1130, 1130, 1290, 1290, 1280, 1390, 940,
|
||||
1520, 1520, 1980, 1620, 1510, 1490, 1240, 1290, 1450, 880, 880, 1060, 1670, 1520 },
|
||||
{ 800, 1500, 1370, 1730, 1590, 1020, 1060, 1470, 1600, 1830, 1630, 2000, 650, 660, 1020, 880,
|
||||
940, 720, 570, 620, 570, 550, 970, 920, 1040, 1150, 1200, 1550, 1520, 1020, 820, 1010 },
|
||||
{ 1320, 1320, 1090, 1510, 1480, 940, 920, 910, 800, 820, 1150, 1000, 1800, 1660,
|
||||
1090, 1630, 710, 1670, 830, 770, 800, 850, 830, 820, 1800, 1090, 850 },
|
||||
{ 1080, 1420, 1620, 1040, 940, 1190, 1310, 1090, 1380, 1080 },
|
||||
{ 1070, 1180, 1270, 990, 1280, 1450, 1680, 1530, 760, 860, 1500, 800 },
|
||||
};
|
||||
static s16 sRoomCompassOffsetX[10]
|
||||
[44] = {
|
||||
{ 1090, 1390, 1560, 1220, 1200, 1390, 1770, 1610, 2000, 1290,
|
||||
1420, 1110, 1040, 470, 790, 1570, 720, 1000, 1580, 70 },
|
||||
{ 940, 320, 1500, 240, 580, 1510, 720, 1030, 800, 660,
|
||||
180, 520, 310, 550, 790, 1650, 1000, 1570, 80, 70 },
|
||||
{ 1130, 1070, 1090, 1160, 1500, 690, 1540, 920, 1160, 700, 1650, 950, 1380, 1460, 830,
|
||||
1170, 1620 },
|
||||
{ 1130, 1170, 965, 890, 1170, 1460, 1170, 800, 1320, 880, 1130,
|
||||
1590, 1390, 830, 610, 580, 710, 980, 1640, 1510, 590, 1610,
|
||||
1130, 1130, 820, 1320, 1620, 0, 0, 0, 0, 1300, 1270 },
|
||||
{ 1160, 620, 1330, 1280, 440, 600, 810, 830, 720, 1170, 1490, 1640, 1870,
|
||||
1800, 1610, 1130, 860, 1310, 1140, 850, 760, 380, 800, 800, 1930, 1410,
|
||||
640, 845, 810, 810, 850, 1390, 1540, 1650, 1880, 1530, 420, 1950 },
|
||||
{ 1120, 1290, 1120, 1380, 930, 1520, 1980, 2010, 1590, 1510, 1500,
|
||||
1300, 1240, 1800, 1290, 1450, 1560, 880, 820, 820, 1060, 1670,
|
||||
1120, 1130, 1130, 1290, 1290, 1280, 1390, 940, 1520, 1520, 1980,
|
||||
1620, 1510, 1490, 1240, 1290, 1450, 880, 880, 1060, 1670, 1520 },
|
||||
{ 800, 1500, 1370, 1730, 1590, 1020, 1060, 1470, 1600, 1830, 1630,
|
||||
2000, 650, 660, 1020, 880, 940, 720, 570, 620, 570, 550,
|
||||
970, 920, 1040, 1150, 1200, 1550, 1520, 1020, 820, 1010 },
|
||||
{ 1320, 1320, 1090, 1510, 1480, 940, 920, 910, 800, 820, 1150, 1000, 1800, 1660,
|
||||
1090, 1630, 710, 1670, 830, 770, 800, 850, 830, 820, 1800, 1090, 850 },
|
||||
{ 1080, 1420, 1620, 1040, 940, 1190, 1310, 1090, 1380, 1080 },
|
||||
{ 1070, 1180, 1270, 990, 1280, 1450, 1680, 1530, 760, 860, 1500, 800 },
|
||||
};
|
||||
|
||||
static s16 sRoomCompassOffsetY[10][44] = {
|
||||
{ -660, -570, -410, -690, -500, -380, -470, -630, -990, -870,
|
||||
|
@ -277,7 +284,7 @@ static u8 sSwitchFromFloor[10][51] = {
|
|||
};
|
||||
|
||||
static u8 sSwitchToRoom[10][51] = {
|
||||
{ 12, 11, 12, 11 },
|
||||
{ 12, 11, 12, 11, 0 },
|
||||
{ 16, 17, 18, 0, 2, 3 },
|
||||
{ 15, 16, 1, 6 },
|
||||
{ 22, 23, 24, 25, 26, 0, 6, 7, 8, 11 },
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "textures/parameter_static/parameter_static.h"
|
||||
#include "textures/map_i_static/map_i_static.h"
|
||||
#include "textures/map_grand_static/map_grand_static.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include <assert.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
|
||||
|
@ -14,6 +16,8 @@ s16 sPlayerInitialPosX = 0;
|
|||
s16 sPlayerInitialPosZ = 0;
|
||||
s16 sPlayerInitialDirection = 0;
|
||||
s16 sEntranceIconMapIndex = 0;
|
||||
s16 sOwEntranceIconPosX = 0;
|
||||
s16 sOwEntranceIconPosY = 0;
|
||||
|
||||
s16 Top_MM_Margin = 0;
|
||||
s16 Left_MM_Margin = 0;
|
||||
|
@ -31,7 +35,8 @@ void Map_SavePlayerInitialInfo(PlayState* play) {
|
|||
void Map_SetPaletteData(PlayState* play, s16 room) {
|
||||
s32 mapIndex = gSaveContext.mapIndex;
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s16 paletteIndex = gMapData->roomPalette[mapIndex][room];
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(mapIndex);
|
||||
s16 paletteIndex = entry->dungeonData.palettes[room];
|
||||
|
||||
if (interfaceCtx->mapRoomNum == room) {
|
||||
interfaceCtx->mapPaletteIndex = paletteIndex;
|
||||
|
@ -52,6 +57,7 @@ void Map_SetFloorPalettesData(PlayState* play, s16 floor) {
|
|||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s16 room;
|
||||
s16 i;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(mapIndex);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
interfaceCtx->mapPalette[i] = 0;
|
||||
|
@ -63,32 +69,13 @@ void Map_SetFloorPalettesData(PlayState* play, s16 floor) {
|
|||
interfaceCtx->mapPalette[31] = 1;
|
||||
}
|
||||
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
for (i = 0; i < gMapData->maxPaletteCount[mapIndex]; i++) {
|
||||
room = gMapData->paletteRoom[mapIndex][floor][i];
|
||||
if ((room != 0xFF) && (gSaveContext.sceneFlags[mapIndex].rooms & gBitFlags[room])) {
|
||||
Map_SetPaletteData(play, room);
|
||||
}
|
||||
if (SCENEDB_ISDUNGEON(entry)) {
|
||||
for (i = 0; i < entry->dungeonData.floors[floor].numRooms; i++) {
|
||||
room = entry->dungeonData.floors[floor].rooms[i];
|
||||
if ((room != 0xFF) && (gSaveContext.sceneFlags[mapIndex].rooms & gBitFlags[room])) {
|
||||
Map_SetPaletteData(play, room);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,101 +352,50 @@ void Map_InitData(PlayState* play, s16 room) {
|
|||
s32 mapIndex = gSaveContext.mapIndex;
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s16 extendedMapIndex;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(mapIndex);
|
||||
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_HYRULE_FIELD:
|
||||
case SCENE_KAKARIKO_VILLAGE:
|
||||
case SCENE_GRAVEYARD:
|
||||
case SCENE_ZORAS_RIVER:
|
||||
case SCENE_KOKIRI_FOREST:
|
||||
case SCENE_SACRED_FOREST_MEADOW:
|
||||
case SCENE_LAKE_HYLIA:
|
||||
case SCENE_ZORAS_DOMAIN:
|
||||
case SCENE_ZORAS_FOUNTAIN:
|
||||
case SCENE_GERUDO_VALLEY:
|
||||
case SCENE_LOST_WOODS:
|
||||
case SCENE_DESERT_COLOSSUS:
|
||||
case SCENE_GERUDOS_FORTRESS:
|
||||
case SCENE_HAUNTED_WASTELAND:
|
||||
case SCENE_HYRULE_CASTLE:
|
||||
case SCENE_DEATH_MOUNTAIN_TRAIL:
|
||||
case SCENE_DEATH_MOUNTAIN_CRATER:
|
||||
case SCENE_GORON_CITY:
|
||||
case SCENE_LON_LON_RANCH:
|
||||
case SCENE_OUTSIDE_GANONS_CASTLE:
|
||||
extendedMapIndex = mapIndex;
|
||||
if (play->sceneNum == SCENE_GRAVEYARD) {
|
||||
if (CHECK_QUEST_ITEM(QUEST_SONG_NOCTURNE)) {
|
||||
extendedMapIndex = 0x14;
|
||||
}
|
||||
} else if (play->sceneNum == SCENE_LAKE_HYLIA) {
|
||||
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
|
||||
((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
|
||||
(IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)))) {
|
||||
extendedMapIndex = 0x15;
|
||||
}
|
||||
} else if (play->sceneNum == SCENE_GERUDO_VALLEY) {
|
||||
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) && !GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {
|
||||
extendedMapIndex = 0x16;
|
||||
}
|
||||
} else if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
|
||||
if ((!IS_RANDO && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
|
||||
(IS_RANDO && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
|
||||
extendedMapIndex = 0x17;
|
||||
}
|
||||
}
|
||||
osSyncPrintf(VT_FGCOL(BLUE));
|
||||
osSyncPrintf("KKK=%d\n", extendedMapIndex);
|
||||
osSyncPrintf(VT_RST);
|
||||
sEntranceIconMapIndex = extendedMapIndex;
|
||||
// DmaMgr_SendRequest1(interfaceCtx->mapSegment,
|
||||
//(uintptr_t)_map_grand_staticSegmentRomStart + gMapData->owMinimapTexOffset[extendedMapIndex],
|
||||
// gMapData->owMinimapTexSize[mapIndex], __FILE__, __LINE__);
|
||||
if (SCENEDB_ISOVERWORLD(entry)) {
|
||||
if (play->sceneNum == SCENE_GRAVEYARD && CHECK_QUEST_ITEM(QUEST_SONG_NOCTURNE)) {
|
||||
sOwEntranceIconPosX = 294;
|
||||
sOwEntranceIconPosY = -825;
|
||||
play->interfaceCtx.mapSegmentName[0] = gExploredShadowGraveyardMinimapTex;
|
||||
} else if (play->sceneNum == SCENE_LAKE_HYLIA && (LINK_AGE_IN_YEARS == YEARS_ADULT) &&
|
||||
((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
|
||||
(IS_RANDO && !Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)))) {
|
||||
sOwEntranceIconPosX = 259;
|
||||
sOwEntranceIconPosY = -829;
|
||||
play->interfaceCtx.mapSegmentName[0] = gDrainedLakeHyliaMinimapTex;
|
||||
} else if (play->sceneNum == SCENE_GERUDO_VALLEY && (LINK_AGE_IN_YEARS == YEARS_ADULT) &&
|
||||
!GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {
|
||||
sOwEntranceIconPosX = 1;
|
||||
sOwEntranceIconPosY = 0;
|
||||
play->interfaceCtx.mapSegmentName[0] = gGerudoValleyWithBrokenBridgeMinimapTex;
|
||||
} else if (play->sceneNum == SCENE_GERUDOS_FORTRESS && (!IS_RANDO && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
|
||||
(IS_RANDO && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
|
||||
sOwEntranceIconPosX = 243;
|
||||
sOwEntranceIconPosY = -833;
|
||||
play->interfaceCtx.mapSegmentName[0] = gGerudosFortressMinimapTex;
|
||||
} else {
|
||||
sOwEntranceIconPosX = entry->worldData.iconX;
|
||||
sOwEntranceIconPosY = entry->worldData.iconY;
|
||||
play->interfaceCtx.mapSegmentName[0] = entry->worldData.minimapTexture;
|
||||
}
|
||||
play->interfaceCtx.mapSegment[0] = ResourceGetDataByName(play->interfaceCtx.mapSegmentName[0]);
|
||||
|
||||
if (sEntranceIconMapIndex < 24) {
|
||||
play->interfaceCtx.mapSegment[0] = ResourceGetDataByName(minimapTableOW[sEntranceIconMapIndex]);
|
||||
play->interfaceCtx.mapSegmentName[0] = minimapTableOW[sEntranceIconMapIndex];
|
||||
}
|
||||
interfaceCtx->unk_258 = mapIndex;
|
||||
} else if (SCENEDB_ISDUNGEON(entry)) {
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Deku Tree Dungeon MAP Texture DMA"
|
||||
osSyncPrintf("デクの樹ダンジョンMAP テクスチャDMA(%x) scene_id_offset=%d VREG(30)=%d\n", room, mapIndex,
|
||||
VREG(30));
|
||||
osSyncPrintf(VT_RST);
|
||||
|
||||
interfaceCtx->unk_258 = mapIndex;
|
||||
break;
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Deku Tree Dungeon MAP Texture DMA"
|
||||
osSyncPrintf("デクの樹ダンジョンMAP テクスチャDMA(%x) scene_id_offset=%d VREG(30)=%d\n", room,
|
||||
mapIndex, VREG(30));
|
||||
osSyncPrintf(VT_RST);
|
||||
// DmaMgr_SendRequest1(play->interfaceCtx.mapSegment,
|
||||
//(uintptr_t)_map_i_staticSegmentRomStart +
|
||||
//((gMapData->dgnMinimapTexIndexOffset[mapIndex] + room) * 0xFF0),
|
||||
// 0xFF0, __FILE__, __LINE__);
|
||||
|
||||
play->interfaceCtx.mapSegment[0] =
|
||||
ResourceGetDataByName(minimapTableDangeon[gMapData->dgnMinimapTexIndexOffset[mapIndex] + room]);
|
||||
play->interfaceCtx.mapSegmentName[0] =
|
||||
minimapTableDangeon[gMapData->dgnMinimapTexIndexOffset[mapIndex] + room];
|
||||
R_COMPASS_OFFSET_X = gMapData->roomCompassOffsetX[mapIndex][room];
|
||||
R_COMPASS_OFFSET_Y = gMapData->roomCompassOffsetY[mapIndex][room];
|
||||
Map_SetFloorPalettesData(play, VREG(30));
|
||||
osSyncPrintf("MAP 各階ONチェック\n"); // "MAP Individual Floor ON Check"
|
||||
break;
|
||||
play->interfaceCtx.mapSegmentName[0] = entry->dungeonData.rooms[room].minimapTexture;
|
||||
play->interfaceCtx.mapSegment[0] = ResourceGetDataByName(play->interfaceCtx.mapSegmentName[0]);
|
||||
R_COMPASS_OFFSET_X = entry->dungeonData.rooms[room].compassOffsetX;
|
||||
R_COMPASS_OFFSET_Y = entry->dungeonData.rooms[room].compassOffsetY;
|
||||
Map_SetFloorPalettesData(play, VREG(30));
|
||||
osSyncPrintf("MAP 各階ONチェック\n"); // "MAP Individual Floor ON Check"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -470,37 +406,16 @@ void Map_InitRoomData(PlayState* play, s16 room) {
|
|||
osSyncPrintf("*******\n*******\nroom_no=%d (%d)(%d)\n*******\n*******\n", room,
|
||||
mapIndex, play->sceneNum);
|
||||
|
||||
if (room >= 0) {
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
gSaveContext.sceneFlags[mapIndex].rooms |= gBitFlags[room];
|
||||
osSyncPrintf("ROOM_INF=%d\n", gSaveContext.sceneFlags[mapIndex].rooms);
|
||||
interfaceCtx->mapRoomNum = room;
|
||||
interfaceCtx->unk_25A = mapIndex;
|
||||
Map_SetPaletteData(play, room);
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("部屋部屋=%d\n", room); // "Room Room = %d"
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(play, room);
|
||||
break;
|
||||
}
|
||||
if ((room >= 0) && (SceneDB_IsDungeon(play->sceneNum) || SceneDB_IsBoss(play->sceneNum))) {
|
||||
gSaveContext.sceneFlags[mapIndex].rooms |= gBitFlags[room];
|
||||
osSyncPrintf("ROOM_INF=%d\n", gSaveContext.sceneFlags[mapIndex].rooms);
|
||||
interfaceCtx->mapRoomNum = room;
|
||||
interfaceCtx->unk_25A = mapIndex;
|
||||
Map_SetPaletteData(play, room);
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("部屋部屋=%d\n", room); // "Room Room = %d"
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(play, room);
|
||||
} else {
|
||||
interfaceCtx->mapRoomNum = 0;
|
||||
}
|
||||
|
@ -521,6 +436,8 @@ void Map_Init(PlayState* play) {
|
|||
|
||||
gMapData = &gMapDataTable;
|
||||
|
||||
SceneDB_SetMapMarkData(play->sceneNum, ResourceMgr_IsGameMasterQuest());
|
||||
|
||||
interfaceCtx->unk_258 = -1;
|
||||
interfaceCtx->unk_25A = -1;
|
||||
|
||||
|
@ -530,75 +447,29 @@ void Map_Init(PlayState* play) {
|
|||
interfaceCtx->mapSegment, play);
|
||||
assert(interfaceCtx->mapSegment != NULL);
|
||||
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_HYRULE_FIELD:
|
||||
case SCENE_KAKARIKO_VILLAGE:
|
||||
case SCENE_GRAVEYARD:
|
||||
case SCENE_ZORAS_RIVER:
|
||||
case SCENE_KOKIRI_FOREST:
|
||||
case SCENE_SACRED_FOREST_MEADOW:
|
||||
case SCENE_LAKE_HYLIA:
|
||||
case SCENE_ZORAS_DOMAIN:
|
||||
case SCENE_ZORAS_FOUNTAIN:
|
||||
case SCENE_GERUDO_VALLEY:
|
||||
case SCENE_LOST_WOODS:
|
||||
case SCENE_DESERT_COLOSSUS:
|
||||
case SCENE_GERUDOS_FORTRESS:
|
||||
case SCENE_HAUNTED_WASTELAND:
|
||||
case SCENE_HYRULE_CASTLE:
|
||||
case SCENE_DEATH_MOUNTAIN_TRAIL:
|
||||
case SCENE_DEATH_MOUNTAIN_CRATER:
|
||||
case SCENE_GORON_CITY:
|
||||
case SCENE_LON_LON_RANCH:
|
||||
case SCENE_OUTSIDE_GANONS_CASTLE:
|
||||
mapIndex = play->sceneNum - SCENE_HYRULE_FIELD;
|
||||
R_MAP_INDEX = gSaveContext.mapIndex = mapIndex;
|
||||
R_COMPASS_SCALE_X = gMapData->owCompassInfo[mapIndex][0];
|
||||
R_COMPASS_SCALE_Y = gMapData->owCompassInfo[mapIndex][1];
|
||||
R_COMPASS_OFFSET_X = gMapData->owCompassInfo[mapIndex][2];
|
||||
R_COMPASS_OFFSET_Y = gMapData->owCompassInfo[mapIndex][3];
|
||||
Map_InitData(play, mapIndex);
|
||||
R_OW_MINIMAP_X = gMapData->owMinimapPosX[mapIndex];
|
||||
R_OW_MINIMAP_Y = gMapData->owMinimapPosY[mapIndex];
|
||||
break;
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_GANONS_TOWER:
|
||||
case SCENE_GERUDO_TRAINING_GROUND:
|
||||
case SCENE_THIEVES_HIDEOUT:
|
||||
case SCENE_INSIDE_GANONS_CASTLE:
|
||||
case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR:
|
||||
case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE:
|
||||
case SCENE_TREASURE_BOX_SHOP:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
mapIndex =
|
||||
(play->sceneNum >= SCENE_DEKU_TREE_BOSS) ? play->sceneNum - SCENE_DEKU_TREE_BOSS : play->sceneNum;
|
||||
R_MAP_INDEX = gSaveContext.mapIndex = mapIndex;
|
||||
if ((play->sceneNum <= SCENE_ICE_CAVERN) || (play->sceneNum >= SCENE_DEKU_TREE_BOSS)) {
|
||||
R_COMPASS_SCALE_X = gMapData->dgnCompassInfo[mapIndex][0];
|
||||
R_COMPASS_SCALE_Y = gMapData->dgnCompassInfo[mapIndex][1];
|
||||
R_COMPASS_OFFSET_X = gMapData->dgnCompassInfo[mapIndex][2];
|
||||
R_COMPASS_OFFSET_Y = gMapData->dgnCompassInfo[mapIndex][3];
|
||||
R_MAP_TEX_INDEX = R_MAP_TEX_INDEX_BASE = gMapData->dgnMinimapTexIndexBase[mapIndex];
|
||||
Map_InitRoomData(play, play->roomCtx.curRoom.num);
|
||||
MapMark_Init(play);
|
||||
}
|
||||
break;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
|
||||
if (SCENEDB_ISBOSS(entry)) {
|
||||
gSaveContext.mapIndex = entry->bossData.mapScene;
|
||||
} else {
|
||||
gSaveContext.mapIndex = play->sceneNum;
|
||||
}
|
||||
|
||||
if (SCENEDB_ISOVERWORLD(entry)) {
|
||||
R_COMPASS_SCALE_X = entry->compassInfo.scaleX;
|
||||
R_COMPASS_SCALE_Y = entry->compassInfo.scaleY;
|
||||
R_COMPASS_OFFSET_X = entry->compassInfo.x;
|
||||
R_COMPASS_OFFSET_Y = entry->compassInfo.y;
|
||||
Map_InitData(play, 0);
|
||||
R_OW_MINIMAP_X = sOwEntranceIconPosX;
|
||||
R_OW_MINIMAP_Y = sOwEntranceIconPosY;
|
||||
} else if (SCENEDB_ISDUNGEON(entry) || SCENEDB_ISBOSS(entry)) {
|
||||
R_COMPASS_SCALE_X = entry->compassInfo.scaleX;
|
||||
R_COMPASS_SCALE_Y = entry->compassInfo.scaleY;
|
||||
R_COMPASS_OFFSET_X = entry->compassInfo.x;
|
||||
R_COMPASS_OFFSET_Y = entry->compassInfo.y;
|
||||
Map_InitRoomData(play, play->roomCtx.curRoom.num);
|
||||
MapMark_Init(play);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,6 +478,7 @@ void Minimap_DrawCompassIcons(PlayState* play) {
|
|||
Player* player = GET_PLAYER(play);
|
||||
s16 tempX, tempZ;
|
||||
Color_RGB8 lastEntranceColor = { 200, 0, 0 };
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.MinimapEntrance.Changed"), 0)) {
|
||||
lastEntranceColor = CVarGetColor24(CVAR_COSMETIC("HUD.MinimapEntrance.Value"), lastEntranceColor);
|
||||
}
|
||||
|
@ -640,10 +512,10 @@ void Minimap_DrawCompassIcons(PlayState* play) {
|
|||
|
||||
s16 mapWidth = 0;
|
||||
s16 mapStartPosX = 0;
|
||||
if (play->sceneNum >= SCENE_HYRULE_FIELD && play->sceneNum <= SCENE_OUTSIDE_GANONS_CASTLE) { // Overworld
|
||||
mapStartPosX = R_OW_MINIMAP_X;
|
||||
mapWidth = gMapData->owMinimapWidth[R_MAP_INDEX];
|
||||
} else if (play->sceneNum >= SCENE_DEKU_TREE && play->sceneNum <= SCENE_ICE_CAVERN) { // Dungeons
|
||||
if (SCENEDB_ISOVERWORLD(entry)) {
|
||||
mapStartPosX = entry->worldData.minimapX;
|
||||
mapWidth = entry->worldData.minimapWidth;
|
||||
} else if (SCENEDB_ISDUNGEON(entry)) {
|
||||
mapStartPosX = R_DGN_MINIMAP_X;
|
||||
mapWidth = 96;
|
||||
}
|
||||
|
@ -767,6 +639,7 @@ void Minimap_Draw(PlayState* play) {
|
|||
s32 pad[2];
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s32 mapIndex = gSaveContext.mapIndex;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
Color_RGB8 minimapColor = { 0, 255, 255 };
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.Changed"), 0)) {
|
||||
minimapColor = CVarGetColor24(CVAR_COSMETIC("HUD.Minimap.Value"), minimapColor);
|
||||
|
@ -793,256 +666,181 @@ void Minimap_Draw(PlayState* play) {
|
|||
Y_Margins_Minimap = 0;
|
||||
}
|
||||
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
if (!R_MINIMAP_DISABLED && CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != 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);
|
||||
if (SCENEDB_ISDUNGEON(entry)) {
|
||||
if (!R_MINIMAP_DISABLED &&
|
||||
CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != HIDDEN) { // 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);
|
||||
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, mapIndex)) {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b,
|
||||
interfaceCtx->minimapAlpha);
|
||||
|
||||
u8 mirrorMode =
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? G_TX_MIRROR : G_TX_NOMIRROR;
|
||||
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_I, 96, 85, 0,
|
||||
mirrorMode | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
|
||||
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
s16 dgnMiniMapX = OTRGetRectDimensionFromRightEdge(R_DGN_MINIMAP_X + X_Margins_Minimap);
|
||||
s16 dgnMiniMapY = R_DGN_MINIMAP_Y + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
dgnMiniMapY = R_DGN_MINIMAP_Y + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) +
|
||||
Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
dgnMiniMapX = OTRGetDimensionFromLeftEdge(
|
||||
R_DGN_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
dgnMiniMapX = OTRGetDimensionFromRightEdge(
|
||||
R_DGN_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
dgnMiniMapX = CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
s32 sValue = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||
// Flip the minimap on the x-axis (s-axis) by setting s to the textures mirror boundary
|
||||
sValue = 96 << 5;
|
||||
}
|
||||
|
||||
gSPWideTextureRectangle(OVERLAY_DISP++, dgnMiniMapX << 2, dgnMiniMapY << 2,
|
||||
(dgnMiniMapX + 96) << 2, (dgnMiniMapY + 85) << 2, G_TX_RENDERTILE,
|
||||
sValue, 0, 1 << 10, 1 << 10);
|
||||
}
|
||||
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, mapIndex)) {
|
||||
Minimap_DrawCompassIcons(play); // Draw icons for the player spawn and current position
|
||||
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
|
||||
MapMark_Draw(play);
|
||||
}
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) &&
|
||||
enableMapToggle) {
|
||||
osSyncPrintf("Game_play_demo_mode_check=%d\n", Play_InCsMode(play));
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case SCENE_HYRULE_FIELD:
|
||||
case SCENE_KAKARIKO_VILLAGE:
|
||||
case SCENE_GRAVEYARD:
|
||||
case SCENE_ZORAS_RIVER:
|
||||
case SCENE_KOKIRI_FOREST:
|
||||
case SCENE_SACRED_FOREST_MEADOW:
|
||||
case SCENE_LAKE_HYLIA:
|
||||
case SCENE_ZORAS_DOMAIN:
|
||||
case SCENE_ZORAS_FOUNTAIN:
|
||||
case SCENE_GERUDO_VALLEY:
|
||||
case SCENE_LOST_WOODS:
|
||||
case SCENE_DESERT_COLOSSUS:
|
||||
case SCENE_GERUDOS_FORTRESS:
|
||||
case SCENE_HAUNTED_WASTELAND:
|
||||
case SCENE_HYRULE_CASTLE:
|
||||
case SCENE_DEATH_MOUNTAIN_TRAIL:
|
||||
case SCENE_DEATH_MOUNTAIN_CRATER:
|
||||
case SCENE_GORON_CITY:
|
||||
case SCENE_LON_LON_RANCH:
|
||||
case SCENE_OUTSIDE_GANONS_CASTLE:
|
||||
if (!R_MINIMAP_DISABLED && CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != 4) { // Not Hidden
|
||||
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
|
||||
|
||||
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, mapIndex)) {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b,
|
||||
interfaceCtx->minimapAlpha);
|
||||
|
||||
u8 mirrorMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? G_TX_MIRROR : G_TX_NOMIRROR;
|
||||
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_IA,
|
||||
gMapData->owMinimapWidth[mapIndex], gMapData->owMinimapHeight[mapIndex], 0,
|
||||
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_I, 96, 85, 0,
|
||||
mirrorMode | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
s16 oWMiniMapX = OTRGetRectDimensionFromRightEdge(R_OW_MINIMAP_X + X_Margins_Minimap);
|
||||
s16 oWMiniMapY = R_OW_MINIMAP_Y + Y_Margins_Minimap;
|
||||
s16 dgnMiniMapX = OTRGetRectDimensionFromRightEdge(R_DGN_MINIMAP_X + X_Margins_Minimap);
|
||||
s16 dgnMiniMapY = R_DGN_MINIMAP_Y + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
oWMiniMapY =
|
||||
R_OW_MINIMAP_Y + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) + Y_Margins_Minimap;
|
||||
dgnMiniMapY =
|
||||
R_DGN_MINIMAP_Y + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
oWMiniMapX = OTRGetDimensionFromLeftEdge(
|
||||
R_OW_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
dgnMiniMapX = OTRGetDimensionFromLeftEdge(
|
||||
R_DGN_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
oWMiniMapX = OTRGetDimensionFromRightEdge(
|
||||
R_OW_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
dgnMiniMapX = OTRGetDimensionFromRightEdge(
|
||||
R_DGN_MINIMAP_X + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
oWMiniMapX = CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
dgnMiniMapX = CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
s32 sValue = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||
// Flip the minimap on the x-axis (s-axis) by setting s to the textures mirror boundary
|
||||
sValue = gMapData->owMinimapWidth[mapIndex] << 5;
|
||||
sValue = 96 << 5;
|
||||
}
|
||||
|
||||
gSPWideTextureRectangle(OVERLAY_DISP++, oWMiniMapX << 2, oWMiniMapY << 2,
|
||||
(oWMiniMapX + gMapData->owMinimapWidth[mapIndex]) << 2,
|
||||
(oWMiniMapY + gMapData->owMinimapHeight[mapIndex]) << 2, G_TX_RENDERTILE,
|
||||
sValue, 0, 1 << 10, 1 << 10);
|
||||
gSPWideTextureRectangle(OVERLAY_DISP++, dgnMiniMapX << 2, dgnMiniMapY << 2, (dgnMiniMapX + 96) << 2,
|
||||
(dgnMiniMapY + 85) << 2, G_TX_RENDERTILE, sValue, 0, 1 << 10, 1 << 10);
|
||||
}
|
||||
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b,
|
||||
interfaceCtx->minimapAlpha);
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, mapIndex)) {
|
||||
Minimap_DrawCompassIcons(play); // Draw icons for the player spawn and current position
|
||||
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
|
||||
MapMark_Draw(play);
|
||||
}
|
||||
}
|
||||
|
||||
s16 iconSize = 8;
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) {
|
||||
osSyncPrintf("Game_play_demo_mode_check=%d\n", Play_InCsMode(play));
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
}
|
||||
} else if (SCENEDB_ISOVERWORLD(entry)) {
|
||||
if (!R_MINIMAP_DISABLED && CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != 4) { // Not Hidden
|
||||
Gfx_SetupDL_39Overlay(play->state.gfxCtx);
|
||||
|
||||
if (((play->sceneNum != SCENE_KAKARIKO_VILLAGE) && (play->sceneNum != SCENE_KOKIRI_FOREST) &&
|
||||
(play->sceneNum != SCENE_ZORAS_FOUNTAIN)) ||
|
||||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) {
|
||||
s16 origX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex];
|
||||
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b,
|
||||
interfaceCtx->minimapAlpha);
|
||||
|
||||
// Compute the distance of the center of the original texture location to the center of the map
|
||||
// Then duplicate that and right-align the texture (extra 2 pixels are due to the texture being
|
||||
// a 6px left-aligned in a 8px tex)
|
||||
s16 distFromCenter =
|
||||
(R_OW_MINIMAP_X + (gMapData->owMinimapWidth[mapIndex] / 2)) - (origX + (iconSize / 2));
|
||||
s16 mirrorOffset = distFromCenter * 2 + (iconSize / 2) - 2;
|
||||
s16 newX = origX + (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? mirrorOffset : 0);
|
||||
u8 mirrorMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? G_TX_MIRROR : G_TX_NOMIRROR;
|
||||
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegmentName[0], G_IM_FMT_IA,
|
||||
entry->worldData.minimapWidth, entry->worldData.minimapHeight, 0,
|
||||
mirrorMode | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
// 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 entranceX = OTRGetRectDimensionFromRightEdge(newX + X_Margins_Minimap);
|
||||
s16 entranceY = newY + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
entranceY = newY + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromLeftEdge(
|
||||
newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromRightEdge(
|
||||
newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
entranceX =
|
||||
newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 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(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 0)
|
||||
? -9999
|
||||
: OTRGetRectDimensionFromLeftEdge(0);
|
||||
}
|
||||
|
||||
//! @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(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 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);
|
||||
}
|
||||
s16 oWMiniMapX = OTRGetRectDimensionFromRightEdge(entry->worldData.minimapX + X_Margins_Minimap);
|
||||
s16 oWMiniMapY = entry->worldData.minimapY + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
oWMiniMapY = entry->worldData.minimapY + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) +
|
||||
Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
oWMiniMapX = OTRGetDimensionFromLeftEdge(entry->worldData.minimapX +
|
||||
CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
oWMiniMapX = OTRGetDimensionFromRightEdge(entry->worldData.minimapX +
|
||||
CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) +
|
||||
X_Margins_Minimap);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
oWMiniMapX = CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
s16 origX = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 256 : 270;
|
||||
s16 entranceX = OTRGetRectDimensionFromRightEdge(origX + X_Margins_Minimap);
|
||||
s16 entranceY = 154 + Y_Margins_Minimap;
|
||||
s32 sValue = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
|
||||
// Flip the minimap on the x-axis (s-axis) by setting s to the textures mirror boundary
|
||||
sValue = entry->worldData.minimapWidth << 5;
|
||||
}
|
||||
|
||||
gSPWideTextureRectangle(
|
||||
OVERLAY_DISP++, oWMiniMapX << 2, oWMiniMapY << 2, (oWMiniMapX + entry->worldData.minimapWidth) << 2,
|
||||
(oWMiniMapY + entry->worldData.minimapHeight) << 2, G_TX_RENDERTILE, sValue, 0, 1 << 10, 1 << 10);
|
||||
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, minimapColor.r, minimapColor.g, minimapColor.b,
|
||||
interfaceCtx->minimapAlpha);
|
||||
|
||||
s16 iconSize = 8;
|
||||
|
||||
if (((play->sceneNum != SCENE_KAKARIKO_VILLAGE) && (play->sceneNum != SCENE_KOKIRI_FOREST) &&
|
||||
(play->sceneNum != SCENE_ZORAS_FOUNTAIN)) ||
|
||||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) {
|
||||
s16 origX = R_OW_MINIMAP_X;
|
||||
|
||||
// Compute the distance of the center of the original texture location to the center of the map
|
||||
// Then duplicate that and right-align the texture (extra 2 pixels are due to the texture being a
|
||||
// 6px left-aligned in a 8px tex)
|
||||
s16 distFromCenter =
|
||||
(entry->worldData.minimapX + (entry->worldData.minimapWidth / 2)) - (origX + (iconSize / 2));
|
||||
s16 mirrorOffset = distFromCenter * 2 + (iconSize / 2) - 2;
|
||||
s16 newX = origX + (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? mirrorOffset : 0);
|
||||
|
||||
// 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 = R_OW_MINIMAP_Y & 0x3FF;
|
||||
|
||||
s16 entranceX = OTRGetRectDimensionFromRightEdge(newX + X_Margins_Minimap);
|
||||
s16 entranceY = newY + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
entranceY = 154 + Y_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0);
|
||||
entranceY = newY + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0) + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromLeftEdge(
|
||||
origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromRightEdge(
|
||||
origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
entranceX =
|
||||
origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
entranceX = newX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Ice Cavern entrance icon
|
||||
if ((play->sceneNum == SCENE_ZORAS_FOUNTAIN) &&
|
||||
((gSaveContext.infTable[26] & gBitFlags[9]) ||
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 0))) {
|
||||
// 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 (R_OW_MINIMAP_Y == 0) {
|
||||
entranceY = 0;
|
||||
entranceX = CVarGetInteger(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 0)
|
||||
? -9999
|
||||
: OTRGetRectDimensionFromLeftEdge(0);
|
||||
}
|
||||
|
||||
if ((entry->worldData.entranceFlag == -1) ||
|
||||
((entry->worldData.entranceFlag != -1) &&
|
||||
((gSaveContext.infTable[26] & gBitFlags[entry->worldData.entranceFlag]) ||
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 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);
|
||||
|
@ -1050,22 +848,53 @@ void Minimap_Draw(PlayState* play) {
|
|||
(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
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) &&
|
||||
enableMapToggle) {
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
s16 origX = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 256 : 270;
|
||||
s16 entranceX = OTRGetRectDimensionFromRightEdge(origX + X_Margins_Minimap);
|
||||
s16 entranceY = 154 + Y_Margins_Minimap;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
entranceY = 154 + Y_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0);
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Left_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromLeftEdge(
|
||||
origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap = Right_MM_Margin;
|
||||
};
|
||||
entranceX = OTRGetRectDimensionFromRightEdge(
|
||||
origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0));
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
entranceX = origX + X_Margins_Minimap + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
// Ice Cavern entrance icon
|
||||
if ((play->sceneNum == SCENE_ZORAS_FOUNTAIN) &&
|
||||
((gSaveContext.infTable[26] & gBitFlags[9]) ||
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"), 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);
|
||||
}
|
||||
|
||||
Minimap_DrawCompassIcons(play); // Draw icons for the player spawn and current position
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) {
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,6 +912,7 @@ void Map_Update(PlayState* play) {
|
|||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s16 floor;
|
||||
s16 i;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
|
||||
Top_MM_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.T"), 0);
|
||||
Left_MM_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.L"), 0);
|
||||
|
@ -1090,71 +920,47 @@ void Map_Update(PlayState* play) {
|
|||
Bottom_MM_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.B"), 0);
|
||||
|
||||
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugState == 0)) {
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
interfaceCtx->mapPalette[30] = 0;
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, mapIndex)) {
|
||||
interfaceCtx->mapPalette[31] = 1;
|
||||
} else {
|
||||
interfaceCtx->mapPalette[31] = 0;
|
||||
}
|
||||
if (SCENEDB_ISDUNGEON(entry)) {
|
||||
interfaceCtx->mapPalette[30] = 0;
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, play->sceneNum)) {
|
||||
interfaceCtx->mapPalette[31] = 1;
|
||||
} else {
|
||||
interfaceCtx->mapPalette[31] = 0;
|
||||
}
|
||||
|
||||
for (floor = 0; floor < 8; floor++) {
|
||||
if (player->actor.world.pos.y > gMapData->floorCoordY[mapIndex][floor]) {
|
||||
break;
|
||||
}
|
||||
for (floor = 0; floor < 8; floor++) {
|
||||
if (player->actor.world.pos.y > entry->dungeonData.floors[floor].height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gSaveContext.sceneFlags[mapIndex].floors |= gBitFlags[floor];
|
||||
VREG(30) = floor;
|
||||
if (R_MAP_TEX_INDEX != (R_MAP_TEX_INDEX_BASE + Map_GetFloorTextIndexOffset(mapIndex, floor))) {
|
||||
R_MAP_TEX_INDEX = R_MAP_TEX_INDEX_BASE + Map_GetFloorTextIndexOffset(mapIndex, floor);
|
||||
gSaveContext.sceneFlags[play->sceneNum].floors |= gBitFlags[floor];
|
||||
VREG(30) = floor;
|
||||
|
||||
if (interfaceCtx->mapRoomNum != sLastRoomNum) {
|
||||
// "Current floor = %d Current room = %x Number of rooms = %d"
|
||||
osSyncPrintf("現在階=%d 現在部屋=%x 部屋数=%d\n", floor, interfaceCtx->mapRoomNum,
|
||||
entry->dungeonData.numRooms);
|
||||
sLastRoomNum = interfaceCtx->mapRoomNum;
|
||||
}
|
||||
|
||||
for (i = 0; i < entry->dungeonData.numIntraRoomTransitions; i++) {
|
||||
if ((interfaceCtx->mapRoomNum == entry->dungeonData.intraRoomTransitions[i].fromRoom) &&
|
||||
(floor == entry->dungeonData.intraRoomTransitions[i].toFloor)) {
|
||||
interfaceCtx->mapRoomNum = entry->dungeonData.intraRoomTransitions[i].toRoom;
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Layer switching = %x"
|
||||
osSyncPrintf("階層切替=%x\n", interfaceCtx->mapRoomNum);
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(play, interfaceCtx->mapRoomNum);
|
||||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||||
Map_SavePlayerInitialInfo(play);
|
||||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->mapRoomNum != sLastRoomNum) {
|
||||
// "Current floor = %d Current room = %x Number of rooms = %d"
|
||||
osSyncPrintf("現在階=%d 現在部屋=%x 部屋数=%d\n", floor, interfaceCtx->mapRoomNum,
|
||||
gMapData->switchEntryCount[mapIndex]);
|
||||
sLastRoomNum = interfaceCtx->mapRoomNum;
|
||||
}
|
||||
|
||||
for (i = 0; i < gMapData->switchEntryCount[mapIndex]; i++) {
|
||||
if ((interfaceCtx->mapRoomNum == gMapData->switchFromRoom[mapIndex][i]) &&
|
||||
(floor == gMapData->switchFromFloor[mapIndex][i])) {
|
||||
interfaceCtx->mapRoomNum = gMapData->switchToRoom[mapIndex][i];
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
// "Layer switching = %x"
|
||||
osSyncPrintf("階層切替=%x\n", interfaceCtx->mapRoomNum);
|
||||
osSyncPrintf(VT_RST);
|
||||
Map_InitData(play, interfaceCtx->mapRoomNum);
|
||||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||||
Map_SavePlayerInitialInfo(play);
|
||||
}
|
||||
}
|
||||
|
||||
VREG(10) = interfaceCtx->mapRoomNum;
|
||||
break;
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
VREG(30) = gMapData->bossFloor[play->sceneNum - SCENE_DEKU_TREE_BOSS];
|
||||
R_MAP_TEX_INDEX = R_MAP_TEX_INDEX_BASE +
|
||||
gMapData->floorTexIndexOffset[play->sceneNum - SCENE_DEKU_TREE_BOSS][VREG(30)];
|
||||
break;
|
||||
VREG(10) = interfaceCtx->mapRoomNum;
|
||||
} else if (SCENEDB_ISBOSS(entry)) {
|
||||
VREG(30) = SceneDB_Retrieve(entry->bossData.mapScene)->dungeonData.bossFloor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "global.h"
|
||||
#include "vt.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "textures/parameter_static/parameter_static.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
|
@ -95,138 +96,112 @@ void MapMark_DrawForDungeon(PlayState* play) {
|
|||
|
||||
interfaceCtx = &play->interfaceCtx;
|
||||
|
||||
if ((gMapData != NULL) && (play->interfaceCtx.mapRoomNum >= gMapData->dgnMinimapCount[dungeon])) {
|
||||
// "Room number exceeded, yikes %d/%d MapMarkDraw processing interrupted"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "部屋番号がオーバーしてるで,ヤバイで %d/%d \nMapMarkDraw の処理を中断します\n",
|
||||
VT_RST, play->interfaceCtx.mapRoomNum, gMapData->dgnMinimapCount[dungeon]);
|
||||
return;
|
||||
}
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(dungeon);
|
||||
SceneDBRoom* room = &entry->dungeonData.rooms[interfaceCtx->mapRoomNum];
|
||||
|
||||
mapMarkIconData = &sLoadedMarkDataTable[dungeon][interfaceCtx->mapRoomNum][0];
|
||||
s32 Top_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.T"), 0);
|
||||
s32 Left_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.L"), 0);
|
||||
s32 Right_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.R"), 0);
|
||||
s32 Bottom_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.B"), 0);
|
||||
|
||||
s32 X_Margins_Minimap_ic;
|
||||
s32 Y_Margins_Minimap_ic;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ORIGINAL_LOCATION) {
|
||||
X_Margins_Minimap_ic = Right_MC_Margin;
|
||||
};
|
||||
Y_Margins_Minimap_ic = Bottom_MC_Margin;
|
||||
} else {
|
||||
X_Margins_Minimap_ic = 0;
|
||||
Y_Margins_Minimap_ic = 0;
|
||||
}
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
while (true) {
|
||||
if (mapMarkIconData->markType == MAP_MARK_NONE) {
|
||||
break;
|
||||
gDPPipeSync(OVERLAY_DISP++);
|
||||
gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->minimapAlpha);
|
||||
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, interfaceCtx->minimapAlpha);
|
||||
|
||||
// Chest and boss icon code is nearly identical, so let's draw them in the same loop
|
||||
for (i = 0; i < room->numChestMarks + room->numBossMarks; i++) {
|
||||
if (i < room->numChestMarks) {
|
||||
if (Flags_GetTreasure(play, markPoint->chestFlag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
markPoint = &room->chestMarks[i];
|
||||
markInfo = &sMapMarkInfoTable[MAP_MARK_CHEST];
|
||||
} else { // This is a boss icon
|
||||
markPoint = &room->bossMarks[i - room->numChestMarks];
|
||||
markInfo = &sMapMarkInfoTable[MAP_MARK_BOSS];
|
||||
}
|
||||
|
||||
int height = markInfo->textureHeight * 1.0f; // Adjust Height with scale
|
||||
int width = markInfo->textureWidth * 1.0f; // Adjust Width with scale
|
||||
int height_factor = (1 << 10) * markInfo->textureHeight / height;
|
||||
int width_factor = (1 << 10) * markInfo->textureWidth / width;
|
||||
|
||||
// The original mark point X originates from the left edge of the map
|
||||
// For mirror mode, we compute the new mark point X by subtracting it from the right side of the
|
||||
// dungeon map and the textures width
|
||||
s16 markPointX =
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 96 - markPoint->x - width : markPoint->x;
|
||||
|
||||
// Minimap chest / boss icon
|
||||
const s32 PosX_Minimap_ori =
|
||||
GREG(94) + OTRGetRectDimensionFromRightEdge(markPointX + X_Margins_Minimap_ic) + 204;
|
||||
const s32 PosY_Minimap_ori = GREG(95) + markPoint->y + Y_Margins_Minimap_ic + 140;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
rectTop =
|
||||
(markPoint->y + Y_Margins_Minimap_ic + 140 + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0));
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap_ic = Left_MC_Margin;
|
||||
};
|
||||
if (play->sceneNum == SCENE_DEKU_TREE || play->sceneNum == SCENE_DODONGOS_CAVERN ||
|
||||
play->sceneNum == SCENE_JABU_JABU || play->sceneNum == SCENE_FOREST_TEMPLE ||
|
||||
play->sceneNum == SCENE_FIRE_TEMPLE || play->sceneNum == SCENE_WATER_TEMPLE ||
|
||||
play->sceneNum == SCENE_SPIRIT_TEMPLE || play->sceneNum == SCENE_SHADOW_TEMPLE ||
|
||||
play->sceneNum == SCENE_BOTTOM_OF_THE_WELL || play->sceneNum == SCENE_ICE_CAVERN) {
|
||||
rectLeft = OTRGetRectDimensionFromLeftEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 + X_Margins_Minimap_ic);
|
||||
} else {
|
||||
rectLeft = OTRGetRectDimensionFromLeftEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 + X_Margins_Minimap_ic);
|
||||
}
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap_ic = Right_MC_Margin;
|
||||
};
|
||||
rectLeft = OTRGetRectDimensionFromRightEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 + X_Margins_Minimap_ic);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
rectLeft =
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 + X_Margins_Minimap_ic;
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == HIDDEN) {
|
||||
rectLeft = -9999;
|
||||
}
|
||||
} else {
|
||||
rectLeft = PosX_Minimap_ori;
|
||||
rectTop = PosY_Minimap_ori;
|
||||
}
|
||||
|
||||
gDPPipeSync(OVERLAY_DISP++);
|
||||
gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->minimapAlpha);
|
||||
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, interfaceCtx->minimapAlpha);
|
||||
|
||||
s32 Top_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.T"), 0);
|
||||
s32 Left_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.L"), 0);
|
||||
s32 Right_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.R"), 0);
|
||||
s32 Bottom_MC_Margin = CVarGetInteger(CVAR_COSMETIC("HUD.Margin.B"), 0);
|
||||
|
||||
s32 X_Margins_Minimap_ic;
|
||||
s32 Y_Margins_Minimap_ic;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ORIGINAL_LOCATION) {
|
||||
X_Margins_Minimap_ic = Right_MC_Margin;
|
||||
};
|
||||
Y_Margins_Minimap_ic = Bottom_MC_Margin;
|
||||
} else {
|
||||
X_Margins_Minimap_ic = 0;
|
||||
Y_Margins_Minimap_ic = 0;
|
||||
}
|
||||
|
||||
markPoint = &mapMarkIconData->points[0];
|
||||
// Place each chest / boss room icon
|
||||
for (i = 0; i < mapMarkIconData->count; i++) {
|
||||
if ((mapMarkIconData->markType != MAP_MARK_CHEST) || !Flags_GetTreasure(play, markPoint->chestFlag)) {
|
||||
markInfo = &sMapMarkInfoTable[mapMarkIconData->markType];
|
||||
int height = markInfo->textureHeight * 1.0f; // Adjust Height with scale
|
||||
int width = markInfo->textureWidth * 1.0f; // Adjust Width with scale
|
||||
int height_factor = (1 << 10) * markInfo->textureHeight / height;
|
||||
int width_factor = (1 << 10) * markInfo->textureWidth / width;
|
||||
|
||||
// The original mark point X originates from the left edge of the map
|
||||
// For mirror mode, we compute the new mark point X by subtracting it from the right side of the
|
||||
// dungeon map and the textures width
|
||||
s16 markPointX =
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 96 - markPoint->x - width : markPoint->x;
|
||||
|
||||
// Minimap chest / boss icon
|
||||
const s32 PosX_Minimap_ori =
|
||||
GREG(94) + OTRGetRectDimensionFromRightEdge(markPointX + X_Margins_Minimap_ic) + 204;
|
||||
const s32 PosY_Minimap_ori = GREG(95) + markPoint->y + Y_Margins_Minimap_ic + 140;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) != ORIGINAL_LOCATION) {
|
||||
rectTop = (markPoint->y + Y_Margins_Minimap_ic + 140 +
|
||||
CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosY"), 0));
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_LEFT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap_ic = Left_MC_Margin;
|
||||
};
|
||||
if (play->sceneNum == SCENE_DEKU_TREE || play->sceneNum == SCENE_DODONGOS_CAVERN ||
|
||||
play->sceneNum == SCENE_JABU_JABU || play->sceneNum == SCENE_FOREST_TEMPLE ||
|
||||
play->sceneNum == SCENE_FIRE_TEMPLE || play->sceneNum == SCENE_WATER_TEMPLE ||
|
||||
play->sceneNum == SCENE_SPIRIT_TEMPLE || play->sceneNum == SCENE_SHADOW_TEMPLE ||
|
||||
play->sceneNum == SCENE_BOTTOM_OF_THE_WELL || play->sceneNum == SCENE_ICE_CAVERN) {
|
||||
rectLeft = OTRGetRectDimensionFromLeftEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 +
|
||||
X_Margins_Minimap_ic);
|
||||
} else {
|
||||
rectLeft = OTRGetRectDimensionFromLeftEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 +
|
||||
X_Margins_Minimap_ic);
|
||||
}
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.UseMargins"), 0) != 0) {
|
||||
X_Margins_Minimap_ic = Right_MC_Margin;
|
||||
};
|
||||
rectLeft = OTRGetRectDimensionFromRightEdge(
|
||||
markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 +
|
||||
X_Margins_Minimap_ic);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == ANCHOR_NONE) {
|
||||
rectLeft = markPointX + CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosX"), 0) + 204 +
|
||||
X_Margins_Minimap_ic;
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.Minimap.PosType"), 0) == HIDDEN) {
|
||||
rectLeft = -9999;
|
||||
}
|
||||
} else {
|
||||
rectLeft = PosX_Minimap_ori;
|
||||
rectTop = PosY_Minimap_ori;
|
||||
}
|
||||
|
||||
gDPPipeSync(OVERLAY_DISP++);
|
||||
|
||||
gDPLoadTextureBlock(OVERLAY_DISP++, markInfo->texture, markInfo->imageFormat, G_IM_SIZ_MARK,
|
||||
markInfo->textureWidth, markInfo->textureHeight, 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);
|
||||
// Changed to a Wide texture to support Left anchor.
|
||||
gSPWideTextureRectangle(OVERLAY_DISP++, rectLeft << 2, rectTop << 2, rectLeft + width << 2,
|
||||
rectTop + height << 2, G_TX_RENDERTILE, 0, 0, width_factor, height_factor);
|
||||
}
|
||||
|
||||
markPoint++;
|
||||
}
|
||||
mapMarkIconData++;
|
||||
gDPLoadTextureBlock(OVERLAY_DISP++, markInfo->texture, markInfo->imageFormat, G_IM_SIZ_MARK,
|
||||
markInfo->textureWidth, markInfo->textureHeight, 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);
|
||||
// Changed to a Wide texture to support Left anchor.
|
||||
gSPWideTextureRectangle(OVERLAY_DISP++, rectLeft << 2, rectTop << 2, rectLeft + width << 2,
|
||||
rectTop + height << 2, G_TX_RENDERTILE, 0, 0, width_factor, height_factor);
|
||||
}
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
void MapMark_Draw(PlayState* play) {
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
MapMark_DrawForDungeon(play);
|
||||
break;
|
||||
if (SceneDB_IsDungeon(play->sceneNum) || SceneDB_IsBoss(play->sceneNum)) {
|
||||
MapMark_DrawForDungeon(play);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3765,7 +3765,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
|||
if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS &&
|
||||
(msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET ||
|
||||
msgCtx->ocarinaAction >= OCARINA_ACTION_PLAYBACK_SARIA)) {
|
||||
if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs == 3 && !IS_RANDO)) {
|
||||
if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs && !IS_RANDO)) {
|
||||
Message_StartTextbox(play, 0x88C, NULL); // "You can't warp here!"
|
||||
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
|
||||
} else if ((gSaveContext.eventInf[0] & 0xF) != 1) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
|
||||
#include "libultraship/bridge.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "soh/Enhancements/gameplaystats.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
||||
#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h"
|
||||
|
@ -1068,7 +1069,7 @@ void func_80083108(PlayState* play) {
|
|||
|
||||
Interface_ChangeAlpha(50);
|
||||
} else {
|
||||
if (interfaceCtx->restrictions.bButton == 0) {
|
||||
if (!interfaceCtx->restrictions.bButton) {
|
||||
if ((gSaveContext.equips.buttonItems[0] == ITEM_SLINGSHOT) ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_BOW) ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU) ||
|
||||
|
@ -1095,7 +1096,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0] & 0xFF;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.bButton == 1) {
|
||||
} else {
|
||||
if ((gSaveContext.equips.buttonItems[0] == ITEM_SLINGSHOT) ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_BOW) ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU) ||
|
||||
|
@ -1133,7 +1134,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.bottles != 0) {
|
||||
if (interfaceCtx->restrictions.bottles) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
|
||||
(gSaveContext.equips.buttonItems[i] <= ITEM_POE)) {
|
||||
|
@ -1144,7 +1145,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] = BTN_DISABLED;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.bottles == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
|
||||
(gSaveContext.equips.buttonItems[i] <= ITEM_POE)) {
|
||||
|
@ -1157,7 +1158,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.tradeItems != 0) {
|
||||
if (interfaceCtx->restrictions.tradeItems) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) !=
|
||||
BUNNY_HOOD_VANILLA) &&
|
||||
|
@ -1173,7 +1174,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] = BTN_DISABLED;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.tradeItems == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
|
||||
(gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK)) {
|
||||
|
@ -1186,7 +1187,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.hookshot != 0) {
|
||||
if (interfaceCtx->restrictions.hookshot) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_HOOKSHOT) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_LONGSHOT)) {
|
||||
|
@ -1197,7 +1198,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] = BTN_DISABLED;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.hookshot == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_HOOKSHOT) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_LONGSHOT)) {
|
||||
|
@ -1210,7 +1211,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.ocarina != 0) {
|
||||
if (interfaceCtx->restrictions.ocarina) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_OCARINA_FAIRY) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_OCARINA_TIME)) {
|
||||
|
@ -1221,7 +1222,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] = BTN_DISABLED;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.ocarina == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_OCARINA_FAIRY) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_OCARINA_TIME)) {
|
||||
|
@ -1234,7 +1235,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.farores != 0) {
|
||||
if (interfaceCtx->restrictions.farores) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if (gSaveContext.equips.buttonItems[i] == ITEM_FARORES_WIND) {
|
||||
if (gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] == BTN_ENABLED) {
|
||||
|
@ -1245,7 +1246,7 @@ void func_80083108(PlayState* play) {
|
|||
osSyncPrintf("***(i=%d)*** ", i);
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.farores == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if (gSaveContext.equips.buttonItems[i] == ITEM_FARORES_WIND) {
|
||||
if (gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] == BTN_DISABLED) {
|
||||
|
@ -1257,7 +1258,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.dinsNayrus != 0) {
|
||||
if (interfaceCtx->restrictions.dinsNayrus) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_DINS_FIRE) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_NAYRUS_LOVE)) {
|
||||
|
@ -1268,7 +1269,7 @@ void func_80083108(PlayState* play) {
|
|||
gSaveContext.buttonStatus[BUTTON_STATUS_INDEX(i)] = BTN_DISABLED;
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.dinsNayrus == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] == ITEM_DINS_FIRE) ||
|
||||
(gSaveContext.equips.buttonItems[i] == ITEM_NAYRUS_LOVE)) {
|
||||
|
@ -1281,7 +1282,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
|
||||
if (interfaceCtx->restrictions.all != 0) {
|
||||
if (interfaceCtx->restrictions.all) {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] != ITEM_OCARINA_FAIRY) &&
|
||||
(gSaveContext.equips.buttonItems[i] != ITEM_OCARINA_TIME) &&
|
||||
|
@ -1308,7 +1309,7 @@ void func_80083108(PlayState* play) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (interfaceCtx->restrictions.all == 0) {
|
||||
} else {
|
||||
for (i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if ((gSaveContext.equips.buttonItems[i] != ITEM_DINS_FIRE) &&
|
||||
(gSaveContext.equips.buttonItems[i] != ITEM_HOOKSHOT) &&
|
||||
|
@ -1346,61 +1347,26 @@ void func_80083108(PlayState* play) {
|
|||
|
||||
void Interface_SetSceneRestrictions(PlayState* play) {
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
s16 i;
|
||||
u8 currentScene;
|
||||
|
||||
// clang-format off
|
||||
interfaceCtx->restrictions.hGauge = interfaceCtx->restrictions.bButton =
|
||||
interfaceCtx->restrictions.aButton = interfaceCtx->restrictions.bottles =
|
||||
interfaceCtx->restrictions.tradeItems = interfaceCtx->restrictions.hookshot =
|
||||
interfaceCtx->restrictions.ocarina = interfaceCtx->restrictions.warpSongs =
|
||||
interfaceCtx->restrictions.sunsSong = interfaceCtx->restrictions.farores =
|
||||
interfaceCtx->restrictions.dinsNayrus = interfaceCtx->restrictions.all = 0;
|
||||
// clang-format on
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
interfaceCtx->restrictions.hGauge = entry->restrictions.hGauge;
|
||||
interfaceCtx->restrictions.bButton = entry->restrictions.bButton;
|
||||
interfaceCtx->restrictions.aButton = entry->restrictions.aButton;
|
||||
interfaceCtx->restrictions.bottles = entry->restrictions.bottles;
|
||||
interfaceCtx->restrictions.tradeItems = entry->restrictions.tradeItems;
|
||||
interfaceCtx->restrictions.hookshot = entry->restrictions.hookshot;
|
||||
interfaceCtx->restrictions.ocarina = entry->restrictions.ocarina;
|
||||
interfaceCtx->restrictions.warpSongs = entry->restrictions.warpSongs;
|
||||
interfaceCtx->restrictions.sunsSong = entry->restrictions.sunsSong;
|
||||
interfaceCtx->restrictions.farores = entry->restrictions.farores;
|
||||
interfaceCtx->restrictions.dinsNayrus = entry->restrictions.dinsNayrus;
|
||||
interfaceCtx->restrictions.all = entry->restrictions.all;
|
||||
|
||||
i = 0;
|
||||
|
||||
// "Data settings related to button display scene_data_ID=%d\n"
|
||||
osSyncPrintf("ボタン表示関係データ設定 scene_data_ID=%d\n", play->sceneNum);
|
||||
|
||||
do {
|
||||
currentScene = (u8)play->sceneNum;
|
||||
if (sRestrictionFlags[i].scene == currentScene) {
|
||||
interfaceCtx->restrictions.hGauge = (sRestrictionFlags[i].flags1 & 0xC0) >> 6;
|
||||
interfaceCtx->restrictions.bButton = (sRestrictionFlags[i].flags1 & 0x30) >> 4;
|
||||
interfaceCtx->restrictions.aButton = (sRestrictionFlags[i].flags1 & 0x0C) >> 2;
|
||||
interfaceCtx->restrictions.bottles = (sRestrictionFlags[i].flags1 & 0x03) >> 0;
|
||||
interfaceCtx->restrictions.tradeItems = (sRestrictionFlags[i].flags2 & 0xC0) >> 6;
|
||||
interfaceCtx->restrictions.hookshot = (sRestrictionFlags[i].flags2 & 0x30) >> 4;
|
||||
interfaceCtx->restrictions.ocarina = (sRestrictionFlags[i].flags2 & 0x0C) >> 2;
|
||||
interfaceCtx->restrictions.warpSongs = (sRestrictionFlags[i].flags2 & 0x03) >> 0;
|
||||
interfaceCtx->restrictions.sunsSong = (sRestrictionFlags[i].flags3 & 0xC0) >> 6;
|
||||
interfaceCtx->restrictions.farores = (sRestrictionFlags[i].flags3 & 0x30) >> 4;
|
||||
interfaceCtx->restrictions.dinsNayrus = (sRestrictionFlags[i].flags3 & 0x0C) >> 2;
|
||||
interfaceCtx->restrictions.all = (sRestrictionFlags[i].flags3 & 0x03) >> 0;
|
||||
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("parameter->button_status = %x,%x,%x\n", sRestrictionFlags[i].flags1,
|
||||
sRestrictionFlags[i].flags2, sRestrictionFlags[i].flags3);
|
||||
osSyncPrintf("h_gage=%d, b_button=%d, a_button=%d, c_bottle=%d\n", interfaceCtx->restrictions.hGauge,
|
||||
interfaceCtx->restrictions.bButton, interfaceCtx->restrictions.aButton,
|
||||
interfaceCtx->restrictions.bottles);
|
||||
osSyncPrintf("c_warasibe=%d, c_hook=%d, c_ocarina=%d, c_warp=%d\n", interfaceCtx->restrictions.tradeItems,
|
||||
interfaceCtx->restrictions.hookshot, interfaceCtx->restrictions.ocarina,
|
||||
interfaceCtx->restrictions.warpSongs);
|
||||
osSyncPrintf("c_sunmoon=%d, m_wind=%d, m_magic=%d, another=%d\n", interfaceCtx->restrictions.sunsSong,
|
||||
interfaceCtx->restrictions.farores, interfaceCtx->restrictions.dinsNayrus,
|
||||
interfaceCtx->restrictions.all);
|
||||
osSyncPrintf(VT_RST);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) {
|
||||
if (currentScene == SCENE_GERUDO_TRAINING_GROUND || currentScene == SCENE_INSIDE_GANONS_CASTLE) {
|
||||
interfaceCtx->restrictions.farores = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) {
|
||||
if (play->sceneNum == SCENE_GERUDO_TRAINING_GROUND || play->sceneNum == SCENE_INSIDE_GANONS_CASTLE) {
|
||||
interfaceCtx->restrictions.farores = 0;
|
||||
}
|
||||
i++;
|
||||
} while (sRestrictionFlags[i].scene != 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
Gfx* Gfx_TextureIA8(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop,
|
||||
|
@ -1427,6 +1393,141 @@ Gfx* Gfx_TextureI8(Gfx* displayListHead, void* texture, s16 textureWidth, s16 te
|
|||
return displayListHead;
|
||||
}
|
||||
|
||||
void Inventory_DoBA(u8 cRight) {
|
||||
if (cRight >= ITEM_STICK && cRight <= ITEM_POTION_BLUE) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.items[cRight];
|
||||
} else if (cRight >= ITEM_FAIRY && cRight <= ITEM_MASK_BUNNY) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.ammo[cRight - ITEM_FAIRY];
|
||||
} else if (cRight == ITEM_MASK_GORON) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.equipment >> 8) & 0xFF;
|
||||
} else if (cRight == ITEM_MASK_ZORA) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.equipment & 0xFF;
|
||||
} else if (cRight == ITEM_MASK_GERUDO || cRight == ITEM_MASK_TRUTH) {
|
||||
// ITEM_MASK_GERUDO and ITEM_MASK_TRUTH land in padding bytes
|
||||
gSaveContext.equips.buttonItems[0] = 0;
|
||||
} else if (cRight == ITEM_SOLD_OUT) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.upgrades >> 24) & 0xFF;
|
||||
} else if (cRight == ITEM_POCKET_EGG) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.upgrades >> 16) & 0xFF;
|
||||
} else if (cRight == ITEM_POCKET_CUCCO) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.upgrades >> 8) & 0xFF;
|
||||
} else if (cRight == ITEM_COJIRO) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.upgrades & 0xFF;
|
||||
} else if (cRight == ITEM_ODD_MUSHROOM) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.questItems >> 24) & 0xFF;
|
||||
} else if (cRight == ITEM_ODD_POTION) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.questItems >> 16) & 0xFF;
|
||||
} else if (cRight == ITEM_SAW) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.questItems >> 8) & 0xFF;
|
||||
} else if (cRight == ITEM_SWORD_BROKEN) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.questItems & 0xFF;
|
||||
} else if (cRight >= ITEM_PRESCRIPTION && cRight <= ITEM_BULLET_BAG_30) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.dungeonItems[cRight - ITEM_PRESCRIPTION];
|
||||
} else if (cRight >= ITEM_BULLET_BAG_40 && cRight <= ITEM_SWORD_KNIFE) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.dungeonKeys[cRight - ITEM_BULLET_BAG_40];
|
||||
} else if (cRight == ITEM_SONG_BOLERO) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.defenseHearts;
|
||||
} else if (cRight == ITEM_SONG_SERENADE) {
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.inventory.gsTokens >> 8) & 0xFF;
|
||||
} else if (cRight == ITEM_SONG_REQUIEM) {
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.inventory.gsTokens & 0xFF;
|
||||
} else if (cRight == ITEM_SONG_NOCTURNE || cRight == ITEM_SONG_PRELUDE) {
|
||||
// ITEM_SONG_NOCTURNE and ITEM_SONG_PRELUDE land in padding bytes
|
||||
gSaveContext.equips.buttonItems[0] = 0;
|
||||
} else if (cRight >= ITEM_SONG_LULLABY) {
|
||||
// The rest of the items fall into the saved scene flags. Let's calculate the scene and which field it pulls
|
||||
// from
|
||||
u32 offset = cRight - ITEM_SONG_LULLABY;
|
||||
u32 scene = offset / sizeof(SavedSceneFlags);
|
||||
switch (offset % sizeof(SavedSceneFlags)) {
|
||||
case 0:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 24) & 0xFF;
|
||||
break;
|
||||
case 1:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 16) & 0xFF;
|
||||
break;
|
||||
case 2:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 8) & 0xFF;
|
||||
break;
|
||||
case 3:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].chest & 0xFF;
|
||||
break;
|
||||
case 4:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 24) & 0xFF;
|
||||
break;
|
||||
case 5:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 16) & 0xFF;
|
||||
break;
|
||||
case 6:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 8) & 0xFF;
|
||||
break;
|
||||
case 7:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].swch & 0xFF;
|
||||
break;
|
||||
case 8:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 24) & 0xFF;
|
||||
break;
|
||||
case 9:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 16) & 0xFF;
|
||||
break;
|
||||
case 10:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 8) & 0xFF;
|
||||
break;
|
||||
case 11:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].clear & 0xFF;
|
||||
break;
|
||||
case 12:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 24) & 0xFF;
|
||||
break;
|
||||
case 13:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 16) & 0xFF;
|
||||
break;
|
||||
case 14:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 8) & 0xFF;
|
||||
break;
|
||||
case 15:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].collect & 0xFF;
|
||||
break;
|
||||
case 16:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 24) & 0xFF;
|
||||
break;
|
||||
case 17:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 16) & 0xFF;
|
||||
break;
|
||||
case 18:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 8) & 0xFF;
|
||||
break;
|
||||
case 19:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].unk & 0xFF;
|
||||
break;
|
||||
case 20:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 24) & 0xFF;
|
||||
break;
|
||||
case 21:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 16) & 0xFF;
|
||||
break;
|
||||
case 22:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 8) & 0xFF;
|
||||
break;
|
||||
case 23:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].rooms & 0xFF;
|
||||
break;
|
||||
case 24:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 24) & 0xFF;
|
||||
break;
|
||||
case 25:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 16) & 0xFF;
|
||||
break;
|
||||
case 26:
|
||||
gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 8) & 0xFF;
|
||||
break;
|
||||
case 27:
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].floors & 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rando_Inventory_SwapAgeEquipment(void) {
|
||||
s16 i;
|
||||
u16 shieldEquipValue;
|
||||
|
@ -6864,7 +6965,7 @@ void Interface_Update(PlayState* play) {
|
|||
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
|
||||
}
|
||||
} else if ((play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_1) &&
|
||||
(interfaceCtx->restrictions.sunsSong != 3)) {
|
||||
(!interfaceCtx->restrictions.sunsSong)) {
|
||||
if ((gSaveContext.dayTime >= 0x4555) && (gSaveContext.dayTime < 0xC001)) {
|
||||
gSaveContext.nextDayTime = 0;
|
||||
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/framebuffer_effects.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
|
@ -478,23 +479,21 @@ void Play_Init(GameState* thisx) {
|
|||
|
||||
// save the base scene layer (before accounting for the special cases below) to use later for the transition type
|
||||
baseSceneLayer = gSaveContext.sceneSetupIndex;
|
||||
|
||||
if ((gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_HYRULE_FIELD) && !LINK_IS_ADULT &&
|
||||
!IS_CUTSCENE_LAYER) {
|
||||
EntranceDBEntry* entrance = EntranceDB_Retrieve(gSaveContext.entranceIndex);
|
||||
if ((entrance->sceneId == SCENE_HYRULE_FIELD) && !LINK_IS_ADULT && !IS_CUTSCENE_LAYER) {
|
||||
if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) &&
|
||||
CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)) {
|
||||
gSaveContext.sceneSetupIndex = 1;
|
||||
} else {
|
||||
gSaveContext.sceneSetupIndex = 0;
|
||||
}
|
||||
} else if ((gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KOKIRI_FOREST) && LINK_IS_ADULT &&
|
||||
!IS_CUTSCENE_LAYER) {
|
||||
} else if ((entrance->sceneId == SCENE_KOKIRI_FOREST) && LINK_IS_ADULT && !IS_CUTSCENE_LAYER) {
|
||||
gSaveContext.sceneSetupIndex = (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) ? 3 : 2;
|
||||
}
|
||||
|
||||
Play_SpawnScene(
|
||||
play, gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].scene,
|
||||
gEntranceTable[((void)0, gSaveContext.sceneSetupIndex) + ((void)0, gSaveContext.entranceIndex)].spawn);
|
||||
EntranceDBEntry* adjustedEntrance =
|
||||
EntranceDB_RetrieveLayer(gSaveContext.entranceIndex, gSaveContext.sceneSetupIndex);
|
||||
Play_SpawnScene(play, adjustedEntrance->sceneId, adjustedEntrance->spawn);
|
||||
|
||||
osSyncPrintf("\nSCENE_NO=%d COUNTER=%d\n", ((void)0, gSaveContext.entranceIndex), gSaveContext.sceneSetupIndex);
|
||||
|
||||
|
@ -549,8 +548,8 @@ void Play_Init(GameState* thisx) {
|
|||
|
||||
if (gSaveContext.gameMode != GAMEMODE_TITLE_SCREEN) {
|
||||
if (gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) {
|
||||
play->transitionType = ENTRANCE_INFO_END_TRANS_TYPE(
|
||||
gEntranceTable[((void)0, gSaveContext.entranceIndex) + baseSceneLayer].field); // Fade In
|
||||
EntranceDBEntry* transEntrance = EntranceDB_RetrieveLayer(gSaveContext.entranceIndex, baseSceneLayer);
|
||||
play->transitionType = transEntrance->endTransition; // Fade In
|
||||
} else {
|
||||
play->transitionType = gSaveContext.nextTransitionType;
|
||||
gSaveContext.nextTransitionType = TRANS_NEXT_TYPE_DEFAULT;
|
||||
|
@ -819,8 +818,7 @@ void Play_Update(PlayState* play) {
|
|||
}
|
||||
|
||||
// fade out bgm if "continue bgm" flag is not set
|
||||
if (!(gEntranceTable[play->nextEntranceIndex + sceneLayer].field &
|
||||
ENTRANCE_INFO_CONTINUE_BGM_FLAG)) {
|
||||
if (!EntranceDB_RetrieveLayer(play->nextEntranceIndex, sceneLayer)->continueBgm) {
|
||||
// "Sound initalized. 111"
|
||||
osSyncPrintf("\n\n\nサウンドイニシャル来ました。111");
|
||||
if ((play->transitionType < TRANS_TYPE_MAX) && !Environment_IsForcedSequenceDisabled()) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <soh/SceneDB.h>
|
||||
|
||||
#include "public/bridge/gfxbridge.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
@ -646,7 +647,7 @@ void func_80097534(PlayState* play, RoomContext* roomCtx) {
|
|||
func_80031B14(play, &play->actorCtx); // kills all actors without room num set to -1
|
||||
Actor_SpawnTransitionActors(play, &play->actorCtx);
|
||||
Map_InitRoomData(play, roomCtx->curRoom.num);
|
||||
if (!((play->sceneNum >= SCENE_HYRULE_FIELD) && (play->sceneNum <= SCENE_LON_LON_RANCH))) {
|
||||
if (!SceneDB_IsOverworld(play->sceneNum)) {
|
||||
Map_SavePlayerInitialInfo(play);
|
||||
}
|
||||
Audio_SetEnvReverb(play->roomCtx.curRoom.echo);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "soh/mq_asset_hacks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
// Entrance Table definition
|
||||
#define DEFINE_ENTRANCE(_0, sceneId, spawn, continueBgm, displayTitleCard, endTransType, startTransType) \
|
||||
|
@ -87,23 +88,23 @@ Gfx sDefaultDisplayList[] = {
|
|||
|
||||
// Computes next entrance index based on age and day time to set the fade out transition
|
||||
void Scene_SetTransitionForNextEntrance(PlayState* play) {
|
||||
s16 entranceIndex;
|
||||
s16 layer = 0;
|
||||
|
||||
if (!IS_DAY) {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex + 1;
|
||||
layer = 1;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 3;
|
||||
layer = 3;
|
||||
}
|
||||
} else {
|
||||
if (!LINK_IS_ADULT) {
|
||||
entranceIndex = play->nextEntranceIndex;
|
||||
layer = 0;
|
||||
} else {
|
||||
entranceIndex = play->nextEntranceIndex + 2;
|
||||
layer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
play->transitionType = ENTRANCE_INFO_START_TRANS_TYPE(gEntranceTable[entranceIndex].field); // Fade out
|
||||
play->transitionType = EntranceDB_RetrieveLayer(play->nextEntranceIndex, layer)->startTransition; // Fade out
|
||||
}
|
||||
|
||||
// Scene Draw Config 0
|
||||
|
|
|
@ -1413,11 +1413,11 @@ void func_80A053F0(Actor* thisx, PlayState* play) {
|
|||
} else {
|
||||
this->actionFunc(this, play);
|
||||
thisx->shape.rot.y = this->unk_2BC;
|
||||
nREG(80) = gSaveContext.sceneFlags[127].chest;
|
||||
nREG(80) = HIGH_SCORE(HS_HBA);
|
||||
|
||||
if (nREG(81) != 0) {
|
||||
if (gSaveContext.sceneFlags[127].chest) {
|
||||
LOG_NUM("z_common_data.memory.information.room_inf[127][ 0 ]", gSaveContext.sceneFlags[127].chest);
|
||||
if (HIGH_SCORE(HS_HBA)) {
|
||||
LOG_NUM("z_common_data.memory.information.room_inf[127][ 0 ]", HIGH_SCORE(HS_HBA));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "objects/object_hni/object_hni.h"
|
||||
#include "scenes/overworld/spot09/spot09_scene.h"
|
||||
#include <assert.h>
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
|
||||
|
||||
|
@ -679,35 +680,39 @@ s32 EnHorse_Spawn(EnHorse* this, PlayState* play) {
|
|||
Player* player;
|
||||
Vec3f spawnPos;
|
||||
|
||||
for (i = 0; i < 169; i++) {
|
||||
if (sHorseSpawns[i].scene == play->sceneNum) {
|
||||
player = GET_PLAYER(play);
|
||||
if (play->sceneNum != SCENE_LON_LON_RANCH ||
|
||||
//! Same flag checked twice
|
||||
(Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) &&
|
||||
((gSaveContext.eventInf[0] & 0xF) != 6 || Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED))) ||
|
||||
// always load two spawns inside lon lon
|
||||
((sHorseSpawns[i].pos.x == 856 && sHorseSpawns[i].pos.y == 0 && sHorseSpawns[i].pos.z == -918) ||
|
||||
(sHorseSpawns[i].pos.x == -1003 && sHorseSpawns[i].pos.y == 0 && sHorseSpawns[i].pos.z == -755))) {
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(play->sceneNum);
|
||||
if (!entry->epona.allowed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
spawnPos.x = sHorseSpawns[i].pos.x;
|
||||
spawnPos.y = sHorseSpawns[i].pos.y;
|
||||
spawnPos.z = sHorseSpawns[i].pos.z;
|
||||
dist = Math3D_Vec3f_DistXYZ(&player->actor.world.pos, &spawnPos);
|
||||
for (i = 0; i < entry->epona.numSpawns; i++) {
|
||||
player = GET_PLAYER(play);
|
||||
if (play->sceneNum != SCENE_LON_LON_RANCH ||
|
||||
//! Same flag checked twice
|
||||
(Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) &&
|
||||
((gSaveContext.eventInf[0] & 0xF) != 6 || Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED))) ||
|
||||
// always load two spawns inside lon lon
|
||||
((entry->epona.spawnPos[i].x == 856 && entry->epona.spawnPos[i].y == 0 &&
|
||||
entry->epona.spawnPos[i].z == -918) ||
|
||||
(entry->epona.spawnPos[i].x == -1003 && entry->epona.spawnPos[i].y == 0 &&
|
||||
entry->epona.spawnPos[i].z == -755))) {
|
||||
|
||||
if (play->sceneNum) {}
|
||||
if (!(minDist < dist) && !func_80A5BBBC(play, this, &spawnPos)) {
|
||||
minDist = dist;
|
||||
this->actor.world.pos.x = sHorseSpawns[i].pos.x;
|
||||
this->actor.world.pos.y = sHorseSpawns[i].pos.y;
|
||||
this->actor.world.pos.z = sHorseSpawns[i].pos.z;
|
||||
this->actor.prevPos = this->actor.world.pos;
|
||||
this->actor.world.rot.y = sHorseSpawns[i].angle;
|
||||
this->actor.shape.rot.y = Actor_WorldYawTowardActor(&this->actor, &GET_PLAYER(play)->actor);
|
||||
spawn = true;
|
||||
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &this->actor.world.pos,
|
||||
&this->actor.projectedPos, &this->actor.projectedW);
|
||||
}
|
||||
spawnPos.x = entry->epona.spawnPos[i].x;
|
||||
spawnPos.y = entry->epona.spawnPos[i].y;
|
||||
spawnPos.z = entry->epona.spawnPos[i].z;
|
||||
dist = Math3D_Vec3f_DistXYZ(&player->actor.world.pos, &spawnPos);
|
||||
|
||||
if (!(minDist < dist) && !func_80A5BBBC(play, this, &spawnPos)) {
|
||||
minDist = dist;
|
||||
this->actor.world.pos.x = entry->epona.spawnPos[i].x;
|
||||
this->actor.world.pos.y = entry->epona.spawnPos[i].y;
|
||||
this->actor.world.pos.z = entry->epona.spawnPos[i].z;
|
||||
this->actor.prevPos = this->actor.world.pos;
|
||||
this->actor.world.rot.y = 0;
|
||||
this->actor.shape.rot.y = Actor_WorldYawTowardActor(&this->actor, &GET_PLAYER(play)->actor);
|
||||
spawn = true;
|
||||
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &this->actor.world.pos,
|
||||
&this->actor.projectedPos, &this->actor.projectedW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -10866,11 +10867,9 @@ void Player_Init(Actor* thisx, PlayState* play2) {
|
|||
}
|
||||
|
||||
if ((respawnFlag == 0) || (respawnFlag < -1)) {
|
||||
titleFileSize = scene->titleFile.vromEnd - scene->titleFile.vromStart;
|
||||
if (GameInteractor_Should(VB_SHOW_TITLE_CARD, gSaveContext.showTitleCard)) {
|
||||
if ((gSaveContext.sceneSetupIndex < 4) &&
|
||||
(gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].field &
|
||||
ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG) &&
|
||||
EntranceDB_RetrieveLayer(gSaveContext.entranceIndex, gSaveContext.sceneSetupIndex)->displayTitleCard &&
|
||||
((play->sceneNum != SCENE_DODONGOS_CAVERN) ||
|
||||
(Flags_GetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN))) &&
|
||||
((play->sceneNum != SCENE_BOMBCHU_SHOP) ||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "soh/Enhancements/randomizer/randomizer_grotto.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
void Select_SwitchBetterWarpMode(SelectContext* this, u8 isBetterWarpMode);
|
||||
void Sram_InitDebugSave(void);
|
||||
|
@ -57,7 +58,7 @@ void Select_LoadGame(SelectContext* this, s32 entranceIndex) {
|
|||
this->betterScenes[this->currentScene].entrancePairs[this->pageDownIndex];
|
||||
// Check to see if the scene/entrance we just picked can be MQ'd
|
||||
if (entrancePair.canBeMQ) {
|
||||
s16 scene = gEntranceTable[entrancePair.entranceIndex].scene;
|
||||
s16 scene = EntranceDB_Retrieve(entrancePair.entranceIndex)->sceneId;
|
||||
u8 isEntranceDefaultMQ = ResourceMgr_IsSceneMasterQuest(scene);
|
||||
if (!isEntranceDefaultMQ && this->opt) { // Force vanilla for default MQ scene
|
||||
CVarSetInteger(CVAR_GENERAL("BetterDebugWarpScreenMQMode"), WARP_MODE_OVERRIDE_MQ_AS_VANILLA);
|
||||
|
@ -1212,7 +1213,8 @@ void Better_Select_UpdateMenu(SelectContext* this) {
|
|||
BetterSceneSelectEntrancePair entrancePair =
|
||||
this->betterScenes[this->currentScene].entrancePairs[this->pageDownIndex];
|
||||
// Update the MQ status to match the new scene
|
||||
if (entrancePair.canBeMQ && ResourceMgr_IsSceneMasterQuest(gEntranceTable[entrancePair.entranceIndex].scene)) {
|
||||
if (entrancePair.canBeMQ &&
|
||||
ResourceMgr_IsSceneMasterQuest(EntranceDB_Retrieve(entrancePair.entranceIndex)->sceneId)) {
|
||||
this->opt = 1;
|
||||
} else {
|
||||
this->opt = 0;
|
||||
|
@ -1795,7 +1797,7 @@ void Select_SwitchBetterWarpMode(SelectContext* this, u8 isBetterWarpMode) {
|
|||
BetterSceneSelectEntrancePair entrancePair =
|
||||
this->betterScenes[this->currentScene].entrancePairs[this->pageDownIndex];
|
||||
if (entrancePair.canBeMQ &&
|
||||
ResourceMgr_IsSceneMasterQuest(gEntranceTable[entrancePair.entranceIndex].scene)) {
|
||||
ResourceMgr_IsSceneMasterQuest(EntranceDB_Retrieve(entrancePair.entranceIndex)->sceneId)) {
|
||||
this->opt = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "z_kaleido_scope.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "textures/icon_item_24_static/icon_item_24_static.h"
|
||||
#include "textures/icon_item_nes_static/icon_item_nes_static.h"
|
||||
#include "textures/icon_item_ger_static/icon_item_ger_static.h"
|
||||
|
@ -60,6 +61,7 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
s16 stepB;
|
||||
u16 rgba16;
|
||||
bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0);
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(gSaveContext.mapIndex);
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
|
@ -91,9 +93,6 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
pauseCtx->cursorX[PAUSE_MAP] = 0;
|
||||
pauseCtx->cursorPoint[PAUSE_MAP] = pauseCtx->dungeonMapSlot;
|
||||
osSyncPrintf("kscope->cursor_point=%d\n", pauseCtx->cursorPoint[PAUSE_MAP]);
|
||||
R_MAP_TEX_INDEX =
|
||||
R_MAP_TEX_INDEX_BASE +
|
||||
gMapData->floorTexIndexOffset[gSaveContext.mapIndex][pauseCtx->cursorPoint[PAUSE_MAP] - 3];
|
||||
KaleidoScope_UpdateDungeonMap(play);
|
||||
}
|
||||
}
|
||||
|
@ -121,12 +120,13 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
s16 oldFloor = pauseCtx->dungeonMapSlot;
|
||||
if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) {
|
||||
if (pauseCtx->cursorPoint[PAUSE_MAP] >= 4) {
|
||||
for (i = pauseCtx->cursorPoint[PAUSE_MAP] - 3 - 1; i >= 0; i--) {
|
||||
if ((gSaveContext.sceneFlags[gSaveContext.mapIndex].floors & gBitFlags[i]) ||
|
||||
(CHECK_DUNGEON_ITEM(DUNGEON_MAP, gSaveContext.mapIndex) &&
|
||||
(gMapData->floorID[interfaceCtx->unk_25A][i] != 0))) {
|
||||
(entry->dungeonData.floors[i].id != F_NA))) {
|
||||
pauseCtx->cursorPoint[PAUSE_MAP] = i + 3;
|
||||
break;
|
||||
}
|
||||
|
@ -137,20 +137,15 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
for (i = pauseCtx->cursorPoint[PAUSE_MAP] - 3 + 1; i < 11; i++) {
|
||||
if ((gSaveContext.sceneFlags[gSaveContext.mapIndex].floors & gBitFlags[i]) ||
|
||||
(CHECK_DUNGEON_ITEM(DUNGEON_MAP, gSaveContext.mapIndex) &&
|
||||
(gMapData->floorID[interfaceCtx->unk_25A][i] != 0))) {
|
||||
(entry->dungeonData.floors[i].id != F_NA))) {
|
||||
pauseCtx->cursorPoint[PAUSE_MAP] = i + 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = R_MAP_TEX_INDEX;
|
||||
R_MAP_TEX_INDEX =
|
||||
R_MAP_TEX_INDEX_BASE +
|
||||
gMapData->floorTexIndexOffset[gSaveContext.mapIndex][pauseCtx->cursorPoint[PAUSE_MAP] - 3];
|
||||
pauseCtx->dungeonMapSlot = pauseCtx->cursorPoint[PAUSE_MAP];
|
||||
if (i != R_MAP_TEX_INDEX) {
|
||||
if (pauseCtx->dungeonMapSlot != oldFloor) {
|
||||
KaleidoScope_UpdateDungeonMap(play);
|
||||
}
|
||||
}
|
||||
|
@ -179,10 +174,6 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
pauseCtx->cursorX[PAUSE_MAP] = 0;
|
||||
pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_MAP] =
|
||||
pauseCtx->dungeonMapSlot;
|
||||
R_MAP_TEX_INDEX =
|
||||
R_MAP_TEX_INDEX_BASE +
|
||||
gMapData
|
||||
->floorTexIndexOffset[gSaveContext.mapIndex][pauseCtx->cursorPoint[PAUSE_MAP] - 3];
|
||||
KaleidoScope_UpdateDungeonMap(play);
|
||||
}
|
||||
}
|
||||
|
@ -263,9 +254,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
if ((gSaveContext.sceneFlags[gSaveContext.mapIndex].floors & gBitFlags[i]) ||
|
||||
CHECK_DUNGEON_ITEM(DUNGEON_MAP, gSaveContext.mapIndex)) {
|
||||
if (i != (pauseCtx->dungeonMapSlot - 3)) {
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, floorIconTexs[gMapData->floorID[interfaceCtx->unk_25A][i]],
|
||||
G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, G_TX_WRAP | G_TX_NOMIRROR,
|
||||
G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, floorIconTexs[entry->dungeonData.floors[i].id], G_IM_FMT_IA,
|
||||
G_IM_SIZ_8b, 24, 16, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR,
|
||||
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0);
|
||||
}
|
||||
|
@ -277,8 +268,7 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 150, 150, 255, pauseCtx->alpha);
|
||||
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++,
|
||||
floorIconTexs[gMapData->floorID[interfaceCtx->unk_25A][pauseCtx->dungeonMapSlot - 3]],
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, floorIconTexs[entry->dungeonData.floors[pauseCtx->dungeonMapSlot - 3].id],
|
||||
G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR,
|
||||
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
|
@ -303,10 +293,9 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
|||
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
|
||||
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, gSaveContext.mapIndex) &&
|
||||
(gMapData->skullFloorIconY[gSaveContext.mapIndex] != -99)) {
|
||||
pauseCtx->mapPageVtx[120].v.ob[1] = pauseCtx->mapPageVtx[121].v.ob[1] =
|
||||
gMapData->skullFloorIconY[gSaveContext.mapIndex] + pauseCtx->offsetY;
|
||||
if (CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, gSaveContext.mapIndex) && (entry->dungeonData.bossFloor != -1)) {
|
||||
s16 skullFloorIconY = 51 - 14 * entry->dungeonData.bossFloor;
|
||||
pauseCtx->mapPageVtx[120].v.ob[1] = pauseCtx->mapPageVtx[121].v.ob[1] = skullFloorIconY + pauseCtx->offsetY;
|
||||
pauseCtx->mapPageVtx[122].v.ob[1] = pauseCtx->mapPageVtx[123].v.ob[1] = pauseCtx->mapPageVtx[120].v.ob[1] - 16;
|
||||
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gDungeonMapSkullTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0,
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/Enhancements/kaleido.h"
|
||||
#include "soh/SceneDB.h"
|
||||
|
||||
static void* sEquipmentFRATexs[] = {
|
||||
gPauseEquipment00FRATex, gPauseEquipment01Tex, gPauseEquipment02Tex, gPauseEquipment03Tex, gPauseEquipment04Tex,
|
||||
|
@ -3680,6 +3681,7 @@ static uint8_t mapBlendMask[MAP_48x85_TEX_WIDTH * MAP_48x85_TEX_HEIGHT];
|
|||
// SoH [General] - Modified to account for our resource system and HD textures
|
||||
void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(gSaveContext.mapIndex);
|
||||
|
||||
// Free old textures
|
||||
if (mapLeftTexModifiedRaw != NULL) {
|
||||
|
@ -3691,12 +3693,13 @@ void KaleidoScope_LoadDungeonMap(PlayState* play) {
|
|||
mapRightTexModifiedRaw = NULL;
|
||||
}
|
||||
|
||||
s16 floor = play->pauseCtx.cursorPoint[PAUSE_MAP] - 3;
|
||||
// Unload original textures to bypass cache result for lookups
|
||||
ResourceMgr_UnloadOriginalWhenAltExists(sDungeonMapTexs[R_MAP_TEX_INDEX]);
|
||||
ResourceMgr_UnloadOriginalWhenAltExists(sDungeonMapTexs[R_MAP_TEX_INDEX + 1]);
|
||||
ResourceMgr_UnloadOriginalWhenAltExists(entry->dungeonData.floors[floor].mapLeftTexture);
|
||||
ResourceMgr_UnloadOriginalWhenAltExists(entry->dungeonData.floors[floor].mapRightTexture);
|
||||
|
||||
interfaceCtx->mapSegmentName[0] = sDungeonMapTexs[R_MAP_TEX_INDEX];
|
||||
interfaceCtx->mapSegmentName[1] = sDungeonMapTexs[R_MAP_TEX_INDEX + 1];
|
||||
interfaceCtx->mapSegmentName[0] = entry->dungeonData.floors[floor].mapLeftTexture;
|
||||
interfaceCtx->mapSegmentName[1] = entry->dungeonData.floors[floor].mapRightTexture;
|
||||
|
||||
// When the texture is HD (raw) we need to copy a dynamic amount of data
|
||||
// Otherwise the original asset has a static size
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "z_kaleido_scope.h"
|
||||
#include "soh/SceneDB.h"
|
||||
#include "textures/parameter_static/parameter_static.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
|
||||
|
@ -36,12 +37,21 @@ static const u32 sLineBytesImageSizes[] = { 0, 1, 2, 2 };
|
|||
extern PauseMapMarksData gPauseMapMarkDataTable[];
|
||||
extern PauseMapMarksData gPauseMapMarkDataTableMasterQuest[];
|
||||
|
||||
static const Vtx sMarkBossVtx[] = {
|
||||
VTX(-4, 4, 0, 0, 0, 255, 255, 255, 255),
|
||||
VTX(-4, -4, 0, 0, 256, 255, 255, 255, 255),
|
||||
VTX(4, 4, 0, 256, 0, 255, 255, 255, 255),
|
||||
VTX(4, -4, 0, 256, 256, 255, 255, 255, 255),
|
||||
};
|
||||
|
||||
static const Vtx sMarkChestVtx[] = {
|
||||
VTX(-4, 4, 0, 0, 0, 255, 255, 255, 255),
|
||||
VTX(-4, -4, 0, 0, 256, 255, 255, 255, 255),
|
||||
VTX(4, 4, 0, 256, 0, 255, 255, 255, 255),
|
||||
VTX(4, -4, 0, 256, 256, 255, 255, 255, 255),
|
||||
};
|
||||
|
||||
void PauseMapMark_Init(PlayState* play) {
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gLoadedPauseMarkDataTable = gPauseMapMarkDataTableMasterQuest;
|
||||
} else {
|
||||
gLoadedPauseMarkDataTable = gPauseMapMarkDataTable;
|
||||
}
|
||||
}
|
||||
|
||||
void PauseMapMark_Clear(PlayState* play) {
|
||||
|
@ -54,138 +64,102 @@ void PauseMapMark_DrawForDungeon(PlayState* play) {
|
|||
PauseMapMarkInfo* markInfo;
|
||||
f32 scale;
|
||||
s32 i = 0;
|
||||
SceneDBEntry* entry = SceneDB_Retrieve(gSaveContext.mapIndex);
|
||||
SceneDBFloor* floor = &entry->dungeonData.floors[play->pauseCtx.dungeonMapSlot - 3];
|
||||
|
||||
mapMarkData = &gLoadedPauseMarkDataTable[R_MAP_TEX_INDEX >> 1][i];
|
||||
if (SceneDB_IsBoss(play->sceneNum)) {
|
||||
if (gBossMarkState == 0) {
|
||||
Math_ApproachF(&gBossMarkScale, 1.5f, 1.0f, 0.041f);
|
||||
if (gBossMarkScale == 1.5f) {
|
||||
gBossMarkState = 1;
|
||||
}
|
||||
} else {
|
||||
Math_ApproachF(&gBossMarkScale, 1.0f, 1.0f, 0.041f);
|
||||
if (gBossMarkScale == 1.0f) {
|
||||
gBossMarkState = 0;
|
||||
}
|
||||
}
|
||||
scale = gBossMarkScale;
|
||||
} else {
|
||||
scale = 1.0f;
|
||||
}
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
while (true) {
|
||||
if (mapMarkData->markType == PAUSE_MAP_MARK_NONE) {
|
||||
break;
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
|
||||
|
||||
Matrix_Push();
|
||||
|
||||
if ((play->pauseCtx.state == 4) || (play->pauseCtx.state >= 0x12)) {
|
||||
Matrix_Translate(-36.0f, 101.0f, 0.0f, MTXMODE_APPLY);
|
||||
} else {
|
||||
Matrix_Translate(-36.0f, 21.0f, 0.0f, MTXMODE_APPLY);
|
||||
}
|
||||
|
||||
markInfo = &sMapMarkInfoTable[MAP_MARK_CHEST];
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, markInfo->texture, markInfo->imageFormat, G_IM_SIZ_MARK,
|
||||
markInfo->textureWidth, markInfo->textureHeight, 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);
|
||||
for (s32 i = 0; i < floor->numChestMarks; i++) {
|
||||
s32 display;
|
||||
|
||||
if (Flags_GetTreasure(play, floor->chestMarks[i].chestFlag)) {
|
||||
display = false;
|
||||
} else {
|
||||
display = SceneDB_IsDungeon(play->sceneNum);
|
||||
}
|
||||
|
||||
if ((mapMarkData->markType == PAUSE_MAP_MARK_BOSS) && (play->sceneNum >= SCENE_DEKU_TREE_BOSS) &&
|
||||
(play->sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR)) {
|
||||
if (gBossMarkState == 0) {
|
||||
Math_ApproachF(&gBossMarkScale, 1.5f, 1.0f, 0.041f);
|
||||
if (gBossMarkScale == 1.5f) {
|
||||
gBossMarkState = 1;
|
||||
}
|
||||
} else {
|
||||
Math_ApproachF(&gBossMarkScale, 1.0f, 1.0f, 0.041f);
|
||||
if (gBossMarkScale == 1.0f) {
|
||||
gBossMarkState = 0;
|
||||
}
|
||||
}
|
||||
scale = gBossMarkScale;
|
||||
} else {
|
||||
scale = 1.0f;
|
||||
if (display) {
|
||||
// Compute the offset to mirror icons over the map center (48) as an axis line
|
||||
s16 mirrorOffset =
|
||||
CVarGetInteger("gMirroredWorld", 0) ? mirrorOffset = (48 - floor->chestMarks[i].x) * 2 + 1 : 0;
|
||||
|
||||
Matrix_Push();
|
||||
Matrix_Translate(GREG(92) + floor->chestMarks[i].x + mirrorOffset, GREG(93) + floor->chestMarks[i].y, 0.0f,
|
||||
MTXMODE_APPLY);
|
||||
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
Matrix_Pop();
|
||||
|
||||
gSPVertex(POLY_OPA_DISP++, sMarkChestVtx, 4, 0);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 1, 3, 2, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
markInfo = &sMapMarkInfoTable[MAP_MARK_BOSS];
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, markInfo->texture, markInfo->imageFormat, G_IM_SIZ_MARK,
|
||||
markInfo->textureWidth, markInfo->textureHeight, 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);
|
||||
for (s32 i = 0; i < floor->numBossMarks; i++) {
|
||||
// Compute the offset to mirror icons over the map center (48) as an axis line
|
||||
s16 mirrorOffset = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)
|
||||
? mirrorOffset = (48 - floor->bossMarks[i].x) * 2 + 1
|
||||
: 0;
|
||||
|
||||
Matrix_Push();
|
||||
|
||||
if ((play->pauseCtx.state == 4) || (play->pauseCtx.state >= 0x12)) {
|
||||
Matrix_Translate(-36.0f, 101.0f, 0.0f, MTXMODE_APPLY);
|
||||
} else {
|
||||
Matrix_Translate(-36.0f, 21.0f, 0.0f, MTXMODE_APPLY);
|
||||
}
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
|
||||
|
||||
markPoint = &mapMarkData->points[0];
|
||||
for (i = 0; i < mapMarkData->count; i++) {
|
||||
s32 display;
|
||||
|
||||
if (mapMarkData->markType == PAUSE_MAP_MARK_CHEST) {
|
||||
if (Flags_GetTreasure(play, markPoint->chestFlag)) {
|
||||
display = false;
|
||||
} else {
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
display = false;
|
||||
break;
|
||||
default:
|
||||
display = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
display = true;
|
||||
}
|
||||
|
||||
if (display) {
|
||||
markInfo = &sMapMarkInfoTable[mapMarkData->markType];
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, markInfo->texture, markInfo->imageFormat, G_IM_SIZ_MARK,
|
||||
markInfo->textureWidth, markInfo->textureHeight, 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);
|
||||
|
||||
// Compute the offset to mirror icons over the map center (48) as an axis line
|
||||
s16 mirrorOffset = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)
|
||||
? mirrorOffset = (48 - markPoint->x) * 2 + 1
|
||||
: 0;
|
||||
|
||||
Matrix_Push();
|
||||
Matrix_Translate(GREG(92) + markPoint->x + mirrorOffset, GREG(93) + markPoint->y, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
Matrix_Pop();
|
||||
|
||||
gSPVertex(POLY_OPA_DISP++, mapMarkData->vtx, mapMarkData->vtxCount, 0);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 1, 3, 2, 0, 0);
|
||||
}
|
||||
|
||||
markPoint++;
|
||||
}
|
||||
|
||||
mapMarkData++;
|
||||
Matrix_Translate(GREG(92) + floor->bossMarks[i].x + mirrorOffset, GREG(93) + floor->bossMarks[i].y, 0.0f,
|
||||
MTXMODE_APPLY);
|
||||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
Matrix_Pop();
|
||||
|
||||
gSPVertex(POLY_OPA_DISP++, sMarkBossVtx, 4, 0);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 1, 3, 2, 0, 0);
|
||||
}
|
||||
|
||||
Matrix_Pop();
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
void PauseMapMark_Draw(PlayState* play) {
|
||||
PauseMapMark_Init(play);
|
||||
|
||||
switch (play->sceneNum) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_ICE_CAVERN:
|
||||
PauseMapMark_DrawForDungeon(play);
|
||||
break;
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
case SCENE_GANONDORF_BOSS:
|
||||
case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR:
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("PulsateBossIcon"), 0) != 0) {
|
||||
PauseMapMark_DrawForDungeon(play);
|
||||
}
|
||||
break;
|
||||
if (SceneDB_IsDungeon(play->sceneNum) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PulsateBossIcon"), 0) != 0 && SceneDB_IsBoss(play->sceneNum))) {
|
||||
PauseMapMark_DrawForDungeon(play);
|
||||
}
|
||||
|
||||
PauseMapMark_Clear(play);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue