Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround for location tracker ending too early #624

Merged
merged 1 commit into from
Jan 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def are_existing_symbols_valid(hppFilePath, newSymbolsInfo):
sections = ((sec[0], int(sec[2],16), int(sec[4],16), int(sec[1],16)) for sec in sectionsInfo if int(sec[2],16) != 0)

# Put here the symbols from the patch which are needed by the app
desiredSymbols = ("rItemOverrides", "gSettingsContext", "gSpoilerData", "rScrubRandomItemPrices", "rDungeonRewardOverrides", "rCustomMessages",
desiredSymbols = ("rItemOverrides", "gSettingsContext", "gSpoilerData", "gSpoilerDataLocs", "rScrubRandomItemPrices", "rDungeonRewardOverrides", "rCustomMessages",
"numCustomMessageEntries", "ptrCustomMessageEntries", "rShopsanityPrices", "rEntranceOverrides", "rBGMOverrides", "rSfxData", "rDungeonInfoData")

nmResult = subprocess.run([os.environ["DEVKITARM"] + r'/bin/arm-none-eabi-nm', elf], stdout=subprocess.PIPE)
Expand Down
21 changes: 13 additions & 8 deletions code/src/gfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static s8 spoilerGroupDungeonIds[] = {
DUNGEON_SPIRIT_TEMPLE,
-1,
-1,
DUNGEON_GANONS_TOWER,
DUNGEON_INSIDE_GANONS_CASTLE,
};

static char* spoilerCollectionGroupNames[] = {
Expand Down Expand Up @@ -468,7 +468,12 @@ static void Gfx_DrawDungeonItems(void) {
Draw_DrawFormattedString(208, yPos, keysHave > 0 ? COLOR_WHITE : COLOR_DARK_GRAY, "%d", keysHave);
Draw_DrawString(214, yPos, COLOR_WHITE, "/");

u8 keysFound = Dungeon_FoundSmallKeys(dungeonId);
u8 keysFound = Dungeon_FoundSmallKeys(dungeonId);
if (gSettingsContext.keysanity == KEYSANITY_START_WITH &&
(dungeonId <= DUNGEON_BOTTOM_OF_THE_WELL || dungeonId == DUNGEON_GERUDO_TRAINING_GROUNDS ||
dungeonId == DUNGEON_INSIDE_GANONS_CASTLE)) {
keysFound += Dungeon_KeyAmount(dungeonId);
}
u32 keysFoundColor = COLOR_WHITE;
if (keysFound >= Dungeon_KeyAmount(dungeonId) &&
(dungeonId == DUNGEON_THIEVES_HIDEOUT || dungeonId == DUNGEON_TREASURE_CHEST_SHOP ||
Expand Down Expand Up @@ -546,9 +551,9 @@ static void Gfx_DrawSpoilerData(void) {
u32 color = COLOR_WHITE;
if (SpoilerData_GetIsItemLocationCollected(itemIndex)) {
color = COLOR_GREEN;
} else if (gSpoilerData.ItemLocations[itemIndex].CollectType == COLLECTTYPE_REPEATABLE) {
} else if (SpoilerData_ItemLoc(itemIndex)->CollectType == COLLECTTYPE_REPEATABLE) {
color = COLOR_BLUE;
} else if (gSpoilerData.ItemLocations[itemIndex].CollectType == COLLECTTYPE_NEVER) {
} else if (SpoilerData_ItemLoc(itemIndex)->CollectType == COLLECTTYPE_NEVER) {
color = COLOR_ORANGE;
}
Draw_DrawString_Small(10, locPosY, color, SpoilerData_GetItemLocationString(itemIndex));
Expand Down Expand Up @@ -603,8 +608,8 @@ static void Gfx_DrawItemTracker(void) {
u32 locIndex = i + startIndex;
if (SpoilerData_GetIsItemLocationCollected(locIndex)) {
completeItems++;
} else if (gSpoilerData.ItemLocations[locIndex].CollectType == COLLECTTYPE_NEVER ||
(gSpoilerData.ItemLocations[locIndex].CollectType == COLLECTTYPE_REPEATABLE &&
} else if (SpoilerData_ItemLoc(locIndex)->CollectType == COLLECTTYPE_NEVER ||
(SpoilerData_ItemLoc(locIndex)->CollectType == COLLECTTYPE_REPEATABLE &&
SpoilerData_GetIsItemLocationRevealed(locIndex))) {
uncollectableItems++;
}
Expand Down Expand Up @@ -650,10 +655,10 @@ static void Gfx_DrawItemTracker(void) {
if (isCollected) {
color = COLOR_GREEN;
} else if (canShowGroup) {
if (gSpoilerData.ItemLocations[locIndex].CollectType == COLLECTTYPE_REPEATABLE &&
if (SpoilerData_ItemLoc(locIndex)->CollectType == COLLECTTYPE_REPEATABLE &&
SpoilerData_GetIsItemLocationRevealed(locIndex)) {
color = COLOR_BLUE;
} else if (gSpoilerData.ItemLocations[locIndex].CollectType == COLLECTTYPE_NEVER) {
} else if (SpoilerData_ItemLoc(locIndex)->CollectType == COLLECTTYPE_NEVER) {
color = COLOR_ORANGE;
}
}
Expand Down
76 changes: 40 additions & 36 deletions code/src/spoiler_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,38 @@
#include "savefile.h"
#include "entrance.h"

SpoilerData gSpoilerData = { 0 };
SpoilerData gSpoilerData = { 0 };
SpoilerDataLocs gSpoilerDataLocs[SPOILER_LOCDATS] = { 0 };

char* SpoilerData_GetItemLocationString(u16 itemIndex) {
return &gSpoilerData.StringData[gSpoilerData.ItemLocations[itemIndex].LocationStrOffset];
SpoilerItemLocation* SpoilerData_ItemLoc(u16 itemIndex) {
return &gSpoilerDataLocs[itemIndex / SPOILER_ITEMS_MAX].ItemLocations[itemIndex % SPOILER_ITEMS_MAX];
}

char* SpoilerData_GetItemNameString(u16 itemIndex) {
return &gSpoilerData.StringData[gSpoilerData.ItemLocations[itemIndex].ItemStrOffset];
char* SpoilerData_StringData(u16 itemIndex) {
return gSpoilerDataLocs[itemIndex / SPOILER_ITEMS_MAX].StringData;
}

char* SpoilerData_GetItemLocationString(u16 itemIndex) {
return &SpoilerData_StringData(itemIndex)[SpoilerData_ItemLoc(itemIndex)->LocationStrOffset];
}

SpoilerItemLocation GetSpoilerItemLocation(u8 sphere, u16 itemIndex) {
return gSpoilerData
.ItemLocations[gSpoilerData.SphereItemLocations[gSpoilerData.Spheres[sphere].ItemLocationsOffset]];
char* SpoilerData_GetItemNameString(u16 itemIndex) {
return &SpoilerData_StringData(itemIndex)[SpoilerData_ItemLoc(itemIndex)->ItemStrOffset];
}

u8 SpoilerData_ChestCheck(SpoilerItemLocation itemLoc) {
if (gGlobalContext->sceneNum == itemLoc.LocationScene) {
return (gGlobalContext->actorCtx.flags.chest & (1 << itemLoc.LocationFlag)) != 0;
u8 SpoilerData_ChestCheck(SpoilerItemLocation* itemLoc) {
if (gGlobalContext->sceneNum == itemLoc->LocationScene) {
return (gGlobalContext->actorCtx.flags.chest & (1 << itemLoc->LocationFlag)) != 0;
} else {
return (gSaveContext.sceneFlags[itemLoc.LocationScene].chest & (1 << itemLoc.LocationFlag)) != 0;
return (gSaveContext.sceneFlags[itemLoc->LocationScene].chest & (1 << itemLoc->LocationFlag)) != 0;
}
}

u8 SpoilerData_CollectableCheck(SpoilerItemLocation itemLoc) {
if (gGlobalContext->sceneNum == itemLoc.LocationScene) {
return (gGlobalContext->actorCtx.flags.collect & (1 << itemLoc.LocationFlag)) != 0;
u8 SpoilerData_CollectableCheck(SpoilerItemLocation* itemLoc) {
if (gGlobalContext->sceneNum == itemLoc->LocationScene) {
return (gGlobalContext->actorCtx.flags.collect & (1 << itemLoc->LocationFlag)) != 0;
} else {
return (gSaveContext.sceneFlags[itemLoc.LocationScene].collect & (1 << itemLoc.LocationFlag)) != 0;
return (gSaveContext.sceneFlags[itemLoc->LocationScene].collect & (1 << itemLoc->LocationFlag)) != 0;
}
}

Expand All @@ -58,20 +62,20 @@ u8 SpoilerData_UpgradeCheck(u8 bit) {
return (gSaveContext.upgrades & (1 << bit)) != 0;
}

u8 SpoilerData_CowCheck(SpoilerItemLocation itemLoc) {
if (gGlobalContext->sceneNum == itemLoc.LocationScene) {
return (gGlobalContext->actorCtx.flags.collect & (itemLoc.LocationFlag << 0x18)) != 0;
u8 SpoilerData_CowCheck(SpoilerItemLocation* itemLoc) {
if (gGlobalContext->sceneNum == itemLoc->LocationScene) {
return (gGlobalContext->actorCtx.flags.collect & (itemLoc->LocationFlag << 0x18)) != 0;
} else {
return (gSaveContext.sceneFlags[itemLoc.LocationScene].collect & (itemLoc.LocationFlag << 0x18)) != 0;
return (gSaveContext.sceneFlags[itemLoc->LocationScene].collect & (itemLoc->LocationFlag << 0x18)) != 0;
}
}

u8 SpoilerData_FishingCheck(SpoilerItemLocation itemLoc) {
return (gSaveContext.fishingStats.flags & (1 << itemLoc.LocationFlag)) != 0;
u8 SpoilerData_FishingCheck(SpoilerItemLocation* itemLoc) {
return (gSaveContext.fishingStats.flags & (1 << itemLoc->LocationFlag)) != 0;
}

u8 SpoilerData_ScrubCheck(SpoilerItemLocation itemLoc) {
return (gSaveContext.sceneFlags[itemLoc.LocationScene].unk & (1 << itemLoc.LocationFlag)) != 0;
u8 SpoilerData_ScrubCheck(SpoilerItemLocation* itemLoc) {
return (gSaveContext.sceneFlags[itemLoc->LocationScene].unk & (1 << itemLoc->LocationFlag)) != 0;
}

u8 SpoilerData_BiggoronCheck(u8 mask) {
Expand All @@ -92,12 +96,12 @@ u8 SpoilerData_BigPoePointsCheck() {
return gSaveContext.bigPoePoints >= (gSettingsContext.bigPoeTargetCount * 100);
}

u8 SpoilerData_ShopItemCheck(SpoilerItemLocation itemLoc) {
u32 itemBit = 1 << itemLoc.LocationFlag;
return (gSaveContext.sceneFlags[itemLoc.LocationScene].unk & itemBit) != 0;
u8 SpoilerData_ShopItemCheck(SpoilerItemLocation* itemLoc) {
u32 itemBit = 1 << itemLoc->LocationFlag;
return (gSaveContext.sceneFlags[itemLoc->LocationScene].unk & itemBit) != 0;
}

u8 SpoilerData_MagicBeansCheck(SpoilerItemLocation itemLoc) {
u8 SpoilerData_MagicBeansCheck(SpoilerItemLocation* itemLoc) {
if (gSettingsContext.shuffleMagicBeans) {
return SpoilerData_CollectableCheck(itemLoc);
} else {
Expand All @@ -114,8 +118,8 @@ u8 SpoilerData_GetIsItemLocationCollected(u16 itemIndex) {
return 0;
}

SpoilerItemLocation itemLoc = gSpoilerData.ItemLocations[itemIndex];
switch (itemLoc.CollectionCheckType) {
SpoilerItemLocation* itemLoc = SpoilerData_ItemLoc(itemIndex);
switch (itemLoc->CollectionCheckType) {
case SPOILER_CHK_NONE: { // Not ever 'collectable' (Ganon, or any item that didn't have a type set)
return 0;
}
Expand All @@ -129,16 +133,16 @@ u8 SpoilerData_GetIsItemLocationCollected(u16 itemIndex) {
return SpoilerData_CollectableCheck(itemLoc);
}
case SPOILER_CHK_GOLD_SKULLTULA: { // Gold skulltula
return gSaveContext.gsFlags[itemLoc.LocationScene] & itemLoc.LocationFlag;
return gSaveContext.gsFlags[itemLoc->LocationScene] & itemLoc->LocationFlag;
}
case SPOILER_CHK_ITEM_GET_INF: { // Check a flag set in item_get_inf
return SpoilerData_ItemGetInfCheck(itemLoc.LocationFlag);
return SpoilerData_ItemGetInfCheck(itemLoc->LocationFlag);
}
case SPOILER_CHK_EVENT_CHK_INF: { // Check a flag set in event_check_inf
return EventCheck(itemLoc.LocationFlag) != 0;
return EventCheck(itemLoc->LocationFlag) != 0;
}
case SPOILER_CHK_INF_TABLE: { // Check a flag set in event_check_inf
return SpoilerData_InfTableCheck(itemLoc.LocationScene, itemLoc.LocationFlag);
return SpoilerData_InfTableCheck(itemLoc->LocationScene, itemLoc->LocationFlag);
}
case SPOILER_CHK_COW: {
return SpoilerData_CowCheck(itemLoc);
Expand All @@ -150,7 +154,7 @@ u8 SpoilerData_GetIsItemLocationCollected(u16 itemIndex) {
return SpoilerData_ScrubCheck(itemLoc);
}
case SPOILER_CHK_BIGGORON: {
return SpoilerData_BiggoronCheck(itemLoc.LocationFlag);
return SpoilerData_BiggoronCheck(itemLoc->LocationFlag);
}
case SPOILER_CHK_GERUDO_TOKEN: {
return SpoilerData_GerudoTokenCheck();
Expand Down Expand Up @@ -179,7 +183,7 @@ u8 SpoilerData_GetIsItemLocationRevealed(u16 itemIndex) {
return 1;
}

SpoilerItemLocation* itemLoc = &gSpoilerData.ItemLocations[itemIndex];
SpoilerItemLocation* itemLoc = SpoilerData_ItemLoc(itemIndex);

if (itemLoc->RevealType == REVEALTYPE_ALWAYS) {
return 1;
Expand Down
28 changes: 17 additions & 11 deletions code/src/spoiler_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

#include "../include/z3D/z3D.h"

#define SPOILER_LOCDATS 2
#define SPOILER_SPHERES_MAX 50
#define SPOILER_ITEMS_MAX 512
#define SPOILER_ITEMS_MAX 450
#define SPOILER_STRING_DATA_SIZE 16384

typedef enum {
Expand Down Expand Up @@ -96,32 +97,37 @@ typedef struct {
u8 SphereCount;
u16 ItemLocationsCount;
SpoilerSphere Spheres[SPOILER_SPHERES_MAX];
SpoilerItemLocation ItemLocations[SPOILER_ITEMS_MAX];
u16 SphereItemLocations[SPOILER_ITEMS_MAX];
char StringData[SPOILER_STRING_DATA_SIZE];
u16 GroupItemCounts[SPOILER_COLLECTION_GROUP_COUNT];
u16 GroupOffsets[SPOILER_COLLECTION_GROUP_COUNT];
} SpoilerData;

typedef struct {
SpoilerItemLocation ItemLocations[SPOILER_ITEMS_MAX];
char StringData[SPOILER_STRING_DATA_SIZE];
} SpoilerDataLocs;

extern SpoilerData gSpoilerData;

SpoilerItemLocation* SpoilerData_ItemLoc(u16 itemIndex);
char* SpoilerData_StringData(u16 itemIndex);

char* SpoilerData_GetItemLocationString(u16 itemIndex);
char* SpoilerData_GetItemNameString(u16 itemIndex);
SpoilerItemLocation GetSpoilerItemLocation(u8 sphere, u16 itemIndex);
u8 SpoilerData_GetIsItemLocationCollected(u16 itemIndex);
u8 SpoilerData_ChestCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_CollectableCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_ChestCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_CollectableCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_ItemGetInfCheck(u8 slot);
u8 SpoilerData_InfTableCheck(u8 offset, u8 bit);
u8 SpoilerData_UpgradeCheck(u8 bit);
u8 SpoilerData_CowCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_FishingCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_ScrubCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_CowCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_FishingCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_ScrubCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_BiggoronCheck(u8 mask);
u8 SpoilerData_GerudoTokenCheck();
u8 SpoilerData_BigPoePointsCheck();
u8 SpoilerData_ShopItemCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_MagicBeansCheck(SpoilerItemLocation itemLoc);
u8 SpoilerData_ShopItemCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_MagicBeansCheck(SpoilerItemLocation* itemLoc);
u8 SpoilerData_GetIsItemLocationRevealed(u16 itemIndex);

#endif // _SPOILER_DATA_H_
49 changes: 34 additions & 15 deletions source/patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,34 @@
#include <string>
#include <vector>

const PatchSymbols UsaSymbols = { GSETTINGSCONTEXT_USA_ADDR, GSPOILERDATA_USA_ADDR,
NUMCUSTOMMESSAGEENTRIES_USA_ADDR, PTRCUSTOMMESSAGEENTRIES_USA_ADDR,
RBGMOVERRIDES_USA_ADDR, RCUSTOMMESSAGES_USA_ADDR,
RDUNGEONINFODATA_USA_ADDR, RDUNGEONREWARDOVERRIDES_USA_ADDR,
RENTRANCEOVERRIDES_USA_ADDR, RITEMOVERRIDES_USA_ADDR,
RSCRUBRANDOMITEMPRICES_USA_ADDR, RSFXDATA_USA_ADDR,
const PatchSymbols UsaSymbols = { GSETTINGSCONTEXT_USA_ADDR,
GSPOILERDATA_USA_ADDR,
GSPOILERDATALOCS_USA_ADDR,
NUMCUSTOMMESSAGEENTRIES_USA_ADDR,
PTRCUSTOMMESSAGEENTRIES_USA_ADDR,
RBGMOVERRIDES_USA_ADDR,
RCUSTOMMESSAGES_USA_ADDR,
RDUNGEONINFODATA_USA_ADDR,
RDUNGEONREWARDOVERRIDES_USA_ADDR,
RENTRANCEOVERRIDES_USA_ADDR,
RITEMOVERRIDES_USA_ADDR,
RSCRUBRANDOMITEMPRICES_USA_ADDR,
RSFXDATA_USA_ADDR,
RSHOPSANITYPRICES_USA_ADDR };

const PatchSymbols EurSymbols = { GSETTINGSCONTEXT_EUR_ADDR, GSPOILERDATA_EUR_ADDR,
NUMCUSTOMMESSAGEENTRIES_EUR_ADDR, PTRCUSTOMMESSAGEENTRIES_EUR_ADDR,
RBGMOVERRIDES_EUR_ADDR, RCUSTOMMESSAGES_EUR_ADDR,
RDUNGEONINFODATA_EUR_ADDR, RDUNGEONREWARDOVERRIDES_EUR_ADDR,
RENTRANCEOVERRIDES_EUR_ADDR, RITEMOVERRIDES_EUR_ADDR,
RSCRUBRANDOMITEMPRICES_EUR_ADDR, RSFXDATA_EUR_ADDR,
const PatchSymbols EurSymbols = { GSETTINGSCONTEXT_EUR_ADDR,
GSPOILERDATA_EUR_ADDR,
GSPOILERDATALOCS_EUR_ADDR,
NUMCUSTOMMESSAGEENTRIES_EUR_ADDR,
PTRCUSTOMMESSAGEENTRIES_EUR_ADDR,
RBGMOVERRIDES_EUR_ADDR,
RCUSTOMMESSAGES_EUR_ADDR,
RDUNGEONINFODATA_EUR_ADDR,
RDUNGEONREWARDOVERRIDES_EUR_ADDR,
RENTRANCEOVERRIDES_EUR_ADDR,
RITEMOVERRIDES_EUR_ADDR,
RSCRUBRANDOMITEMPRICES_EUR_ADDR,
RSFXDATA_EUR_ADDR,
RSHOPSANITYPRICES_EUR_ADDR };

// For specification on the IPS file format, visit: https://zerosoft.zophar.net/ips.php
Expand Down Expand Up @@ -247,11 +261,16 @@ bool WriteAllPatches() {

patchOffset = V_TO_P(patchSymbols.GSPOILERDATA_ADDR);
patchSize = sizeof(SpoilerData);
// Get the spoiler data
SpoilerData spoilerData = GetSpoilerData();
if (!WritePatch(patchOffset, patchSize, (char*)(&spoilerData), code, bytesWritten, totalRW, buf)) {
if (!WritePatch(patchOffset, patchSize, (char*)(GetSpoilerData()), code, bytesWritten, totalRW, buf)) {
return false;
}
patchSize = sizeof(SpoilerDataLocs);
for (size_t idx = 0; idx < SPOILER_LOCDATS; idx++) {
patchOffset = V_TO_P(patchSymbols.GSPOILERDATALOCS_ADDR) + (patchSize * idx);
if (!WritePatch(patchOffset, patchSize, (char*)(GetSpoilerDataLocs(idx)), code, bytesWritten, totalRW, buf)) {
return false;
}
}

/*-------------------------------
| rScrubRandomItemPrices |
Expand Down
1 change: 1 addition & 0 deletions source/patch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
typedef struct {
u32 GSETTINGSCONTEXT_ADDR;
u32 GSPOILERDATA_ADDR;
u32 GSPOILERDATALOCS_ADDR;
u32 NUMCUSTOMMESSAGEENTRIES_ADDR;
u32 PTRCUSTOMMESSAGEENTRIES_ADDR;
u32 RBGMOVERRIDES_ADDR;
Expand Down
Loading