Skip to content

Commit

Permalink
3DS: Add ROM pre-load settings for *The Legend of Zelda: Phantom Hour…
Browse files Browse the repository at this point in the history
…glass*
  • Loading branch information
RocketRobz committed Jan 5, 2025
1 parent 6358393 commit 3ab3617
Show file tree
Hide file tree
Showing 24 changed files with 142 additions and 65 deletions.
4 changes: 2 additions & 2 deletions retail/arm9/include/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ typedef struct configuration {
u32 apPatchSize;
u32 cheatSize;
u32 musicsSize;
u32 dataToPreloadAddr[3];
u32 dataToPreloadSize[3];
u32 dataToPreloadAddr[4];
u32 dataToPreloadSize[4];
// u32 dataToPreloadFrame;
u8 language;
char* guiLanguage;
Expand Down
131 changes: 86 additions & 45 deletions retail/arm9/source/conf_sd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,33 @@ void addTwlDevice(const char letter, u8 flags, u8 accessRights, const char* name
}
}

static const char* getLangString(const int language) {
switch (language) {
case 0:
return "ja";
case 1:
default:
return "en";
case 2:
return "fr";
case 3:
return "de";
case 4:
return "it";
case 5:
return "es";
case 6:
return "zh";
case 7:
return "ko";
}
return "en";
}

extern std::string ReplaceAll(std::string str, const std::string& from, const std::string& to);
extern bool extension(const std::string& filename, const char* ext);

