diff options
| author | Baoulettes <perlouzerie@hotmail.fr> | 2022-06-20 22:32:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-20 22:32:45 +0200 |
| commit | 14df96eacdc85f1c3742dca4ed80d67dc8a862e4 (patch) | |
| tree | 100d7103930cd0538ef5ad195e01db9c611c0cc4 /soh/src/code | |
| parent | ea0ea0366be367fa6c8015772728489a22ebfdde (diff) | |
| parent | 39d8b77b0254138913daac7b4bd39702bc558b85 (diff) | |
Merge branch 'develop' into 3DProjectiles
Diffstat (limited to 'soh/src/code')
| -rw-r--r-- | soh/src/code/audio_data.c | 6 | ||||
| -rw-r--r-- | soh/src/code/audio_heap.c | 8 | ||||
| -rw-r--r-- | soh/src/code/audio_init_params.c | 37 | ||||
| -rw-r--r-- | soh/src/code/audio_load.c | 470 | ||||
| -rw-r--r-- | soh/src/code/audio_playback.c | 70 | ||||
| -rw-r--r-- | soh/src/code/audio_seqplayer.c | 44 | ||||
| -rw-r--r-- | soh/src/code/audio_synthesis.c | 21 | ||||
| -rw-r--r-- | soh/src/code/code_800E4FE0.c | 4 | ||||
| -rw-r--r-- | soh/src/code/code_800F9280.c | 6 | ||||
| -rw-r--r-- | soh/src/code/shrink_window.c | 8 | ||||
| -rw-r--r-- | soh/src/code/z_actor.c | 20 | ||||
| -rw-r--r-- | soh/src/code/z_camera.c | 2 | ||||
| -rw-r--r-- | soh/src/code/z_common_data.c | 4 | ||||
| -rw-r--r-- | soh/src/code/z_en_item00.c | 3 | ||||
| -rw-r--r-- | soh/src/code/z_kankyo.c | 11 | ||||
| -rw-r--r-- | soh/src/code/z_map_exp.c | 13 | ||||
| -rw-r--r-- | soh/src/code/z_parameter.c | 2 | ||||
| -rw-r--r-- | soh/src/code/z_play.c | 1 | ||||
| -rw-r--r-- | soh/src/code/z_player_lib.c | 3 | ||||
| -rw-r--r-- | soh/src/code/z_sram.c | 687 | ||||
| -rw-r--r-- | soh/src/code/z_ss_sram.c | 31 |
21 files changed, 544 insertions, 907 deletions
diff --git a/soh/src/code/audio_data.c b/soh/src/code/audio_data.c index 540eedca8..5fe49139b 100644 --- a/soh/src/code/audio_data.c +++ b/soh/src/code/audio_data.c @@ -544,16 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = { }; AdsrEnvelope gDefaultEnvelope[] = { - // OTRTODO: Byteswapped manually for quick audio support. { 0x0100, 0x007D }, { 0xE803, 0x007D }, { 0xFFFF, 0x0000 }, { 0x0000, 0x0000 }, - /* { 1, 32000 }, - { 1000, 32000 }, - { -1, 0 }, - { 0, 0 }, - */ }; NoteSubEu gZeroNoteSub = { 0 }; diff --git a/soh/src/code/audio_heap.c b/soh/src/code/audio_heap.c index 765fd8b09..84e91d439 100644 --- a/soh/src/code/audio_heap.c +++ b/soh/src/code/audio_heap.c @@ -10,6 +10,8 @@ void AudioHeap_DiscardSampleCaches(void); void AudioHeap_DiscardSampleBank(s32 sampleBankId); void AudioHeap_DiscardSampleBanks(void); +extern bool gUseLegacySD; + f32 func_800DDE20(f32 arg0) { return 256.0f * gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled / arg0; } @@ -1201,7 +1203,11 @@ void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) { } } -void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) { +void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) +{ + if (!gUseLegacySD) + return; + if (sample != NULL) { if (sample->sampleAddr == entry->allocatedAddr) { sample->sampleAddr = entry->sampleAddr; diff --git a/soh/src/code/audio_init_params.c b/soh/src/code/audio_init_params.c index 0cebdf596..95af11421 100644 --- a/soh/src/code/audio_init_params.c +++ b/soh/src/code/audio_init_params.c @@ -10,7 +10,8 @@ const s16 D_8014A6C0[] = { 0x0030, // gTatumsPerBeat }; -const AudioContextInitSizes D_8014A6C4 = { 0x37F00, 0xE0E0, 0xBCE0 }; +//const AudioContextInitSizes D_8014A6C4 = { 0x37F00, 0xE0E0, 0xBCE0 }; +const AudioContextInitSizes D_8014A6C4 = { 0x37F000, 0xE0E00, 0xBCE00 }; // OTRTODO: This might be overkill... ReverbSettings D_80133420[][3] = { { @@ -67,22 +68,22 @@ ReverbSettings D_80133420[][3] = { }; AudioSpec gAudioSpecs[18] = { - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 }, - { 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 }, - { 32000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 }, + { 44100, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 }, + { 44100, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 }, + { 44100, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, + { 44100, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, { 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, - { 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 }, + { 44100, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 }, }; diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index 7af9037a6..5a579e2a0 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -4,6 +4,7 @@ #include "ultra64.h" #include "global.h" +#include "soh/OTRGlobals.h" #define MK_ASYNC_MSG(retData, tableType, id, status) (((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (status)) #define ASYNC_TBLTYPE(v) ((u8)(v >> 16)) @@ -37,14 +38,14 @@ void AudioLoad_ProcessAsyncLoads(s32 resetStatus); void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus); void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus); void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo, s32 temporary); -void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo); +void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId); void AudioLoad_DiscardFont(s32 fontId); u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad); void* AudioLoad_SyncLoad(u32 tableType, u32 tableId, s32* didAllocate); u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 tableId); void* AudioLoad_SearchCaches(s32 tableType, s32 id); AudioTable* AudioLoad_GetLoadTable(s32 tableType); -void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium); +void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium); void AudioLoad_SyncDmaUnkMedium(u32 devAddr, u8* addr, size_t size, s32 unkMediumParam); s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, u32 devAddr, void* ramAddr, size_t size, OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType); @@ -74,6 +75,14 @@ void* sUnusedHandler = NULL; s32 gAudioContextInitalized = false; +char* sequenceMap[256]; +char* fontMap[256]; + +uintptr_t fontStart; +uint32_t fontOffsets[8192]; + +bool gUseLegacySD = false; + void AudioLoad_DecreaseSampleDmaTtls(void) { u32 i; @@ -278,8 +287,11 @@ void AudioLoad_InitSampleDmaBuffers(s32 arg0) { } s32 AudioLoad_IsFontLoadComplete(s32 fontId) { + return true; + if (fontId == 0xFF) { return true; + } else if (gAudioContext.fontLoadStatus[fontId] >= 2) { return true; } else if (gAudioContext.fontLoadStatus[AudioLoad_GetRealTableIndex(FONT_TABLE, fontId)] >= 2) { @@ -352,6 +364,9 @@ void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumPara for (i = 0; i < table->numEntries; i++) { if ((table->entries[i].size != 0) && (table->entries[i].medium == MEDIUM_CART)) { + if (romAddr == fontStart) + fontOffsets[i] = table->entries[i].romAddr; + table->entries[i].romAddr += romAddr; } } @@ -360,7 +375,7 @@ void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumPara SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) { char pad[0x8]; s32 index; - SoundFontData* font; + SoundFontData* font = NULL; s32 numFonts; s32 fontId; s32 i; @@ -375,6 +390,7 @@ SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) { while (numFonts > 0) { fontId = gAudioContext.sequenceFontTable[index++]; + font = AudioLoad_SyncLoadFont(fontId); numFonts--; } @@ -400,7 +416,8 @@ void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1) { s32 AudioLoad_SyncLoadSample(SoundFontSample* sample, s32 fontId) { void* sampleAddr; - if (sample->unk_bit25 == 1) { + if (sample->unk_bit25 == 1) + { if (sample->medium != MEDIUM_RAM) { sampleAddr = AudioHeap_AllocSampleCache(sample->size, fontId, (void*)sample->sampleAddr, sample->medium, CACHE_PERSISTENT); @@ -466,13 +483,26 @@ void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* ret u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) { s32 index; - index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + if (!gUseLegacySD) + { + if (seqId == 255) + return NULL; - *outNumFonts = gAudioContext.sequenceFontTable[index++]; - if (*outNumFonts == 0) { - return NULL; + SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqId]); + + if (sDat.numFonts == 0) + return NULL; + + return sDat.fonts; + } else { + index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + + *outNumFonts = gAudioContext.sequenceFontTable[index++]; + if (*outNumFonts == 0) { + return NULL; + } + return &gAudioContext.sequenceFontTable[index]; } - return &gAudioContext.sequenceFontTable[index]; } void AudioLoad_DiscardSeqFonts(s32 seqId) { @@ -544,30 +574,52 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { s32 numFonts; s32 fontId; - if (seqId >= gAudioContext.numSequences) { + if (gUseLegacySD && seqId >= gAudioContext.numSequences) { return 0; } AudioSeq_SequencePlayerDisable(seqPlayer); fontId = 0xFF; - index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; - numFonts = gAudioContext.sequenceFontTable[index++]; - while (numFonts > 0) { - fontId = gAudioContext.sequenceFontTable[index++]; - AudioLoad_SyncLoadFont(fontId); - numFonts--; + if (gUseLegacySD) { + index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + numFonts = gAudioContext.sequenceFontTable[index++]; + + while (numFonts > 0) { + fontId = gAudioContext.sequenceFontTable[index++]; + + AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds... + + numFonts--; + } + } + else + { + SequenceData seqData2 = ResourceMgr_LoadSeqByName(sequenceMap[seqId]); + + for (int i = 0; i < seqData2.numFonts; i++) + { + fontId = seqData2.fonts[i]; + AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds... + numFonts--; + } } seqData = AudioLoad_SyncLoadSeq(seqId); + if (seqData == NULL) { return 0; } AudioSeq_ResetSequencePlayer(seqPlayer); seqPlayer->seqId = seqId; - seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); + + if (gUseLegacySD) + seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); + else + seqPlayer->defaultFont = fontId; + seqPlayer->seqData = seqData; seqPlayer->enabled = 1; seqPlayer->scriptState.pc = seqData; @@ -637,8 +689,18 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) { if (gAudioContext.fontLoadStatus[realFontId] == 1) { return NULL; } - sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1; - sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2; + + if (!gUseLegacySD) { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont + (fontMap[fontId]); + + sampleBankId1 = sf->sampleBankId1; + sampleBankId2 = sf->sampleBankId2; + } else { + + sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2; + } relocInfo.sampleBankId1 = sampleBankId1; relocInfo.sampleBankId2 = sampleBankId2; @@ -681,13 +743,38 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { if (ret != NULL) { *didAllocate = false; status = 2; - } else { - table = AudioLoad_GetLoadTable(tableType); - size = table->entries[realId].size; - size = ALIGN16(size); - medium = table->entries[id].medium; - cachePolicy = table->entries[id].cachePolicy; - romAddr = table->entries[realId].romAddr; + } else + { + char* seqData = 0; + SoundFont* fnt; + + if (!gUseLegacySD && tableType == SEQUENCE_TABLE) + { + SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[id]); + seqData = sData.seqData; + size = sData.seqDataSize; + medium = sData.medium; + cachePolicy = sData.cachePolicy; + romAddr = 0; + } + else if (!gUseLegacySD && tableType == FONT_TABLE) + { + fnt = ResourceMgr_LoadAudioSoundFont(fontMap[id]); + size = sizeof(SoundFont); + medium = 2; + cachePolicy = 0; + romAddr = 0; + } + else + { + table = AudioLoad_GetLoadTable(tableType); + size = table->entries[realId].size; + size = ALIGN16(size); + medium = table->entries[id].medium; + cachePolicy = table->entries[id].cachePolicy; + romAddr = table->entries[realId].romAddr; + } + switch (cachePolicy) { case 0: ret = AudioHeap_AllocPermanent(tableType, realId, size); @@ -720,7 +807,14 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { if (medium == MEDIUM_UNK) { AudioLoad_SyncDmaUnkMedium(romAddr, ret, size, (s16)table->unkMediumParam); } else { - AudioLoad_SyncDma(romAddr, ret, size, medium); + if (!gUseLegacySD && tableType == SEQUENCE_TABLE && seqData != NULL) { + AudioLoad_SyncDma(seqData, ret, size, medium); + } else if (!gUseLegacySD && tableType == FONT_TABLE) { + AudioLoad_SyncDma(fnt, ret, size, medium); + } + else { + AudioLoad_SyncDma(romAddr, ret, size, medium); + } } status = cachePolicy == 0 ? 5 : 2; @@ -743,9 +837,16 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) { return ret; } -u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id) { +u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id) +{ + if ((tableType == SEQUENCE_TABLE || tableType == FONT_TABLE) && !gUseLegacySD) { + return id; + } + AudioTable* table = AudioLoad_GetLoadTable(tableType); + // If the size is 0, then this entry actually redirects to another entry. + // The rom address is actually an index into the same table where the "real" data is. if (table->entries[id].size == 0) { id = table->entries[id].romAddr; } @@ -796,29 +897,64 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo Drum* drum; SoundFontSound* sfx; s32 i; - s32 numDrums = gAudioContext.soundFonts[fontId].numDrums; - s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments; - s32 numSfx = gAudioContext.soundFonts[fontId].numSfx; + SoundFont* sf = NULL; + + s32 numDrums = 0; + s32 numInstruments = 0; + s32 numSfx = 0; + + if (gUseLegacySD) { + numDrums = gAudioContext.soundFonts[fontId].numDrums; + numInstruments = gAudioContext.soundFonts[fontId].numInstruments; + numSfx = gAudioContext.soundFonts[fontId].numSfx; + } else { + sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + numDrums = sf->numDrums; + numInstruments = sf->numInstruments; + numSfx = sf->numSfx; + } + void** ptrs = (void**)mem; + #define BASE_OFFSET(x) (void*)((u32)(x) + (u32)(mem)) reloc2 = ptrs[0]; if (1) {} - if ((reloc2 != 0) && (numDrums != 0)) { + if ((reloc2 != 0 || !gUseLegacySD) && (numDrums != 0)) + { ptrs[0] = BASE_OFFSET(reloc2); - for (i = 0; i < numDrums; i++) { - reloc = ((Drum**)ptrs[0])[i]; - - if (reloc != 0) { - reloc = BASE_OFFSET(reloc); - - ((Drum**)ptrs[0])[i] = drum = reloc; - if (!drum->loaded) { - AudioLoad_RelocateSample(&drum->sound, mem, relocInfo); - reloc = drum->envelope; - drum->envelope = BASE_OFFSET(reloc); - drum->loaded = 1; + for (i = 0; i < numDrums; i++) + { + if (gUseLegacySD) + reloc = ((Drum**)ptrs[0])[i]; + + if (reloc != 0 || !gUseLegacySD) + { + if (gUseLegacySD) + { + reloc = BASE_OFFSET(reloc); + ((Drum**)ptrs[0])[i] = drum = reloc; + } + + if (!gUseLegacySD) + drum = sf->drums[i]; + + if (!drum->loaded) + { + if (!gUseLegacySD) + { + AudioLoad_RelocateSample(&sf->drums[i]->sound, mem, relocInfo, fontOffsets[fontId]); + //reloc = drum->envelope; + drum->loaded = 1; + } + else + { + AudioLoad_RelocateSample(&drum->sound, mem, relocInfo, fontOffsets[fontId]); + reloc = drum->envelope; + drum->envelope = BASE_OFFSET(reloc); + drum->loaded = 1; + } } } } @@ -826,39 +962,56 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo reloc2 = ptrs[1]; if (1) {} - if ((reloc2 != 0) && (numSfx != 0)) { + if ((reloc2 != 0 || !gUseLegacySD) && (numSfx != 0)) { ptrs[1] = BASE_OFFSET(reloc2); for (i = 0; i < numSfx; i++) { reloc = (SoundFontSound*)ptrs[1] + i; - if (reloc != 0) { - sfx = reloc; - if (sfx->sample != NULL) { - AudioLoad_RelocateSample(sfx, mem, relocInfo); + if (reloc != 0 || !gUseLegacySD) + { + if (!gUseLegacySD) { + AudioLoad_RelocateSample(&sf->soundEffects[i].sample, mem, relocInfo, fontOffsets[fontId]); + } else { + sfx = reloc; + if (sfx->sample != NULL) { + AudioLoad_RelocateSample(sfx, mem, relocInfo, fontOffsets[fontId]); + } } } } } - + if (numInstruments > 0x7E) { numInstruments = 0x7E; } - for (i = 2; i <= 2 + numInstruments - 1; i++) { - if (ptrs[i] != NULL) { + int startI = gUseLegacySD ? 2 : 0; + int startEC = gUseLegacySD ? 2 + numInstruments - 1 : numInstruments - 1; + //for (i = 2; i <= 2 + numInstruments - 1; i++) { + for (i = startI; i <= startEC; i++) { + if (!gUseLegacySD || ptrs[i] != NULL) + { ptrs[i] = BASE_OFFSET(ptrs[i]); - inst = ptrs[i]; - if (!inst->loaded) { - if (inst->normalRangeLo != 0) { - AudioLoad_RelocateSample(&inst->lowNotesSound, mem, relocInfo); + if (gUseLegacySD) + inst = ptrs[i]; + else + inst = sf->instruments[i]; + + if (inst != NULL && !inst->loaded) { + if (inst->normalRangeLo != 0) + { + AudioLoad_RelocateSample(&inst->lowNotesSound, mem, relocInfo, fontOffsets[fontId]); } - AudioLoad_RelocateSample(&inst->normalNotesSound, mem, relocInfo); + AudioLoad_RelocateSample(&inst->normalNotesSound, mem, relocInfo, fontOffsets[fontId]); if (inst->normalRangeHi != 0x7F) { - AudioLoad_RelocateSample(&inst->highNotesSound, mem, relocInfo); + AudioLoad_RelocateSample(&inst->highNotesSound, mem, relocInfo, fontOffsets[fontId]); } reloc = inst->envelope; - inst->envelope = BASE_OFFSET(reloc); + + if (gUseLegacySD) + inst->envelope = BASE_OFFSET(reloc); + inst->loaded = 1; } } @@ -866,12 +1019,14 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo #undef BASE_OFFSET - gAudioContext.soundFonts[fontId].drums = ptrs[0]; - gAudioContext.soundFonts[fontId].soundEffects = ptrs[1]; - gAudioContext.soundFonts[fontId].instruments = (Instrument**)(ptrs + 2); + if (gUseLegacySD) { + gAudioContext.soundFonts[fontId].drums = ptrs[0]; + gAudioContext.soundFonts[fontId].soundEffects = ptrs[1]; + gAudioContext.soundFonts[fontId].instruments = (Instrument**)(ptrs + 2); + } } -void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium) { +void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium) { OSMesgQueue* msgQueue = &gAudioContext.syncDmaQueue; OSIoMesg* ioMesg = &gAudioContext.syncDmaIoMesg; size = ALIGN16(size); @@ -1054,7 +1209,6 @@ s32 AudioLoad_AssertValidAddr(uintptr_t ramAddr, uintptr_t startAddr, size_t siz #define BASE_ROM_OFFSET(x) (void*)((u32)(x) + (u32)(romAddr)) void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romAddr) { - // OTRTODO: This will be removed when we actually extract the data. size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0 AdpcmLoop* loop; AdpcmBook* book; @@ -1270,17 +1424,64 @@ void AudioLoad_Init(void* heap, u32 heapSize) { uintptr_t bankStart = ResourceMgr_LoadFileRaw(_AudiobankSegmentRomStart); uintptr_t tableStart = ResourceMgr_LoadFileRaw(_AudiotableSegmentRomStart); + // If we have the old audioseq files present (and this is a 32-bit build), use the legacy audio system + if (seqStart != NULL && bankStart != NULL && tableStart != NULL) + gUseLegacySD = true; + + fontStart = bankStart; + AudioLoad_InitTable(gAudioContext.sequenceTable, seqStart, 0); AudioLoad_InitTable(gAudioContext.soundFontTable, bankStart, 0); AudioLoad_InitTable(gAudioContext.sampleBankTable, tableStart, 0); - numFonts = gAudioContext.soundFontTable->numEntries; - gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont)); - for (i = 0; i < numFonts; i++) { - AudioLoad_InitSoundFontMeta(i); + if (gUseLegacySD) + numFonts = gAudioContext.soundFontTable->numEntries; + + if (gUseLegacySD) + { + gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont)); + + for (i = 0; i < numFonts; i++) { + AudioLoad_InitSoundFontMeta(i); + } + + AudioLoad_InitSwapFont(); + } else { + int seqListSize = 0; + char** seqList = ResourceMgr_ListFiles("audio/sequences*", &seqListSize); + + for (int i = 0; i < seqListSize; i++) + { + SequenceData sDat = ResourceMgr_LoadSeqByName(seqList[i]); + + char* str = malloc(strlen(seqList[i]) + 1); + strcpy(str, seqList[i]); + + sequenceMap[sDat.seqNumber] = str; + } + + free(seqList); + + int fntListSize = 0; + char** fntList = ResourceMgr_ListFiles("audio/fonts*", &fntListSize); + + for (int i = 0; i < fntListSize; i++) + { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fntList[i]); + + char* str = malloc(strlen(fntList[i]) + 1); + strcpy(str, fntList[i]); + + fontMap[sf->fntIndex] = str; + } + + numFonts = fntListSize; + + free(fntList); + gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont)); + } - AudioLoad_InitSwapFont(); if (temp_v0_3 = AudioHeap_Alloc(&gAudioContext.audioInitPool, D_8014A6C4.permanentPoolSize), temp_v0_3 == NULL) { // cast away const from D_8014A6C4 @@ -1300,7 +1501,6 @@ void AudioLoad_InitSlowLoads(void) { s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) { SoundFontSample* sample; AudioSlowLoad* slowLoad; - sample = AudioLoad_GetFontSample(fontId, instId); if (sample == NULL) { *isDone = 0; @@ -1454,28 +1654,42 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) { AudioTable* seqTable; size_t size; - if (seqId >= gAudioContext.numSequences) { + if (gUseLegacySD && seqId >= gAudioContext.numSequences) { *isDone = 0; return -1; } seqId = AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId); + seqTable = AudioLoad_GetLoadTable(SEQUENCE_TABLE); + slowLoad = &gAudioContext.slowLoads[gAudioContext.slowLoadPos]; if (slowLoad->status == LOAD_STATUS_DONE) { slowLoad->status = LOAD_STATUS_WAITING; } + slowLoad->sample.sampleAddr = NULL; slowLoad->isDone = isDone; - size = seqTable->entries[seqId].size; - size = ALIGN16(size); + + if (!gUseLegacySD) + { + SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[seqId]); + char* seqData = sData.seqData; + size = sData.seqDataSize; + slowLoad->curDevAddr = seqData; + slowLoad->medium = sData.medium; + } else { + size = seqTable->entries[seqId].size; + size = ALIGN16(size); + slowLoad->curDevAddr = seqTable->entries[seqId].romAddr; + slowLoad->medium = seqTable->entries[seqId].medium; + } + slowLoad->curRamAddr = ramAddr; slowLoad->status = LOAD_STATUS_START; slowLoad->bytesRemaining = size; slowLoad->ramAddr = ramAddr; - slowLoad->curDevAddr = seqTable->entries[seqId].romAddr; - slowLoad->medium = seqTable->entries[seqId].medium; slowLoad->seqOrFontId = seqId; if (slowLoad->medium == MEDIUM_UNK) { @@ -1687,44 +1901,52 @@ void AudioLoad_AsyncDmaUnkMedium(u32 devAddr, void* ramAddr, size_t size, s16 ar #define RELOC(v, base) (reloc = (void*)((u32)(v) + (u32)(base))) -void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo) { - // OTRTODO: This is hack to detect whether or not the sample has been relocated. +void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId) { size_t maxSoundBankSize = 0x3EB2A0; // sample bank 0 is largest size at 0x3EB2A0 - if ((uintptr_t)mem <= maxSoundBankSize) { - // OTRTODO: This can be removed once we have properly byteswapped files on the disk. - assert("mem for sound font bank is too low."); + if (gUseLegacySD) + { + // NOTE: This is hack to detect whether or not the sample has been relocated. + if ((uintptr_t)mem <= maxSoundBankSize) { + assert("mem for sound font bank is too low."); + } } SoundFontSample* sample; void* reloc; - // OTRTODO: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works. - if ((uintptr_t)sound->sample < maxSoundBankSize) { - sample = sound->sample = RELOC(sound->sample, mem); - if (sample->size != 0 && sample->unk_bit25 != 1) { - sample->loop = RELOC(sample->loop, mem); - sample->book = RELOC(sample->book, mem); - - // Resolve the sample medium 2-bit bitfield into a real value based on relocInfo. - switch (sample->medium) { - case 0: - sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1); - sample->medium = relocInfo->medium1; - break; - case 1: - sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2); - sample->medium = relocInfo->medium2; - break; - case 2: - case 3: - // Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE - // respectively, and the sampleAddr unrelocated. - break; - } + // NOTE: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works. + if ((uintptr_t)sound->sample < maxSoundBankSize || !gUseLegacySD) + { + if (!gUseLegacySD) { + SoundFontSample* sample2 = sound; + } else { + sample = sound->sample = RELOC(sound->sample, mem); + + if (sample->size != 0 && sample->unk_bit25 != 1) { + sample->loop = RELOC(sample->loop, mem); + sample->book = RELOC(sample->book, mem); + + // Resolve the sample medium 2-bit bitfield into a real value based on relocInfo. + switch (sample->medium) { + case 0: + sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1); + sample->medium = relocInfo->medium1; + break; + case 1: + sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2); + sample->medium = relocInfo->medium2; + break; + case 2: + case 3: + // Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE + // respectively, and the sampleAddr unrelocated. + break; + } - sample->unk_bit25 = 1; - if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) { - gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + sample->unk_bit25 = 1; + if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) { + gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + } } } } @@ -1949,8 +2171,10 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) { void AudioLoad_AddUsedSample(SoundFontSound* sound) { SoundFontSample* sample = sound->sample; - if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) { - gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + if (sample != NULL) { + if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) { + gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + } } } @@ -1977,9 +2201,17 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo gAudioContext.numUsedSamples = 0; - numDrums = gAudioContext.soundFonts[fontId].numDrums; - numInstruments = gAudioContext.soundFonts[fontId].numInstruments; - numSfx = gAudioContext.soundFonts[fontId].numSfx; + if (!gUseLegacySD) { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + + numDrums = sf->numDrums; + numInstruments = sf->numInstruments; + numSfx = sf->numSfx; + } else { + numDrums = gAudioContext.soundFonts[fontId].numDrums; + numInstruments = gAudioContext.soundFonts[fontId].numInstruments; + numSfx = gAudioContext.soundFonts[fontId].numSfx; + } for (i = 0; i < numInstruments; i++) { instrument = Audio_GetInstrumentInner(fontId, i); @@ -2024,6 +2256,7 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo } sample = gAudioContext.usedSamples[i]; + if (sample->medium == MEDIUM_RAM) { continue; } @@ -2100,10 +2333,19 @@ void AudioLoad_LoadPermanentSamples(void) { for (i = 0; i < gAudioContext.permanentPool.count; i++) { RelocInfo relocInfo; - if (gAudioContext.permanentCache[i].tableType == FONT_TABLE) { + if (gAudioContext.permanentCache[i].tableType == FONT_TABLE) + { fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioContext.permanentCache[i].id); - relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; - relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + //fontId = gAudioContext.permanentCache[i].id; + + if (!gUseLegacySD) { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + relocInfo.sampleBankId1 = sf->sampleBankId1; + relocInfo.sampleBankId2 = sf->sampleBankId2; + } else { + relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + } if (relocInfo.sampleBankId1 != 0xFF) { relocInfo.sampleBankId1 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId1); diff --git a/soh/src/code/audio_playback.c b/soh/src/code/audio_playback.c index c116b4ddb..df64e2c7b 100644 --- a/soh/src/code/audio_playback.c +++ b/soh/src/code/audio_playback.c @@ -1,6 +1,8 @@ #include "global.h" #include "Cvar.h" +extern bool gUseLegacySD; + void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { f32 volRight, volLeft; s32 smallPanIndex; @@ -284,7 +286,18 @@ void Audio_ProcessNotes(void) { } subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; - subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate; + + f32 resampRate = gAudioContext.audioBufferParameters.resampleRate; + + if (!gUseLegacySD && !noteSubEu2->bitField1.isSyntheticWave && noteSubEu2->sound.soundFontSound != NULL && + noteSubEu2->sound.soundFontSound->sample != NULL && + noteSubEu2->sound.soundFontSound->sample->sampleRateMagicValue == 'RIFF') { + resampRate = CALC_RESAMPLE_FREQ(noteSubEu2->sound.soundFontSound->sample->sampleRate); + } + + subAttrs.frequency *= resampRate; + + subAttrs.velocity *= scale; Audio_InitNoteSub(note, noteSubEu2, &subAttrs); noteSubEu->bitField1.bookOffset = bookOffset; @@ -307,7 +320,7 @@ SoundFontSound* Audio_InstrumentGetSound(Instrument* instrument, s32 semitone) { Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) { Instrument* inst; - + if (fontId == 0xFF) { return NULL; } @@ -317,16 +330,31 @@ Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) { return NULL; } - if (instId >= gAudioContext.soundFonts[fontId].numInstruments) { - gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000; - return NULL; + int instCnt = 0; + + if (gUseLegacySD) { + instCnt = gAudioContext.soundFonts[fontId].numInstruments; + inst = gAudioContext.soundFonts[fontId].instruments[instId]; + + if (instId >= gAudioContext.soundFonts[fontId].numInstruments) + if (instId >= instCnt) { + gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000; + return NULL; + } + } else { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + + if (instId >= sf->numInstruments) + return NULL; + + inst = sf->instruments[instId]; } - inst = gAudioContext.soundFonts[fontId].instruments[instId]; if (inst == NULL) { gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000; return inst; } + return inst; } @@ -343,12 +371,17 @@ Drum* Audio_GetDrum(s32 fontId, s32 drumId) { return NULL; } - if (drumId >= gAudioContext.soundFonts[fontId].numDrums) { - gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000; - return NULL; - } + if (gUseLegacySD) { + if (drumId >= gAudioContext.soundFonts[fontId].numDrums) { + gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000; + return NULL; + } - drum = gAudioContext.soundFonts[fontId].drums[drumId]; + drum = gAudioContext.soundFonts[fontId].drums[drumId]; + } else { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + drum = sf->drums[drumId]; + } if (drum == NULL) { gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000; @@ -369,12 +402,17 @@ SoundFontSound* Audio_GetSfx(s32 fontId, s32 sfxId) { return NULL; } - if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) { - gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000; - return NULL; - } + if (gUseLegacySD) { + if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) { + gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000; + return NULL; + } - sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId]; + sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId]; + } else { + SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]); + sfx = &sf->soundEffects[sfxId]; + } if (sfx == NULL) { gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000; diff --git a/soh/src/code/audio_seqplayer.c b/soh/src/code/audio_seqplayer.c index 3dd7b811e..beac78269 100644 --- a/soh/src/code/audio_seqplayer.c +++ b/soh/src/code/audio_seqplayer.c @@ -3,6 +3,9 @@ #include "ultra64.h" #include "global.h" +extern bool gUseLegacySD; +extern char* sequenceMap[256]; + #define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80) #define PORTAMENTO_MODE(x) ((x).mode & ~0x80) #define PORTAMENTO_MODE_1 1 @@ -938,8 +941,16 @@ u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** inst *instOut = NULL; return 0; } - adsr->envelope = inst->envelope; - adsr->releaseRate = inst->releaseRate; + + if (inst->envelope != NULL) + { + adsr->envelope = inst->envelope; + adsr->releaseRate = (inst->releaseRate); + } + else { + adsr->envelope = gDefaultEnvelope; + } + *instOut = inst; instId += 2; return instId; @@ -1052,9 +1063,15 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { command = (u8)parameters[0]; if (seqPlayer->defaultFont != 0xFF) { - offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; - lowBits = gAudioContext.sequenceFontTable[offset]; - command = gAudioContext.sequenceFontTable[offset + lowBits - result]; + if (gUseLegacySD) { + offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; + lowBits = gAudioContext.sequenceFontTable[offset]; + command = gAudioContext.sequenceFontTable[offset + lowBits - result]; + } + else { + SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]); + command = sDat.fonts[sDat.numFonts - result - 1]; + } } if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) { @@ -1162,10 +1179,17 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { result = (u8)parameters[0]; command = (u8)parameters[0]; - if (seqPlayer->defaultFont != 0xFF) { - offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; - lowBits = gAudioContext.sequenceFontTable[offset]; - command = gAudioContext.sequenceFontTable[offset + lowBits - result]; + if (seqPlayer->defaultFont != 0xFF) + { + if (gUseLegacySD) { + offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId]; + lowBits = gAudioContext.sequenceFontTable[offset]; + command = gAudioContext.sequenceFontTable[offset + lowBits - result]; + } + else { + SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]); + command = sDat.fonts[sDat.numFonts - result - 1]; + } } if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) { @@ -1322,14 +1346,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) { break; case 0xB2: offset = (u16)parameters[0]; - // OTRTODO: Byteswap added for quick audio channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2))); break; case 0xB4: channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22]; break; case 0xB5: - // OTRTODO: Byteswap added for quick audio channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]); break; case 0xB6: diff --git a/soh/src/code/audio_synthesis.c b/soh/src/code/audio_synthesis.c index 037bd2ec3..2c5d03102 100644 --- a/soh/src/code/audio_synthesis.c +++ b/soh/src/code/audio_synthesis.c @@ -440,11 +440,11 @@ void func_800DBE64(void) { void func_800DBE6C(void) { } -void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, s32 addr) { +void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, uintptr_t addr) { aFilter(cmd, flags, countOrBuf, addr); } -void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, s32 addr) { +void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, uintptr_t addr) { aFilter(cmd, 2, count, addr); } @@ -561,6 +561,9 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat NoteSubEu* noteSubEu2; s32 unk14; + //if (aiBufLen == 0) + //return; + t = gAudioContext.numNotes * updateIndex; count = 0; if (gAudioContext.numSynthesisReverbs == 0) { @@ -749,8 +752,10 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS cmd = AudioSynth_LoadWaveSamples(cmd, noteSubEu, synthState, nSamplesToLoad); noteSamplesDmemAddrBeforeResampling = DMEM_UNCOMPRESSED_NOTE + (synthState->samplePosInt * 2); synthState->samplePosInt += nSamplesToLoad; - } else { + } else + { audioFontSample = noteSubEu->sound.soundFontSound->sample; + loopInfo = audioFontSample->loop; loopEndPos = loopInfo->end; sampleAddr = audioFontSample->sampleAddr; @@ -822,6 +827,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS noteFinished = true; } } + switch (audioFontSample->codec) { case CODEC_ADPCM: @@ -848,6 +854,9 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS goto skip; case CODEC_S16: AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, (samplesLenAdjusted * 2) + 0x20); + AudioSynth_LoadBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, ALIGN16(nSamplesToLoad * 2), + audioFontSample->sampleAddr + (synthState->samplePosInt * 2)); + flags = A_CONTINUE; skipBytes = 0; nSamplesProcessed = samplesLenAdjusted; @@ -860,7 +869,8 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS if (nFramesToDecode != 0) { frameIndex = (synthState->samplePosInt + skipInitialSamples - nFirstFrameSamplesToIgnore) / 16; sampleDataOffset = frameIndex * frameSize; - if (audioFontSample->medium == MEDIUM_RAM) { + if (audioFontSample->medium == MEDIUM_RAM) + { sampleData = (u8*)(sampleDataStart + sampleDataOffset + sampleAddr); } else if (audioFontSample->medium == MEDIUM_UNK) { return cmd; @@ -1024,7 +1034,8 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS unk7 = noteSubEu->unk_07; unkE = noteSubEu->unk_0E; buf = &synthState->synthesisBuffers->panSamplesBuffer[0x18]; - if (unk7 != 0 && noteSubEu->unk_0E != 0) { + if (unk7 != 0 && noteSubEu->unk_0E != 0) + { AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_SCRATCH2, aiBufLen * 2); thing = DMEM_SCRATCH2 - unk7; if (synthState->unk_1A != 0) { diff --git a/soh/src/code/code_800E4FE0.c b/soh/src/code/code_800E4FE0.c index c46ae7a07..d88e731f4 100644 --- a/soh/src/code/code_800E4FE0.c +++ b/soh/src/code/code_800E4FE0.c @@ -213,11 +213,7 @@ AudioTask* func_800E5000(void) { task = &gAudioContext.currTask->task.t; task->type = M_AUDTASK; task->flags = 0; - //task->ucode_boot = D_801120C0; task->ucode_boot_size = 0x1000; - //task->ucode_data_size = ((rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64)) - 1; - //task->ucode = D_801120C0; - //task->ucode_data = rspAspMainDataStart; task->ucode_size = 0x1000; task->dram_stack = NULL; task->dram_stack_size = 0; diff --git a/soh/src/code/code_800F9280.c b/soh/src/code/code_800F9280.c index e23ede0e9..6ca2ad75d 100644 --- a/soh/src/code/code_800F9280.c +++ b/soh/src/code/code_800F9280.c @@ -363,7 +363,11 @@ void Audio_ProcessSeqCmd(u32 cmd) { } } -void Audio_QueueSeqCmd(u32 cmd) { +extern f32 D_80130F24; +extern f32 D_80130F28; + +void Audio_QueueSeqCmd(u32 cmd) +{ sAudioSeqCmds[sSeqCmdWrPos++] = cmd; } diff --git a/soh/src/code/shrink_window.c b/soh/src/code/shrink_window.c index cc68129e2..ee7822df0 100644 --- a/soh/src/code/shrink_window.c +++ b/soh/src/code/shrink_window.c @@ -6,6 +6,10 @@ s32 sShrinkWindowVal = 0; s32 sShrinkWindowCurrentVal = 0; void ShrinkWindow_SetVal(s32 value) { + if (CVar_GetS32("gDisableBlackBars", 0)) { + sShrinkWindowVal = 0; + return; + } if (HREG(80) == 0x13 && HREG(81) == 1) { osSyncPrintf("shrink_window_setval(%d)\n", value); } @@ -17,6 +21,10 @@ u32 ShrinkWindow_GetVal(void) { } void ShrinkWindow_SetCurrentVal(s32 currentVal) { + if (CVar_GetS32("gDisableBlackBars", 0)) { + sShrinkWindowCurrentVal = 0; + return; + } if (HREG(80) == 0x13 && HREG(81) == 1) { osSyncPrintf("shrink_window_setnowval(%d)\n", currentVal); } diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index bdb2fe78c..79a3f4032 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -339,19 +339,19 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl if (CVar_GetS32("gUseNaviCol",0) != 1 ) { if (actorCategory == ACTORCAT_PLAYER) { naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 255; - naviColor->outer.r = 115; naviColor->outer.g = 230; naviColor->outer.b = 255; + naviColor->outer.r = 0; naviColor->outer.g = 0; naviColor->outer.b = 255; } if (actorCategory == ACTORCAT_NPC) { - naviColor->inner.r = 100; naviColor->inner.g = 100; naviColor->inner.b = 255; - naviColor->outer.r = 90; naviColor->outer.g = 90; naviColor->outer.b = 255; + naviColor->inner.r = 150; naviColor->inner.g = 150; naviColor->inner.b = 255; + naviColor->outer.r = 150; naviColor->outer.g = 150; naviColor->outer.b = 255; } if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) { naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 0; - naviColor->outer.r = 220; naviColor->outer.g = 220; naviColor->outer.b = 0; + naviColor->outer.r = 220; naviColor->outer.g = 155; naviColor->outer.b = 0; } if (actorCategory == ACTORCAT_PROP) { - naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 90; - naviColor->outer.r = 0; naviColor->outer.g = 220; naviColor->outer.b = 0; + naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 0; + naviColor->outer.r = 0; naviColor->outer.g = 255; naviColor->outer.b = 0; } } else { if (actorCategory == ACTORCAT_PLAYER) { @@ -1163,7 +1163,9 @@ void Actor_Init(Actor* actor, GlobalContext* globalCtx) { actor->uncullZoneForward = 1000.0f; actor->uncullZoneScale = 350.0f; actor->uncullZoneDownward = 700.0f; - if (CVar_GetS32("gDisableDrawDistance", 0) != 0) { + if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room + && actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence + && actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning actor->uncullZoneForward = 32767.0f; actor->uncullZoneScale = 32767.0f; actor->uncullZoneDownward = 32767.0f; @@ -2690,7 +2692,9 @@ s32 func_800314B0(GlobalContext* globalCtx, Actor* actor) { s32 func_800314D4(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3) { f32 var; - if (CVar_GetS32("gDisableDrawDistance", 0) != 0) { + if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room + && actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence + && actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning return true; } diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 00f3f70f0..e29cf2bf6 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -7532,7 +7532,7 @@ Vec3s Camera_Update(Camera* camera) { BINANG_TO_DEGF(camera->camDir.x), camera->camDir.y, BINANG_TO_DEGF(camera->camDir.y)); } - if (camera->timer != -1 && CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_DRIGHT)) { + if (camera->timer != -1 && CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_DRIGHT) && CVar_GetS32("gDebugCamera", 0)) { camera->timer = 0; } diff --git a/soh/src/code/z_common_data.c b/soh/src/code/z_common_data.c index e6682b18e..c92a36b71 100644 --- a/soh/src/code/z_common_data.c +++ b/soh/src/code/z_common_data.c @@ -2,13 +2,9 @@ #include <string.h> SaveContext gSaveContext; -u32 D_8015FA88; -u32 D_8015FA8C; void SaveContext_Init(void) { memset(&gSaveContext, 0, sizeof(gSaveContext)); - D_8015FA88 = 0; - D_8015FA8C = 0; gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = NATURE_ID_DISABLED; gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX; diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index d0179a5e1..a7de67900 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -896,6 +896,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { if (this->unk_15A > 0) { this->unk_15A--; + if (CVar_GetS32("gDropsDontDie", 0) && (this->unk_154 <= 0)) { + this->unk_15A++; + } } if ((this->unk_15A > 0) && (this->unk_15A < 41) && (this->unk_154 <= 0)) { diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index 9f7518374..6f1fc0c8f 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -2093,9 +2093,14 @@ void func_80075B44(GlobalContext* globalCtx) { case 7: Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_1, 0); - if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0) { - Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5, - CHANNEL_IO_PORT_1, 1); + if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0) + { + // OTRTODO: This is where corrupt audio happens. Commenting this out seems to not introduce any side effects? + // Further investigation is needed... + + if (gUseLegacySD) + Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5, + CHANNEL_IO_PORT_1, 1); } globalCtx->envCtx.unk_E0++; break; diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c index 5402cee44..aaee434b0 100644 --- a/soh/src/code/z_map_exp.c +++ b/soh/src/code/z_map_exp.c @@ -755,22 +755,23 @@ void Minimap_Draw(GlobalContext* globalCtx) { if (((globalCtx->sceneNum != SCENE_SPOT01) && (globalCtx->sceneNum != SCENE_SPOT04) && (globalCtx->sceneNum != SCENE_SPOT08)) || (LINK_AGE_IN_YEARS != YEARS_ADULT)) { + bool Map0 = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 == 0; s16 IconSize = 8; - s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex]+Right_MM_Margin; - s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex]+Bottom_MM_Margin; + s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + (Map0 ? 0 : Right_MM_Margin); + s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + (Map0 ? 0 : Bottom_MM_Margin); //gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed. - if (CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){ + if (CVar_GetS32("gFixDungeonMinimapIcon", 0) != 0){ //No idea why and how Original value work but this does actually fix them all. PosY = PosY+1024; } - s16 TopLeftX = OTRGetRectDimensionFromRightEdge(PosX) << 2; + s16 TopLeftX = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX) : OTRGetRectDimensionFromRightEdge(PosX)) << 2; s16 TopLeftY = PosY << 2; - s16 TopLeftW = OTRGetRectDimensionFromRightEdge(PosX + IconSize) << 2; + s16 TopLeftW = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX + IconSize) : OTRGetRectDimensionFromRightEdge(PosX + IconSize)) << 2; s16 TopLeftH = (PosY + IconSize) << 2; if ((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) || ((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) && (gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]]))) { - if (gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 != 0 && CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){ + if (!Map0 || !CVar_GetS32("gFixDungeonMinimapIcon", 0)) { gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, IconSize, IconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index a9e9e4f9e..14d677219 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2935,7 +2935,7 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) { } const s16 rCUpBtnX = OTRGetRectDimensionFromRightEdge(R_C_UP_BTN_X+Right_HUD_Margin); - const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin); + const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin-!!CVar_GetS32("gNaviTextFix", 0)); if (CVar_GetS32("gHudColors", 1) == 0) { gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp); } else if (CVar_GetS32("gHudColors", 1) == 1) { diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 632ed41f6..4e48fc512 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -240,7 +240,6 @@ void Gameplay_Init(GameState* thisx) { globalCtx->cameraPtrs[MAIN_CAM]->uid = 0; globalCtx->activeCamera = MAIN_CAM; func_8005AC48(&globalCtx->mainCamera, 0xFF); - Sram_Init(globalCtx, &globalCtx->sramCtx); func_80112098(globalCtx); Message_Init(globalCtx); GameOver_Init(globalCtx); diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index cf7fbd51c..77c569951 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -360,7 +360,8 @@ s32 Player_ActionToModelGroup(Player* this, s32 actionParam) { void Player_SetModelsForHoldingShield(Player* this) { if ((this->stateFlags1 & 0x400000) && ((this->itemActionParam < 0) || (this->itemActionParam == this->heldItemActionParam))) { - if (!Player_HoldsTwoHandedWeapon(this) && !Player_IsChildWithHylianShield(this)) { + if ((CVar_GetS32("gShieldTwoHanded", 0) && (this->heldItemActionParam != PLAYER_AP_STICK) || + !Player_HoldsTwoHandedWeapon(this)) && !Player_IsChildWithHylianShield(this)) { this->rightHandType = 10; this->rightHandDLists = &sPlayerDListGroups[10][(void)0, gSaveContext.linkAge]; if (this->sheathType == 18) { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 16835d7ad..597a33dd9 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -3,242 +3,14 @@ #include <string.h> -// these are the main substructs of save context. -// we are going to hold off on splitting save context until later on, -// so these temporary structs will live here for now. - -typedef struct { - /* 0x00 */ char newf[6]; // string "ZELDAZ" - /* 0x06 */ s16 deaths; - /* 0x08 */ char playerName[8]; - /* 0x10 */ s16 n64ddFlag; - /* 0x12 */ s16 healthCapacity; // "max_life" - /* 0x14 */ s16 health; // "now_life" - /* 0x16 */ s8 magicLevel; - /* 0x17 */ s8 magic; - /* 0x18 */ s16 rupees; - /* 0x1A */ u16 swordHealth; - /* 0x1C */ u16 naviTimer; - /* 0x1E */ u8 magicAcquired; - /* 0x1F */ u8 unk_1F; - /* 0x20 */ u8 doubleMagic; - /* 0x21 */ u8 doubleDefense; - /* 0x22 */ u8 bgsFlag; - /* 0x23 */ u8 ocarinaGameRoundNum; - /* 0x24 */ ItemEquips childEquips; - /* 0x2E */ ItemEquips adultEquips; - /* 0x38 */ u32 unk_38; // this may be incorrect, currently used for alignement - /* 0x3C */ char unk_3C[0x0E]; - /* 0x4A */ s16 savedSceneNum; -} SavePlayerData; // size = 0x4C - -typedef struct { - /* 0x0000 */ SavePlayerData playerData; // "S_Private" substruct name - /* 0x004C */ ItemEquips equips; - /* 0x0058 */ Inventory inventory; - /* 0x00B8 */ SavedSceneFlags sceneFlags[124]; - /* 0x0E48 */ FaroresWindData fw; - /* 0x0E70 */ char unk_E70[0x10]; - /* 0x0E80 */ s32 gsFlags[6]; - /* 0x0E98 */ char unk_E98[0x10]; - /* 0x0EA8 */ s32 horseRaceRecord; - /* 0x0EAC */ char unk_EAC[0x0C]; - /* 0x0EB8 */ u16 eventChkInf[14]; // "event_chk_inf" - /* 0x0ED4 */ u16 itemGetInf[4]; // "item_get_inf" - /* 0x0EDC */ u16 infTable[30]; // "inf_table" - /* 0x0F18 */ char unk_F18[0x04]; - /* 0x0F1C */ u32 worldMapAreaData; // "area_arrival" - /* 0x0F20 */ char unk_F20[0x4]; - /* 0x0F24 */ u8 scarecrowCustomSongSet; - /* 0x0F25 */ u8 scarecrowCustomSong[0x360]; - /* 0x1285 */ char unk_1285[0x24]; - /* 0x12A9 */ u8 scarecrowSpawnSongSet; - /* 0x12AA */ u8 scarecrowSpawnSong[0x80]; - /* 0x132A */ char unk_132A[0x02]; - /* 0x132C */ HorseData horseData; - /* 0x1336 */ u16 checksum; // "check_sum" -} SaveInfo; // size = 0x1338 - -typedef struct { - /* 0x00 */ s32 entranceIndex; - /* 0x04 */ s32 linkAge; // 0: Adult; 1: Child - /* 0x08 */ s32 cutsceneIndex; - /* 0x0C */ u16 dayTime; // "zelda_time" - /* 0x10 */ s32 nightFlag; - /* 0x14 */ s32 totalDays; - /* 0x18 */ s32 unk_18; // increments with totalDays, gets reset by goron for bgs and one other use - /* 0x1C */ SaveInfo info; // "information" -} Save; // size = 0x1354 - -#define SAVE_PLAYER_DATA (*((SavePlayerData*)&gSaveContext.newf)) -#define SAVE_INFO (*((SaveInfo*)&gSaveContext.newf)) - -#define SLOT_SIZE (sizeof(SaveContext) + 0x28) -#define CHECKSUM_SIZE (sizeof(Save) / 2) - -#define DEATHS OFFSETOF(SaveContext, deaths) -#define NAME OFFSETOF(SaveContext, playerName) -#define N64DD OFFSETOF(SaveContext, n64ddFlag) -#define HEALTH_CAP OFFSETOF(SaveContext, healthCapacity) -#define QUEST OFFSETOF(SaveContext, inventory.questItems) -#define DEFENSE OFFSETOF(SaveContext, inventory.defenseHearts) -#define HEALTH OFFSETOF(SaveContext, health) - -#define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE)) - -u16 gSramSlotOffsets[] = { - SLOT_OFFSET(0), - SLOT_OFFSET(1), - SLOT_OFFSET(2), - // the latter three saves are backup saves for the former saves - SLOT_OFFSET(3), - SLOT_OFFSET(4), - SLOT_OFFSET(5), -}; - -static u8 sZeldaMagic[] = { '\0', '\0', '\0', '\x98', '\x09', '\x10', '\x21', 'Z', 'E', 'L', 'D', 'A' }; - -static SavePlayerData sNewSavePlayerData = { - { '\0', '\0', '\0', '\0', '\0', '\0' }, // newf - 0, // deaths - { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName - 0, // n64ddFlag - 0x30, // healthCapacity - 0x30, // defense - 0, // magicLevel - 0x30, // magic - 0, // rupees - 0, // swordHealth - 0, // naviTimer - 0, // magicAcquired - 0, // unk_1F - 0, // doubleMagic - 0, // doubleDefense - 0, // bgsFlag - 0, // ocarinaGameRoundNum - { - { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems - { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots - 0, // equipment - }, // childEquips - { - { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems - { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots - 0, // equipment - }, // adultEquips - 0, // unk_38 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C - 0x34, // savedSceneNum -}; - -static ItemEquips sNewSaveEquips = { - { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems - { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots - 0x1100, // equipment -}; - -static Inventory sNewSaveInventory = { - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // items - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ammo - 0x1100, // equipment - 0, // upgrades - 0, // questItems - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }, // dungeonKeys - 0, // defenseHearts - 0, // gsTokens -}; - -static u16 sNewSaveChecksum = 0; - /** * Initialize new save. * This save has an empty inventory with 3 hearts and single magic. */ void Sram_InitNewSave(void) { - SaveContext* temp = &gSaveContext; - - memset(&SAVE_INFO, 0, sizeof(SaveInfo)); - gSaveContext.totalDays = 0; - gSaveContext.bgsDayCount = 0; - - SAVE_PLAYER_DATA = sNewSavePlayerData; - gSaveContext.equips = sNewSaveEquips; - gSaveContext.inventory = sNewSaveInventory; - - temp->checksum = sNewSaveChecksum; - gSaveContext.horseData.scene = SCENE_SPOT00; - gSaveContext.horseData.pos.x = -1840; - gSaveContext.horseData.pos.y = 72; - gSaveContext.horseData.pos.z = 5497; - gSaveContext.horseData.angle = -0x6AD9; - gSaveContext.magicLevel = 0; - gSaveContext.infTable[29] = 1; - gSaveContext.sceneFlags[5].swch = 0x40000000; + Save_InitFile(false); } -static SavePlayerData sDebugSavePlayerData = { - { 'Z', 'E', 'L', 'D', 'A', 'Z' }, // newf - 0, // deaths - { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName ( "LINK" ) - 0, // n64ddFlag - 0xE0, // healthCapacity - 0xE0, // health - 0, // magicLevel - 0x30, // magic - 150, // rupees - 8, // swordHealth - 0, // naviTimer - 1, // magicAcquired - 0, // unk_1F - 0, // doubleMagic - 0, // doubleDefense - 0, // bgsFlag - 0, // ocarinaGameRoundNum - { - { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems - { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots - 0, // equipment - }, // childEquips - { - { ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems - { SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots - 0, // equipment - }, // adultEquips - 0, // unk_38 - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C - 0x51, // savedSceneNum -}; - -static ItemEquips sDebugSaveEquips = { - { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_BOMB, ITEM_OCARINA_FAIRY }, // buttonItems - { SLOT_BOW, SLOT_BOMB, SLOT_OCARINA }, // cButtonSlots - 0x1122, // equipment -}; - -static Inventory sDebugSaveInventory = { - { - ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_ARROW_FIRE, ITEM_DINS_FIRE, - ITEM_SLINGSHOT, ITEM_OCARINA_FAIRY, ITEM_BOMBCHU, ITEM_HOOKSHOT, ITEM_ARROW_ICE, ITEM_FARORES_WIND, - ITEM_BOOMERANG, ITEM_LENS, ITEM_BEAN, ITEM_HAMMER, ITEM_ARROW_LIGHT, ITEM_NAYRUS_LOVE, - ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, ITEM_POCKET_EGG, ITEM_WEIRD_EGG, - }, // items - { 50, 50, 10, 30, 1, 1, 30, 1, 50, 1, 1, 1, 1, 1, 1, 1 }, // ammo - 0x7777, // equipment - 0x125249, // upgrades - 0x1E3FFFF, // questItems - { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, // dungeonKeys - 0, // defenseHearts - 0, // gsTokens -}; - -static u16 sDebugSaveChecksum = 0; - /** * Initialize debug save. This is also used on the Title Screen * This save has a mostly full inventory with 10 hearts and single magic. @@ -249,40 +21,7 @@ static u16 sDebugSaveChecksum = 0; * and set water level in Water Temple to lowest level. */ void Sram_InitDebugSave(void) { - SaveContext* temp = &gSaveContext; - - memset(&SAVE_INFO, 0, sizeof(SaveInfo)); - gSaveContext.totalDays = 0; - gSaveContext.bgsDayCount = 0; - - SAVE_PLAYER_DATA = sDebugSavePlayerData; - gSaveContext.equips = sDebugSaveEquips; - gSaveContext.inventory = sDebugSaveInventory; - - temp->checksum = sDebugSaveChecksum; - gSaveContext.horseData.scene = SCENE_SPOT00; - gSaveContext.horseData.pos.x = -1840; - gSaveContext.horseData.pos.y = 72; - gSaveContext.horseData.pos.z = 5497; - gSaveContext.horseData.angle = -0x6AD9; - gSaveContext.infTable[0] |= 0x5009; - gSaveContext.eventChkInf[0] |= 0x123F; - gSaveContext.eventChkInf[8] |= 1; - gSaveContext.eventChkInf[12] |= 0x10; - - if (LINK_AGE_IN_YEARS == YEARS_CHILD) { - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_SWORD, 1); - if (gSaveContext.fileNum == 0xFF) { - gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT; - gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT; - Inventory_ChangeEquipment(EQUIP_SHIELD, 1); - } - } - - gSaveContext.entranceIndex = 0xCD; - gSaveContext.magicLevel = 0; - gSaveContext.sceneFlags[5].swch = 0x40000000; + Save_InitFile(true); } /** @@ -295,7 +34,7 @@ void Sram_InitDebugSave(void) { * - Give and equip master sword if player is adult and doesnt have kokiri sword (bug?) * - Revert any trade items that spoil */ -void Sram_OpenSave(SramContext* sramCtx) { +void Sram_OpenSave() { static s16 dungeonEntrances[] = { 0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037, 0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C, @@ -304,15 +43,7 @@ void Sram_OpenSave(SramContext* sramCtx) { u16 j; u8* ptr; - osSyncPrintf("個人File作成\n"); // "Create personal file" - i = gSramSlotOffsets[gSaveContext.fileNum]; - osSyncPrintf("ぽいんと=%x(%d)\n", i, gSaveContext.fileNum); // "Point=" - - memcpy(&gSaveContext, sramCtx->readBuff + i, sizeof(Save)); - - osSyncPrintf(VT_FGCOL(YELLOW)); - osSyncPrintf("SCENE_DATA_ID = %d SceneNo = %d\n", gSaveContext.savedSceneNum, - ((void)0, gSaveContext.entranceIndex)); + Save_LoadFile(); switch (gSaveContext.savedSceneNum) { case SCENE_YDAN: @@ -446,232 +177,7 @@ void Sram_OpenSave(SramContext* sramCtx) { gSaveContext.magicLevel = 0; } -/** - * Write the contents of the Save Context to a main and backup slot in SRAM. - * Note: The whole Save Context is written even though only the `save` substruct is read back later - */ -void Sram_WriteSave(SramContext* sramCtx) { - u16 offset; - u16 checksum; - u16 j; - u16* ptr; - - gSaveContext.checksum = 0; - - ptr = (u16*)&gSaveContext; - checksum = 0; - j = 0; - - for (offset = 0; offset < CHECKSUM_SIZE; offset++) { - if (++j == 0x20) { - j = 0; - } - checksum += *ptr++; - } - - gSaveContext.checksum = checksum; - - ptr = (u16*)&gSaveContext; - checksum = 0; - - for (offset = 0; offset < CHECKSUM_SIZE; offset++) { - if (++j == 0x20) { - j = 0; - } - checksum += *ptr++; - } - - offset = gSramSlotOffsets[gSaveContext.fileNum]; - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); - - ptr = (u16*)&gSaveContext; - checksum = 0; - - for (offset = 0; offset < CHECKSUM_SIZE; offset++) { - if (++j == 0x20) { - j = 0; - } - checksum += *ptr++; - } - - offset = gSramSlotOffsets[gSaveContext.fileNum + 3]; - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); -} - -/** - * For all 3 slots, verify that the checksum is correct. If corrupted, attempt to load a backup save. - * If backup is also corrupted, default to a new save (or debug save for slot 0 on debug rom). - * - * After verifying all 3 saves, pass relevant data to File Select to be displayed. - */ -void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { - u16 i; - u16 newChecksum; - u16 slotNum; - u16 offset; - u16 j; - u16 oldChecksum; - u16* ptr; - u16 dayTime; - - osSyncPrintf("SRAM START─LOAD\n"); - memset(sramCtx->readBuff,0, SRAM_SIZE); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); - - dayTime = ((void)0, gSaveContext.dayTime); - - for (slotNum = 0; slotNum < 3; slotNum++) { - offset = gSramSlotOffsets[slotNum]; - osSyncPrintf("ぽいんと=%x(%d) SAVE_MAX=%d\n", offset, gSaveContext.fileNum, sizeof(Save)); - memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); - - oldChecksum = gSaveContext.checksum; - gSaveContext.checksum = 0; - ptr = (u16*)&gSaveContext; - osSyncPrintf("\n============= S(%d) =============\n", slotNum); - - for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) { - newChecksum += *ptr++; - } - - // "SAVE checksum calculation" - osSyncPrintf("\nSAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum); - - if (newChecksum != oldChecksum) { - // checksum didnt match, try backup save - osSyncPrintf("ERROR!!! = %x(%d)\n", gSramSlotOffsets[slotNum], slotNum); - offset = gSramSlotOffsets[slotNum + 3]; - memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); - - oldChecksum = gSaveContext.checksum; - gSaveContext.checksum = 0; - ptr = (u16*)&gSaveContext; - osSyncPrintf("================= BACK─UP ========================\n"); - - for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) { - newChecksum += *ptr++; - } - // "(B) SAVE checksum calculation" - osSyncPrintf("\n(B)SAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum); - - if (newChecksum != oldChecksum) { - // backup save didnt work, make new save - osSyncPrintf("ERROR!!! = %x(%d+3)\n", gSramSlotOffsets[slotNum + 3], slotNum); - memset(&gSaveContext.entranceIndex, 0, sizeof(s32)); - memset(&gSaveContext.linkAge, 0, sizeof(s32)); - memset(&gSaveContext.cutsceneIndex, 0, sizeof(s32)); - // note that gSaveContext.dayTime is not actually the sizeof(s32) - memset(&gSaveContext.dayTime, 0, sizeof(s32)); - memset(&gSaveContext.nightFlag, 0, sizeof(s32)); - memset(&gSaveContext.totalDays, 0, sizeof(s32)); - memset(&gSaveContext.bgsDayCount, 0, sizeof(s32)); - - if (!slotNum && CVar_GetS32("gDebugEnabled", 0)) { - Sram_InitDebugSave(); - gSaveContext.newf[0] = 'Z'; - gSaveContext.newf[1] = 'E'; - gSaveContext.newf[2] = 'L'; - gSaveContext.newf[3] = 'D'; - gSaveContext.newf[4] = 'A'; - gSaveContext.newf[5] = 'Z'; - osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], - gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], - gSaveContext.newf[5]); - } else { - Sram_InitNewSave(); - } - - ptr = (u16*)&gSaveContext; - osSyncPrintf("\n--------------------------------------------------------------\n"); - - for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++) { - osSyncPrintf("%x ", *ptr); - if (++j == 0x20) { - osSyncPrintf("\n"); - j = 0; - } - newChecksum += *ptr++; - } - - gSaveContext.checksum = newChecksum; - osSyncPrintf("\nCheck_Sum=%x(%x)\n", gSaveContext.checksum, newChecksum); - - i = gSramSlotOffsets[slotNum + 3]; - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE); - - osSyncPrintf("????#%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], - gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]); - osSyncPrintf("\nぽいんと=%x(%d+3) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum, - newChecksum); - } - - i = gSramSlotOffsets[slotNum]; - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE); - - osSyncPrintf("ぽいんと=%x(%d) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum, newChecksum); - } else { - osSyncPrintf("\nSAVEデータ OK!!!!\n"); // "SAVE data OK! ! ! !" - } - } - - memset(sramCtx->readBuff,0, SRAM_SIZE); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); - gSaveContext.dayTime = dayTime; - - osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, 64DD=%x, HEART=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD, - DEFENSE); - - memcpy(&fileChooseCtx->deaths[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEATHS, sizeof(fileChooseCtx->deaths[0])); - memcpy(&fileChooseCtx->deaths[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEATHS, sizeof(fileChooseCtx->deaths[0])); - memcpy(&fileChooseCtx->deaths[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEATHS, sizeof(fileChooseCtx->deaths[0])); - - memcpy(&fileChooseCtx->fileNames[0], sramCtx->readBuff + SLOT_OFFSET(0) + NAME, - sizeof(fileChooseCtx->fileNames[0])); - memcpy(&fileChooseCtx->fileNames[1], sramCtx->readBuff + SLOT_OFFSET(1) + NAME, - sizeof(fileChooseCtx->fileNames[0])); - memcpy(&fileChooseCtx->fileNames[2], sramCtx->readBuff + SLOT_OFFSET(2) + NAME, - sizeof(fileChooseCtx->fileNames[0])); - - memcpy(&fileChooseCtx->healthCapacities[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH_CAP, - sizeof(fileChooseCtx->healthCapacities[0])); - memcpy(&fileChooseCtx->healthCapacities[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH_CAP, - sizeof(fileChooseCtx->healthCapacities[0])); - memcpy(&fileChooseCtx->healthCapacities[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH_CAP, - sizeof(fileChooseCtx->healthCapacities[0])); - - memcpy(&fileChooseCtx->questItems[0], sramCtx->readBuff + SLOT_OFFSET(0) + QUEST, - sizeof(fileChooseCtx->questItems[0])); - memcpy(&fileChooseCtx->questItems[1], sramCtx->readBuff + SLOT_OFFSET(1) + QUEST, - sizeof(fileChooseCtx->questItems[0])); - memcpy(&fileChooseCtx->questItems[2], sramCtx->readBuff + SLOT_OFFSET(2) + QUEST, - sizeof(fileChooseCtx->questItems[0])); - - memcpy(&fileChooseCtx->n64ddFlags[0], sramCtx->readBuff + SLOT_OFFSET(0) + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - memcpy(&fileChooseCtx->n64ddFlags[1], sramCtx->readBuff + SLOT_OFFSET(1) + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - memcpy(&fileChooseCtx->n64ddFlags[2], sramCtx->readBuff + SLOT_OFFSET(2) + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - - memcpy(&fileChooseCtx->defense[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEFENSE, - sizeof(fileChooseCtx->defense[0])); - memcpy(&fileChooseCtx->defense[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEFENSE, - sizeof(fileChooseCtx->defense[0])); - memcpy(&fileChooseCtx->defense[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEFENSE, - sizeof(fileChooseCtx->defense[0])); - - memcpy(&fileChooseCtx->health[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH, sizeof(fileChooseCtx->health[0])); - memcpy(&fileChooseCtx->health[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH, sizeof(fileChooseCtx->health[0])); - memcpy(&fileChooseCtx->health[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH, sizeof(fileChooseCtx->health[0])); - - osSyncPrintf("f_64dd=%d, %d, %d\n", fileChooseCtx->n64ddFlags[0], fileChooseCtx->n64ddFlags[1], - fileChooseCtx->n64ddFlags[2]); - osSyncPrintf("heart_status=%d, %d, %d\n", fileChooseCtx->defense[0], fileChooseCtx->defense[1], - fileChooseCtx->defense[2]); - osSyncPrintf("now_life=%d, %d, %d\n", fileChooseCtx->health[0], fileChooseCtx->health[1], fileChooseCtx->health[2]); -} - -void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { +void Sram_InitSave(FileChooseContext* fileChooseCtx) { u16 offset; u16 j; u16* ptr; @@ -693,189 +199,14 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { } for (offset = 0; offset < 8; offset++) { - gSaveContext.playerName[offset] = fileChooseCtx->fileNames[fileChooseCtx->buttonIndex][offset]; + gSaveContext.playerName[offset] = Save_GetSaveMetaInfo(fileChooseCtx->buttonIndex)->playerName[offset]; } - gSaveContext.newf[0] = 'Z'; - gSaveContext.newf[1] = 'E'; - gSaveContext.newf[2] = 'L'; - gSaveContext.newf[3] = 'D'; - gSaveContext.newf[4] = 'A'; - gSaveContext.newf[5] = 'Z'; - - gSaveContext.n64ddFlag = fileChooseCtx->n64ddFlag; - osSyncPrintf("64DDフラグ=%d\n", fileChooseCtx->n64ddFlag); - osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], gSaveContext.newf[2], - gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]); - osSyncPrintf("\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); - - ptr = (u16*)&gSaveContext; - j = 0; - checksum = 0; - - for (offset = 0; offset < CHECKSUM_SIZE; offset++) { - osSyncPrintf("%x ", *ptr); - checksum += *ptr++; - if (++j == 0x20) { - osSyncPrintf("\n"); - j = 0; - } - } - - gSaveContext.checksum = checksum; - osSyncPrintf("\nチェックサム=%x\n", gSaveContext.checksum); // "Checksum = %x" - - offset = gSramSlotOffsets[gSaveContext.fileNum]; - osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum); - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); - - offset = gSramSlotOffsets[gSaveContext.fileNum + 3]; - osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum + 3); - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); - - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); - - osSyncPrintf("SAVE終了\n"); // "SAVE end" - osSyncPrintf("z_common_data.file_no = %d\n", gSaveContext.fileNum); - osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, SAVE_64DD=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD); - - j = gSramSlotOffsets[gSaveContext.fileNum]; - - memcpy(&fileChooseCtx->deaths[gSaveContext.fileNum], sramCtx->readBuff + j + DEATHS, - sizeof(fileChooseCtx->deaths[0])); - memcpy(&fileChooseCtx->fileNames[gSaveContext.fileNum], sramCtx->readBuff + j + NAME, - sizeof(fileChooseCtx->fileNames[0])); - memcpy(&fileChooseCtx->healthCapacities[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH_CAP, - sizeof(fileChooseCtx->healthCapacities[0])); - memcpy(&fileChooseCtx->questItems[gSaveContext.fileNum], sramCtx->readBuff + j + QUEST, - sizeof(fileChooseCtx->questItems[0])); - memcpy(&fileChooseCtx->n64ddFlags[gSaveContext.fileNum], sramCtx->readBuff + j + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - memcpy(&fileChooseCtx->defense[gSaveContext.fileNum], sramCtx->readBuff + j + DEFENSE, - sizeof(fileChooseCtx->defense[0])); - memcpy(&fileChooseCtx->health[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH, - sizeof(fileChooseCtx->health[0])); - - osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]); - osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]); - osSyncPrintf("now_life[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->health[gSaveContext.fileNum]); + Save_SaveFile(); } -void Sram_EraseSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { - s32 offset; - - Sram_InitNewSave(); - - offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex]; - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); - - memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->selectedFileIndex], sramCtx->readBuff + offset + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - - offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex + 3]; - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE); - - osSyncPrintf("CLEAR終了\n"); -} - -void Sram_CopySave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { - s32 offset; - - osSyncPrintf("READ=%d(%x) COPY=%d(%x)\n", fileChooseCtx->selectedFileIndex, - gSramSlotOffsets[fileChooseCtx->selectedFileIndex], fileChooseCtx->copyDestFileIndex, - gSramSlotOffsets[fileChooseCtx->copyDestFileIndex]); - - offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex]; - memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save)); - - offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex]; - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); - - offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex + 3]; - memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save)); +void Sram_InitSram(GameState* gameState) { + Save_Init(); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); - - offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex]; - - memcpy(&fileChooseCtx->deaths[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEATHS, - sizeof(fileChooseCtx->deaths[0])); - memcpy(&fileChooseCtx->fileNames[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + NAME, - sizeof(fileChooseCtx->fileNames[0])); - memcpy(&fileChooseCtx->healthCapacities[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + HEALTH_CAP, - sizeof(fileChooseCtx->healthCapacities[0])); - memcpy(&fileChooseCtx->questItems[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + QUEST, - sizeof(fileChooseCtx->questItems[0])); - memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + N64DD, - sizeof(fileChooseCtx->n64ddFlags[0])); - memcpy(&fileChooseCtx->defense[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEFENSE, - sizeof(fileChooseCtx->defense[0])); - memcpy(&fileChooseCtx->health[fileChooseCtx->copyDestFileIndex], (sramCtx->readBuff + offset) + HEALTH, - sizeof(fileChooseCtx->health[0])); - - osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]); - osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]); - osSyncPrintf("COPY終了\n"); // "Copy end" -} - -/** - * Write the first 16 bytes of the read buffer to the SRAM header - */ -void Sram_WriteSramHeader(SramContext* sramCtx) { - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_HEADER_SIZE, OS_WRITE); -} - -void Sram_InitSram(GameState* gameState, SramContext* sramCtx) { - u16 i; - - osSyncPrintf("sram_initialize( Game *game, Sram *sram )\n"); - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); - - for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) { - if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) { - osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !" - gSaveContext.language = CVar_GetS32("gLanguages", 0); - memcpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic)); - sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language; - Sram_WriteSramHeader(sramCtx); - } - } - - gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3; - gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1; - gSaveContext.language = CVar_GetS32("gLanguages", 0); - - if (gSaveContext.language >= LANGUAGE_MAX) { - gSaveContext.language = LANGUAGE_ENG; - sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language; - Sram_WriteSramHeader(sramCtx); - } - - if (CHECK_BTN_ANY(gameState->input[2].cur.button, BTN_DRIGHT)) { - memset(sramCtx->readBuff, 0,SRAM_SIZE); - for (i = 0; i < CHECKSUM_SIZE; i++) { - sramCtx->readBuff[i] = i; - } - SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE); - osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !" - } - - // "GOOD! GOOD! Size = %d + %d = %d" - osSyncPrintf("GOOD!GOOD! サイズ=%d + %d = %d\n", sizeof(SaveInfo), 4, sizeof(SaveInfo) + 4); - osSyncPrintf(VT_FGCOL(BLUE)); - osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); - osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); - osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting); - osSyncPrintf(VT_RST); func_800F6700(gSaveContext.audioSetting); } - -void Sram_Alloc(GameState* gameState, SramContext* sramCtx) { - sramCtx->readBuff = GameState_Alloc(gameState, SRAM_SIZE, "../z_sram.c", 1294); - ASSERT(sramCtx->readBuff != NULL, "sram->read_buff != NULL", "../z_sram.c", 1295); -} - -void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx) { -} diff --git a/soh/src/code/z_ss_sram.c b/soh/src/code/z_ss_sram.c index 6b4ea50ca..8be84e07b 100644 --- a/soh/src/code/z_ss_sram.c +++ b/soh/src/code/z_ss_sram.c @@ -58,38 +58,13 @@ void SsSram_Dma(void* dramAddr, size_t size, s32 direction) { void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction) { osSyncPrintf("ssSRAMReadWrite:%08x %08x %08x %d\n", addr, (uintptr_t)dramAddr, size, direction); - //Check to see if the file exists - FILE* saveFile; - saveFile = fopen("oot_save.sav", "rb"); - - if (saveFile == NULL) { - - saveFile = fopen("oot_save.sav", "wb"); - fseek(saveFile, 0, SEEK_SET); - assert(saveFile != NULL); // OTRTODO LOG - uint8_t zero = 0; - - for (uint32_t i = 0; i < SRAM_SIZE; i++) { - fwrite(&zero, 1, 1, saveFile); - } - fclose(saveFile); - } else { - fclose(saveFile); - } + switch (direction) { case OS_WRITE: { - saveFile = fopen("oot_save.sav", "r+b"); - rewind(saveFile); - fseek(saveFile, addr, SEEK_SET); - fwrite(dramAddr, size, 1, saveFile); - fclose(saveFile); + Ctx_WriteSaveFile(addr, dramAddr, size); } break; case OS_READ: { - saveFile = fopen("oot_save.sav", "rb+"); - rewind(saveFile); - fseek(saveFile, addr, SEEK_SET); - fread(dramAddr, size, 1, saveFile); - fclose(saveFile); + Ctx_ReadSaveFile(addr, dramAddr, size); } break; } //SsSram_Init(addr, DEVICE_TYPE_SRAM, PI_DOMAIN2, 5, 0xD, 2, 0xC, 0); |