static void loadPreLoadSettings(configuration* conf, const char* pckPath, const char* romTid, const u16 headerCRC) {
static bool loadPreLoadSettings(configuration* conf, const char* pckPath, const char* romTid, const u16 headerCRC) {
FILE *file = NULL;

// Pre-load sound data for mainline Gen 4 Pokemon games
Expand All @@ -149,69 +172,75 @@ static void loadPreLoadSettings(configuration* conf, const char* pckPath, const
conf->dataToPreloadSize[0] = getFileSize(file);
// conf->dataToPreloadFrame = 0;
fclose(file);
return;
return true;
}

file = fopen(pckPath, "rb");
if (!file) {
return;
return false;
}

char buf[5] = {0};
fread(buf, 1, 4, file);
if (strcmp(buf, ".PCK") == 0) {

u32 fileCount;
fread(&fileCount, 1, sizeof(fileCount), file);
if (strcmp(buf, ".PCK") != 0) {
return false;
}

u32 offset = 0, size = 0;
u32 fileCount;
fread(&fileCount, 1, sizeof(fileCount), file);

// Try binary search for the game
int left = 0;
int right = fileCount;
u32 offset = 0, size = 0;

while (left <= right) {
int mid = left + ((right - left) / 2);
fseek(file, 16 + mid * 16, SEEK_SET);
fread(buf, 1, 4, file);
int cmp = strcmp(buf, romTid);
if (cmp == 0) { // TID matches, check CRC
u16 crc;
fread(&crc, 1, sizeof(crc), file);
// Try binary search for the game
int left = 0;
int right = fileCount;

if (crc == headerCRC) { // CRC matches
fread(&offset, 1, sizeof(offset), file);
fread(&size, 1, sizeof(size), file);
break;
} else if (crc < headerCRC) {
left = mid + 1;
} else {
right = mid - 1;
}
} else if (cmp < 0) {
while (left <= right) {
int mid = left + ((right - left) / 2);
fseek(file, 16 + mid * 16, SEEK_SET);
fread(buf, 1, 4, file);
int cmp = strcmp(buf, romTid);
if (cmp == 0) { // TID matches, check CRC
u16 crc;
fread(&crc, 1, sizeof(crc), file);

if (crc == headerCRC) { // CRC matches
fread(&offset, 1, sizeof(offset), file);
fread(&size, 1, sizeof(size), file);
break;
} else if (crc < headerCRC) {
left = mid + 1;
} else {
right = mid - 1;
}
} else if (cmp < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}

if (offset > 0) {
if (size > 0x18) {
size = 0x18;
}
fseek(file, offset, SEEK_SET);
u32 *buffer = new u32[size/4];
fread(buffer, 1, size, file);
if (offset > 0) {
if (size > 0x20) {
size = 0x20;
}
fseek(file, offset, SEEK_SET);
u32 *buffer = new u32[size/4];
fread(buffer, 1, size, file);

for (u32 i = 0; i < size/8; i++) {
conf->dataToPreloadAddr[i] = buffer[0+(i*2)];
conf->dataToPreloadSize[i] = buffer[1+(i*2)];
}
// conf->dataToPreloadFrame = (size == 0xC) ? buffer[2] : 0;
delete[] buffer;
for (u32 i = 0; i < size/8; i++) {
conf->dataToPreloadAddr[i] = buffer[0+(i*2)];
conf->dataToPreloadSize[i] = buffer[1+(i*2)];
}
// conf->dataToPreloadFrame = (size == 0xC) ? buffer[2] : 0;
delete[] buffer;
} else {
fclose(file);
return false;
}

fclose(file);
return true;
}

static void loadApFix(configuration* conf, const char* bootstrapPath, const char* romTid, const u16 headerCRC) {
Expand Down Expand Up @@ -1127,7 +1156,7 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
}
} else {
// Determine region by language
int language = (conf->language >= 0 && conf->language <= 7) ? conf->language : PersonalData->language;
const int language = (conf->language >= 0 && conf->language <= 7) ? conf->language : PersonalData->language;
if (language == 0) {
newRegion = 0; // Japan
} else if (language == 6) {
Expand Down Expand Up @@ -1589,8 +1618,20 @@ int loadFromSD(configuration* conf, const char *bootstrapPath) {
}
fclose(cebin);

loadPreLoadSettings(conf, conf->consoleModel > 0 ? "nitro:/preLoadSettings3DS.pck" : "nitro:/preLoadSettingsDSi.pck", romTid, headerCRC);
if (conf->dataToPreloadAddr[0] == 0) {
const int language = (conf->language >= 0 && conf->language <= 7) ? conf->language : PersonalData->language;
char path[256];
sprintf(path, "nitro:/preLoadSettings%s-%s.pck", conf->consoleModel > 0 ? "3DS" : "DSi", getLangString(language));

bool preLoadRes = loadPreLoadSettings(conf, path, romTid, headerCRC);
if (!preLoadRes && language != 1) {
sprintf(path, "nitro:/preLoadSettings%s-%s.pck", conf->consoleModel > 0 ? "3DS" : "DSi", getLangString(1));
preLoadRes = loadPreLoadSettings(conf, path, romTid, headerCRC);
}
if (!preLoadRes) {
sprintf(path, "nitro:/preLoadSettings%s.pck", conf->consoleModel > 0 ? "3DS" : "DSi");
preLoadRes = loadPreLoadSettings(conf, path, romTid, headerCRC);
}
if (!preLoadRes) {
// Set NitroFS pre-load, in case if full ROM pre-load fails
conf->dataToPreloadAddr[0] = ndsArm7BinOffset+ndsArm7Size;
conf->dataToPreloadSize[0] = ((internalRomSize == 0 || internalRomSize > conf->romSize) ? conf->romSize : internalRomSize)-conf->dataToPreloadAddr[0];
Expand Down
2 changes: 1 addition & 1 deletion retail/arm9/source/nds_loader_arm9.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ int runNds(u32 cluster, u32 saveCluster, u32 donorTwlCluster, /* u32 gbaCluster,
loader->saveSize = conf->saveSize;
// loader->gbaRomSize = conf->gbaRomSize;
// loader->gbaSaveSize = conf->gbaSaveSize;
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 4; i++) {
loader->dataToPreloadAddr[i] = conf->dataToPreloadAddr[i];
loader->dataToPreloadSize[i] = conf->dataToPreloadSize[i];
}
Expand Down
2 changes: 2 additions & 0 deletions retail/bootloader/source/arm7/load_crt0.s
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ dataToPreloadAddr:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
dataToPreloadSize:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
@dataToPreloadFrame:
@ .word 0x00000000
wideCheatFileCluster:
Expand Down
6 changes: 3 additions & 3 deletions retail/bootloaderi/source/arm7/hook_arm9.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ int hookNdsRetailArm9(
extern u32 baseFatOff;
extern u32 baseFatSize;
extern u32 romPaddingSize;
extern u32 dataToPreloadAddr[3];
extern u32 dataToPreloadSize[3];
extern u32 dataToPreloadAddr[4];
extern u32 dataToPreloadSize[4];
// extern u32 dataToPreloadFrame;
extern bool romLocationAdjust(const tNDSHeader* ndsHeader, const bool laterSdk, const bool isSdk5, u32* romLocation);
extern u32 dataToPreloadFullSize(void);
Expand Down Expand Up @@ -343,7 +343,7 @@ int hookNdsRetailArm9(
romLocationAdjust(ndsHeader, laterSdk, (ce9->valueBits & b_isSdk5), &ce9->cacheAddress);
ce9->cacheSlots--;
}
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 4; i++) {
ce9->romPartSrc[i] = dataToPreloadAddr[i];
ce9->romPartSize[i] = dataToPreloadSize[i];
}
Expand Down
2 changes: 2 additions & 0 deletions retail/bootloaderi/source/arm7/load_crt0.s
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ dataToPreloadAddr:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
dataToPreloadSize:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
@dataToPreloadFrame:
@ .word 0x00000000
wideCheatFileCluster:
Expand Down
17 changes: 10 additions & 7 deletions retail/bootloaderi/source/arm7/main.arm7.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ extern u32 romSize;
extern u32 saveSize;
// extern u32 gbaRomSize;
// extern u32 gbaSaveSize;
extern u32 dataToPreloadAddr[3];
extern u32 dataToPreloadSize[3];
extern u32 dataToPreloadAddr[4];
extern u32 dataToPreloadSize[4];
// extern u32 dataToPreloadFrame;
extern u32 wideCheatFileCluster;
extern u32 wideCheatSize;
Expand Down Expand Up @@ -1019,15 +1019,15 @@ static void my_readUserSettings(tNDSHeader* ndsHeader) {
}

u32 dataToPreloadFullSize(void) {
u32 dataToPreloadSizeAlign[3] = {dataToPreloadSize[0], dataToPreloadSize[1], dataToPreloadSize[2]};
for (int i = 0; i < 3; i++) {
u32 dataToPreloadSizeAlign[4] = {dataToPreloadSize[0], dataToPreloadSize[1], dataToPreloadSize[2], dataToPreloadSize[3]};
for (int i = 0; i < 4; i++) {
if (!dataToPreloadSize[i]) break;
while ((dataToPreloadSizeAlign[i] % 0x4000) != 0) {
dataToPreloadSizeAlign[i]++;
}
}

return dataToPreloadSizeAlign[0] + dataToPreloadSizeAlign[1] + dataToPreloadSizeAlign[2];
return dataToPreloadSizeAlign[0] + dataToPreloadSizeAlign[1] + dataToPreloadSizeAlign[2] + dataToPreloadSizeAlign[3];
}

bool dataToPreloadFound(const tNDSHeader* ndsHeader) {
Expand Down Expand Up @@ -1174,8 +1174,8 @@ static void buildRomMap(const tNDSHeader* ndsHeader, const module_params_t* modu
// Load ROM into RAM
const u32 romLocation = ROMinRAM ? getRomLocation(ndsHeader, !laterSdk, isSdk5(moduleParams), dsiBios) : getRomPartLocation(ndsHeader, !laterSdk, isSdk5(moduleParams), dsiBios);

u32 romOffset[3] = {(ROMinRAM ? 0 : dataToPreloadAddr[0]), (ROMinRAM ? 0 : dataToPreloadAddr[1]), (ROMinRAM ? 0 : dataToPreloadAddr[2])};
s32 romSizeEdit[3] = {(ROMinRAM ? baseRomSize : dataToPreloadSize[0]), (ROMinRAM ? baseRomSize : dataToPreloadSize[1]), (ROMinRAM ? baseRomSize : dataToPreloadSize[2])};
u32 romOffset[4] = {(ROMinRAM ? 0 : dataToPreloadAddr[0]), (ROMinRAM ? 0 : dataToPreloadAddr[1]), (ROMinRAM ? 0 : dataToPreloadAddr[2]), (ROMinRAM ? 0 : dataToPreloadAddr[3])};
s32 romSizeEdit[4] = {(ROMinRAM ? baseRomSize : dataToPreloadSize[0]), (ROMinRAM ? baseRomSize : dataToPreloadSize[1]), (ROMinRAM ? baseRomSize : dataToPreloadSize[2]), (ROMinRAM ? baseRomSize : dataToPreloadSize[3])};
int iCount = 1;
if (ROMinRAM) {
if (usesCloneboot) {
Expand Down Expand Up @@ -1209,6 +1209,9 @@ static void buildRomMap(const tNDSHeader* ndsHeader, const module_params_t* modu
if (dataToPreloadSize[2]) {
iCount++;
}
if (dataToPreloadSize[3]) {
iCount++;
}
}

/* dbg_printf("romOffset[0]: ");
Expand Down
2 changes: 1 addition & 1 deletion retail/cardenginei/arm9/source/cardDma.thumb.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ void cardSetDma(u32 * params) {
//int romPartNo = 0;
if (!(ce9->valueBits & ROMinRAM)) {
#ifndef TWLSDK
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 4; i++) {
if (ce9->romPartSize[i] == 0) {
break;
}
Expand Down
2 changes: 2 additions & 0 deletions retail/cardenginei/arm9/source/card_engine_header.s
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ romPartSrc:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
romPartSize:
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
#ifndef TWLSDK
romMapLines:
.word 0x00000000
Expand Down
2 changes: 1 addition & 1 deletion retail/cardenginei/arm9/source/cardengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ void cardRead(u32* cacheStruct, u8* dst0, u32 src0, u32 len0) {
//int romPartNo = 0;
if (!(ce9->valueBits & ROMinRAM)) {
#ifndef TWLSDK
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 4; i++) {
if (ce9->romPartSize[i] == 0) {
break;
}
Expand Down
4 changes: 2 additions & 2 deletions retail/common/include/cardengine_header_arm9.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ typedef struct cardengineArm9 {
u32 cacheAddress;
u16 cacheSlots;
u16 cacheBlockSize;
u32 romPartSrc[3];
u32 romPartSize[3];
u32 romPartSrc[4];
u32 romPartSize[4];
u32 romMapLines;
u32 romMap[8][3]; // 0: ROM part start, 1: ROM part start in RAM, 2: ROM part end in RAM
} cardengineArm9;
Expand Down
4 changes: 2 additions & 2 deletions retail/common/include/load_crt0.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ typedef struct loadCrt0 {
u32 saveSize;
// u32 gbaRomSize;
// u32 gbaSaveSize;
u32 dataToPreloadAddr[3];
u32 dataToPreloadSize[3];
u32 dataToPreloadAddr[4];
u32 dataToPreloadSize[4];
// u32 dataToPreloadFrame;
u32 wideCheatFileCluster;
u32 wideCheatSize;
Expand Down
22 changes: 21 additions & 1 deletion retail/preLoadSettings/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ OUTPUT_DIR := ../nitrofiles
FILESMEP := files-mep
FILESDSI := files-dsi
FILES3DS := files-3ds
FILES3DSEN := files-3ds-en
FILES3DSFR := files-3ds-fr
FILES3DSDE := files-3ds-de
FILES3DSIT := files-3ds-it
FILES3DSES := files-3ds-es

#---------------------------------------------------------------------------------
# Goals for Build
#---------------------------------------------------------------------------------
.PHONY:

all: $(OUTPUT_DIR)/preLoadSettingsMEP.pck $(OUTPUT_DIR)/preLoadSettingsDSi.pck $(OUTPUT_DIR)/preLoadSettings3DS.pck
all: $(OUTPUT_DIR)/preLoadSettingsMEP.pck $(OUTPUT_DIR)/preLoadSettingsDSi.pck $(OUTPUT_DIR)/preLoadSettings3DS.pck $(OUTPUT_DIR)/preLoadSettings3DS-en.pck $(OUTPUT_DIR)/preLoadSettings3DS-fr.pck $(OUTPUT_DIR)/preLoadSettings3DS-de.pck $(OUTPUT_DIR)/preLoadSettings3DS-it.pck $(OUTPUT_DIR)/preLoadSettings3DS-es.pck

$(OUTPUT_DIR)/preLoadSettingsMEP.pck: $(FILESMEP)
$(PYTHON) pack.py $^ -o $@
Expand All @@ -32,3 +37,18 @@ $(OUTPUT_DIR)/preLoadSettingsDSi.pck: $(FILESDSI)

$(OUTPUT_DIR)/preLoadSettings3DS.pck: $(FILES3DS)
$(PYTHON) pack.py $^ -o $@

$(OUTPUT_DIR)/preLoadSettings3DS-en.pck: $(FILES3DSEN)
$(PYTHON) pack.py $^ -o $@

$(OUTPUT_DIR)/preLoadSettings3DS-fr.pck: $(FILES3DSFR)
$(PYTHON) pack.py $^ -o $@

$(OUTPUT_DIR)/preLoadSettings3DS-de.pck: $(FILES3DSDE)
$(PYTHON) pack.py $^ -o $@

$(OUTPUT_DIR)/preLoadSettings3DS-it.pck: $(FILES3DSDE)
$(PYTHON) pack.py $^ -o $@

$(OUTPUT_DIR)/preLoadSettings3DS-es.pck: $(FILES3DSES)
$(PYTHON) pack.py $^ -o $@
Loading

0 comments on commit 3ab3617

Please sign in to comment.