merge master

This commit is contained in:
engineer124
2022-09-25 18:48:20 -04:00
492 changed files with 10840 additions and 3992 deletions
+7 -7
View File
@@ -63,7 +63,7 @@ void AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer) {
}
seqPlayer->fadeTimer--;
if (seqPlayer->fadeTimer == 0 && seqPlayer->state == 2) {
if ((seqPlayer->fadeTimer == 0) && (seqPlayer->state == SEQPLAYER_STATE_2)) {
AudioSeq_SequencePlayerDisable(seqPlayer);
return;
}
@@ -243,12 +243,10 @@ f32 AudioEffects_AdsrUpdate(AdsrState* adsr) {
break;
}
// fallthrough
case ADSR_STATE_START_LOOP:
adsr->envIndex = 0;
adsr->action.s.state = ADSR_STATE_LOOP;
// fallthrough
retry:
case ADSR_STATE_LOOP:
adsr->delay = adsr->envelope[adsr->envIndex].delay;
@@ -256,18 +254,21 @@ f32 AudioEffects_AdsrUpdate(AdsrState* adsr) {
case ADSR_DISABLE:
adsr->action.s.state = ADSR_STATE_DISABLED;
break;
case ADSR_HANG:
adsr->action.s.state = ADSR_STATE_HANG;
break;
case ADSR_GOTO:
adsr->envIndex = adsr->envelope[adsr->envIndex].arg;
goto retry;
case ADSR_RESTART:
adsr->action.s.state = ADSR_STATE_INITIAL;
break;
default:
adsr->delay *= gAudioContext.audioBufferParameters.unk_24;
adsr->delay *= gAudioContext.audioBufferParameters.updatesPerFrameScaled;
if (adsr->delay == 0) {
adsr->delay = 1;
}
@@ -282,14 +283,13 @@ f32 AudioEffects_AdsrUpdate(AdsrState* adsr) {
break;
}
// fallthrough
case ADSR_STATE_FADE:
adsr->current += adsr->velocity;
if (--adsr->delay <= 0) {
adsr->delay--;
if (adsr->delay <= 0) {
adsr->action.s.state = ADSR_STATE_LOOP;
}
// fallthrough
case ADSR_STATE_HANG:
break;
+117 -112
View File
@@ -4,7 +4,7 @@ void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id);
void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize);
SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size);
void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry);
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample);
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, Sample* sample);
SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size);
void AudioHeap_DiscardSampleCaches(void);
void AudioHeap_DiscardSampleBank(s32 sampleBankId);
@@ -14,29 +14,37 @@ void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags);
#define gTatumsPerBeat (gAudioTatumInit[1])
f32 func_8018B0F0(f32 arg0) {
return 256.0f * gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled / arg0;
/**
* Effectively scales `updatesPerFrameInv` by the reciprocal of `scaleInv`
* `updatesPerFrameInvScaled` is just `updatesPerFrameInv` scaled down by a factor of 256.0f
* i.e. (256.0f * `updatesPerFrameInvScaled`) is just `updatesPerFrameInv`
*/
f32 AudioHeap_CalculateAdsrDecay(f32 scaleInv) {
return 256.0f * gAudioContext.audioBufferParameters.updatesPerFrameInvScaled / scaleInv;
}
void func_8018B10C(void) {
/**
* Initialize the decay rate table used for decaying notes as part of adsr
*/
void AudioHeap_InitAdsrDecayTable(void) {
s32 i;
gAudioContext.adsrDecayTable[255] = func_8018B0F0(0.25f);
gAudioContext.adsrDecayTable[254] = func_8018B0F0(0.33f);
gAudioContext.adsrDecayTable[253] = func_8018B0F0(0.5f);
gAudioContext.adsrDecayTable[252] = func_8018B0F0(0.66f);
gAudioContext.adsrDecayTable[251] = func_8018B0F0(0.75f);
gAudioContext.adsrDecayTable[255] = AudioHeap_CalculateAdsrDecay(0.25f);
gAudioContext.adsrDecayTable[254] = AudioHeap_CalculateAdsrDecay(0.33f);
gAudioContext.adsrDecayTable[253] = AudioHeap_CalculateAdsrDecay(0.5f);
gAudioContext.adsrDecayTable[252] = AudioHeap_CalculateAdsrDecay(0.66f);
gAudioContext.adsrDecayTable[251] = AudioHeap_CalculateAdsrDecay(0.75f);
for (i = 128; i < 251; i++) {
gAudioContext.adsrDecayTable[i] = func_8018B0F0(251 - i);
gAudioContext.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(251 - i);
}
for (i = 16; i < 128; i++) {
gAudioContext.adsrDecayTable[i] = func_8018B0F0(4 * (143 - i));
gAudioContext.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(4 * (143 - i));
}
for (i = 1; i < 16; i++) {
gAudioContext.adsrDecayTable[i] = func_8018B0F0(60 * (23 - i));
gAudioContext.adsrDecayTable[i] = AudioHeap_CalculateAdsrDecay(60 * (23 - i));
}
gAudioContext.adsrDecayTable[0] = 0.0f;
@@ -71,7 +79,7 @@ void AudioHeap_DiscardFont(s32 fontId) {
Note* note = &gAudioContext.notes[i];
if (note->playbackState.fontId == fontId) {
if ((note->playbackState.unk_04 == 0) && (note->playbackState.priority != 0)) {
if ((note->playbackState.status == PLAYBACK_STATUS_0) && (note->playbackState.priority != 0)) {
note->playbackState.parentLayer->enabled = false;
note->playbackState.parentLayer->finished = true;
}
@@ -233,19 +241,19 @@ void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size) {
* Initialize a pool at the requested address with the requested size.
* Store the metadata of this pool in AudioAllocPool* pool
*/
void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* addr, size_t size) {
void AudioHeap_InitPool(AudioAllocPool* pool, void* addr, size_t size) {
pool->curAddr = pool->startAddr = (u8*)ALIGN16((uintptr_t)addr);
pool->size = size - ((uintptr_t)addr & 0xF);
pool->count = 0;
}
void AudioHeap_ClearPersistentCache(AudioPersistentCache* persistent) {
void AudioHeap_InitPersistentCache(AudioPersistentCache* persistent) {
persistent->pool.count = 0;
persistent->numEntries = 0;
persistent->pool.curAddr = persistent->pool.startAddr;
}
void AudioHeap_ClearTemporaryCache(AudioTemporaryCache* temporary) {
void AudioHeap_InitTemporaryCache(AudioTemporaryCache* temporary) {
temporary->pool.count = 0;
temporary->pool.curAddr = temporary->pool.startAddr;
temporary->nextSide = 0;
@@ -260,7 +268,7 @@ void AudioHeap_ResetPool(AudioAllocPool* pool) {
pool->curAddr = pool->startAddr;
}
void AudioHeap_PopCache(s32 tableType) {
void AudioHeap_PopPersistentCache(s32 tableType) {
AudioCache* loadedCache;
AudioAllocPool* persistentHeap;
AudioPersistentCache* persistent;
@@ -306,69 +314,65 @@ void AudioHeap_PopCache(s32 tableType) {
persistent->numEntries--;
}
void AudioHeap_InitMainPool(size_t mainPoolSplitSize) {
AudioHeap_AllocPoolInit(&gAudioContext.audioInitPool, gAudioContext.audioHeap, mainPoolSplitSize);
AudioHeap_AllocPoolInit(&gAudioContext.audioSessionPool, gAudioContext.audioHeap + mainPoolSplitSize,
gAudioContext.audioHeapSize - mainPoolSplitSize);
void AudioHeap_InitMainPool(size_t initPoolSize) {
AudioHeap_InitPool(&gAudioContext.initPool, gAudioContext.audioHeap, initPoolSize);
AudioHeap_InitPool(&gAudioContext.sessionPool, gAudioContext.audioHeap + initPoolSize,
gAudioContext.audioHeapSize - initPoolSize);
gAudioContext.externalPool.startAddr = NULL;
}
void AudioHeap_InitSessionPool(AudioSessionPoolSplit* split) {
gAudioContext.audioSessionPool.curAddr = gAudioContext.audioSessionPool.startAddr;
gAudioContext.sessionPool.curAddr = gAudioContext.sessionPool.startAddr;
AudioHeap_AllocPoolInit(&gAudioContext.miscPool,
AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->miscPoolSize), split->miscPoolSize);
AudioHeap_AllocPoolInit(&gAudioContext.cachePool,
AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->cachePoolSize),
split->cachePoolSize);
AudioHeap_InitPool(&gAudioContext.miscPool, AudioHeap_Alloc(&gAudioContext.sessionPool, split->miscPoolSize),
split->miscPoolSize);
AudioHeap_InitPool(&gAudioContext.cachePool, AudioHeap_Alloc(&gAudioContext.sessionPool, split->cachePoolSize),
split->cachePoolSize);
}
void AudioHeap_InitCachePool(AudioCachePoolSplit* split) {
gAudioContext.cachePool.curAddr = gAudioContext.cachePool.startAddr;
AudioHeap_AllocPoolInit(&gAudioContext.persistentCommonPool,
AudioHeap_Alloc(&gAudioContext.cachePool, split->persistentCommonPoolSize),
split->persistentCommonPoolSize);
AudioHeap_AllocPoolInit(&gAudioContext.temporaryCommonPool,
AudioHeap_Alloc(&gAudioContext.cachePool, split->temporaryCommonPoolSize),
split->temporaryCommonPoolSize);
AudioHeap_InitPool(&gAudioContext.persistentCommonPool,
AudioHeap_Alloc(&gAudioContext.cachePool, split->persistentCommonPoolSize),
split->persistentCommonPoolSize);
AudioHeap_InitPool(&gAudioContext.temporaryCommonPool,
AudioHeap_Alloc(&gAudioContext.cachePool, split->temporaryCommonPoolSize),
split->temporaryCommonPoolSize);
}
void AudioHeap_InitPersistentCache(AudioCommonPoolSplit* split) {
void AudioHeap_InitPersistentPoolsAndCaches(AudioCommonPoolSplit* split) {
gAudioContext.persistentCommonPool.curAddr = gAudioContext.persistentCommonPool.startAddr;
AudioHeap_AllocPoolInit(&gAudioContext.seqCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->seqCacheSize),
split->seqCacheSize);
AudioHeap_AllocPoolInit(&gAudioContext.fontCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->fontCacheSize),
split->fontCacheSize);
AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_InitPool(&gAudioContext.seqCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->seqCacheSize), split->seqCacheSize);
AudioHeap_InitPool(&gAudioContext.fontCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->fontCacheSize),
split->fontCacheSize);
AudioHeap_InitPool(&gAudioContext.sampleBankCache.persistent.pool,
AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_ClearPersistentCache(&gAudioContext.seqCache.persistent);
AudioHeap_ClearPersistentCache(&gAudioContext.fontCache.persistent);
AudioHeap_ClearPersistentCache(&gAudioContext.sampleBankCache.persistent);
AudioHeap_InitPersistentCache(&gAudioContext.seqCache.persistent);
AudioHeap_InitPersistentCache(&gAudioContext.fontCache.persistent);
AudioHeap_InitPersistentCache(&gAudioContext.sampleBankCache.persistent);
}
void AudioHeap_InitTemporaryCache(AudioCommonPoolSplit* split) {
void AudioHeap_InitTemporaryPoolsAndCaches(AudioCommonPoolSplit* split) {
gAudioContext.temporaryCommonPool.curAddr = gAudioContext.temporaryCommonPool.startAddr;
AudioHeap_AllocPoolInit(&gAudioContext.seqCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->seqCacheSize),
split->seqCacheSize);
AudioHeap_AllocPoolInit(&gAudioContext.fontCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->fontCacheSize),
split->fontCacheSize);
AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_InitPool(&gAudioContext.seqCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->seqCacheSize), split->seqCacheSize);
AudioHeap_InitPool(&gAudioContext.fontCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->fontCacheSize), split->fontCacheSize);
AudioHeap_InitPool(&gAudioContext.sampleBankCache.temporary.pool,
AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->sampleBankCacheSize),
split->sampleBankCacheSize);
AudioHeap_ClearTemporaryCache(&gAudioContext.seqCache.temporary);
AudioHeap_ClearTemporaryCache(&gAudioContext.fontCache.temporary);
AudioHeap_ClearTemporaryCache(&gAudioContext.sampleBankCache.temporary);
AudioHeap_InitTemporaryCache(&gAudioContext.seqCache.temporary);
AudioHeap_InitTemporaryCache(&gAudioContext.fontCache.temporary);
AudioHeap_InitTemporaryCache(&gAudioContext.sampleBankCache.temporary);
}
void* AudioHeap_AllocCached(s32 tableType, size_t size, s32 cache, s32 id) {
@@ -764,7 +768,7 @@ void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff) {
s32 cutOff;
//! @bug filter is never set if (lowPassCutoff == highPassCutoff) and does not equal 0
if (lowPassCutoff == 0 && highPassCutoff == 0) {
if ((lowPassCutoff == 0) && (highPassCutoff == 0)) {
// Identity filter
AudioHeap_LoadLowPassFilter(filter, 0);
} else if (highPassCutoff == 0) {
@@ -830,13 +834,13 @@ void AudioHeap_UpdateReverbs(void) {
* Clear the Audio Interface Buffers
*/
void AudioHeap_ClearAiBuffers(void) {
s32 curAiBuffferIndex = gAudioContext.curAiBuffferIndex;
s32 curAiBufferIndex = gAudioContext.curAiBufferIndex;
s32 i;
gAudioContext.aiBufLengths[curAiBuffferIndex] = gAudioContext.audioBufferParameters.minAiBufferLength;
gAudioContext.aiBufNumSamples[curAiBufferIndex] = gAudioContext.audioBufferParameters.minAiBufNumSamples;
for (i = 0; i < AIBUF_LEN; i++) {
gAudioContext.aiBuffers[curAiBuffferIndex][i] = 0;
gAudioContext.aiBuffers[curAiBufferIndex][i] = 0;
}
}
@@ -902,8 +906,8 @@ s32 AudioHeap_ResetStep(void) {
case 1:
AudioHeap_Init();
gAudioContext.resetStatus = 0;
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) {
gAudioContext.aiBufLengths[i] = gAudioContext.audioBufferParameters.maxAiBufferLength;
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufNumSamples); i++) {
gAudioContext.aiBufNumSamples[i] = gAudioContext.audioBufferParameters.maxAiBufNumSamples;
for (j = 0; j < AIBUF_LEN; j++) {
gAudioContext.aiBuffers[i][j] = 0;
}
@@ -940,9 +944,9 @@ void AudioHeap_Init(void) {
gAudioContext.audioBufferParameters.samplesPerFrameTarget =
ALIGN16(gAudioContext.audioBufferParameters.samplingFreq / gAudioContext.refreshRate);
gAudioContext.audioBufferParameters.minAiBufferLength =
gAudioContext.audioBufferParameters.minAiBufNumSamples =
gAudioContext.audioBufferParameters.samplesPerFrameTarget - 0x10;
gAudioContext.audioBufferParameters.maxAiBufferLength =
gAudioContext.audioBufferParameters.maxAiBufNumSamples =
gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10;
gAudioContext.audioBufferParameters.updatesPerFrame =
((gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1;
@@ -952,9 +956,10 @@ void AudioHeap_Init(void) {
gAudioContext.audioBufferParameters.samplesPerUpdateMax = gAudioContext.audioBufferParameters.samplesPerUpdate + 8;
gAudioContext.audioBufferParameters.samplesPerUpdateMin = gAudioContext.audioBufferParameters.samplesPerUpdate - 8;
gAudioContext.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioContext.audioBufferParameters.samplingFreq;
gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled =
gAudioContext.audioBufferParameters.updatesPerFrameInvScaled =
(1.0f / 256.0f) / gAudioContext.audioBufferParameters.updatesPerFrame;
gAudioContext.audioBufferParameters.unk_24 = gAudioContext.audioBufferParameters.updatesPerFrame * 0.25f;
gAudioContext.audioBufferParameters.updatesPerFrameScaled =
gAudioContext.audioBufferParameters.updatesPerFrame / 4.0f;
gAudioContext.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioContext.audioBufferParameters.updatesPerFrame;
// sample dma size
@@ -980,12 +985,12 @@ void AudioHeap_Init(void) {
gAudioContext.audioBufferParameters.specUnk4 = spec->unk_04;
gAudioContext.audioBufferParameters.samplesPerFrameTarget *= gAudioContext.audioBufferParameters.specUnk4;
gAudioContext.audioBufferParameters.maxAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4;
gAudioContext.audioBufferParameters.minAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4;
gAudioContext.audioBufferParameters.maxAiBufNumSamples *= gAudioContext.audioBufferParameters.specUnk4;
gAudioContext.audioBufferParameters.minAiBufNumSamples *= gAudioContext.audioBufferParameters.specUnk4;
gAudioContext.audioBufferParameters.updatesPerFrame *= gAudioContext.audioBufferParameters.specUnk4;
if (gAudioContext.audioBufferParameters.specUnk4 >= 2) {
gAudioContext.audioBufferParameters.maxAiBufferLength -= 0x10;
gAudioContext.audioBufferParameters.maxAiBufNumSamples -= 0x10;
}
// Determine the maximum allowable number of audio command list entries for the rsp microcode
@@ -998,7 +1003,7 @@ void AudioHeap_Init(void) {
temporarySize =
spec->temporarySeqCacheSize + spec->temporaryFontCacheSize + spec->temporarySampleBankCacheSize + 0x10;
cachePoolSize = persistentSize + temporarySize;
miscPoolSize = gAudioContext.audioSessionPool.size - cachePoolSize - 0x100;
miscPoolSize = gAudioContext.sessionPool.size - cachePoolSize - 0x100;
if (gAudioContext.externalPool.startAddr != NULL) {
gAudioContext.externalPool.curAddr = gAudioContext.externalPool.startAddr;
@@ -1018,13 +1023,13 @@ void AudioHeap_Init(void) {
gAudioContext.persistentCommonPoolSplit.seqCacheSize = spec->persistentSeqCacheSize;
gAudioContext.persistentCommonPoolSplit.fontCacheSize = spec->persistentFontCacheSize;
gAudioContext.persistentCommonPoolSplit.sampleBankCacheSize = spec->persistentSampleBankCacheSize;
AudioHeap_InitPersistentCache(&gAudioContext.persistentCommonPoolSplit);
AudioHeap_InitPersistentPoolsAndCaches(&gAudioContext.persistentCommonPoolSplit);
// Temporary Pool Split (Split into Sequences, SoundFonts, Samples)
gAudioContext.temporaryCommonPoolSplit.seqCacheSize = spec->temporarySeqCacheSize;
gAudioContext.temporaryCommonPoolSplit.fontCacheSize = spec->temporaryFontCacheSize;
gAudioContext.temporaryCommonPoolSplit.sampleBankCacheSize = spec->temporarySampleBankCacheSize;
AudioHeap_InitTemporaryCache(&gAudioContext.temporaryCommonPoolSplit);
AudioHeap_InitTemporaryPoolsAndCaches(&gAudioContext.temporaryCommonPoolSplit);
AudioHeap_ResetLoadStatus();
@@ -1039,12 +1044,12 @@ void AudioHeap_Init(void) {
// Initialize audio binary interface command list buffer
for (j = 0; j < ARRAY_COUNT(gAudioContext.abiCmdBufs); j++) {
gAudioContext.abiCmdBufs[j] =
AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, gAudioContext.maxAudioCmds * sizeof(u64));
AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, gAudioContext.maxAudioCmds * sizeof(Acmd));
}
// Initialize adsrDecayTable (fadeOutVelocities for ADSR)
// Initialize the decay rate table for ADSR
gAudioContext.adsrDecayTable = AudioHeap_Alloc(&gAudioContext.miscPool, 0x100 * sizeof(f32));
func_8018B10C();
AudioHeap_InitAdsrDecayTable();
// Initialize reverbs
for (i = 0; i < ARRAY_COUNT(gAudioContext.synthesisReverbs); i++) {
@@ -1139,14 +1144,14 @@ void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t tempora
if (addr == NULL) {
gAudioContext.persistentSampleCache.pool.size = 0;
} else {
AudioHeap_AllocPoolInit(&gAudioContext.persistentSampleCache.pool, addr, persistentSampleCacheSize);
AudioHeap_InitPool(&gAudioContext.persistentSampleCache.pool, addr, persistentSampleCacheSize);
}
addr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, temporarySampleCacheSize);
if (addr == NULL) {
gAudioContext.temporarySampleCache.pool.size = 0;
} else {
AudioHeap_AllocPoolInit(&gAudioContext.temporarySampleCache.pool, addr, temporarySampleCacheSize);
AudioHeap_InitPool(&gAudioContext.temporarySampleCache.pool, addr, temporarySampleCacheSize);
}
gAudioContext.persistentSampleCache.numEntries = 0;
@@ -1257,35 +1262,35 @@ SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size) {
void AudioHeap_UnapplySampleCacheForFont(SampleCacheEntry* entry, s32 fontId) {
Drum* drum;
Instrument* inst;
SoundFontSound* sfx;
SoundEffect* soundEffect;
s32 instId;
s32 drumId;
s32 sfxId;
for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) {
for (instId = 0; instId < gAudioContext.soundFontList[fontId].numInstruments; instId++) {
inst = AudioPlayback_GetInstrumentInner(fontId, instId);
if (inst != NULL) {
if (inst->normalRangeLo != 0) {
AudioHeap_UnapplySampleCache(entry, inst->lowNotesSound.sample);
AudioHeap_UnapplySampleCache(entry, inst->lowPitchTunedSample.sample);
}
if (inst->normalRangeHi != 0x7F) {
AudioHeap_UnapplySampleCache(entry, inst->highNotesSound.sample);
AudioHeap_UnapplySampleCache(entry, inst->highPitchTunedSample.sample);
}
AudioHeap_UnapplySampleCache(entry, inst->normalNotesSound.sample);
AudioHeap_UnapplySampleCache(entry, inst->normalPitchTunedSample.sample);
}
}
for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) {
for (drumId = 0; drumId < gAudioContext.soundFontList[fontId].numDrums; drumId++) {
drum = AudioPlayback_GetDrum(fontId, drumId);
if (drum != NULL) {
AudioHeap_UnapplySampleCache(entry, drum->sound.sample);
AudioHeap_UnapplySampleCache(entry, drum->tunedSample.sample);
}
}
for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) {
sfx = AudioPlayback_GetSfx(fontId, sfxId);
if (sfx != NULL) {
AudioHeap_UnapplySampleCache(entry, sfx->sample);
for (sfxId = 0; sfxId < gAudioContext.soundFontList[fontId].numSfx; sfxId++) {
soundEffect = AudioPlayback_GetSoundEffect(fontId, sfxId);
if (soundEffect != NULL) {
AudioHeap_UnapplySampleCache(entry, soundEffect->tunedSample.sample);
}
}
}
@@ -1298,8 +1303,8 @@ void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) {
numFonts = gAudioContext.soundFontTable->numEntries;
for (fontId = 0; fontId < numFonts; fontId++) {
sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
sampleBankId1 = gAudioContext.soundFontList[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFontList[fontId].sampleBankId2;
if (((sampleBankId1 != 0xFF) && (entry->sampleBankId == sampleBankId1)) ||
((sampleBankId2 != 0xFF) && (entry->sampleBankId == sampleBankId2)) || entry->sampleBankId == 0 ||
entry->sampleBankId == 0xFE) {
@@ -1313,7 +1318,7 @@ void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) {
}
}
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) {
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, Sample* sample) {
if (sample != NULL) {
if (sample->sampleAddr == entry->allocatedAddr) {
sample->sampleAddr = entry->sampleAddr;
@@ -1362,8 +1367,8 @@ void AudioHeap_DiscardSampleCaches(void) {
numFonts = gAudioContext.soundFontTable->numEntries;
for (fontId = 0; fontId < numFonts; fontId++) {
sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
sampleBankId1 = gAudioContext.soundFontList[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFontList[fontId].sampleBankId2;
if ((sampleBankId1 == 0xFF) && (sampleBankId2 == 0xFF)) {
continue;
}
@@ -1390,7 +1395,7 @@ typedef struct {
u8 newMedium;
} StorageChange;
void AudioHeap_ChangeStorage(StorageChange* change, SoundFontSample* sample) {
void AudioHeap_ChangeStorage(StorageChange* change, Sample* sample) {
if (sample != NULL && ((sample->medium == change->newMedium) || (D_801FD120 != 1)) &&
((sample->medium == MEDIUM_RAM) || (D_801FD120 != 0))) {
uintptr_t startAddr = change->oldAddr;
@@ -1430,7 +1435,7 @@ void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) {
s32 fontId;
Drum* drum;
Instrument* inst;
SoundFontSound* sfx;
SoundEffect* soundEffect;
uintptr_t* newAddr;
s32 pad[4];
@@ -1457,8 +1462,8 @@ void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) {
}
for (fontId = 0; fontId < numFonts; fontId++) {
sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
sampleBankId1 = gAudioContext.soundFontList[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFontList[fontId].sampleBankId2;
if ((sampleBankId1 != 0xFF) || (sampleBankId2 != 0xFF)) {
if (!AudioLoad_IsFontLoadComplete(fontId) ||
AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) == NULL) {
@@ -1471,30 +1476,30 @@ void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) {
continue;
}
for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) {
for (instId = 0; instId < gAudioContext.soundFontList[fontId].numInstruments; instId++) {
inst = AudioPlayback_GetInstrumentInner(fontId, instId);
if (inst != NULL) {
if (inst->normalRangeLo != 0) {
AudioHeap_ChangeStorage(&change, inst->lowNotesSound.sample);
AudioHeap_ChangeStorage(&change, inst->lowPitchTunedSample.sample);
}
if (inst->normalRangeHi != 0x7F) {
AudioHeap_ChangeStorage(&change, inst->highNotesSound.sample);
AudioHeap_ChangeStorage(&change, inst->highPitchTunedSample.sample);
}
AudioHeap_ChangeStorage(&change, inst->normalNotesSound.sample);
AudioHeap_ChangeStorage(&change, inst->normalPitchTunedSample.sample);
}
}
for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) {
for (drumId = 0; drumId < gAudioContext.soundFontList[fontId].numDrums; drumId++) {
drum = AudioPlayback_GetDrum(fontId, drumId);
if (drum != NULL) {
AudioHeap_ChangeStorage(&change, drum->sound.sample);
AudioHeap_ChangeStorage(&change, drum->tunedSample.sample);
}
}
for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) {
sfx = AudioPlayback_GetSfx(fontId, sfxId);
if (sfx != NULL) {
AudioHeap_ChangeStorage(&change, sfx->sample);
for (sfxId = 0; sfxId < gAudioContext.soundFontList[fontId].numSfx; sfxId++) {
soundEffect = AudioPlayback_GetSoundEffect(fontId, sfxId);
if (soundEffect != NULL) {
AudioHeap_ChangeStorage(&change, soundEffect->tunedSample.sample);
}
}
}
@@ -1671,9 +1676,9 @@ void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags)
reverb->framesToIgnore = 2;
}
reverb->sound.sample = &reverb->sample;
reverb->tunedSample.sample = &reverb->sample;
reverb->sample.loop = &reverb->loop;
reverb->sound.tuning = 1.0f;
reverb->tunedSample.tuning = 1.0f;
reverb->sample.codec = CODEC_REVERB;
reverb->sample.medium = MEDIUM_RAM;
reverb->sample.size = reverb->windowSize * 2;
+2 -2
View File
@@ -5,8 +5,8 @@ const s16 gAudioTatumInit[] = {
0x30, // gTatumsPerBeat
};
const AudioContextInitSizes gAudioContextInitSizes = {
const AudioHeapInitSizes gAudioHeapInitSizes = {
0x137F00, // heapSize
0x1C480, // mainPoolSplitSize
0x1C480, // initPoolSize
0x1A000, // permanentPoolSize
};
+265 -184
View File
@@ -16,7 +16,7 @@
* SoundFont Notes:
*
*/
// opaque type for unpatched sound font data (should maybe get rid of this?)
// opaque type for soundfont data loaded into ram (should maybe get rid of this?)
typedef void SoundFontData;
typedef struct {
@@ -26,7 +26,7 @@ typedef struct {
/* 0x0C */ uintptr_t baseAddr2;
/* 0x10 */ u32 medium1;
/* 0x14 */ u32 medium2;
} AudioRelocInfo; // size = 0x18
} SampleBankRelocInfo; // size = 0x18
void AudioLoad_DiscardFont(s32 fontId);
s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIndex, s32 seqId, s32 arg2);
@@ -42,7 +42,7 @@ void AudioLoad_SyncDmaUnkMedium(uintptr_t devAddr, u8* addr, size_t size, s32 un
s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr, void* ramAddr, size_t size,
OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType);
void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue);
SoundFontSample* AudioLoad_GetFontSample(s32 fontId, s32 instId);
Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId);
void AudioLoad_ProcessSlowLoads(s32 resetStatus);
void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, size_t size);
void AudioLoad_DmaSlowCopyUnkMedium(intptr_t devAddr, intptr_t ramAddr, size_t size, s32 arg3);
@@ -56,8 +56,9 @@ void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus);
void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size);
void AudioLoad_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size);
void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t size, s16 arg3);
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* fontData, AudioRelocInfo* relocInfo);
void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, AudioRelocInfo* relocInfo, s32 async);
void AudioLoad_RelocateSample(TunedSample* tunedSample, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc);
void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc,
s32 isAsync);
s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus);
#define MK_ASYNC_MSG(retData, tableType, id, loadStatus) \
@@ -217,7 +218,7 @@ void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaI
dma->devAddr = dmaDevAddr;
dma->sizeUnused = transfer;
AudioLoad_Dma(&gAudioContext.currAudioFrameDmaIoMesgBuf[gAudioContext.curAudioFrameDmaCount++], OS_MESG_PRI_NORMAL,
OS_READ, dmaDevAddr, dma->ramAddr, transfer, &gAudioContext.currAudioFrameDmaQueue, medium,
OS_READ, dmaDevAddr, dma->ramAddr, transfer, &gAudioContext.curAudioFrameDmaQueue, medium,
"SUPERDMA");
*dmaIndexRef = dmaIndex;
return (devAddr - dmaDevAddr) + dma->ramAddr;
@@ -423,10 +424,10 @@ void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue* arg3
}
}
s32 AudioLoad_SyncLoadSample(SoundFontSample* sample, s32 fontId) {
s32 AudioLoad_SyncLoadSample(Sample* sample, s32 fontId) {
void* sampleAddr;
if (sample->unk_bit25 == true) {
if (sample->isRelocated == true) {
if (sample->medium != MEDIUM_RAM) {
sampleAddr = AudioHeap_AllocSampleCache(sample->size, fontId, (void*)sample->sampleAddr, sample->medium,
CACHE_PERSISTENT);
@@ -454,11 +455,11 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) {
return -1;
}
if (instrument->normalRangeLo != 0) {
AudioLoad_SyncLoadSample(instrument->lowNotesSound.sample, fontId);
AudioLoad_SyncLoadSample(instrument->lowPitchTunedSample.sample, fontId);
}
AudioLoad_SyncLoadSample(instrument->normalNotesSound.sample, fontId);
AudioLoad_SyncLoadSample(instrument->normalPitchTunedSample.sample, fontId);
if (instrument->normalRangeHi != 0x7F) {
return AudioLoad_SyncLoadSample(instrument->highNotesSound.sample, fontId);
return AudioLoad_SyncLoadSample(instrument->highPitchTunedSample.sample, fontId);
}
// TODO: is this missing return UB?
} else if (instId == 0x7F) {
@@ -467,7 +468,7 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) {
if (drum == NULL) {
return -1;
}
AudioLoad_SyncLoadSample(drum->sound.sample, fontId);
AudioLoad_SyncLoadSample(drum->tunedSample.sample, fontId);
return 0;
}
// TODO: is this missing return UB?
@@ -680,28 +681,29 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) {
s32 sampleBankId1;
s32 sampleBankId2;
s32 didAllocate;
AudioRelocInfo relocInfo;
SampleBankRelocInfo sampleBankReloc;
s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
if (gAudioContext.fontLoadStatus[realFontId] == LOAD_STATUS_IN_PROGRESS) {
return NULL;
}
sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2;
sampleBankId1 = gAudioContext.soundFontList[realFontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFontList[realFontId].sampleBankId2;
relocInfo.sampleBankId1 = sampleBankId1;
relocInfo.sampleBankId2 = sampleBankId2;
if (relocInfo.sampleBankId1 != 0xFF) {
relocInfo.baseAddr1 = AudioLoad_TrySyncLoadSampleBank(relocInfo.sampleBankId1, &relocInfo.medium1, false);
sampleBankReloc.sampleBankId1 = sampleBankId1;
sampleBankReloc.sampleBankId2 = sampleBankId2;
if (sampleBankReloc.sampleBankId1 != 0xFF) {
sampleBankReloc.baseAddr1 =
AudioLoad_TrySyncLoadSampleBank(sampleBankReloc.sampleBankId1, &sampleBankReloc.medium1, false);
} else {
relocInfo.baseAddr1 = 0;
sampleBankReloc.baseAddr1 = 0;
}
if (sampleBankId2 != 0xFF) {
relocInfo.baseAddr2 = AudioLoad_TrySyncLoadSampleBank(sampleBankId2, &relocInfo.medium2, false);
sampleBankReloc.baseAddr2 = AudioLoad_TrySyncLoadSampleBank(sampleBankId2, &sampleBankReloc.medium2, false);
} else {
relocInfo.baseAddr2 = 0;
sampleBankReloc.baseAddr2 = 0;
}
fontData = AudioLoad_SyncLoad(FONT_TABLE, fontId, &didAllocate);
@@ -709,7 +711,7 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) {
return NULL;
}
if (didAllocate == true) {
AudioLoad_RelocateFontAndPreloadSamples(realFontId, fontData, &relocInfo, false);
AudioLoad_RelocateFontAndPreloadSamples(realFontId, fontData, &sampleBankReloc, false);
}
return fontData;
@@ -778,7 +780,7 @@ void* AudioLoad_SyncLoad(s32 tableType, u32 id, s32* didAllocate) {
}
if (tableType == FONT_TABLE) {
SoundFont* soundFont = &gAudioContext.soundFonts[realId];
SoundFont* soundFont = &gAudioContext.soundFontList[realId];
soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments;
soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums;
@@ -861,89 +863,131 @@ AudioTable* AudioLoad_GetLoadTable(s32 tableType) {
}
/**
* Read and extract information from soundFont binary loaded into ram.
* Also relocate offsets into pointers within this loaded soundFont
*
* SoundFontData* mem -> the address of the soundFont as stored in memory
* @param fontId index of font being processed
* @param fontDataStartAddr ram address of raw soundfont binary loaded into cache
* @param sampleBankReloc information on the sampleBank containing raw audio samples
*/
void AudioLoad_RelocateFont(s32 fontId, SoundFontData* fontData, AudioRelocInfo* relocInfo) {
uintptr_t reloc;
uintptr_t reloc2;
void AudioLoad_RelocateFont(s32 fontId, SoundFontData* fontDataStartAddr, SampleBankRelocInfo* sampleBankReloc) {
uintptr_t soundOffset;
uintptr_t soundListOffset;
Instrument* inst;
Drum* drum;
SoundFontSound* sfx;
SoundEffect* soundEffect;
s32 i;
s32 numDrums = gAudioContext.soundFonts[fontId].numDrums;
s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
s32 numSfx = gAudioContext.soundFonts[fontId].numSfx;
void** ptrs = (void**)fontData;
s32 numDrums = gAudioContext.soundFontList[fontId].numDrums;
s32 numInstruments = gAudioContext.soundFontList[fontId].numInstruments;
s32 numSfx = gAudioContext.soundFontList[fontId].numSfx;
u32* fontData = (u32*)fontDataStartAddr;
#define BASE_OFFSET(x) (void*)((uintptr_t)(x) + (uintptr_t)(fontData))
// Relocate an offset (relative to the start of the font data) to a pointer (a ram address)
#define RELOC_TO_RAM(x) (void*)((uintptr_t)(x) + (uintptr_t)(fontDataStartAddr))
// relocate drums
reloc2 = ptrs[0];
// Drums relocation
// The first u32 in fontData is an offset to a list of offsets to the drums
soundListOffset = fontData[0];
if (1) {}
if ((reloc2 != 0) && (numDrums != 0)) {
ptrs[0] = BASE_OFFSET(reloc2);
// If the soundFont has drums
if ((soundListOffset != 0) && (numDrums != 0)) {
fontData[0] = RELOC_TO_RAM(soundListOffset);
// Loop through the drum offsets
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, fontData, relocInfo);
reloc = drum->envelope;
drum->envelope = BASE_OFFSET(reloc);
drum->loaded = true;
// Get the i'th drum offset
soundOffset = ((Drum**)fontData[0])[i];
// Some drum data entries are empty, represented by an offset of 0 in the list of drum offsets
if (soundOffset != 0) {
soundOffset = RELOC_TO_RAM(soundOffset);
((Drum**)fontData[0])[i] = drum = soundOffset;
// The drum may be in the list multiple times and already relocated
if (!drum->isRelocated) {
AudioLoad_RelocateSample(&drum->tunedSample, fontDataStartAddr, sampleBankReloc);
soundOffset = drum->envelope;
drum->envelope = RELOC_TO_RAM(soundOffset);
drum->isRelocated = true;
}
}
}
}
// relocate sfxs
reloc2 = ptrs[1];
// Sound effects relocation
// The second u32 in fontData is an offset to the first sound effect entry
soundListOffset = fontData[1];
if (1) {}
if ((reloc2 != 0) && (numSfx != 0)) {
ptrs[1] = BASE_OFFSET(reloc2);
// If the soundFont has sound effects
if ((soundListOffset != 0) && (numSfx != 0)) {
fontData[1] = RELOC_TO_RAM(soundListOffset);
// Loop through the sound effects
for (i = 0; i < numSfx; i++) {
reloc = (SoundFontSound*)ptrs[1] + i;
if (reloc != 0) {
sfx = reloc;
if (sfx->sample != NULL) {
AudioLoad_RelocateSample(sfx, fontData, relocInfo);
}
// Get a pointer to the i'th sound effect
soundOffset = (TunedSample*)fontData[1] + i;
soundEffect = (SoundEffect*)soundOffset;
// Check for NULL (note: the pointer is guaranteed to be in fontData and can never be NULL)
if ((soundEffect != NULL) && (soundEffect->tunedSample.sample != NULL)) {
AudioLoad_RelocateSample(&soundEffect->tunedSample, fontDataStartAddr, sampleBankReloc);
}
}
}
if (numInstruments > 0x7E) {
numInstruments = 0x7E;
// Instruments relocation
// Instrument Id 126 and above is reserved.
// There can only be 126 instruments, indexed from 0 to 125
if (numInstruments > 126) {
numInstruments = 126;
}
// relocate instruments
// Starting from the 3rd u32 in fontData is the list of offsets to the instruments
// Loop through the instruments
for (i = 2; i <= 2 + numInstruments - 1; i++) {
if (ptrs[i] != NULL) {
ptrs[i] = BASE_OFFSET(ptrs[i]);
inst = ptrs[i];
if (!inst->loaded) {
// Some instrument data entries are empty, represented by an offset of 0 in the list of instrument offsets
if (fontData[i] != 0) {
fontData[i] = RELOC_TO_RAM(fontData[i]);
inst = (Instrument*)fontData[i];
// The instrument may be in the list multiple times and already relocated
if (!inst->isRelocated) {
// Some instruments have a different sample for low pitches
if (inst->normalRangeLo != 0) {
AudioLoad_RelocateSample(&inst->lowNotesSound, fontData, relocInfo);
}
AudioLoad_RelocateSample(&inst->normalNotesSound, fontData, relocInfo);
if (inst->normalRangeHi != 0x7F) {
AudioLoad_RelocateSample(&inst->highNotesSound, fontData, relocInfo);
AudioLoad_RelocateSample(&inst->lowPitchTunedSample, fontDataStartAddr, sampleBankReloc);
}
reloc = inst->envelope;
inst->envelope = BASE_OFFSET(reloc);
inst->loaded = true;
// Every instrument has a sample for the default range
AudioLoad_RelocateSample(&inst->normalPitchTunedSample, fontDataStartAddr, sampleBankReloc);
// Some instruments have a different sample for high pitches
if (inst->normalRangeHi != 0x7F) {
AudioLoad_RelocateSample(&inst->highPitchTunedSample, fontDataStartAddr, sampleBankReloc);
}
soundOffset = inst->envelope;
inst->envelope = (EnvelopePoint*)RELOC_TO_RAM(soundOffset);
inst->isRelocated = true;
}
}
}
#undef BASE_OFFSET
#undef RELOC_TO_RAM
gAudioContext.soundFonts[fontId].drums = ptrs[0];
gAudioContext.soundFonts[fontId].soundEffects = ptrs[1];
gAudioContext.soundFonts[fontId].instruments = (Instrument**)(&ptrs[2]);
// Store the relocated pointers
gAudioContext.soundFontList[fontId].drums = (Drum**)fontData[0];
gAudioContext.soundFontList[fontId].soundEffects = (SoundEffect*)fontData[1];
gAudioContext.soundFontList[fontId].instruments = (Instrument**)(&fontData[2]);
}
void AudioLoad_SyncDma(uintptr_t devAddr, u8* ramAddr, size_t size, s32 medium) {
@@ -1102,7 +1146,7 @@ void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData,
}
if (tableType == FONT_TABLE) {
soundFont = &gAudioContext.soundFonts[realId];
soundFont = &gAudioContext.soundFontList[realId];
soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments;
soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums;
@@ -1154,8 +1198,8 @@ void AudioLoad_SetUnusedHandler(void* callback) {
sUnusedHandler = callback;
}
void AudioLoad_InitSoundFontMeta(s32 fontId) {
SoundFont* font = &gAudioContext.soundFonts[fontId];
void AudioLoad_InitSoundFont(s32 fontId) {
SoundFont* font = &gAudioContext.soundFontList[fontId];
AudioTableEntry* entry = &gAudioContext.soundFontTable->entries[fontId];
font->sampleBankId1 = (entry->shortData1 >> 8) & 0xFF;
@@ -1210,20 +1254,20 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
AudioThread_InitMesgQueues();
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) {
gAudioContext.aiBufLengths[i] = 0xA0;
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufNumSamples); i++) {
gAudioContext.aiBufNumSamples[i] = 0xA0;
}
gAudioContext.totalTaskCount = 0;
gAudioContext.rspTaskIndex = 0;
gAudioContext.curAiBuffferIndex = 0;
gAudioContext.curAiBufferIndex = 0;
gAudioContext.soundMode = SOUNDMODE_STEREO;
gAudioContext.curTask = NULL;
gAudioContext.rspTask[0].task.t.dataSize = 0;
gAudioContext.rspTask[1].task.t.dataSize = 0;
osCreateMesgQueue(&gAudioContext.syncDmaQueue, &gAudioContext.syncDmaMesg, 1);
osCreateMesgQueue(&gAudioContext.currAudioFrameDmaQueue, gAudioContext.currAudioFrameDmaMesgBuf,
osCreateMesgQueue(&gAudioContext.curAudioFrameDmaQueue, gAudioContext.currAudioFrameDmaMesgBuf,
ARRAY_COUNT(gAudioContext.currAudioFrameDmaMesgBuf));
osCreateMesgQueue(&gAudioContext.externalLoadQueue, gAudioContext.externalLoadMesgBuf,
ARRAY_COUNT(gAudioContext.externalLoadMesgBuf));
@@ -1235,23 +1279,24 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
if (heap == NULL) {
gAudioContext.audioHeap = gAudioHeap;
gAudioContext.audioHeapSize = gAudioContextInitSizes.heapSize;
gAudioContext.audioHeapSize = gAudioHeapInitSizes.heapSize;
} else {
void** hp = &heap;
gAudioContext.audioHeap = *hp;
gAudioContext.audioHeapSize = heapSize;
}
for (i = 0; i < (s32)gAudioContext.audioHeapSize / 8; i++) {
for (i = 0; i < ((s32)gAudioContext.audioHeapSize / (s32)sizeof(u64)); i++) {
((u64*)gAudioContext.audioHeap)[i] = 0;
}
// Main Pool Split (split entirety of audio heap into initPool and sessionPool)
AudioHeap_InitMainPool(gAudioContextInitSizes.mainPoolSplitSize);
AudioHeap_InitMainPool(gAudioHeapInitSizes.initPoolSize);
// Initialize the audio interface buffer
// Initialize the audio interface buffers
for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBuffers); i++) {
gAudioContext.aiBuffers[i] = AudioHeap_AllocZeroed(&gAudioContext.audioInitPool, AIBUF_LEN * sizeof(s16));
gAudioContext.aiBuffers[i] = AudioHeap_AllocZeroed(&gAudioContext.initPool, AIBUF_LEN * sizeof(s16));
}
// Connect audio tables to their tables in memory
@@ -1272,18 +1317,18 @@ void AudioLoad_Init(void* heap, size_t heapSize) {
AudioLoad_InitTable(gAudioContext.sampleBankTable, SEGMENT_ROM_START(Audiotable), 0);
numFonts = gAudioContext.soundFontTable->numEntries;
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
gAudioContext.soundFontList = AudioHeap_Alloc(&gAudioContext.initPool, numFonts * sizeof(SoundFont));
for (i = 0; i < numFonts; i++) {
AudioLoad_InitSoundFontMeta(i);
AudioLoad_InitSoundFont(i);
}
if (addr = AudioHeap_Alloc(&gAudioContext.audioInitPool, gAudioContextInitSizes.permanentPoolSize), addr == NULL) {
// cast away const from D_8014A6C4
*((u32*)&gAudioContextInitSizes.permanentPoolSize) = 0;
if (addr = AudioHeap_Alloc(&gAudioContext.initPool, gAudioHeapInitSizes.permanentPoolSize), addr == NULL) {
// cast away const from gAudioHeapInitSizes
*((u32*)&gAudioHeapInitSizes.permanentPoolSize) = 0;
}
AudioHeap_AllocPoolInit(&gAudioContext.permanentPool, addr, gAudioContextInitSizes.permanentPoolSize);
AudioHeap_InitPool(&gAudioContext.permanentPool, addr, gAudioHeapInitSizes.permanentPoolSize);
gAudioContextInitalized = true;
osSendMesg(gAudioContext.taskStartQueueP, (void*)gAudioContext.totalTaskCount, OS_MESG_NOBLOCK);
}
@@ -1294,7 +1339,7 @@ void AudioLoad_InitSlowLoads(void) {
}
s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
SoundFontSample* sample;
Sample* sample;
AudioSlowLoad* slowLoad;
sample = AudioLoad_GetFontSample(fontId, instId);
@@ -1344,8 +1389,8 @@ s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
return 0;
}
SoundFontSample* AudioLoad_GetFontSample(s32 fontId, s32 instId) {
SoundFontSample* sample;
Sample* AudioLoad_GetFontSample(s32 fontId, s32 instId) {
Sample* sample;
if (instId < 0x80) {
Instrument* instrument = AudioPlayback_GetInstrumentInner(fontId, instId);
@@ -1353,21 +1398,21 @@ SoundFontSample* AudioLoad_GetFontSample(s32 fontId, s32 instId) {
if (instrument == NULL) {
return NULL;
}
sample = instrument->normalNotesSound.sample;
sample = instrument->normalPitchTunedSample.sample;
} else if (instId < 0x100) {
Drum* drum = AudioPlayback_GetDrum(fontId, instId - 0x80);
if (drum == NULL) {
return NULL;
}
sample = drum->sound.sample;
sample = drum->tunedSample.sample;
} else {
SoundFontSound* sound = AudioPlayback_GetSfx(fontId, instId - 0x100);
SoundEffect* soundEffect = AudioPlayback_GetSoundEffect(fontId, instId - 0x100);
if (sound == NULL) {
if (soundEffect == NULL) {
return NULL;
}
sample = sound->sample;
sample = soundEffect->tunedSample.sample;
}
return sample;
@@ -1377,7 +1422,7 @@ void AudioLoad_Unused2(void) {
}
void AudioLoad_FinishSlowLoad(AudioSlowLoad* slowLoad) {
SoundFontSample* sample;
Sample* sample;
if (slowLoad->sample.sampleAddr == NULL) {
return;
@@ -1596,7 +1641,7 @@ void AudioLoad_FinishAsyncLoad(AudioAsyncLoad* asyncLoad) {
OSMesg doneMsg;
u32 sampleBankId1;
u32 sampleBankId2;
AudioRelocInfo relocInfo;
SampleBankRelocInfo sampleBankReloc;
if (1) {}
switch (ASYNC_TBLTYPE(retMsg)) {
@@ -1608,16 +1653,16 @@ void AudioLoad_FinishAsyncLoad(AudioAsyncLoad* asyncLoad) {
break;
case FONT_TABLE:
fontId = ASYNC_ID(retMsg);
sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
relocInfo.sampleBankId1 = sampleBankId1;
relocInfo.sampleBankId2 = sampleBankId2;
relocInfo.baseAddr1 =
sampleBankId1 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId1, &relocInfo.medium1) : 0;
relocInfo.baseAddr2 =
sampleBankId2 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId2, &relocInfo.medium2) : 0;
sampleBankId1 = gAudioContext.soundFontList[fontId].sampleBankId1;
sampleBankId2 = gAudioContext.soundFontList[fontId].sampleBankId2;
sampleBankReloc.sampleBankId1 = sampleBankId1;
sampleBankReloc.sampleBankId2 = sampleBankId2;
sampleBankReloc.baseAddr1 =
(sampleBankId1 != 0xFF) ? AudioLoad_GetSampleBank(sampleBankId1, &sampleBankReloc.medium1) : 0;
sampleBankReloc.baseAddr2 =
(sampleBankId2 != 0xFF) ? AudioLoad_GetSampleBank(sampleBankId2, &sampleBankReloc.medium2) : 0;
AudioLoad_SetFontLoadStatus(fontId, ASYNC_STATUS(retMsg));
AudioLoad_RelocateFontAndPreloadSamples(fontId, asyncLoad->ramAddr, &relocInfo, true);
AudioLoad_RelocateFontAndPreloadSamples(fontId, asyncLoad->ramAddr, &sampleBankReloc, true);
break;
}
@@ -1700,28 +1745,48 @@ void AudioLoad_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size) {
void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t size, s16 arg3) {
}
#define RELOC(v, base) (reloc = (void*)((uintptr_t)(v) + (uintptr_t)(base)))
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, AudioRelocInfo* relocInfo) {
SoundFontSample* sample;
/**
* Read and extract information from TunedSample and its Sample
* contained in the soundFont binary loaded into ram
* TunedSample contains metadata on a sample used by a particular instrument/drum/sfx
* Also relocate offsets into pointers within this loaded TunedSample
*
* @param fontId index of font being processed
* @param fontData ram address of raw soundfont binary loaded into cache
* @param sampleBankReloc information on the sampleBank containing raw audio samples
*/
void AudioLoad_RelocateSample(TunedSample* tunedSample, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc) {
Sample* sample;
void* reloc;
if ((uintptr_t)sound->sample <= 0x80000000) {
sample = sound->sample = RELOC(sound->sample, mem);
if (sample->size != 0 && sample->unk_bit25 != true) {
sample->loop = RELOC(sample->loop, mem);
sample->book = RELOC(sample->book, mem);
// Relocate an offset (relative to data loaded in ram at `base`) to a pointer (a ram address)
#define AUDIO_RELOC(v, base) (reloc = (void*)((uintptr_t)(v) + (uintptr_t)(base)))
// Resolve the sample medium 2-bit bitfield into a real value based on relocInfo.
if ((uintptr_t)tunedSample->sample <= AUDIO_RELOCATED_ADDRESS_START) {
sample = tunedSample->sample = AUDIO_RELOC(tunedSample->sample, fontData);
// If the sample exists and has not already been relocated
// Note: this is important, as the same sample can be used by different drums, sound effects, instruments
if ((sample->size != 0) && (sample->isRelocated != true)) {
sample->loop = AUDIO_RELOC(sample->loop, fontData);
sample->book = AUDIO_RELOC(sample->book, fontData);
// Resolve the sample medium 2-bit bitfield into a real value based on sampleBankReloc.
// Then relocate the offset sample within the sampleBank (not the fontData) into absolute address.
// sampleAddr can be either rom or ram depending on sampleBank cache policy
// in practice, this is always in rom
switch (sample->medium) {
case 0:
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1);
sample->medium = relocInfo->medium1;
sample->sampleAddr = AUDIO_RELOC(sample->sampleAddr, sampleBankReloc->baseAddr1);
sample->medium = sampleBankReloc->medium1;
break;
case 1:
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2);
sample->medium = relocInfo->medium2;
sample->sampleAddr = AUDIO_RELOC(sample->sampleAddr, sampleBankReloc->baseAddr2);
sample->medium = sampleBankReloc->medium2;
break;
case 2:
case 3:
// Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE
@@ -1729,7 +1794,8 @@ void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, AudioRe
break;
}
sample->unk_bit25 = true;
sample->isRelocated = true;
if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) {
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
}
@@ -1737,12 +1803,19 @@ void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, AudioRe
}
}
#undef RELOC
#undef AUDIO_RELOC
void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, AudioRelocInfo* relocInfo, s32 async) {
/**
* @param fontId index of font being processed
* @param fontData ram address of raw soundfont binary loaded into cache
* @param sampleBankReloc information on the sampleBank containing raw audio samples
* @param isAsync bool for whether this is an asynchronous load or not
*/
void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, SampleBankRelocInfo* sampleBankReloc,
s32 isAsync) {
AudioPreloadReq* preload;
AudioPreloadReq* topPreload;
SoundFontSample* sample;
Sample* sample;
size_t size;
s32 nChunks;
u8* sampleRamAddr;
@@ -1757,7 +1830,7 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, Aud
}
gAudioContext.numUsedSamples = 0;
AudioLoad_RelocateFont(fontId, mem, relocInfo);
AudioLoad_RelocateFont(fontId, fontData, sampleBankReloc);
size = 0;
for (i = 0; i < gAudioContext.numUsedSamples; i++) {
@@ -1772,13 +1845,13 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, Aud
sample = gAudioContext.usedSamples[i];
sampleRamAddr = NULL;
switch (async) {
switch (isAsync) {
case false:
if (sample->medium == relocInfo->medium1) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1,
if (sample->medium == sampleBankReloc->medium1) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1,
sample->sampleAddr, sample->medium, CACHE_PERSISTENT);
} else if (sample->medium == relocInfo->medium2) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2,
} else if (sample->medium == sampleBankReloc->medium2) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2,
sample->sampleAddr, sample->medium, CACHE_PERSISTENT);
} else if (sample->medium == MEDIUM_DISK_DRIVE) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium,
@@ -1787,23 +1860,26 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, Aud
break;
case true:
if (sample->medium == relocInfo->medium1) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1,
if (sample->medium == sampleBankReloc->medium1) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1,
sample->sampleAddr, sample->medium, CACHE_TEMPORARY);
} else if (sample->medium == relocInfo->medium2) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2,
} else if (sample->medium == sampleBankReloc->medium2) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2,
sample->sampleAddr, sample->medium, CACHE_TEMPORARY);
} else if (sample->medium == MEDIUM_DISK_DRIVE) {
sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium,
CACHE_TEMPORARY);
}
break;
default:
break;
}
if (sampleRamAddr == NULL) {
continue;
}
switch (async) {
switch (isAsync) {
case false:
if (sample->medium == MEDIUM_UNK) {
AudioLoad_SyncDmaUnkMedium((uintptr_t)sample->sampleAddr, sampleRamAddr, sample->size,
@@ -1827,6 +1903,9 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, Aud
preload->endAndMediumKey = (uintptr_t)sample->sampleAddr + sample->size + sample->medium;
gAudioContext.preloadSampleStackTop++;
break;
default:
break;
}
}
gAudioContext.numUsedSamples = 0;
@@ -1841,7 +1920,7 @@ void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, Aud
}
s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus) {
SoundFontSample* sample;
Sample* sample;
AudioPreloadReq* preload;
u32 preloadIndex;
u32 key;
@@ -1902,7 +1981,7 @@ s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus) {
return true;
}
s32 AudioLoad_AddToSampleSet(SoundFontSample* sample, s32 numSamples, SoundFontSample** sampleSet) {
s32 AudioLoad_AddToSampleSet(Sample* sample, s32 numSamples, Sample** sampleSet) {
s32 i;
for (i = 0; i < numSamples; i++) {
@@ -1919,18 +1998,18 @@ s32 AudioLoad_AddToSampleSet(SoundFontSample* sample, s32 numSamples, SoundFontS
return numSamples;
}
s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
s32 AudioLoad_GetSamplesForFont(s32 fontId, Sample** sampleSet) {
s32 i;
s32 numSamples = 0;
s32 numDrums = gAudioContext.soundFonts[fontId].numDrums;
s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
s32 numDrums = gAudioContext.soundFontList[fontId].numDrums;
s32 numInstruments = gAudioContext.soundFontList[fontId].numInstruments;
for (i = 0; i < numDrums; i++) {
Drum* drum = AudioPlayback_GetDrum(fontId, i);
if (1) {}
if (drum != NULL) {
numSamples = AudioLoad_AddToSampleSet(drum->sound.sample, numSamples, sampleSet);
numSamples = AudioLoad_AddToSampleSet(drum->tunedSample.sample, numSamples, sampleSet);
}
}
@@ -1939,12 +2018,12 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
if (instrument != NULL) {
if (instrument->normalRangeLo != 0) {
numSamples = AudioLoad_AddToSampleSet(instrument->lowNotesSound.sample, numSamples, sampleSet);
numSamples = AudioLoad_AddToSampleSet(instrument->lowPitchTunedSample.sample, numSamples, sampleSet);
}
if (instrument->normalRangeHi != 0x7F) {
numSamples = AudioLoad_AddToSampleSet(instrument->highNotesSound.sample, numSamples, sampleSet);
numSamples = AudioLoad_AddToSampleSet(instrument->highPitchTunedSample.sample, numSamples, sampleSet);
}
numSamples = AudioLoad_AddToSampleSet(instrument->normalNotesSound.sample, numSamples, sampleSet);
numSamples = AudioLoad_AddToSampleSet(instrument->normalPitchTunedSample.sample, numSamples, sampleSet);
}
}
@@ -1952,27 +2031,27 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
return numSamples;
}
void AudioLoad_AddUsedSample(SoundFontSound* sound) {
SoundFontSample* sample = sound->sample;
void AudioLoad_AddUsedSample(TunedSample* tunedSample) {
Sample* sample = tunedSample->sample;
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
}
}
void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, AudioRelocInfo* relocInfo) {
void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, SampleBankRelocInfo* sampleBankReloc) {
s32 numDrums;
s32 numInstruments;
s32 numSfx;
Drum* drum;
Instrument* instrument;
SoundFontSound* sound;
SoundEffect* soundEffect;
AudioPreloadReq* preload;
AudioPreloadReq* topPreload;
u8* addr;
size_t size;
s32 i;
SoundFontSample* sample;
Sample* sample;
s32 preloadInProgress;
s32 nChunks;
@@ -1983,34 +2062,34 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, AudioRelocInfo* relo
gAudioContext.numUsedSamples = 0;
numDrums = gAudioContext.soundFonts[fontId].numDrums;
numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
numSfx = gAudioContext.soundFonts[fontId].numSfx;
numDrums = gAudioContext.soundFontList[fontId].numDrums;
numInstruments = gAudioContext.soundFontList[fontId].numInstruments;
numSfx = gAudioContext.soundFontList[fontId].numSfx;
for (i = 0; i < numInstruments; i++) {
instrument = AudioPlayback_GetInstrumentInner(fontId, i);
if (instrument != NULL) {
if (instrument->normalRangeLo != 0) {
AudioLoad_AddUsedSample(&instrument->lowNotesSound);
AudioLoad_AddUsedSample(&instrument->lowPitchTunedSample);
}
if (instrument->normalRangeHi != 0x7F) {
AudioLoad_AddUsedSample(&instrument->highNotesSound);
AudioLoad_AddUsedSample(&instrument->highPitchTunedSample);
}
AudioLoad_AddUsedSample(&instrument->normalNotesSound);
AudioLoad_AddUsedSample(&instrument->normalPitchTunedSample);
}
}
for (i = 0; i < numDrums; i++) {
drum = AudioPlayback_GetDrum(fontId, i);
if (drum != NULL) {
AudioLoad_AddUsedSample(&drum->sound);
AudioLoad_AddUsedSample(&drum->tunedSample);
}
}
for (i = 0; i < numSfx; i++) {
sound = AudioPlayback_GetSfx(fontId, i);
if (sound != NULL) {
AudioLoad_AddUsedSample(sound);
soundEffect = AudioPlayback_GetSoundEffect(fontId, i);
if (soundEffect != NULL) {
AudioLoad_AddUsedSample(&soundEffect->tunedSample);
}
}
@@ -2036,21 +2115,21 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, AudioRelocInfo* relo
switch (async) {
case false:
if (sample->medium == relocInfo->medium1) {
addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, sample->sampleAddr,
if (sample->medium == sampleBankReloc->medium1) {
addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, sample->sampleAddr,
sample->medium, CACHE_PERSISTENT);
} else if (sample->medium == relocInfo->medium2) {
addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, sample->sampleAddr,
} else if (sample->medium == sampleBankReloc->medium2) {
addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, sample->sampleAddr,
sample->medium, CACHE_PERSISTENT);
}
break;
case true:
if (sample->medium == relocInfo->medium1) {
addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, sample->sampleAddr,
if (sample->medium == sampleBankReloc->medium1) {
addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId1, sample->sampleAddr,
sample->medium, CACHE_TEMPORARY);
} else if (sample->medium == relocInfo->medium2) {
addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, sample->sampleAddr,
} else if (sample->medium == sampleBankReloc->medium2) {
addr = AudioHeap_AllocSampleCache(sample->size, sampleBankReloc->sampleBankId2, sample->sampleAddr,
sample->medium, CACHE_TEMPORARY);
}
break;
@@ -2104,23 +2183,25 @@ void AudioLoad_LoadPermanentSamples(void) {
sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE);
for (i = 0; i < gAudioContext.permanentPool.count; i++) {
AudioRelocInfo relocInfo;
SampleBankRelocInfo sampleBankReloc;
if (gAudioContext.permanentEntries[i].tableType == FONT_TABLE) {
fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioContext.permanentEntries[i].id);
relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
sampleBankReloc.sampleBankId1 = gAudioContext.soundFontList[fontId].sampleBankId1;
sampleBankReloc.sampleBankId2 = gAudioContext.soundFontList[fontId].sampleBankId2;
if (relocInfo.sampleBankId1 != 0xFF) {
relocInfo.sampleBankId1 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId1);
relocInfo.medium1 = sampleBankTable->entries[relocInfo.sampleBankId1].medium;
if (sampleBankReloc.sampleBankId1 != 0xFF) {
sampleBankReloc.sampleBankId1 =
AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankReloc.sampleBankId1);
sampleBankReloc.medium1 = sampleBankTable->entries[sampleBankReloc.sampleBankId1].medium;
}
if (relocInfo.sampleBankId2 != 0xFF) {
relocInfo.sampleBankId2 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId2);
relocInfo.medium2 = sampleBankTable->entries[relocInfo.sampleBankId2].medium;
if (sampleBankReloc.sampleBankId2 != 0xFF) {
sampleBankReloc.sampleBankId2 =
AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankReloc.sampleBankId2);
sampleBankReloc.medium2 = sampleBankTable->entries[sampleBankReloc.sampleBankId2].medium;
}
AudioLoad_PreloadSamplesForFont(fontId, false, &relocInfo);
AudioLoad_PreloadSamplesForFont(fontId, false, &sampleBankReloc);
}
}
}
+156 -136
View File
@@ -4,9 +4,10 @@ void AudioPlayback_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRat
void AudioPlayback_AudioListPushFront(AudioListItem* list, AudioListItem* item);
void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer);
void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) {
f32 volRight, volLeft;
s32 smallPanIndex;
void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* noteSubEu, NoteSubAttributes* subAttrs) {
f32 volLeft;
f32 volRight;
s32 halfPanIndex;
u64 pad;
u8 strongLeft;
u8 strongRight;
@@ -16,41 +17,41 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
StereoData stereoData;
s32 stereoHeadsetEffects = note->playbackState.stereoHeadsetEffects;
vel = attrs->velocity;
pan = attrs->pan;
reverbVol = attrs->reverbVol;
stereoData = attrs->stereo.s;
vel = subAttrs->velocity;
pan = subAttrs->pan;
reverbVol = subAttrs->reverbVol;
stereoData = subAttrs->stereo.s;
sub->bitField0 = note->noteSubEu.bitField0;
sub->bitField1 = note->noteSubEu.bitField1;
sub->sound.samples = note->noteSubEu.sound.samples;
sub->unk_06 = note->noteSubEu.unk_06;
noteSubEu->bitField0 = note->noteSubEu.bitField0;
noteSubEu->bitField1 = note->noteSubEu.bitField1;
noteSubEu->waveSampleAddr = note->noteSubEu.waveSampleAddr;
noteSubEu->harmonicIndexCurAndPrev = note->noteSubEu.harmonicIndexCurAndPrev;
AudioPlayback_NoteSetResamplingRate(sub, attrs->frequency);
AudioPlayback_NoteSetResamplingRate(noteSubEu, subAttrs->frequency);
pan &= 0x7F;
sub->bitField0.stereoStrongRight = false;
sub->bitField0.stereoStrongLeft = false;
sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects;
sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects;
if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_HEADSET) {
smallPanIndex = pan >> 1;
if (smallPanIndex > 0x3F) {
smallPanIndex = 0x3F;
noteSubEu->bitField0.stereoStrongRight = false;
noteSubEu->bitField0.stereoStrongLeft = false;
noteSubEu->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects;
noteSubEu->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects;
if (stereoHeadsetEffects && (gAudioContext.soundMode == SOUNDMODE_HEADSET)) {
halfPanIndex = pan >> 1;
if (halfPanIndex > 0x3F) {
halfPanIndex = 0x3F;
}
sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex];
sub->headsetPanRight = gHeadsetPanQuantization[0x3F - smallPanIndex];
sub->bitField1.usesHeadsetPanEffects2 = true;
noteSubEu->headsetPanLeft = gHeadsetPanQuantization[halfPanIndex];
noteSubEu->headsetPanRight = gHeadsetPanQuantization[0x3F - halfPanIndex];
noteSubEu->bitField1.usesHeadsetPanEffects2 = true;
volLeft = gHeadsetPanVolume[pan];
volRight = gHeadsetPanVolume[0x7F - pan];
} else if (stereoHeadsetEffects && gAudioContext.soundMode == SOUNDMODE_STEREO) {
} else if (stereoHeadsetEffects && (gAudioContext.soundMode == SOUNDMODE_STEREO)) {
strongLeft = strongRight = false;
sub->headsetPanRight = 0;
sub->headsetPanLeft = 0;
sub->bitField1.usesHeadsetPanEffects2 = false;
noteSubEu->headsetPanRight = 0;
noteSubEu->headsetPanLeft = 0;
noteSubEu->bitField1.usesHeadsetPanEffects2 = false;
volLeft = gStereoPanVolume[pan];
volRight = gStereoPanVolume[0x7F - pan];
@@ -60,34 +61,38 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
strongRight = true;
}
sub->bitField0.stereoStrongRight = strongRight;
sub->bitField0.stereoStrongLeft = strongLeft;
// case 0:
noteSubEu->bitField0.stereoStrongRight = strongRight;
noteSubEu->bitField0.stereoStrongLeft = strongLeft;
switch (stereoData.bit2) {
case 0:
break;
case 1:
sub->bitField0.stereoStrongRight = stereoData.strongRight;
sub->bitField0.stereoStrongLeft = stereoData.strongLeft;
noteSubEu->bitField0.stereoStrongRight = stereoData.strongRight;
noteSubEu->bitField0.stereoStrongLeft = stereoData.strongLeft;
break;
case 2:
sub->bitField0.stereoStrongRight = stereoData.strongRight | strongRight;
sub->bitField0.stereoStrongLeft = stereoData.strongLeft | strongLeft;
noteSubEu->bitField0.stereoStrongRight = stereoData.strongRight | strongRight;
noteSubEu->bitField0.stereoStrongLeft = stereoData.strongLeft | strongLeft;
break;
case 3:
sub->bitField0.stereoStrongRight = stereoData.strongRight ^ strongRight;
sub->bitField0.stereoStrongLeft = stereoData.strongLeft ^ strongLeft;
noteSubEu->bitField0.stereoStrongRight = stereoData.strongRight ^ strongRight;
noteSubEu->bitField0.stereoStrongLeft = stereoData.strongLeft ^ strongLeft;
break;
}
} else if (gAudioContext.soundMode == SOUNDMODE_MONO) {
sub->bitField0.stereoHeadsetEffects = false;
sub->bitField0.usesHeadsetPanEffects = false;
noteSubEu->bitField0.stereoHeadsetEffects = false;
noteSubEu->bitField0.usesHeadsetPanEffects = false;
volLeft = 0.707f; // approx 1/sqrt(2)
volRight = 0.707f;
} else {
sub->bitField0.stereoStrongRight = stereoData.strongRight;
sub->bitField0.stereoStrongLeft = stereoData.strongLeft;
noteSubEu->bitField0.stereoStrongRight = stereoData.strongRight;
noteSubEu->bitField0.stereoStrongLeft = stereoData.strongLeft;
volLeft = gDefaultPanVolume[pan];
volRight = gDefaultPanVolume[0x7F - pan];
}
@@ -95,15 +100,15 @@ void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* at
vel = 0.0f > vel ? 0.0f : vel;
vel = 1.0f < vel ? 1.0f : vel;
sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f));
sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f));
noteSubEu->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f));
noteSubEu->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f));
sub->gain = attrs->gain;
sub->filter = attrs->filter;
sub->unk_07 = attrs->unk_14;
sub->unk_0E = attrs->unk_16;
sub->reverbVol = reverbVol;
sub->unk_19 = attrs->unk_3;
noteSubEu->gain = subAttrs->gain;
noteSubEu->filter = subAttrs->filter;
noteSubEu->unk_07 = subAttrs->unk_14;
noteSubEu->unk_0E = subAttrs->unk_16;
noteSubEu->reverbVol = reverbVol;
noteSubEu->unk_19 = subAttrs->unk_3;
}
void AudioPlayback_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput) {
@@ -133,7 +138,7 @@ void AudioPlayback_NoteInit(Note* note) {
&note->playbackState.adsrVolScaleUnused);
}
note->playbackState.unk_04 = 0;
note->playbackState.status = PLAYBACK_STATUS_0;
note->playbackState.adsr.action.s.state = ADSR_STATE_INITIAL;
note->noteSubEu = gDefaultNoteSub;
}
@@ -144,7 +149,7 @@ void AudioPlayback_NoteDisable(Note* note) {
}
note->playbackState.priority = 0;
note->noteSubEu.bitField0.enabled = false;
note->playbackState.unk_04 = 0;
note->playbackState.status = PLAYBACK_STATUS_0;
note->noteSubEu.bitField0.finished = false;
note->playbackState.parentLayer = NO_LAYER;
note->playbackState.prevParentLayer = NO_LAYER;
@@ -154,7 +159,7 @@ void AudioPlayback_NoteDisable(Note* note) {
void AudioPlayback_ProcessNotes(void) {
s32 pad;
s32 unk_04;
s32 playbackStatus;
NoteAttributes* attrs;
NoteSubEu* noteSubEu2;
NoteSubEu* noteSubEu;
@@ -174,19 +179,19 @@ void AudioPlayback_ProcessNotes(void) {
continue;
}
if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) {
if ((note != playbackState->parentLayer->note) && (playbackState->status == PLAYBACK_STATUS_0)) {
playbackState->adsr.action.s.release = true;
playbackState->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
playbackState->priority = 1;
playbackState->unk_04 = 2;
playbackState->status = PLAYBACK_STATUS_2;
goto out;
} else if (!playbackState->parentLayer->enabled && playbackState->unk_04 == 0 &&
playbackState->priority >= 1) {
} else if (!playbackState->parentLayer->enabled && (playbackState->status == PLAYBACK_STATUS_0) &&
(playbackState->priority >= 1)) {
// do nothing
} else if (playbackState->parentLayer->channel->seqPlayer == NULL) {
AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel);
playbackState->priority = 1;
playbackState->unk_04 = 1;
playbackState->status = PLAYBACK_STATUS_1;
continue;
} else if (playbackState->parentLayer->channel->seqPlayer->muted &&
(playbackState->parentLayer->channel->muteFlags & MUTE_FLAGS_STOP_NOTES)) {
@@ -199,8 +204,8 @@ void AudioPlayback_ProcessNotes(void) {
AudioPlayback_AudioListRemove(&note->listItem);
AudioPlayback_AudioListPushFront(&note->listItem.pool->decaying, &note->listItem);
playbackState->priority = 1;
playbackState->unk_04 = 2;
} else if (playbackState->unk_04 == 0 && playbackState->priority >= 1) {
playbackState->status = PLAYBACK_STATUS_2;
} else if ((playbackState->status == PLAYBACK_STATUS_0) && (playbackState->priority >= 1)) {
continue;
}
@@ -208,8 +213,8 @@ void AudioPlayback_ProcessNotes(void) {
if (playbackState->priority != 0) {
if (1) {}
noteSubEu = &note->noteSubEu;
if (playbackState->unk_04 >= 1 || noteSubEu->bitField0.finished) {
if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED || noteSubEu->bitField0.finished) {
if ((playbackState->status >= 1) || noteSubEu->bitField0.finished) {
if ((playbackState->adsr.action.s.state == ADSR_STATE_DISABLED) || noteSubEu->bitField0.finished) {
if (playbackState->wantedParentLayer != NO_LAYER) {
AudioPlayback_NoteDisable(note);
if (playbackState->wantedParentLayer->channel != NULL) {
@@ -249,9 +254,9 @@ void AudioPlayback_ProcessNotes(void) {
scale = AudioEffects_AdsrUpdate(&playbackState->adsr);
AudioEffects_NoteVibratoUpdate(note);
unk_04 = playbackState->unk_04;
playbackStatus = playbackState->status;
attrs = &playbackState->attributes;
if (unk_04 == 1 || unk_04 == 2) {
if ((playbackStatus == PLAYBACK_STATUS_1) || (playbackStatus == PLAYBACK_STATUS_2)) {
subAttrs.frequency = attrs->freqScale;
subAttrs.velocity = attrs->velocity;
subAttrs.pan = attrs->pan;
@@ -317,17 +322,18 @@ void AudioPlayback_ProcessNotes(void) {
}
}
SoundFontSound* AudioPlayback_InstrumentGetSound(Instrument* instrument, s32 semitone) {
SoundFontSound* sound;
TunedSample* AudioPlayback_GetInstrumentTunedSample(Instrument* instrument, s32 semitone) {
TunedSample* tunedSample;
if (semitone < instrument->normalRangeLo) {
sound = &instrument->lowNotesSound;
tunedSample = &instrument->lowPitchTunedSample;
} else if (semitone <= instrument->normalRangeHi) {
sound = &instrument->normalNotesSound;
tunedSample = &instrument->normalPitchTunedSample;
} else {
sound = &instrument->highNotesSound;
tunedSample = &instrument->highPitchTunedSample;
}
return sound;
return tunedSample;
}
Instrument* AudioPlayback_GetInstrumentInner(s32 fontId, s32 instId) {
@@ -338,18 +344,18 @@ Instrument* AudioPlayback_GetInstrumentInner(s32 fontId, s32 instId) {
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
gAudioContext.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED);
return NULL;
}
if (instId >= gAudioContext.soundFonts[fontId].numInstruments) {
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000;
if (instId >= gAudioContext.soundFontList[fontId].numInstruments) {
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, instId, AUDIO_ERROR_INVALID_INST_ID);
return NULL;
}
inst = gAudioContext.soundFonts[fontId].instruments[instId];
inst = gAudioContext.soundFontList[fontId].instruments[instId];
if (inst == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000;
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, instId, AUDIO_ERROR_NO_INST);
return inst;
}
@@ -364,58 +370,58 @@ Drum* AudioPlayback_GetDrum(s32 fontId, s32 drumId) {
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
gAudioContext.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED);
return NULL;
}
if (drumId >= gAudioContext.soundFonts[fontId].numDrums) {
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000;
if (drumId >= gAudioContext.soundFontList[fontId].numDrums) {
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, drumId, AUDIO_ERROR_INVALID_DRUM_SFX_ID);
return NULL;
}
if ((u32)gAudioContext.soundFonts[fontId].drums < 0x80000000) {
if ((u32)gAudioContext.soundFontList[fontId].drums < AUDIO_RELOCATED_ADDRESS_START) {
return NULL;
}
drum = gAudioContext.soundFonts[fontId].drums[drumId];
drum = gAudioContext.soundFontList[fontId].drums[drumId];
if (drum == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000;
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, drumId, AUDIO_ERROR_NO_DRUM_SFX);
}
return drum;
}
SoundFontSound* AudioPlayback_GetSfx(s32 fontId, s32 sfxId) {
SoundFontSound* sfx;
SoundEffect* AudioPlayback_GetSoundEffect(s32 fontId, s32 sfxId) {
SoundEffect* soundEffect;
if (fontId == 0xFF) {
return NULL;
}
if (!AudioLoad_IsFontLoadComplete(fontId)) {
gAudioContext.audioErrorFlags = fontId + 0x10000000;
gAudioContext.audioErrorFlags = AUDIO_ERROR(0, fontId, AUDIO_ERROR_FONT_NOT_LOADED);
return NULL;
}
if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) {
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000;
if (sfxId >= gAudioContext.soundFontList[fontId].numSfx) {
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, sfxId, AUDIO_ERROR_INVALID_DRUM_SFX_ID);
return NULL;
}
if ((u32)gAudioContext.soundFonts[fontId].soundEffects < 0x80000000) {
if ((u32)gAudioContext.soundFontList[fontId].soundEffects < AUDIO_RELOCATED_ADDRESS_START) {
return NULL;
}
sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId];
soundEffect = &gAudioContext.soundFontList[fontId].soundEffects[sfxId];
if (sfx == NULL) {
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000;
if (soundEffect == NULL) {
gAudioContext.audioErrorFlags = AUDIO_ERROR(fontId, sfxId, AUDIO_ERROR_NO_DRUM_SFX);
}
if (sfx->sample == NULL) {
if (soundEffect->tunedSample.sample == NULL) {
return NULL;
}
return sfx;
return soundEffect;
}
s32 AudioPlayback_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* value) {
@@ -429,24 +435,24 @@ s32 AudioPlayback_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, v
switch (instrumentType) {
case 0:
if (index >= gAudioContext.soundFonts[fontId].numDrums) {
if (index >= gAudioContext.soundFontList[fontId].numDrums) {
return -3;
}
gAudioContext.soundFonts[fontId].drums[index] = value;
gAudioContext.soundFontList[fontId].drums[index] = value;
break;
case 1:
if (index >= gAudioContext.soundFonts[fontId].numSfx) {
if (index >= gAudioContext.soundFontList[fontId].numSfx) {
return -3;
}
gAudioContext.soundFonts[fontId].soundEffects[index] = *(SoundFontSound*)value;
gAudioContext.soundFontList[fontId].soundEffects[index] = *(SoundEffect*)value;
break;
default:
if (index >= gAudioContext.soundFonts[fontId].numInstruments) {
if (index >= gAudioContext.soundFontList[fontId].numInstruments) {
return -3;
}
gAudioContext.soundFonts[fontId].instruments[index] = value;
gAudioContext.soundFontList[fontId].instruments[index] = value;
break;
}
@@ -456,7 +462,7 @@ s32 AudioPlayback_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, v
void AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
Note* note;
NoteAttributes* attrs;
SequenceChannel* chan;
SequenceChannel* channel;
s32 i;
if (layer == NO_LAYER) {
@@ -491,27 +497,27 @@ void AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
attrs->pan = layer->notePan;
if (layer->channel != NULL) {
chan = layer->channel;
channel = layer->channel;
if (layer->unk_0A.s.bit_2 == 1) {
attrs->reverb = chan->reverb;
attrs->reverb = channel->reverb;
} else {
attrs->reverb = layer->unk_09;
}
if (layer->unk_08 == 0x80) {
attrs->unk_3 = chan->unk_10;
attrs->unk_3 = channel->unk_10;
} else {
attrs->unk_3 = layer->unk_08;
}
if (layer->unk_0A.s.bit_9 == 1) {
attrs->gain = chan->gain;
attrs->gain = channel->gain;
} else {
attrs->gain = 0;
}
attrs->filter = chan->filter;
attrs->filter = channel->filter;
if (attrs->filter != NULL) {
for (i = 0; i < 8; i++) {
@@ -520,18 +526,18 @@ void AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
attrs->filter = attrs->filterBuf;
}
attrs->unk_6 = chan->unk_20;
attrs->unk_4 = chan->unk_0F;
if (chan->seqPlayer->muted && (chan->muteFlags & MUTE_FLAGS_3)) {
attrs->unk_6 = channel->unk_20;
attrs->unk_4 = channel->unk_0F;
if (channel->seqPlayer->muted && (channel->muteFlags & MUTE_FLAGS_3)) {
note->noteSubEu.bitField0.finished = true;
}
if (layer->stereo.asByte == 0) {
attrs->stereo = chan->stereo;
attrs->stereo = channel->stereo;
} else {
attrs->stereo = layer->stereo;
}
note->playbackState.priority = chan->someOtherPriority;
note->playbackState.priority = channel->someOtherPriority;
} else {
attrs->stereo = layer->stereo;
note->playbackState.priority = 1;
@@ -542,9 +548,9 @@ void AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
if (target == ADSR_STATE_RELEASE) {
note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv;
note->playbackState.adsr.action.s.release = true;
note->playbackState.unk_04 = 2;
note->playbackState.status = PLAYBACK_STATUS_2;
} else {
note->playbackState.unk_04 = 1;
note->playbackState.status = PLAYBACK_STATUS_1;
note->playbackState.adsr.action.s.decay = true;
if (layer->adsr.decayIndex == 0) {
note->playbackState.adsr.fadeOutVel = gAudioContext.adsrDecayTable[layer->channel->adsr.decayIndex];
@@ -570,10 +576,18 @@ void AudioPlayback_SeqLayerNoteRelease(SequenceLayer* layer) {
AudioPlayback_SeqLayerDecayRelease(layer, ADSR_STATE_RELEASE);
}
/**
* Extract the synthetic wave to use from gWaveSamples and update corresponding frequencies
*
* @param note
* @param layer
* @param waveId the index of the type of synthetic wave to use, offset by 128
* @return harmonicIndex, the index of the harmonic for the synthetic wave contained in gWaveSamples
*/
s32 AudioPlayback_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveId) {
f32 freqScale;
f32 ratio;
u8 sampleCountIndex;
f32 freqRatio;
u8 harmonicIndex;
if (waveId < 128) {
waveId = 128;
@@ -583,42 +597,48 @@ s32 AudioPlayback_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveI
if (layer->portamento.mode != 0 && 0.0f < layer->portamento.extent) {
freqScale *= (layer->portamento.extent + 1.0f);
}
// Map frequency to the harmonic to use from gWaveSamples
if (freqScale < 0.99999f) {
sampleCountIndex = 0;
ratio = 1.0465f;
harmonicIndex = 0;
freqRatio = 1.0465f;
} else if (freqScale < 1.99999f) {
sampleCountIndex = 1;
ratio = 0.52325f;
harmonicIndex = 1;
freqRatio = 1.0465f / 2;
} else if (freqScale < 3.99999f) {
sampleCountIndex = 2;
ratio = 0.26263f;
harmonicIndex = 2;
freqRatio = 1.0465f / 4 + 1.005E-3;
} else {
sampleCountIndex = 3;
ratio = 0.13081f;
harmonicIndex = 3;
freqRatio = 1.0465f / 8 - 2.5E-6;
}
layer->freqScale *= ratio;
// Update results
layer->freqScale *= freqRatio;
note->playbackState.waveId = waveId;
note->playbackState.sampleCountIndex = sampleCountIndex;
note->playbackState.harmonicIndex = harmonicIndex;
note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64];
// Save the pointer to the synthethic wave
// waveId index starts at 128, there are WAVE_SAMPLE_COUNT samples to read from
note->noteSubEu.waveSampleAddr = &gWaveSamples[waveId - 128][harmonicIndex * WAVE_SAMPLE_COUNT];
return sampleCountIndex;
return harmonicIndex;
}
void AudioPlayback_InitSyntheticWave(Note* note, SequenceLayer* layer) {
s32 sampleCountIndex;
s32 waveSampleCountIndex;
s32 prevHarmonicIndex;
s32 curHarmonicIndex;
s32 waveId = layer->instOrWave;
if (waveId == 0xFF) {
waveId = layer->channel->instOrWave;
}
sampleCountIndex = note->playbackState.sampleCountIndex;
waveSampleCountIndex = AudioPlayback_BuildSyntheticWave(note, layer, waveId);
prevHarmonicIndex = note->playbackState.harmonicIndex;
curHarmonicIndex = AudioPlayback_BuildSyntheticWave(note, layer, waveId);
if (waveSampleCountIndex != sampleCountIndex) {
note->noteSubEu.unk_06 = waveSampleCountIndex * 4 + sampleCountIndex;
if (curHarmonicIndex != prevHarmonicIndex) {
note->noteSubEu.harmonicIndexCurAndPrev = (curHarmonicIndex << 2) + prevHarmonicIndex;
}
}
@@ -805,7 +825,7 @@ void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer) {
if (instId == 0xFF) {
instId = channel->instOrWave;
}
noteSubEu->sound.soundFontSound = layer->sound;
noteSubEu->tunedSample = layer->tunedSample;
if (instId >= 0x80 && instId < 0xC0) {
noteSubEu->bitField1.isSyntheticWave = true;
@@ -815,12 +835,12 @@ void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer) {
if (noteSubEu->bitField1.isSyntheticWave) {
AudioPlayback_BuildSyntheticWave(note, layer, instId);
} else if (channel->unk_DC == 1) {
playbackState->unk_84 = noteSubEu->sound.soundFontSound->sample->loop->start;
} else if (channel->startSamplePos == 1) {
playbackState->startSamplePos = noteSubEu->tunedSample->sample->loop->start;
} else {
playbackState->unk_84 = channel->unk_DC;
if (playbackState->unk_84 >= noteSubEu->sound.soundFontSound->sample->loop->end) {
playbackState->unk_84 = 0;
playbackState->startSamplePos = channel->startSamplePos;
if (playbackState->startSamplePos >= noteSubEu->tunedSample->sample->loop->end) {
playbackState->startSamplePos = 0;
}
}
@@ -969,7 +989,7 @@ void AudioPlayback_NoteInitAll(void) {
note = &gAudioContext.notes[i];
note->noteSubEu = gZeroNoteSub;
note->playbackState.priority = 0;
note->playbackState.unk_04 = 0;
note->playbackState.status = PLAYBACK_STATUS_0;
note->playbackState.parentLayer = NO_LAYER;
note->playbackState.wantedParentLayer = NO_LAYER;
note->playbackState.prevParentLayer = NO_LAYER;
@@ -981,7 +1001,7 @@ void AudioPlayback_NoteInitAll(void) {
note->playbackState.portamento.cur = 0;
note->playbackState.portamento.speed = 0;
note->playbackState.stereoHeadsetEffects = false;
note->playbackState.unk_84 = 0;
note->playbackState.startSamplePos = 0;
note->synthesisState.synthesisBuffers = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x2E0);
note->playbackState.attributes.filterBuf = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10);
}
+49 -48
View File
@@ -33,7 +33,7 @@ u8 AudioSeq_ScriptReadU8(SeqScriptState* state);
s16 AudioSeq_ScriptReadS16(SeqScriptState* state);
u16 AudioSeq_ScriptReadCompressedU16(SeqScriptState* state);
void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer);
s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameSound);
s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample);
s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer);
s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd);
s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd);
@@ -320,7 +320,7 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) {
channel->unused = false;
AudioPlayback_InitNoteLists(&channel->notePool);
channel->unk_DC = 0;
channel->startSamplePos = 0;
channel->unk_E0 = 0;
channel->sfxState = NULL;
}
@@ -582,7 +582,7 @@ void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) {
} while ((cmd == -1) && (layer->delay == 0));
if (cmd != PROCESS_SCRIPT_END) {
// returns `sameSound` instead of a command
// returns `sameTunedSample` instead of a command
cmd = AudioSeq_SeqLayerProcessScriptStep4(layer, cmd);
}
@@ -611,20 +611,20 @@ void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer) {
layer->notePropertiesNeedInit = true;
}
s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameSound) {
s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample) {
Note* note;
if ((layer->continuousNotes == true) && (layer->bit1 == true)) {
return 0;
}
if ((layer->continuousNotes == true) && (layer->note != NULL) && layer->bit3 && (sameSound == true) &&
if ((layer->continuousNotes == true) && (layer->note != NULL) && layer->bit3 && (sameTunedSample == true) &&
(layer->note->playbackState.parentLayer == layer)) {
if (layer->sound == NULL) {
if (layer->tunedSample == NULL) {
AudioPlayback_InitSyntheticWave(layer->note, layer);
}
} else {
if (!sameSound) {
if (!sameTunedSample) {
AudioPlayback_SeqLayerNoteDecay(layer);
}
@@ -815,7 +815,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep2(SequenceLayer* layer) {
}
s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
s32 sameSound = true;
s32 sameTunedSample = true;
s32 instOrWave;
s32 speed;
f32 temp_f14;
@@ -823,10 +823,10 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
Portamento* portamento;
f32 freqScale;
f32 freqScale2;
SoundFontSound* sound;
TunedSample* tunedSample;
Instrument* instrument;
Drum* drum;
s32 pad;
SoundEffect* soundEffect;
SequenceChannel* channel;
SequencePlayer* seqPlayer;
u8 semitone = cmd;
@@ -861,15 +861,15 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
return PROCESS_SCRIPT_END;
}
sound = &drum->sound;
tunedSample = &drum->tunedSample;
layer->adsr.envelope = drum->envelope;
layer->adsr.decayIndex = drum->adsrDecayIndex;
if (!layer->ignoreDrumPan) {
layer->pan = drum->pan;
}
layer->sound = sound;
layer->freqScale = sound->tuning;
layer->tunedSample = tunedSample;
layer->freqScale = tunedSample->tuning;
break;
case 1:
@@ -877,15 +877,16 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
layer->semitone = semitone;
sfxId = (layer->transposition << 6) + semitone;
sound = AudioPlayback_GetSfx(channel->fontId, sfxId);
if (sound == NULL) {
soundEffect = AudioPlayback_GetSoundEffect(channel->fontId, sfxId);
if (soundEffect == NULL) {
layer->stopSomething = true;
layer->delay2 = layer->delay + 1;
return PROCESS_SCRIPT_END;
}
layer->sound = sound;
layer->freqScale = sound->tuning;
tunedSample = &soundEffect->tunedSample;
layer->tunedSample = tunedSample;
layer->freqScale = tunedSample->tuning;
break;
default:
@@ -909,15 +910,15 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
vel = (semitone > layer->portamentoTargetNote) ? semitone : layer->portamentoTargetNote;
if (instrument != NULL) {
sound = AudioPlayback_InstrumentGetSound(instrument, vel);
sameSound = (layer->sound == sound);
layer->sound = sound;
tuning = sound->tuning;
tunedSample = AudioPlayback_GetInstrumentTunedSample(instrument, vel);
sameTunedSample = (layer->tunedSample == tunedSample);
layer->tunedSample = tunedSample;
tuning = tunedSample->tuning;
} else {
layer->sound = NULL;
layer->tunedSample = NULL;
tuning = 1.0f;
if (instOrWave >= 0xC0) {
layer->sound = &gAudioContext.synthesisReverbs[instOrWave - 0xC0].sound;
layer->tunedSample = &gAudioContext.synthesisReverbs[instOrWave - 0xC0].tunedSample;
}
}
@@ -971,15 +972,15 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
}
if (instrument != NULL) {
sound = AudioPlayback_InstrumentGetSound(instrument, semitone);
sameSound = (sound == layer->sound);
layer->sound = sound;
layer->freqScale = gPitchFrequencies[semitone2] * sound->tuning;
tunedSample = AudioPlayback_GetInstrumentTunedSample(instrument, semitone);
sameTunedSample = (tunedSample == layer->tunedSample);
layer->tunedSample = tunedSample;
layer->freqScale = gPitchFrequencies[semitone2] * tunedSample->tuning;
} else {
layer->sound = NULL;
layer->tunedSample = NULL;
layer->freqScale = gPitchFrequencies[semitone2];
if (instOrWave >= 0xC0) {
layer->sound = &gAudioContext.synthesisReverbs[instOrWave - 0xC0].sound;
layer->tunedSample = &gAudioContext.synthesisReverbs[instOrWave - 0xC0].tunedSample;
}
}
break;
@@ -989,8 +990,8 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
layer->freqScale *= layer->bend;
if (layer->delay == 0) {
if (layer->sound != NULL) {
time = layer->sound->sample->loop->end;
if (layer->tunedSample != NULL) {
time = layer->tunedSample->sample->loop->end;
} else {
time = 0.0f;
}
@@ -1020,7 +1021,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
}
}
}
return sameSound;
return sameTunedSample;
}
s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) {
@@ -1571,7 +1572,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
channel->unk_0F = 0;
channel->unk_20 = 0;
channel->bookOffset = 0;
channel->unk_DC = 0;
channel->startSamplePos = 0;
channel->unk_E0 = 0;
channel->freqScale = 1.0f;
break;
@@ -1659,7 +1660,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break;
case 0xBD: // channel:
channel->unk_DC = cmdArgs[0];
channel->startSamplePos = cmdArgs[0];
break;
case 0xBE: // channel:
@@ -1672,10 +1673,10 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
}
break;
case 0xA0: // channel:
case 0xA1: // channel:
case 0xA2: // channel:
case 0xA3: // channel:
case 0xA0: // channel: read from SfxChannelState using arg
case 0xA1: // channel: read from SfxChannelState using unk_22
case 0xA2: // channel: write to SfxChannelState using arg
case 0xA3: // channel: write to SfxChannelState using unk_22
if ((cmd == 0xA0) || (cmd == 0xA2)) {
cmdArgU16 = (u16)cmdArgs[0];
} else {
@@ -1958,15 +1959,15 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
cmd = AudioSeq_ScriptReadU8(seqScript);
temp = AudioSeq_ScriptReadS16(seqScript);
switch (cmd) {
case 0:
case 1:
if (seqPlayer->state != 2) {
case SEQPLAYER_STATE_0:
case SEQPLAYER_STATE_1:
if (seqPlayer->state != SEQPLAYER_STATE_2) {
seqPlayer->fadeTimerUnkEu = temp;
seqPlayer->state = cmd;
}
break;
case 2:
case SEQPLAYER_STATE_2:
seqPlayer->fadeTimer = temp;
seqPlayer->state = cmd;
seqPlayer->fadeVelocity = (0.0f - seqPlayer->fadeVolume) / (s32)seqPlayer->fadeTimer;
@@ -1977,11 +1978,11 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
case 0xDB: // seqPlayer: set volume
value = AudioSeq_ScriptReadU8(seqScript);
switch (seqPlayer->state) {
case 1:
seqPlayer->state = 0;
case SEQPLAYER_STATE_1:
seqPlayer->state = SEQPLAYER_STATE_0;
seqPlayer->fadeVolume = 0.0f;
// fallthrough
case 0:
case SEQPLAYER_STATE_0:
seqPlayer->fadeTimer = seqPlayer->fadeTimerUnkEu;
if (seqPlayer->fadeTimerUnkEu != 0) {
seqPlayer->fadeVelocity =
@@ -1991,7 +1992,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
}
break;
case 2:
case SEQPLAYER_STATE_2:
break;
}
break;
@@ -2102,7 +2103,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
cmd = AudioSeq_ScriptReadU8(seqScript);
if (cmd == 0xFF) {
cmd = seqPlayer->playerIndex;
if (seqPlayer->state == 2) {
if (seqPlayer->state == SEQPLAYER_STATE_2) {
break;
}
}
@@ -2224,7 +2225,7 @@ void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer) {
AudioSeq_SequencePlayerDisable(seqPlayer);
seqPlayer->stopScript = false;
seqPlayer->delay = 0;
seqPlayer->state = 1;
seqPlayer->state = SEQPLAYER_STATE_1;
seqPlayer->fadeTimer = 0;
seqPlayer->fadeTimerUnkEu = 0;
seqPlayer->tempoAcc = 0;
+6 -6
View File
@@ -200,8 +200,8 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
gfxCtx->viConfigFeatures = gViConfigFeatures;
gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale;
gameState->nextGameStateInit = NULL;
gameState->nextGameStateSize = 0;
gameState->init = NULL;
gameState->size = 0;
{
s32 requiredScopeTemp;
@@ -242,12 +242,12 @@ void GameState_Destroy(GameState* gameState) {
GameAlloc_Cleanup(&gameState->alloc);
}
GameStateFunc GameState_GetNextStateInit(GameState* gameState) {
return gameState->nextGameStateInit;
GameStateFunc GameState_GetInit(GameState* gameState) {
return gameState->init;
}
size_t GameState_GetNextStateSize(GameState* gameState) {
return gameState->nextGameStateSize;
size_t GameState_GetSize(GameState* gameState) {
return gameState->size;
}
u32 GameState_IsRunning(GameState* gameState) {
+16 -14
View File
@@ -6,6 +6,7 @@
#include "overlays/gamestates/ovl_opening/z_opening.h"
#include "overlays/gamestates/ovl_select/z_select.h"
#include "overlays/gamestates/ovl_title/z_title.h"
#include "z_title_setup.h"
FaultAddrConvClient sGraphFaultAddrConvClient;
FaultClient sGraphFaultClient;
@@ -63,44 +64,45 @@ void Graph_SetNextGfxPool(GraphicsContext* gfxCtx) {
}
GameStateOverlay* Graph_GetNextGameState(GameState* gameState) {
GameStateFunc gameStateInit = GameState_GetNextStateInit(gameState);
GameStateFunc gameStateInit = GameState_GetInit(gameState);
if (gameStateInit == (GameStateFunc)TitleSetup_Init) {
if (gameStateInit == Setup_Init) {
return &gGameStateOverlayTable[0];
}
if (gameStateInit == (GameStateFunc)MapSelect_Init) {
if (gameStateInit == MapSelect_Init) {
return &gGameStateOverlayTable[1];
}
if (gameStateInit == (GameStateFunc)Title_Init) {
if (gameStateInit == ConsoleLogo_Init) {
return &gGameStateOverlayTable[2];
}
if (gameStateInit == (GameStateFunc)Play_Init) {
if (gameStateInit == Play_Init) {
return &gGameStateOverlayTable[3];
}
if (gameStateInit == (GameStateFunc)Opening_Init) {
if (gameStateInit == TitleSetup_Init) {
return &gGameStateOverlayTable[4];
}
if (gameStateInit == (GameStateFunc)FileChoose_Init) {
if (gameStateInit == FileSelect_Init) {
return &gGameStateOverlayTable[5];
}
if (gameStateInit == (GameStateFunc)Daytelop_Init) {
if (gameStateInit == DayTelop_Init) {
return &gGameStateOverlayTable[6];
}
return NULL;
}
void* Graph_FaultAddrConvFunc(void* address, void* param) {
uintptr_t addr = address;
GameStateOverlay* gamestateOvl = &gGameStateOverlayTable[0];
GameStateOverlay* gameStateOvl = &gGameStateOverlayTable[0];
uintptr_t ramConv;
void* ramStart;
uintptr_t diff;
s32 i;
for (i = 0; i < graphNumGameStates; i++, gamestateOvl++) {
diff = VRAM_PTR_SIZE(gamestateOvl);
ramStart = gamestateOvl->loadedRamAddr;
ramConv = (uintptr_t)gamestateOvl->vramStart - (uintptr_t)ramStart;
for (i = 0; i < graphNumGameStates; i++, gameStateOvl++) {
diff = VRAM_PTR_SIZE(gameStateOvl);
ramStart = gameStateOvl->loadedRamAddr;
ramConv = (uintptr_t)gameStateOvl->vramStart - (uintptr_t)ramStart;
if (ramStart != NULL) {
if (addr >= (uintptr_t)ramStart && addr < (uintptr_t)ramStart + diff) {
@@ -235,7 +237,7 @@ void Graph_UpdateGame(GameState* gameState) {
}
/**
* Run the gamestate logic, then finalize the gfx buffer
* Run the game state logic, then finalize the gfx buffer
* and run the graphics task for this frame.
*/
void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) {
+13 -15
View File
@@ -1,14 +1,14 @@
#include "global.h"
#include "z_title_setup.h"
#include "overlays/gamestates/ovl_title/z_title.h"
void TitleSetup_GameStateResetContext(void) {
void Setup_SetRegs(void) {
XREG(2) = 0;
XREG(10) = 0x1A;
XREG(11) = 0x14;
XREG(12) = 0xE;
XREG(13) = 0;
XREG(31) = 0;
XREG(41) = 0x50;
R_MAGIC_CONSUME_TIMER_GIANTS_MASK = 80;
XREG(43) = 0xFC54;
XREG(44) = 0xD7;
@@ -45,23 +45,21 @@ void TitleSetup_GameStateResetContext(void) {
YREG(43) = 0xB1;
}
void TitleSetup_InitImpl(GameState* gameState) {
void Setup_InitImpl(SetupState* this) {
func_80185908();
SaveContext_Init();
TitleSetup_GameStateResetContext();
Setup_SetRegs();
gameState->running = 0;
setNextGamestate
:; // This label is probably a leftover of a debug ifdef, it's essential to not have gameState->running reordered!
SET_NEXT_GAMESTATE(gameState, Title_Init, TitleContext);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, ConsoleLogo_Init, sizeof(ConsoleLogoState));
}
void TitleSetup_Destroy(GameState* gameState) {
;
void Setup_Destroy(GameState* thisx) {
}
void TitleSetup_Init(GameState* gameState) {
gameState->destroy = TitleSetup_Destroy;
TitleSetup_InitImpl(gameState);
void Setup_Init(GameState* thisx) {
SetupState* this = (SetupState*)thisx;
this->state.destroy = Setup_Destroy;
Setup_InitImpl(this);
}
+48 -49
View File
@@ -692,7 +692,7 @@ void func_800B5814(TargetContext* targetCtx, Player* player, Actor* actor, GameS
*/
s32 Flags_GetSwitch(PlayState* play, s32 flag) {
if (flag >= 0 && flag < 0x80) {
return play->actorCtx.flags.switches[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F));
return play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F));
}
return 0;
}
@@ -702,7 +702,7 @@ s32 Flags_GetSwitch(PlayState* play, s32 flag) {
*/
void Flags_SetSwitch(PlayState* play, s32 flag) {
if (flag >= 0 && flag < 0x80) {
play->actorCtx.flags.switches[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F);
play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F);
}
}
@@ -711,7 +711,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) {
*/
void Flags_UnsetSwitch(PlayState* play, s32 flag) {
if (flag >= 0 && flag < 0x80) {
play->actorCtx.flags.switches[(flag & ~0x1F) >> 5] &= ~(1 << (flag & 0x1F));
play->actorCtx.sceneFlags.switches[(flag & ~0x1F) >> 5] &= ~(1 << (flag & 0x1F));
}
}
@@ -719,70 +719,70 @@ void Flags_UnsetSwitch(PlayState* play, s32 flag) {
* Tests if current scene chest flag is set.
*/
s32 Flags_GetTreasure(PlayState* play, s32 flag) {
return play->actorCtx.flags.chest & (1 << flag);
return play->actorCtx.sceneFlags.chest & (1 << flag);
}
/**
* Sets current scene chest flag.
*/
void Flags_SetTreasure(PlayState* play, s32 flag) {
play->actorCtx.flags.chest |= (1 << flag);
play->actorCtx.sceneFlags.chest |= (1 << flag);
}
/**
* Overrides the all the chest flags.
*/
void Flags_SetAllTreasure(PlayState* play, s32 flag) {
play->actorCtx.flags.chest = flag;
play->actorCtx.sceneFlags.chest = flag;
}
/**
* Returns all the chest flags.
*/
s32 Flags_GetAllTreasure(PlayState* play) {
return play->actorCtx.flags.chest;
return play->actorCtx.sceneFlags.chest;
}
/**
* Tests if current scene clear flag is set.
*/
s32 Flags_GetClear(PlayState* play, s32 roomNumber) {
return play->actorCtx.flags.clearedRoom & (1 << roomNumber);
return play->actorCtx.sceneFlags.clearedRoom & (1 << roomNumber);
}
/**
* Sets current scene clear flag.
*/
void Flags_SetClear(PlayState* play, s32 roomNumber) {
play->actorCtx.flags.clearedRoom |= (1 << roomNumber);
play->actorCtx.sceneFlags.clearedRoom |= (1 << roomNumber);
}
/**
* Unsets current scene clear flag.
*/
void Flags_UnsetClear(PlayState* play, s32 roomNumber) {
play->actorCtx.flags.clearedRoom &= ~(1 << roomNumber);
play->actorCtx.sceneFlags.clearedRoom &= ~(1 << roomNumber);
}
/**
* Tests if current scene temp clear flag is set.
*/
s32 Flags_GetClearTemp(PlayState* play, s32 roomNumber) {
return play->actorCtx.flags.clearedRoomTemp & (1 << roomNumber);
return play->actorCtx.sceneFlags.clearedRoomTemp & (1 << roomNumber);
}
/**
* Sets current scene temp clear flag.
*/
void Flags_SetClearTemp(PlayState* play, s32 roomNumber) {
play->actorCtx.flags.clearedRoomTemp |= (1 << roomNumber);
play->actorCtx.sceneFlags.clearedRoomTemp |= (1 << roomNumber);
}
/**
* Unsets current scene temp clear flag.
*/
void Flags_UnsetClearTemp(PlayState* play, s32 roomNumber) {
play->actorCtx.flags.clearedRoomTemp &= ~(1 << roomNumber);
play->actorCtx.sceneFlags.clearedRoomTemp &= ~(1 << roomNumber);
}
/**
@@ -790,7 +790,7 @@ void Flags_UnsetClearTemp(PlayState* play, s32 roomNumber) {
*/
s32 Flags_GetCollectible(PlayState* play, s32 flag) {
if (flag > 0 && flag < 0x80) {
return play->actorCtx.flags.collectible[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F));
return play->actorCtx.sceneFlags.collectible[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F));
}
return 0;
}
@@ -800,7 +800,7 @@ s32 Flags_GetCollectible(PlayState* play, s32 flag) {
*/
void Flags_SetCollectible(PlayState* play, s32 flag) {
if (flag > 0 && flag < 0x80) {
play->actorCtx.flags.collectible[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F);
play->actorCtx.sceneFlags.collectible[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F);
}
}
@@ -1076,7 +1076,7 @@ void Actor_Init(Actor* actor, PlayState* play) {
actor->uncullZoneScale = 350.0f;
actor->uncullZoneDownward = 700.0f;
actor->hintId = 255;
actor->hintId = TATL_HINT_ID_NONE;
CollisionCheck_InitInfo(&actor->colChkInfo);
actor->floorBgId = BGCHECK_SCENE;
@@ -2212,10 +2212,10 @@ s32 func_800B90AC(PlayState* play, Actor* actor, CollisionPoly* polygon, s32 bgI
return false;
}
void func_800B90F4(PlayState* play) {
if (play->actorCtx.unk3 != 0) {
play->actorCtx.unk3 = 0;
func_80115D5C(&play->state);
void Actor_DeactivateLens(PlayState* play) {
if (play->actorCtx.lensActive) {
play->actorCtx.lensActive = false;
Magic_Reset(play);
}
}
@@ -2249,14 +2249,14 @@ void Actor_InitContext(PlayState* play, ActorContext* actorCtx, ActorEntry* acto
overlayEntry++;
}
actorCtx->flags.chest = cycleFlags->chest;
actorCtx->flags.switches[0] = cycleFlags->switch0;
actorCtx->flags.switches[1] = cycleFlags->switch1;
actorCtx->sceneFlags.chest = cycleFlags->chest;
actorCtx->sceneFlags.switches[0] = cycleFlags->switch0;
actorCtx->sceneFlags.switches[1] = cycleFlags->switch1;
if (play->sceneNum == SCENE_INISIE_R) {
cycleFlags = &gSaveContext.cycleSceneFlags[play->sceneNum];
}
actorCtx->flags.collectible[0] = cycleFlags->collectible;
actorCtx->flags.clearedRoom = cycleFlags->clearedRoom;
actorCtx->sceneFlags.collectible[0] = cycleFlags->collectible;
actorCtx->sceneFlags.clearedRoom = cycleFlags->clearedRoom;
TitleCard_ContextInit(&play->state, &actorCtx->titleCtxt);
func_800B6468(play);
@@ -2594,7 +2594,7 @@ void func_800B9D1C(Actor* actor) {
void Actor_DrawAllSetup(PlayState* play) {
play->actorCtx.undrawnActorCount = 0;
play->actorCtx.unkB = 0;
play->actorCtx.lensActorsDrawn = false;
}
s32 Actor_RecordUndrawnActor(PlayState* play, Actor* actor) {
@@ -2607,13 +2607,12 @@ s32 Actor_RecordUndrawnActor(PlayState* play, Actor* actor) {
return true;
}
void func_800B9E84(Gfx** arg0, s32 arg1) {
func_80164C14(arg0, D_801DE890, 4, 0, 6, 6, ((100 - arg1) * 0.003f) + 1.0f);
void Actor_DrawLensOverlay(Gfx** gfxP, s32 lensMaskSize) {
func_80164C14(gfxP, &gCircleTex, 4, 0, 6, 6, ((LENS_MASK_ACTIVE_SIZE - lensMaskSize) * 0.003f) + 1.0f);
}
#ifdef NON_EQUIVALENT
// Related to draw actors with lens
void func_800B9EF4(PlayState* play, s32 numActors, Actor** actors) {
void Actor_DrawLensActors(PlayState* play, s32 numActors, Actor** actors) {
s32 spB4;
Gfx* spAC;
void* spA8; // pad
@@ -2684,7 +2683,7 @@ void func_800B9EF4(PlayState* play, s32 numActors, Actor** actors) {
}
// spAC = phi_s1;
func_800B9E84(&spAC, play->actorCtx.unk4);
Actor_DrawLensOverlay(&spAC, play->actorCtx.lensMaskSize);
phi_s1_2 = func_801660B8(play, spAC);
for (spB4 = 0; spB4 < numActors; spB4++, actors++) {
@@ -2744,7 +2743,7 @@ void func_800B9EF4(PlayState* play, s32 numActors, Actor** actors) {
spAC = phi_s1_2;
// spAC = temp_s1_11;
func_800B9E84(&spAC, (s32)play->actorCtx.unk4);
Actor_DrawLensOverlay(&spAC, (s32)play->actorCtx.lensMaskSize);
// temp_s1_11->words.w0 = 0xE7000000;
// temp_s1_11->words.w1 = 0;
// temp_s1_12 = temp_s1_11 + 8;
@@ -2796,15 +2795,15 @@ void func_800B9EF4(PlayState* play, s32 numActors, Actor** actors) {
// spAC = temp_s1_18 + 8;
gDPSetPrimColor(spAC++, 0, 0, 74, 0, 0, 74);
func_800B9E84(&spAC, (s32)play->actorCtx.unk4);
Actor_DrawLensOverlay(&spAC, (s32)play->actorCtx.lensMaskSize);
OVERLAY_DISP = spAC;
CLOSE_DISPS(play->state.gfxCtx);
}
#else
void func_800B9EF4(PlayState* play, s32 numActors, Actor** actors);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9EF4.s")
void Actor_DrawLensActors(PlayState* play, s32 numActors, Actor** actors);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_DrawLensActors.s")
#endif
s32 func_800BA2D8(PlayState* play, Actor* actor) {
@@ -2883,7 +2882,7 @@ void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
actor->isDrawn = false;
if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & actorFlags)) {
if ((actor->flags & ACTOR_FLAG_80) &&
((play->roomCtx.currRoom.unk5 == 0) || (play->actorCtx.unk4 == 0x64) ||
((play->roomCtx.currRoom.unk5 == 0) || (play->actorCtx.lensMaskSize == LENS_MASK_ACTIVE_SIZE) ||
(actor->room != play->roomCtx.currRoom.num))) {
if (Actor_RecordUndrawnActor(play, actor)) {}
} else {
@@ -2903,17 +2902,17 @@ void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
gSPDisplayList(sp58, &ref2[1]);
POLY_XLU_DISP = &ref2[1];
if (play->actorCtx.unk3 != 0) {
Math_StepToC(&play->actorCtx.unk4, 100, 20);
if (play->actorCtx.lensActive) {
Math_StepToC(&play->actorCtx.lensMaskSize, LENS_MASK_ACTIVE_SIZE, 20);
if (GET_PLAYER(play)->stateFlags2 & 0x8000000) {
func_800B90F4(play);
Actor_DeactivateLens(play);
}
} else {
Math_StepToC(&play->actorCtx.unk4, 0, 10);
Math_StepToC(&play->actorCtx.lensMaskSize, 0, 10);
}
if (play->actorCtx.unk4 != 0) {
play->actorCtx.unkB = 1;
func_800B9EF4(play, play->actorCtx.undrawnActorCount, play->actorCtx.undrawnActors);
if (play->actorCtx.lensMaskSize != 0) {
play->actorCtx.lensActorsDrawn = true;
Actor_DrawLensActors(play, play->actorCtx.undrawnActorCount, play->actorCtx.undrawnActors);
}
tmp2 = POLY_XLU_DISP;
@@ -2977,9 +2976,9 @@ void func_800BA798(PlayState* play, ActorContext* actorCtx) {
}
CollisionCheck_ClearContext(play, &play->colChkCtx);
actorCtx->flags.clearedRoomTemp = 0;
actorCtx->flags.switches[3] = 0;
actorCtx->flags.collectible[3] = 0;
actorCtx->sceneFlags.clearedRoomTemp = 0;
actorCtx->sceneFlags.switches[3] = 0;
actorCtx->sceneFlags.collectible[3] = 0;
play->msgCtx.unk_12030 = 0;
}
@@ -3815,9 +3814,9 @@ typedef struct {
} DoorLockInfo; // size = 0x1C
DoorLockInfo sDoorLocksInfo[DOORLOCK_MAX] = {
/* DOORLOCK_NORMAL */ { 0.54f, 6000.0f, 5000.0, 1.0f, 0.0f, gDoorChainsDL, gDoorLockDL },
/* DOORLOCK_BOSS */ { 0.644f, 12000.0f, 8000.0f, 1.0f, 0.0f, object_bdoor_DL_000530, object_bdoor_DL_000400 },
/* DOORLOCK_2 */ { 0.6400000453f, 8500.0f, 8000.0f, 1.75f, 0.1f, gDoorChainsDL, gDoorLockDL },
/* DOORLOCK_NORMAL */ { 0.54f, 6000.0f, 5000.0, 1.0f, 0.0f, gDoorChainDL, gDoorLockDL },
/* DOORLOCK_BOSS */ { 0.644f, 12000.0f, 8000.0f, 1.0f, 0.0f, gBossDoorChainDL, gBossDoorLockDL },
/* DOORLOCK_2 */ { 0.6400000453f, 8500.0f, 8000.0f, 1.75f, 0.1f, gDoorChainDL, gDoorLockDL },
};
/**
+5 -9
View File
@@ -126,12 +126,11 @@ void func_800EA2B8(PlayState* play, CutsceneContext* csCtx) {
/* Start of command handling section */
// Command 0x96: Miscellaneous commands.
void Cutscene_Command_Misc(PlayState* play2, CutsceneContext* csCtx, CsCmdBase* cmd) {
void Cutscene_Command_Misc(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
static u16 D_801BB15C = 0xFFFF;
Player* player = GET_PLAYER(play2);
PlayState* play = play2;
u8 isStartFrame = false;
Player* player = GET_PLAYER(play);
f32 progress;
u8 isStartFrame = false;
SceneTableEntry* loadedScene;
if ((csCtx->frames < cmd->startFrame) || ((csCtx->frames >= cmd->endFrame) && (cmd->endFrame != cmd->startFrame))) {
@@ -346,11 +345,8 @@ void Cutscene_Command_Misc(PlayState* play2, CutsceneContext* csCtx, CsCmdBase*
gSaveContext.save.day = 9;
{
GameState* gameState = &play->state;
gameState->running = false;
}
SET_NEXT_GAMESTATE(&play->state, Daytelop_Init, DaytelopContext);
STOP_GAMESTATE(&play->state);
SET_NEXT_GAMESTATE(&play->state, DayTelop_Init, sizeof(DayTelopState));
Sram_SaveSpecialNewDay(play);
break;
+34 -21
View File
@@ -91,63 +91,76 @@ void EffectSsDust_Spawn(PlayState* play, u16 drawFlags, Vec3f* pos, Vec3f* veloc
void func_800B0DE0(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 0, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG0, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10,
DUST_UPDATE_NORMAL);
}
void func_800B0E48(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10,
DUST_UPDATE_NORMAL);
}
void func_800B0EB0(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life) {
EffectSsDust_Spawn(play, 0, pos, velocity, accel, primColor, envColor, scale, scaleStep, life, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG0, pos, velocity, accel, primColor, envColor, scale, scaleStep, life,
DUST_UPDATE_NORMAL);
}
void func_800B0F18(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life) {
EffectSsDust_Spawn(play, 1, pos, velocity, accel, primColor, envColor, scale, scaleStep, life, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG1, pos, velocity, accel, primColor, envColor, scale, scaleStep, life,
DUST_UPDATE_NORMAL);
}
void func_800B0F80(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life) {
EffectSsDust_Spawn(play, 2, pos, velocity, accel, primColor, envColor, scale, scaleStep, life, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG2, pos, velocity, accel, primColor, envColor, scale, scaleStep, life,
DUST_UPDATE_NORMAL);
}
void func_800B0FE8(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 0, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 1);
EffectSsDust_Spawn(play, DUST_DRAWFLAG0, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10,
DUST_UPDATE_FIRE);
}
void func_800B1054(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 1);
EffectSsDust_Spawn(play, DUST_DRAWFLAG1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10,
DUST_UPDATE_FIRE);
}
static Color_RGBA8 sDustBrownPrim = { 170, 130, 90, 255 };
static Color_RGBA8 sDustBrownEnv = { 100, 60, 20, 255 };
void func_800B10C0(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
EffectSsDust_Spawn(play, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG0, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, 100, 5, 10, DUST_UPDATE_NORMAL);
}
void func_800B1130(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
EffectSsDust_Spawn(play, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG1, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, 100, 5, 10, DUST_UPDATE_NORMAL);
}
void func_800B11A0(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG0, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, scale, scaleStep, 10, DUST_UPDATE_NORMAL);
}
void func_800B1210(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) {
EffectSsDust_Spawn(play, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG1, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, scale, scaleStep, 10, DUST_UPDATE_NORMAL);
}
void func_800B1280(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life) {
EffectSsDust_Spawn(play, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG0, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, scale, scaleStep, life, DUST_UPDATE_NORMAL);
}
void func_800B12F0(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life) {
EffectSsDust_Spawn(play, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0);
EffectSsDust_Spawn(play, DUST_DRAWFLAG_RAND_COLOR_OFFSET | DUST_DRAWFLAG1, pos, velocity, accel, &sDustBrownPrim,
&sDustBrownEnv, scale, scaleStep, life, DUST_UPDATE_NORMAL);
}
void func_800B1360(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
@@ -285,7 +298,7 @@ void EffectSsBomb2_SpawnLayered(PlayState* play, Vec3f* pos, Vec3f* velocity, Ve
// EffectSsBlast Spawn Functions
void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 sclaeStepDecay, s16 life) {
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 scaleStepDecay, s16 life) {
EffectSsBlastInitParams initParams;
Math_Vec3f_Copy(&initParams.pos, pos);
@@ -295,7 +308,7 @@ void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* ac
Color_RGBA8_Copy(&initParams.envColor, envColor);
initParams.scale = scale;
initParams.scaleStep = scaleStep;
initParams.sclaeStepDecay = sclaeStepDecay;
initParams.scaleStepDecay = scaleStepDecay;
initParams.life = life;
EffectSs_Spawn(play, EFFECT_SS_BLAST, 128, &initParams);
@@ -391,7 +404,7 @@ void EffectSsGSpk_SpawnSmall(PlayState* play, Actor* actor, Vec3f* pos, Vec3f* v
// EffectSsDFire Spawn Functions
void EffectSsDFire_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep,
s16 alpha, s16 fadeDelay, s16 arg8, s32 life) {
s16 alpha, s16 alphaStep, s16 fadeDelay, s32 life) {
EffectSsDFireInitParams initParams;
Math_Vec3f_Copy(&initParams.pos, pos);
@@ -400,8 +413,8 @@ void EffectSsDFire_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* ac
initParams.scale = scale;
initParams.scaleStep = scaleStep;
initParams.alpha = alpha;
initParams.alphaStep = alphaStep;
initParams.fadeDelay = fadeDelay;
initParams.unk_2C = arg8;
initParams.life = life;
EffectSs_Spawn(play, EFFECT_SS_D_FIRE, 128, &initParams);
@@ -492,7 +505,7 @@ void EffectSsDtBubble_SpawnColorProfile(PlayState* play, Vec3f* pos, Vec3f* velo
Math_Vec3f_Copy(&initParams.pos, pos);
Math_Vec3f_Copy(&initParams.velocity, velocity);
Math_Vec3f_Copy(&initParams.accel, accel);
initParams.customColor = 0;
initParams.customColor = false;
initParams.colorProfile = colorProfile;
initParams.scale = scale;
initParams.life = life;
@@ -513,7 +526,7 @@ void EffectSsDtBubble_SpawnCustomColor(PlayState* play, Vec3f* pos, Vec3f* veloc
initParams.scale = scale;
initParams.life = life;
initParams.randXZ = randXZ;
initParams.customColor = 1;
initParams.customColor = true;
EffectSs_Spawn(play, EFFECT_SS_DT_BUBBLE, 128, &initParams);
}
@@ -927,7 +940,7 @@ void EffectSsExtra_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* ac
// EffectSsDeadDb Spawn Functions
void EffectSsDeadDb_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim,
Color_RGBA8* env, s16 scale, s16 scaleStep, s32 unk) {
Color_RGBA8* env, s16 scale, s16 scaleStep, s32 life) {
EffectSsDeadDbInitParams initParams;
Math_Vec3f_Copy(&initParams.pos, pos);
@@ -942,7 +955,7 @@ void EffectSsDeadDb_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* a
initParams.envColor.r = env->r;
initParams.envColor.g = env->g;
initParams.envColor.b = env->b;
initParams.unk_30 = unk;
initParams.life = life;
EffectSs_Spawn(play, EFFECT_SS_DEAD_DB, 120, &initParams);
}
+1 -1
View File
@@ -25,7 +25,7 @@ u16 ElfMessage_GetFirstCycleHint(PlayState* play) {
}
return 0x21D;
}
if (gSaveContext.save.playerData.magicAcquired != true) {
if (gSaveContext.save.playerData.isMagicAcquired != true) {
return 0x21F;
}
if (INV_CONTENT(ITEM_DEED_LAND) == ITEM_DEED_LAND) {
+133 -73
View File
@@ -18,6 +18,11 @@ void func_800A6650(EnItem00* this, PlayState* play);
void func_800A6780(EnItem00* this, PlayState* play);
void func_800A6A40(EnItem00* this, PlayState* play);
void EnItem00_DrawRupee(EnItem00* this, PlayState* play);
void EnItem00_DrawSprite(EnItem00* this, PlayState* play);
void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play);
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play);
const ActorInit En_Item00_InitVars = {
ACTOR_EN_ITEM00,
ACTORCAT_MISC,
@@ -102,12 +107,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->unk154 = 0.015f;
shadowOffset = 750.0f;
break;
case ITEM00_SMALL_KEY:
this->unk150 = 0;
Actor_SetScale(&this->actor, 0.03f);
this->unk154 = 0.03f;
shadowOffset = 350.0f;
break;
case ITEM00_HEART_PIECE:
case ITEM00_HEART_CONTAINER:
this->unk150 = 0;
@@ -118,12 +125,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
sp30 = -1;
}
break;
case ITEM00_RECOVERY_HEART:
this->actor.home.rot.z = randPlusMinusPoint5Scaled(65535.0f);
this->actor.home.rot.z = randPlusMinusPoint5Scaled(0xFFFF);
shadowOffset = 430.0f;
Actor_SetScale(&this->actor, 0.02f);
this->unk154 = 0.02f;
break;
case ITEM00_ARROWS_10:
case ITEM00_ARROWS_30:
case ITEM00_ARROWS_40:
@@ -132,6 +141,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->unk154 = 0.035f;
shadowOffset = 250.0f;
break;
case ITEM00_BOMBS_A:
case ITEM00_BOMBS_B:
case ITEM00_NUTS_1:
@@ -143,39 +153,47 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->unk154 = 0.03f;
shadowOffset = 320.0f;
break;
case ITEM00_MAGIC_LARGE:
Actor_SetScale(&this->actor, 0.044999998f);
this->unk154 = 0.044999998f;
Actor_SetScale(&this->actor, 4.5f * 0.01f);
this->unk154 = 4.5f * 0.01f;
shadowOffset = 320.0f;
break;
case ITEM00_RUPEE_HUGE:
Actor_SetScale(&this->actor, 0.044999998f);
this->unk154 = 0.044999998f;
Actor_SetScale(&this->actor, 4.5f * 0.01f);
this->unk154 = 4.5f * 0.01f;
shadowOffset = 750.0f;
break;
case ITEM00_RUPEE_PURPLE:
Actor_SetScale(&this->actor, 0.03f);
this->unk154 = 0.03f;
shadowOffset = 750.0f;
break;
case ITEM00_FLEXIBLE:
case ITEM00_BIG_FAIRY:
shadowOffset = 500.0f;
Actor_SetScale(&this->actor, 0.01f);
this->unk154 = 0.01f;
break;
case ITEM00_SHIELD_HERO:
this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_SHIELD_2);
EnItem00_SetObject(this, play, &shadowOffset, &shadowScale);
break;
case ITEM00_MAP:
this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_MAP);
EnItem00_SetObject(this, play, &shadowOffset, &shadowScale);
break;
case ITEM00_COMPASS:
this->actor.objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_COMPASS);
EnItem00_SetObject(this, play, &shadowOffset, &shadowScale);
break;
default:
break;
}
@@ -191,6 +209,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
this->unk152 = -1;
return;
}
if (sp30 == 0) {
this->actionFunc = func_800A640C;
this->unk152 = -1;
@@ -208,61 +227,78 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
case ITEM00_RUPEE_GREEN:
Item_Give(play, ITEM_RUPEE_GREEN);
break;
case ITEM00_RUPEE_BLUE:
Item_Give(play, ITEM_RUPEE_BLUE);
break;
case ITEM00_RUPEE_RED:
Item_Give(play, ITEM_RUPEE_RED);
break;
case ITEM00_RUPEE_PURPLE:
Item_Give(play, ITEM_RUPEE_PURPLE);
break;
case ITEM00_RUPEE_HUGE:
Item_Give(play, ITEM_RUPEE_HUGE);
break;
case ITEM00_RECOVERY_HEART:
Item_Give(play, ITEM_RECOVERY_HEART);
break;
case ITEM00_FLEXIBLE:
case ITEM00_BIG_FAIRY:
Health_ChangeBy(play, 0x70);
break;
case ITEM00_BOMBS_A:
case ITEM00_BOMBS_B:
Item_Give(play, ITEM_BOMBS_5);
break;
case ITEM00_ARROWS_10:
Item_Give(play, ITEM_ARROWS_10);
break;
case ITEM00_ARROWS_30:
Item_Give(play, ITEM_ARROWS_30);
break;
case ITEM00_ARROWS_40:
Item_Give(play, ITEM_ARROWS_40);
break;
case ITEM00_ARROWS_50:
Item_Give(play, ITEM_ARROWS_50);
break;
case ITEM00_MAGIC_LARGE:
Item_Give(play, ITEM_MAGIC_LARGE);
break;
case ITEM00_MAGIC_SMALL:
Item_Give(play, ITEM_MAGIC_SMALL);
break;
case ITEM00_SMALL_KEY:
Item_Give(play, ITEM_KEY_SMALL);
break;
case ITEM00_NUTS_1:
getItemId = GI_NUTS_1;
break;
case ITEM00_NUTS_10:
getItemId = GI_NUTS_10;
break;
default:
break;
}
if ((getItemId != GI_NONE) && (Actor_HasParent(&this->actor, play) == 0)) {
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) {
Actor_PickUp(&this->actor, play, getItemId, 50.0f, 20.0f);
}
@@ -277,11 +313,10 @@ void EnItem00_Destroy(Actor* thisx, PlayState* play) {
}
void EnItem00_WaitForHeartObject(EnItem00* this, PlayState* play) {
s32 sp1C;
s32 objBankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_HEARTS);
sp1C = Object_GetIndex(&play->objectCtx, OBJECT_GI_HEARTS);
if (Object_IsLoaded(&play->objectCtx, sp1C)) {
this->actor.objBankIndex = sp1C;
if (Object_IsLoaded(&play->objectCtx, objBankIndex)) {
this->actor.objBankIndex = objBankIndex;
this->actionFunc = func_800A640C;
}
}
@@ -327,15 +362,15 @@ void func_800A640C(EnItem00* this, PlayState* play) {
}
}
if ((this->actor.gravity != 0.0f) && ((this->actor.bgCheckFlags & 1) == 0)) {
if ((this->actor.gravity != 0.0f) && !(this->actor.bgCheckFlags & 1)) {
this->actionFunc = func_800A6650;
}
}
static Color_RGBA8 D_801ADF10 = { 255, 255, 127, 0 };
static Color_RGBA8 D_801ADF14 = { 255, 255, 255, 0 };
static Vec3f D_801ADF18 = { 0.0f, 0.1f, 0.0f };
static Vec3f D_801ADF24 = { 0.0f, 0.01f, 0.0f };
static Color_RGBA8 sEffectPrimColor = { 255, 255, 127, 0 };
static Color_RGBA8 sEffectEnvColor = { 255, 255, 255, 0 };
static Vec3f sEffectVelocity = { 0.0f, 0.1f, 0.0f };
static Vec3f sEffectAccel = { 0.0f, 0.01f, 0.0f };
void func_800A6650(EnItem00* this, PlayState* play) {
u32 pad;
@@ -344,20 +379,21 @@ void func_800A6650(EnItem00* this, PlayState* play) {
if (this->actor.params <= ITEM00_RUPEE_RED) {
this->actor.shape.rot.y = this->actor.shape.rot.y + 960;
}
if ((play->gameplayFrames & 1) != 0) {
pos.x = this->actor.world.pos.x + randPlusMinusPoint5Scaled(10.0f);
pos.y = this->actor.world.pos.y + randPlusMinusPoint5Scaled(10.0f);
pos.z = this->actor.world.pos.z + randPlusMinusPoint5Scaled(10.0f);
EffectSsKirakira_SpawnSmall(play, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14);
EffectSsKirakira_SpawnSmall(play, &pos, &sEffectVelocity, &sEffectAccel, &sEffectPrimColor, &sEffectEnvColor);
}
if ((this->actor.bgCheckFlags & 3) != 0) {
if (this->actor.bgCheckFlags & 3) {
if (this->actor.velocity.y > -2.0f) {
this->actionFunc = func_800A640C;
return;
} else {
this->actor.velocity.y = this->actor.velocity.y * -0.8f;
this->actor.bgCheckFlags &= ~1;
}
this->actor.velocity.y = this->actor.velocity.y * -0.8f;
this->actor.bgCheckFlags = this->actor.bgCheckFlags & 0xFFFE;
}
}
@@ -384,18 +420,18 @@ void func_800A6780(EnItem00* this, PlayState* play) {
}
if (this->actor.params <= ITEM00_RUPEE_RED) {
this->actor.shape.rot.y += 960;
this->actor.shape.rot.y += 0x3C0;
} else if ((this->actor.params >= ITEM00_SHIELD_HERO) && (this->actor.params != ITEM00_NUTS_10) &&
(this->actor.params != ITEM00_BOMBS_0)) {
this->actor.world.rot.x -= 700;
this->actor.shape.rot.y += 400;
this->actor.world.rot.x -= 0x2BC;
this->actor.shape.rot.y += 0x190;
this->actor.shape.rot.x = this->actor.world.rot.x - 0x4000;
}
if (this->actor.velocity.y <= 2.0f) {
var1 = (u16)this->actor.shape.rot.z + 10000;
if (var1 < 65535) {
this->actor.shape.rot.z += 10000;
var1 = (u16)this->actor.shape.rot.z + 0x2710;
if (var1 < 0xFFFF) {
this->actor.shape.rot.z += 0x2710;
} else {
this->actor.shape.rot.z = -1;
}
@@ -405,10 +441,10 @@ void func_800A6780(EnItem00* this, PlayState* play) {
pos.x = this->actor.world.pos.x + ((Rand_ZeroOne() - 0.5f) * 10.0f);
pos.y = this->actor.world.pos.y + ((Rand_ZeroOne() - 0.5f) * 10.0f);
pos.z = this->actor.world.pos.z + ((Rand_ZeroOne() - 0.5f) * 10.0f);
EffectSsKirakira_SpawnSmall(play, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14);
EffectSsKirakira_SpawnSmall(play, &pos, &sEffectVelocity, &sEffectAccel, &sEffectPrimColor, &sEffectEnvColor);
}
if (this->actor.bgCheckFlags & 0x0003) {
if (this->actor.bgCheckFlags & 3) {
this->actionFunc = func_800A640C;
this->actor.shape.rot.z = 0;
this->actor.speedXZ = 0.0f;
@@ -419,7 +455,7 @@ void func_800A6A40(EnItem00* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->getItemId != GI_NONE) {
if (Actor_HasParent(&this->actor, play) == 0) {
if (!Actor_HasParent(&this->actor, play)) {
Actor_PickUp(&this->actor, play, this->getItemId, 50.0f, 80.0f);
this->unk152++;
} else {
@@ -435,7 +471,7 @@ void func_800A6A40(EnItem00* this, PlayState* play) {
this->actor.world.pos = player->actor.world.pos;
if (this->actor.params <= ITEM00_RUPEE_RED) {
this->actor.shape.rot.y = this->actor.shape.rot.y + 960;
this->actor.shape.rot.y += 0x3C0;
} else if (this->actor.params == ITEM00_RECOVERY_HEART) {
this->actor.shape.rot.y = 0;
}
@@ -443,7 +479,7 @@ void func_800A6A40(EnItem00* this, PlayState* play) {
this->actor.world.pos.y += (40.0f + (Math_SinS(this->unk152 * 15000) * (this->unk152 * 0.3f)));
if (LINK_IS_ADULT) {
this->actor.world.pos.y = this->actor.world.pos.y + 20.0f;
this->actor.world.pos.y += 20.0f;
}
}
@@ -500,7 +536,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
}
}
if (play->gameOverCtx.state != 0) {
if (play->gameOverCtx.state != GAMEOVER_INACTIVE) {
return;
}
@@ -509,78 +545,101 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
this->unk1A4 = 1;
Item_Give(play, ITEM_RUPEE_GREEN);
break;
case ITEM00_RUPEE_BLUE:
this->unk1A4 = 1;
Item_Give(play, ITEM_RUPEE_BLUE);
break;
case ITEM00_RUPEE_RED:
this->unk1A4 = 1;
Item_Give(play, ITEM_RUPEE_RED);
break;
case ITEM00_RUPEE_PURPLE:
this->unk1A4 = 1;
Item_Give(play, ITEM_RUPEE_PURPLE);
break;
case ITEM00_RUPEE_HUGE:
this->unk1A4 = 1;
Item_Give(play, ITEM_RUPEE_HUGE);
break;
case ITEM00_STICK:
getItemId = GI_STICKS_1;
break;
case ITEM00_NUTS_1:
getItemId = GI_NUTS_1;
break;
case ITEM00_NUTS_10:
getItemId = GI_NUTS_10;
break;
case ITEM00_RECOVERY_HEART:
Item_Give(play, ITEM_RECOVERY_HEART);
break;
case ITEM00_FLEXIBLE:
case ITEM00_BIG_FAIRY:
Health_ChangeBy(play, 0x70);
break;
case ITEM00_BOMBS_A:
case ITEM00_BOMBS_B:
Item_Give(play, ITEM_BOMBS_5);
break;
case ITEM00_ARROWS_10:
Item_Give(play, ITEM_ARROWS_10);
break;
case ITEM00_ARROWS_30:
Item_Give(play, ITEM_ARROWS_30);
break;
case ITEM00_ARROWS_40:
Item_Give(play, ITEM_ARROWS_40);
break;
case ITEM00_ARROWS_50:
Item_Give(play, ITEM_ARROWS_50);
break;
case ITEM00_SMALL_KEY:
getItemId = GI_KEY_SMALL;
break;
case ITEM00_HEART_PIECE:
getItemId = GI_HEART_PIECE;
break;
case ITEM00_HEART_CONTAINER:
getItemId = GI_HEART_CONTAINER;
break;
case ITEM00_MAGIC_LARGE:
Item_Give(play, ITEM_MAGIC_LARGE);
break;
case ITEM00_MAGIC_SMALL:
Item_Give(play, ITEM_MAGIC_SMALL);
break;
case ITEM00_SHIELD_HERO:
getItemId = GI_SHIELD_HERO;
break;
case ITEM00_MAP:
getItemId = GI_MAP;
break;
case ITEM00_COMPASS:
getItemId = GI_COMPASS;
break;
default:
break;
}
@@ -603,6 +662,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
Actor_MarkForDeath(&this->actor);
}
return;
default:
break;
}
@@ -634,11 +694,6 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
this->actionFunc = func_800A6A40;
}
void EnItem00_DrawRupee(EnItem00* this, PlayState* play);
void EnItem00_DrawSprite(EnItem00* this, PlayState* play);
void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play);
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play);
void EnItem00_Draw(Actor* thisx, PlayState* play) {
s32 pad;
EnItem00* this = THIS;
@@ -652,16 +707,20 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
case ITEM00_RUPEE_PURPLE:
EnItem00_DrawRupee(this, play);
break;
case ITEM00_HEART_PIECE:
EnItem00_DrawHeartPiece(this, play);
break;
case ITEM00_HEART_CONTAINER:
EnItem00_DrawHeartContainer(this, play);
break;
case ITEM00_RECOVERY_HEART:
if (this->unk152 < 0) {
if (this->unk152 == -1) {
s8 bankIndex = Object_GetIndex(&play->objectCtx, OBJECT_GI_HEART);
if (Object_IsLoaded(&play->objectCtx, bankIndex)) {
this->actor.objBankIndex = bankIndex;
Actor_SetObjectDependency(play, &this->actor);
@@ -673,6 +732,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
}
break;
}
// fallthrough
case ITEM00_BOMBS_A:
case ITEM00_ARROWS_10:
case ITEM00_ARROWS_30:
@@ -688,14 +748,19 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
case ITEM00_BOMBS_0:
EnItem00_DrawSprite(this, play);
break;
case ITEM00_SHIELD_HERO:
GetItem_Draw(play, GID_SHIELD_HERO);
break;
case ITEM00_MAP:
GetItem_Draw(play, GID_DUNGEON_MAP);
break;
case ITEM00_COMPASS:
GetItem_Draw(play, GID_COMPASS);
break;
case ITEM00_MASK:
case ITEM00_FLEXIBLE:
case ITEM00_3_HEARTS:
@@ -706,17 +771,13 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
}
}
TexturePtr D_801ADF30[] = {
gameplay_keep_Tex_061FC0, // Green rupee
gameplay_keep_Tex_061FE0, // Blue rupee
gameplay_keep_Tex_062000, // Red rupee
gameplay_keep_Tex_062040, // Orange rupee
gameplay_keep_Tex_062020 // Purple rupee
static TexturePtr sRupeeTextures[] = {
gRupeeGreenTex, gRupeeBlueTex, gRupeeRedTex, gRupeeOrangeTex, gRupeePurpleTex,
};
void EnItem00_DrawRupee(EnItem00* this, PlayState* play) {
s32 pad;
s32 iconNb;
s32 texIndex;
OPEN_DISPS(play->state.gfxCtx);
@@ -724,67 +785,66 @@ void EnItem00_DrawRupee(EnItem00* this, PlayState* play) {
func_800B8050(&this->actor, play, 0);
if (this->actor.params <= ITEM00_RUPEE_RED) {
iconNb = this->actor.params;
texIndex = this->actor.params;
} else {
iconNb = this->actor.params - 0x10;
texIndex = this->actor.params - 0x10;
}
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_801ADF30[iconNb]));
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sRupeeTextures[texIndex]));
gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0622C0); // TODO symbol
gSPDisplayList(POLY_OPA_DISP++, gRupeeDL);
CLOSE_DISPS(play->state.gfxCtx);
}
TexturePtr D_801ADF44[12] = {
gameplay_keep_Tex_05E6F0, // Heart (Not used)
gameplay_keep_Tex_05CEF0, // Bombs (A), Bombs (0)
gameplay_keep_Tex_05BEF0, // Arrows (10)
gameplay_keep_Tex_05B6F0, // Arrows (30)
gameplay_keep_Tex_05C6F0, // Arrows (40), Arrows (50)
gameplay_keep_Tex_05CEF0, // Bombs (B)
gameplay_keep_Tex_0607C0, // Nuts (1), Nuts (10)
gameplay_keep_Tex_060FC0, // Sticks (1)
gameplay_keep_Tex_0617C0, // Magic (Large)
gameplay_keep_Tex_05FFC0, // Magic (Small)
TexturePtr sItemDropTextures[] = {
gDropRecoveryHeartTex, // Heart (Not used)
gDropBombTex, // Bombs (A), Bombs (0)
gDropArrows1Tex, // Arrows (10)
gDropArrows2Tex, // Arrows (30)
gDropArrows3Tex, // Arrows (40), Arrows (50)
gDropBombTex, // Bombs (B)
gDropDekuNutTex, // Nuts (1), Nuts (10)
gDropDekuStickTex, // Sticks (1)
gDropMagicLargeTex, // Magic (Large)
gDropMagicSmallTex, // Magic (Small)
NULL,
gameplay_keep_Tex_05F7C0 // Small Key
gDropKeySmallTex // Small Key
};
void EnItem00_DrawSprite(EnItem00* this, PlayState* play) {
s32 iconNb = this->actor.params - 3;
s32 texIndex = this->actor.params - 3;
OPEN_DISPS(play->state.gfxCtx);
POLY_OPA_DISP = func_801660B8(play, POLY_OPA_DISP);
if (this->actor.params == ITEM00_NUTS_10) {
iconNb = 6;
texIndex = 6;
} else if (this->actor.params == ITEM00_BOMBS_0) {
iconNb = 1;
texIndex = 1;
} else if (this->actor.params >= ITEM00_ARROWS_30) {
iconNb -= 3;
texIndex -= 3;
if (this->actor.params < ITEM00_ARROWS_50) {
iconNb++;
texIndex++;
}
}
POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_801ADF44[iconNb]));
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sItemDropTextures[texIndex]));
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0);
gSPDisplayList(POLY_OPA_DISP++, gItemDropDL);
CLOSE_DISPS(play->state.gfxCtx);
}
void EnItem00_DrawHeartContainer(EnItem00* actor, PlayState* play) {
s32 pad;
s32 pad2;
s32 pad[2];
if (Object_GetIndex(&play->objectCtx, OBJECT_GI_HEARTS) == actor->actor.objBankIndex) {
OPEN_DISPS(play->state.gfxCtx);
@@ -811,7 +871,7 @@ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_05AAB0);
gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL);
CLOSE_DISPS(play->state.gfxCtx);
}
@@ -893,7 +953,7 @@ Actor* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, u32 params) {
}
spawnedActor->speedXZ = 2.0f;
spawnedActor->gravity = -0.9f;
spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(65536.0f);
spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(0x10000);
Actor_SetScale(spawnedActor, 0.0f);
((EnItem00*)spawnedActor)->actionFunc = func_800A6780;
((EnItem00*)spawnedActor)->unk152 = 0xDC;
@@ -948,7 +1008,7 @@ Actor* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s32 params) {
} else {
spawnedActor->gravity = -0.9f;
}
spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(65536.0f);
spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(0x10000);
spawnedActor->flags |= 0x10;
}
}
+6 -5
View File
@@ -4,6 +4,7 @@
#include "overlays/gamestates/ovl_opening/z_opening.h"
#include "overlays/gamestates/ovl_select/z_select.h"
#include "overlays/gamestates/ovl_title/z_title.h"
#include "z_title_setup.h"
#define GAMESTATE_OVERLAY(name, init, destroy, size) \
{ \
@@ -14,13 +15,13 @@
{ NULL, 0, 0, NULL, NULL, 0, init, destroy, 0, 0, 0, size }
GameStateOverlay gGameStateOverlayTable[] = {
GAMESTATE_OVERLAY_INTERNAL(TitleSetup_Init, TitleSetup_Destroy, sizeof(GameState)),
GAMESTATE_OVERLAY_INTERNAL(Setup_Init, Setup_Destroy, sizeof(SetupState)),
GAMESTATE_OVERLAY(select, MapSelect_Init, MapSelect_Destroy, sizeof(MapSelectState)),
GAMESTATE_OVERLAY(title, Title_Init, Title_Destroy, sizeof(TitleContext)),
GAMESTATE_OVERLAY(title, ConsoleLogo_Init, ConsoleLogo_Destroy, sizeof(ConsoleLogoState)),
GAMESTATE_OVERLAY_INTERNAL(Play_Init, Play_Destroy, sizeof(PlayState)),
GAMESTATE_OVERLAY(opening, Opening_Init, Opening_Destroy, sizeof(OpeningContext)),
GAMESTATE_OVERLAY(file_choose, FileChoose_Init, FileChoose_Destroy, sizeof(FileChooseContext)),
GAMESTATE_OVERLAY(daytelop, Daytelop_Init, Daytelop_Destroy, sizeof(DaytelopContext)),
GAMESTATE_OVERLAY(opening, TitleSetup_Init, TitleSetup_Destroy, sizeof(TitleSetupState)),
GAMESTATE_OVERLAY(file_choose, FileSelect_Init, FileSelect_Destroy, sizeof(FileSelectState)),
GAMESTATE_OVERLAY(daytelop, DayTelop_Init, DayTelop_Destroy, sizeof(DayTelopState)),
};
s32 graphNumGameStates = ARRAY_COUNT(gGameStateOverlayTable);
+5 -3
View File
@@ -75,9 +75,11 @@ void KaleidoSetup_Update(PlayState* play) {
if ((play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF)) {
if ((gSaveContext.save.cutscene < 0xFFF0) && (gSaveContext.nextCutsceneIndex < 0xFFF0)) {
if (!Play_InCsMode(play) || ((msgCtx->msgMode != 0) && (msgCtx->currentTextId == 0xFF))) {
if ((play->unk_1887C < 2) && (gSaveContext.unk_3F28 != 8) && (gSaveContext.unk_3F28 != 9)) {
if ((play->unk_1887C < 2) && (gSaveContext.magicState != MAGIC_STATE_STEP_CAPACITY) &&
(gSaveContext.magicState != MAGIC_STATE_FILL)) {
if (!(gSaveContext.eventInf[1] & 0x80) && !(player->stateFlags1 & 0x20)) {
if (!(play->actorCtx.unk5 & 2) && !(play->actorCtx.unk5 & 4)) {
if (!(play->actorCtx.flags & ACTORCTX_FLAG_1) &&
!(play->actorCtx.flags & ACTORCTX_FLAG_2)) {
if ((play->actorCtx.unk268 == 0) && CHECK_BTN_ALL(input->press.button, BTN_START)) {
gSaveContext.unk_3F26 = gSaveContext.unk_3F22;
pauseCtx->unk_2B9 = 0;
@@ -137,7 +139,7 @@ void KaleidoSetup_Init(PlayState* play) {
pauseCtx->unk_2A0 = -1;
pauseCtx->unk_2BA = 320;
pauseCtx->unk_2BC = 40;
pauseCtx->unk_29E = 100;
pauseCtx->promptAlpha = 100;
View_Init(&pauseCtx->view, play->state.gfxCtx);
}
+477 -17
View File
@@ -139,11 +139,11 @@ u16 sMinigameScoreDigits[] = { 0, 0, 0, 0 };
u16 sCUpInvisible = 0;
u16 sCUpTimer = 0;
s16 sMagicBarOutlinePrimRed = 255;
s16 sMagicBarOutlinePrimGreen = 255;
s16 sMagicBarOutlinePrimBlue = 255;
s16 D_801BF8AC = 2; // sMagicBorderRatio
s16 D_801BF8B0 = 1;
s16 sMagicMeterOutlinePrimRed = 255;
s16 sMagicMeterOutlinePrimGreen = 255;
s16 sMagicMeterOutlinePrimBlue = 255;
s16 sMagicBorderRatio = 2;
s16 sMagicBorderStep = 1;
s16 sExtraItemBases[] = {
ITEM_STICK, // ITEM_STICKS_5
@@ -225,10 +225,14 @@ s16 sFinalHoursClockColorTargetIndex = 0;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010CD98.s")
Gfx* func_8010CFBC(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop,
s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b, s16 a);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010CFBC.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010D2D4.s")
Gfx* func_8010D480(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop,
s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy, s16 r, s16 g, s16 b, s16 a, s32 argE, s32 argF);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010D480.s")
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_8010D7D0.s")
@@ -600,7 +604,7 @@ u8 Item_Give(PlayState* play, u8 item) {
return item;
} else if (item == ITEM_MAGIC_SMALL) {
Parameter_AddMagic(play, 0x18);
Magic_Add(play, MAGIC_NORMAL_METER / 2);
if (!(gSaveContext.save.weekEventReg[12] & 0x80)) {
gSaveContext.save.weekEventReg[12] |= 0x80;
return ITEM_NONE;
@@ -608,7 +612,7 @@ u8 Item_Give(PlayState* play, u8 item) {
return item;
} else if (item == ITEM_MAGIC_LARGE) {
Parameter_AddMagic(play, 0x30);
Magic_Add(play, MAGIC_NORMAL_METER);
if (!(gSaveContext.save.weekEventReg[12] & 0x80)) {
gSaveContext.save.weekEventReg[12] |= 0x80;
return ITEM_NONE;
@@ -1145,26 +1149,482 @@ void Inventory_ChangeAmmo(s16 item, s16 ammoChange) {
}
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Parameter_AddMagic.s")
void Magic_Add(PlayState* play, s16 magicToAdd) {
if (((void)0, gSaveContext.save.playerData.magic) < ((void)0, gSaveContext.magicCapacity)) {
gSaveContext.magicToAdd += magicToAdd;
gSaveContext.isMagicRequested = true;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80115D5C.s")
void Magic_Reset(PlayState* play) {
if ((gSaveContext.magicState != MAGIC_STATE_STEP_CAPACITY) && (gSaveContext.magicState != MAGIC_STATE_FILL)) {
sMagicMeterOutlinePrimRed = sMagicMeterOutlinePrimGreen = sMagicMeterOutlinePrimBlue = 255;
gSaveContext.magicState = MAGIC_STATE_IDLE;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80115DB4.s")
/**
* Request to consume magic.
*
* @param magicToConsume the positive-valued amount to decrease magic by
* @param type how the magic is consumed.
* @return false if the request failed
*/
s32 Magic_Consume(PlayState* play, s16 magicToConsume, s16 type) {
InterfaceContext* interfaceCtx = &play->interfaceCtx;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80116088.s")
// Magic is not acquired yet
if (!gSaveContext.save.playerData.isMagicAcquired) {
return false;
}
s16 magicBorderColors[][3] = {
// Not enough magic available to consume
if ((gSaveContext.save.playerData.magic - magicToConsume) < 0) {
if (gSaveContext.magicCapacity != 0) {
play_sound(NA_SE_SY_ERROR);
}
return false;
}
switch (type) {
case MAGIC_CONSUME_NOW:
case MAGIC_CONSUME_NOW_ALT:
// Drain magic immediately e.g. Deku Bubble
if ((gSaveContext.magicState == MAGIC_STATE_IDLE) ||
(gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS)) {
if (gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS) {
play->actorCtx.lensActive = false;
}
if (gSaveContext.save.weekEventReg[14] & 8) {
// Drank Chateau Romani
magicToConsume = 0;
}
gSaveContext.magicToConsume = magicToConsume;
gSaveContext.magicState = MAGIC_STATE_CONSUME_SETUP;
return true;
} else {
play_sound(NA_SE_SY_ERROR);
return false;
}
case MAGIC_CONSUME_WAIT_NO_PREVIEW:
// Sets consume target but waits to consume.
// No yellow magic to preview target consumption.
if ((gSaveContext.magicState == MAGIC_STATE_IDLE) ||
(gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS)) {
if (gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS) {
play->actorCtx.lensActive = false;
}
if (gSaveContext.save.weekEventReg[14] & 8) {
// Drank Chateau Romani
magicToConsume = 0;
}
gSaveContext.magicToConsume = magicToConsume;
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_3;
return true;
} else {
play_sound(NA_SE_SY_ERROR);
return false;
}
case MAGIC_CONSUME_LENS:
if (gSaveContext.magicState == MAGIC_STATE_IDLE) {
if (gSaveContext.save.playerData.magic != 0) {
interfaceCtx->magicConsumptionTimer = 80;
gSaveContext.magicState = MAGIC_STATE_CONSUME_LENS;
return true;
} else {
return false;
}
} else if (gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS) {
return true;
} else {
return false;
}
case MAGIC_CONSUME_WAIT_PREVIEW:
// Sets consume target but waits to consume.
// Preview consumption with a yellow bar. e.g. Spin Attack
if ((gSaveContext.magicState == MAGIC_STATE_IDLE) ||
(gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS)) {
if (gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS) {
play->actorCtx.lensActive = false;
}
gSaveContext.magicToConsume = magicToConsume;
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_2;
return true;
} else {
play_sound(NA_SE_SY_ERROR);
return false;
}
case MAGIC_CONSUME_GORON_ZORA:
// Goron spiked rolling or Zora electric barrier
if (gSaveContext.save.playerData.magic != 0) {
interfaceCtx->magicConsumptionTimer = 10;
gSaveContext.magicState = MAGIC_STATE_CONSUME_GORON_ZORA_SETUP;
return true;
} else {
return false;
}
case MAGIC_CONSUME_GIANTS_MASK:
// Wearing Giant's Mask
if (gSaveContext.magicState == MAGIC_STATE_IDLE) {
if (gSaveContext.save.playerData.magic != 0) {
interfaceCtx->magicConsumptionTimer = R_MAGIC_CONSUME_TIMER_GIANTS_MASK;
gSaveContext.magicState = MAGIC_STATE_CONSUME_GIANTS_MASK;
return true;
} else {
return false;
}
}
if (gSaveContext.magicState == MAGIC_STATE_CONSUME_GIANTS_MASK) {
return true;
} else {
return false;
}
case MAGIC_CONSUME_DEITY_BEAM:
// Consumes magic immediately
if ((gSaveContext.magicState == MAGIC_STATE_IDLE) ||
(gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS)) {
if (gSaveContext.magicState == MAGIC_STATE_CONSUME_LENS) {
play->actorCtx.lensActive = false;
}
if (gSaveContext.save.weekEventReg[14] & 8) {
// Drank Chateau Romani
magicToConsume = 0;
}
gSaveContext.save.playerData.magic -= magicToConsume;
return true;
} else {
play_sound(NA_SE_SY_ERROR);
return false;
}
}
return false;
}
void Magic_UpdateAddRequest(void) {
if (gSaveContext.isMagicRequested) {
gSaveContext.save.playerData.magic += 4;
play_sound(NA_SE_SY_GAUGE_UP - SFX_FLAG);
if (((void)0, gSaveContext.save.playerData.magic) >= ((void)0, gSaveContext.magicCapacity)) {
gSaveContext.save.playerData.magic = gSaveContext.magicCapacity;
gSaveContext.magicToAdd = 0;
gSaveContext.isMagicRequested = false;
} else {
gSaveContext.magicToAdd -= 4;
if (gSaveContext.magicToAdd <= 0) {
gSaveContext.magicToAdd = 0;
gSaveContext.isMagicRequested = false;
}
}
}
}
s16 sMagicBorderColors[][3] = {
{ 255, 255, 255 },
{ 150, 150, 150 },
};
s16 magicBorderIndices[] = { 0, 1, 1, 0 };
s16 magicBorderColorTimerIndex[] = { 2, 1, 2, 1 };
s16 sMagicBorderIndices[] = { 0, 1, 1, 0 };
s16 sMagicBorderColorTimerIndex[] = { 2, 1, 2, 1 };
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80116114.s")
void Magic_FlashMeterBorder(void) {
s16 borderChangeR;
s16 borderChangeG;
s16 borderChangeB;
s16 index = sMagicBorderIndices[sMagicBorderStep];
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80116348.s")
borderChangeR = ABS_ALT(sMagicMeterOutlinePrimRed - sMagicBorderColors[index][0]) / sMagicBorderRatio;
borderChangeG = ABS_ALT(sMagicMeterOutlinePrimGreen - sMagicBorderColors[index][1]) / sMagicBorderRatio;
borderChangeB = ABS_ALT(sMagicMeterOutlinePrimBlue - sMagicBorderColors[index][2]) / sMagicBorderRatio;
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80116918.s")
if (sMagicMeterOutlinePrimRed >= sMagicBorderColors[index][0]) {
sMagicMeterOutlinePrimRed -= borderChangeR;
} else {
sMagicMeterOutlinePrimRed += borderChangeR;
}
if (sMagicMeterOutlinePrimGreen >= sMagicBorderColors[index][1]) {
sMagicMeterOutlinePrimGreen -= borderChangeG;
} else {
sMagicMeterOutlinePrimGreen += borderChangeG;
}
if (sMagicMeterOutlinePrimBlue >= sMagicBorderColors[index][2]) {
sMagicMeterOutlinePrimBlue -= borderChangeB;
} else {
sMagicMeterOutlinePrimBlue += borderChangeB;
}
sMagicBorderRatio--;
if (sMagicBorderRatio == 0) {
sMagicMeterOutlinePrimRed = sMagicBorderColors[index][0];
sMagicMeterOutlinePrimGreen = sMagicBorderColors[index][1];
sMagicMeterOutlinePrimBlue = sMagicBorderColors[index][2];
sMagicBorderRatio = sMagicBorderColorTimerIndex[sMagicBorderStep];
sMagicBorderStep++;
if (sMagicBorderStep >= 4) {
sMagicBorderStep = 0;
}
}
}
void Magic_Update(PlayState* play) {
MessageContext* msgCtx = &play->msgCtx;
InterfaceContext* interfaceCtx = &play->interfaceCtx;
s16 magicCapacityTarget;
if (gSaveContext.save.weekEventReg[14] & 8) {
// Drank Chateau Romani
Magic_FlashMeterBorder();
}
switch (gSaveContext.magicState) {
case MAGIC_STATE_STEP_CAPACITY:
// Step magicCapacity to the capacity determined by magicLevel
// This changes the width of the magic meter drawn
magicCapacityTarget = gSaveContext.save.playerData.magicLevel * MAGIC_NORMAL_METER;
if (gSaveContext.magicCapacity != magicCapacityTarget) {
if (gSaveContext.magicCapacity < magicCapacityTarget) {
gSaveContext.magicCapacity += 0x10;
if (gSaveContext.magicCapacity > magicCapacityTarget) {
gSaveContext.magicCapacity = magicCapacityTarget;
}
} else {
gSaveContext.magicCapacity -= 0x10;
if (gSaveContext.magicCapacity <= magicCapacityTarget) {
gSaveContext.magicCapacity = magicCapacityTarget;
}
}
} else {
// Once the capacity has reached its target,
// follow up by filling magic to magicFillTarget
gSaveContext.magicState = MAGIC_STATE_FILL;
}
break;
case MAGIC_STATE_FILL:
// Add magic until magicFillTarget is reached
gSaveContext.save.playerData.magic += 0x10;
if ((gSaveContext.gameMode == 0) && (gSaveContext.sceneSetupIndex < 4)) {
play_sound(NA_SE_SY_GAUGE_UP - SFX_FLAG);
}
if (((void)0, gSaveContext.save.playerData.magic) >= ((void)0, gSaveContext.magicFillTarget)) {
gSaveContext.save.playerData.magic = gSaveContext.magicFillTarget;
gSaveContext.magicState = MAGIC_STATE_IDLE;
}
break;
case MAGIC_STATE_CONSUME_SETUP:
// Sets the speed at which magic border flashes
sMagicBorderRatio = 2;
gSaveContext.magicState = MAGIC_STATE_CONSUME;
break;
case MAGIC_STATE_CONSUME:
// Consume magic until target is reached or no more magic is available
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
gSaveContext.save.playerData.magic =
((void)0, gSaveContext.save.playerData.magic) - ((void)0, gSaveContext.magicToConsume);
if (gSaveContext.save.playerData.magic <= 0) {
gSaveContext.save.playerData.magic = 0;
}
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_1;
sMagicMeterOutlinePrimRed = sMagicMeterOutlinePrimGreen = sMagicMeterOutlinePrimBlue = 255;
}
// fallthrough (flash border while magic is being consumed)
case MAGIC_STATE_METER_FLASH_1:
case MAGIC_STATE_METER_FLASH_2:
case MAGIC_STATE_METER_FLASH_3:
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
Magic_FlashMeterBorder();
}
break;
case MAGIC_STATE_RESET:
sMagicMeterOutlinePrimRed = sMagicMeterOutlinePrimGreen = sMagicMeterOutlinePrimBlue = 255;
gSaveContext.magicState = MAGIC_STATE_IDLE;
break;
case MAGIC_STATE_CONSUME_LENS:
// Slowly consume magic while Lens of Truth is active
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) &&
(msgCtx->msgMode == 0) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) &&
(play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF) &&
!Play_InCsMode(play)) {
if ((gSaveContext.save.playerData.magic == 0) ||
((func_801242DC(play) >= 2) && (func_801242DC(play) <= 4)) ||
((BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_LEFT) != ITEM_LENS) &&
(BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_DOWN) != ITEM_LENS) &&
(BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_C_RIGHT) != ITEM_LENS)) ||
!play->actorCtx.lensActive) {
// Deactivate Lens of Truth and set magic state to idle
play->actorCtx.lensActive = false;
play_sound(NA_SE_SY_GLASSMODE_OFF);
gSaveContext.magicState = MAGIC_STATE_IDLE;
sMagicMeterOutlinePrimRed = sMagicMeterOutlinePrimGreen = sMagicMeterOutlinePrimBlue = 255;
break;
}
interfaceCtx->magicConsumptionTimer--;
if (interfaceCtx->magicConsumptionTimer == 0) {
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
gSaveContext.save.playerData.magic--;
}
interfaceCtx->magicConsumptionTimer = 80;
}
}
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
Magic_FlashMeterBorder();
}
break;
case MAGIC_STATE_CONSUME_GORON_ZORA_SETUP:
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
gSaveContext.save.playerData.magic -= 2;
}
if (gSaveContext.save.playerData.magic <= 0) {
gSaveContext.save.playerData.magic = 0;
}
gSaveContext.magicState = MAGIC_STATE_CONSUME_GORON_ZORA;
// fallthrough
case MAGIC_STATE_CONSUME_GORON_ZORA:
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == 0) && (msgCtx->msgMode == 0) &&
(play->gameOverCtx.state == GAMEOVER_INACTIVE) && (play->transitionTrigger == TRANS_TRIGGER_OFF) &&
(play->transitionMode == TRANS_MODE_OFF)) {
if (!Play_InCsMode(play)) {
interfaceCtx->magicConsumptionTimer--;
if (interfaceCtx->magicConsumptionTimer == 0) {
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
gSaveContext.save.playerData.magic--;
}
if (gSaveContext.save.playerData.magic <= 0) {
gSaveContext.save.playerData.magic = 0;
}
interfaceCtx->magicConsumptionTimer = 10;
}
}
}
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
Magic_FlashMeterBorder();
}
break;
case MAGIC_STATE_CONSUME_GIANTS_MASK:
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) &&
(msgCtx->msgMode == 0) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) &&
(play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF)) {
if (!Play_InCsMode(play)) {
interfaceCtx->magicConsumptionTimer--;
if (interfaceCtx->magicConsumptionTimer == 0) {
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
gSaveContext.save.playerData.magic--;
}
if (gSaveContext.save.playerData.magic <= 0) {
gSaveContext.save.playerData.magic = 0;
}
interfaceCtx->magicConsumptionTimer = R_MAGIC_CONSUME_TIMER_GIANTS_MASK;
}
}
}
if (!(gSaveContext.save.weekEventReg[14] & 8)) {
Magic_FlashMeterBorder();
}
break;
default:
gSaveContext.magicState = MAGIC_STATE_IDLE;
break;
}
}
void Magic_DrawMeter(PlayState* play) {
InterfaceContext* interfaceCtx = &play->interfaceCtx;
s16 magicBarY;
OPEN_DISPS(play->state.gfxCtx);
if (gSaveContext.save.playerData.magicLevel != 0) {
if (gSaveContext.save.playerData.healthCapacity > 0xA0) {
magicBarY = 42; // two rows of hearts
} else {
magicBarY = 34; // one row of hearts
}
func_8012C654(play->state.gfxCtx);
gDPSetEnvColor(OVERLAY_DISP++, 100, 50, 50, 255);
OVERLAY_DISP = func_8010CFBC(OVERLAY_DISP, gMagicMeterEndTex, 8, 16, 18, magicBarY, 8, 16, 1 << 10, 1 << 10,
sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen, sMagicMeterOutlinePrimBlue,
interfaceCtx->magicAlpha);
OVERLAY_DISP =
func_8010CFBC(OVERLAY_DISP, gMagicMeterMidTex, 24, 16, 26, magicBarY, ((void)0, gSaveContext.magicCapacity),
16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen,
sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha);
OVERLAY_DISP =
func_8010D480(OVERLAY_DISP, gMagicMeterEndTex, 8, 16, ((void)0, gSaveContext.magicCapacity) + 26, magicBarY,
8, 16, 1 << 10, 1 << 10, sMagicMeterOutlinePrimRed, sMagicMeterOutlinePrimGreen,
sMagicMeterOutlinePrimBlue, interfaceCtx->magicAlpha, 3, 0x100);
gDPPipeSync(OVERLAY_DISP++);
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE, PRIMITIVE,
ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
if (gSaveContext.magicState == MAGIC_STATE_METER_FLASH_2) {
// Yellow part of the meter indicating the amount of magic to be subtracted
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 16, 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);
gSPTextureRectangle(OVERLAY_DISP++, 104, (magicBarY + 3) << 2,
(((void)0, gSaveContext.save.playerData.magic) + 26) << 2, (magicBarY + 10) << 2,
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
// Fill the rest of the meter with the normal magic color
gDPPipeSync(OVERLAY_DISP++);
if (gSaveContext.save.weekEventReg[14] & 8) {
// Blue magic (drank Chateau Romani)
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha);
} else {
// Green magic (default)
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha);
}
gSPTextureRectangle(
OVERLAY_DISP++, 104, (magicBarY + 3) << 2,
((((void)0, gSaveContext.save.playerData.magic) - ((void)0, gSaveContext.magicToConsume)) + 26) << 2,
(magicBarY + 10) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
} else {
// Fill the whole meter with the normal magic color
if (gSaveContext.save.weekEventReg[14] & 8) {
// Blue magic (drank Chateau Romani)
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 200, interfaceCtx->magicAlpha);
} else {
// Green magic (default)
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 200, 0, interfaceCtx->magicAlpha);
}
gDPLoadTextureBlock_4b(OVERLAY_DISP++, gMagicMeterFillTex, G_IM_FMT_I, 16, 16, 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);
gSPTextureRectangle(OVERLAY_DISP++, 104, (magicBarY + 3) << 2,
(((void)0, gSaveContext.save.playerData.magic) + 26) << 2, (magicBarY + 10) << 2,
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
}
CLOSE_DISPS(play->state.gfxCtx);
}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80116FD8.s")
+28 -92
View File
@@ -724,43 +724,19 @@ void Play_UpdateTransition(PlayState* this) {
}
if (gSaveContext.gameMode == 4) {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Opening_Init, OpeningContext);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, TitleSetup_Init, sizeof(TitleSetupState));
} else if (gSaveContext.gameMode != 2) {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Play_Init, PlayState);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, Play_Init, sizeof(PlayState));
gSaveContext.save.entrance = this->nextEntrance;
if (gSaveContext.minigameState == 1) {
gSaveContext.minigameState = 3;
}
} else {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, FileChoose_Init, FileChooseContext);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, FileSelect_Init, sizeof(FileSelectState));
}
} else {
if (this->transitionCtx.transitionType == TRANS_TYPE_21) {
@@ -805,16 +781,8 @@ void Play_UpdateTransition(PlayState* this) {
this->envCtx.screenFillColor[3] = (sTransitionFillTimer / 20.0f) * 255.0f;
if (sTransitionFillTimer >= 20) {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Play_Init, PlayState);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, Play_Init, sizeof(PlayState));
gSaveContext.save.entrance = this->nextEntrance;
this->transitionTrigger = TRANS_TRIGGER_OFF;
this->transitionMode = TRANS_MODE_OFF;
@@ -855,16 +823,8 @@ void Play_UpdateTransition(PlayState* this) {
case TRANS_MODE_INSTANT:
if (this->transitionTrigger != TRANS_TRIGGER_END) {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Play_Init, PlayState);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, Play_Init, sizeof(PlayState));
gSaveContext.save.entrance = this->nextEntrance;
this->transitionTrigger = TRANS_TRIGGER_OFF;
this->transitionMode = TRANS_MODE_OFF;
@@ -905,16 +865,8 @@ void Play_UpdateTransition(PlayState* this) {
}
} else {
if (this->envCtx.sandstormEnvA == 255) {
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Play_Init, PlayState);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, Play_Init, sizeof(PlayState));
gSaveContext.save.entrance = this->nextEntrance;
this->transitionTrigger = TRANS_TRIGGER_OFF;
this->transitionMode = TRANS_MODE_OFF;
@@ -1909,16 +1861,16 @@ void Play_SaveCycleSceneFlags(GameState* thisx) {
CycleSceneFlags* cycleSceneFlags;
cycleSceneFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(this->sceneNum)];
cycleSceneFlags->chest = this->actorCtx.flags.chest;
cycleSceneFlags->switch0 = this->actorCtx.flags.switches[0];
cycleSceneFlags->switch1 = this->actorCtx.flags.switches[1];
cycleSceneFlags->chest = this->actorCtx.sceneFlags.chest;
cycleSceneFlags->switch0 = this->actorCtx.sceneFlags.switches[0];
cycleSceneFlags->switch1 = this->actorCtx.sceneFlags.switches[1];
if (this->sceneNum == SCENE_INISIE_R) { // Inverted Stone Tower Temple
cycleSceneFlags = &gSaveContext.cycleSceneFlags[this->sceneNum];
}
cycleSceneFlags->collectible = this->actorCtx.flags.collectible[0];
cycleSceneFlags->clearedRoom = this->actorCtx.flags.clearedRoom;
cycleSceneFlags->collectible = this->actorCtx.sceneFlags.collectible[0];
cycleSceneFlags->clearedRoom = this->actorCtx.sceneFlags.clearedRoom;
}
void Play_SetRespawnData(GameState* thisx, s32 respawnMode, u16 entrance, s32 roomIndex, s32 playerParams, Vec3f* pos,
@@ -1930,9 +1882,9 @@ void Play_SetRespawnData(GameState* thisx, s32 respawnMode, u16 entrance, s32 ro
gSaveContext.respawn[respawnMode].pos = *pos;
gSaveContext.respawn[respawnMode].yaw = yaw;
gSaveContext.respawn[respawnMode].playerParams = playerParams;
gSaveContext.respawn[respawnMode].tempSwitchFlags = this->actorCtx.flags.switches[2];
gSaveContext.respawn[respawnMode].unk_18 = this->actorCtx.flags.collectible[1];
gSaveContext.respawn[respawnMode].tempCollectFlags = this->actorCtx.flags.collectible[2];
gSaveContext.respawn[respawnMode].tempSwitchFlags = this->actorCtx.sceneFlags.switches[2];
gSaveContext.respawn[respawnMode].unk_18 = this->actorCtx.sceneFlags.collectible[1];
gSaveContext.respawn[respawnMode].tempCollectFlags = this->actorCtx.sceneFlags.collectible[2];
}
void Play_SetupRespawnPoint(GameState* thisx, s32 respawnMode, s32 playerParams) {
@@ -1959,9 +1911,9 @@ void func_80169ECC(PlayState* this) {
void func_80169EFC(GameState* thisx) {
PlayState* this = (PlayState*)thisx;
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwitchFlags = this->actorCtx.flags.switches[2];
gSaveContext.respawn[RESPAWN_MODE_DOWN].unk_18 = this->actorCtx.flags.collectible[1];
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = this->actorCtx.flags.collectible[2];
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwitchFlags = this->actorCtx.sceneFlags.switches[2];
gSaveContext.respawn[RESPAWN_MODE_DOWN].unk_18 = this->actorCtx.sceneFlags.collectible[1];
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = this->actorCtx.sceneFlags.collectible[2];
this->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_DOWN].entrance;
gSaveContext.respawnFlag = 1;
func_80169ECC(this);
@@ -2124,16 +2076,8 @@ void Play_Init(GameState* thisx) {
if ((gSaveContext.respawnFlag == -4) || (gSaveContext.respawnFlag == -0x63)) {
if (gSaveContext.eventInf[2] & 0x80) {
gSaveContext.eventInf[2] &= (u8)~0x80;
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Daytelop_Init, DaytelopContext);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, DayTelop_Init, sizeof(DayTelopState));
return;
}
@@ -2147,16 +2091,8 @@ void Play_Init(GameState* thisx) {
if (gSaveContext.save.entrance == -1) {
gSaveContext.save.entrance = 0;
do {
GameState* state = &this->state;
state->running = false;
} while (0);
do {
GameState* state = &this->state;
SET_NEXT_GAMESTATE(state, Opening_Init, OpeningContext);
} while (0);
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, TitleSetup_Init, sizeof(TitleSetupState));
return;
}
@@ -2267,7 +2203,7 @@ void Play_Init(GameState* thisx) {
if (((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 1)) || (gSaveContext.save.cutscene >= 0xFFF0)) {
gSaveContext.unk_3DC0 = 0;
func_80115D5C(&this->state);
Magic_Reset(this);
gSaveContext.sceneSetupIndex = (gSaveContext.save.cutscene & 0xF) + 1;
gSaveContext.save.cutscene = 0;
} else {
+26 -23
View File
@@ -1,23 +1,22 @@
#include "global.h"
#include "z_prenmi.h"
void PreNMI_Stop(PreNMIContext* prenmiCtx) {
prenmiCtx->state.running = 0;
prenmiCtx->state.nextGameStateInit = NULL;
prenmiCtx->state.nextGameStateSize = 0;
void PreNMI_Stop(PreNMIState* this) {
STOP_GAMESTATE(&this->state);
SET_NEXT_GAMESTATE(&this->state, NULL, 0);
}
void PreNMI_Update(PreNMIContext* prenmiCtx) {
if (prenmiCtx->timer == 0) {
void PreNMI_Update(PreNMIState* this) {
if (this->timer == 0) {
ViConfig_UpdateVi(1);
PreNMI_Stop(prenmiCtx);
PreNMI_Stop(this);
return;
}
prenmiCtx->timer--;
this->timer--;
}
void PreNMI_Draw(PreNMIContext* prenmiCtx) {
GraphicsContext* gfxCtx = prenmiCtx->state.gfxCtx;
void PreNMI_Draw(PreNMIState* this) {
GraphicsContext* gfxCtx = this->state.gfxCtx;
func_8012CF0C(gfxCtx, true, true, 0, 0, 0);
@@ -26,26 +25,30 @@ void PreNMI_Draw(PreNMIContext* prenmiCtx) {
func_8012C470(gfxCtx);
gDPSetFillColor(POLY_OPA_DISP++, (GPACK_RGBA5551(255, 255, 255, 1) << 16) | GPACK_RGBA5551(255, 255, 255, 1));
gDPFillRectangle(POLY_OPA_DISP++, 0, prenmiCtx->timer + 100, SCREEN_WIDTH - 1, prenmiCtx->timer + 100);
gDPFillRectangle(POLY_OPA_DISP++, 0, this->timer + 100, SCREEN_WIDTH - 1, this->timer + 100);
CLOSE_DISPS(gfxCtx);
}
void PreNMI_Main(PreNMIContext* prenmiCtx) {
PreNMI_Update(prenmiCtx);
PreNMI_Draw(prenmiCtx);
void PreNMI_Main(GameState* thisx) {
PreNMIState* this = (PreNMIState*)thisx;
prenmiCtx->state.unk_A3 = 1;
PreNMI_Update(this);
PreNMI_Draw(this);
this->state.unk_A3 = 1;
}
void PreNMI_Destroy(PreNMIContext* prenmiCtx) {
void PreNMI_Destroy(GameState* thisx) {
}
void PreNMI_Init(PreNMIContext* prenmiCtx) {
prenmiCtx->state.main = (GameStateFunc)PreNMI_Main;
prenmiCtx->state.destroy = (GameStateFunc)PreNMI_Destroy;
prenmiCtx->timer = 30;
prenmiCtx->unkA8 = 10;
void PreNMI_Init(GameState* thisx) {
PreNMIState* this = (PreNMIState*)thisx;
Game_SetFramerateDivisor(&prenmiCtx->state, 1);
this->state.main = PreNMI_Main;
this->state.destroy = PreNMI_Destroy;
this->timer = 30;
this->unkA8 = 10;
Game_SetFramerateDivisor(&this->state, 1);
}
+1 -1
View File
@@ -49,7 +49,7 @@ s32 Snap_RecordPictographedActors(PlayState* play) {
// Actors which may be pictographed anywhere
switch (actor->id) {
case ACTOR_EN_KAKASI:
if (GET_KAKASI_ABOVE_GROUND(actor) == 1) {
if (KAKASI_GET_ABOVE_GROUND(actor) == 1) {
seen |= PICTO_SEEN_ANYWHERE;
break; //! @bug break is inside conditional, meaning it falls through if it is false
}
+107 -111
View File
@@ -267,11 +267,11 @@ void Sram_SaveEndOfCycle(PlayState* play) {
sceneNum = Play_GetOriginalSceneNumber(play->sceneNum);
Play_SaveCycleSceneFlags(&play->state);
play->actorCtx.flags.chest &= D_801C5FC0[sceneNum][2];
play->actorCtx.flags.switches[0] &= D_801C5FC0[sceneNum][0];
play->actorCtx.flags.switches[1] &= D_801C5FC0[sceneNum][1];
play->actorCtx.flags.collectible[0] &= D_801C5FC0[sceneNum][3];
play->actorCtx.flags.clearedRoom = 0;
play->actorCtx.sceneFlags.chest &= D_801C5FC0[sceneNum][2];
play->actorCtx.sceneFlags.switches[0] &= D_801C5FC0[sceneNum][0];
play->actorCtx.sceneFlags.switches[1] &= D_801C5FC0[sceneNum][1];
play->actorCtx.sceneFlags.collectible[0] &= D_801C5FC0[sceneNum][3];
play->actorCtx.sceneFlags.clearedRoom = 0;
for (i = 0; i < SCENE_MAX; i++) {
gSaveContext.cycleSceneFlags[i].switch0 = ((void)0, gSaveContext.cycleSceneFlags[i].switch0) & D_801C5FC0[i][0];
@@ -597,12 +597,12 @@ SavePlayerData sSaveDefaultPlayerData = {
0x30, // healthCapacity
0x30, // health
0, // magicLevel
0x30, // magic
MAGIC_NORMAL_METER, // magic
0, // rupees
0, // swordHealth
0, // tatlTimer
0, // magicAcquired
0, // doubleMagic
false, // isMagicAcquired
false, // isDoubleMagicAcquired
0, // doubleDefense
0, // unk_1F
0xFF, // unk_20
@@ -697,12 +697,12 @@ SavePlayerData sSaveDebugPlayerData = {
0x80, // healthCapacity
0x80, // health
0, // magicLevel
0x30, // magic
0x32, // rupees
0x64, // swordHealth
MAGIC_NORMAL_METER, // magic
50, // rupees
100, // swordHealth
0, // tatlTimer
1, // magicAcquired
0, // doubleMagic
true, // isMagicAcquired
false, // isDoubleMagicAcquired
0, // doubleDefense
0, // unk_1F
0xFF, // unk_20
@@ -918,7 +918,7 @@ u16 D_801C6A58[] = {
ENTRANCE(IKANA_CANYON, 4), ENTRANCE(STONE_TOWER, 3),
};
void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
void Sram_OpenSave(FileSelectState* fileSelect, SramContext* sramCtx) {
s32 i;
s32 pad;
s32 phi_t1;
@@ -930,7 +930,7 @@ void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
if (gSaveContext.fileNum == 0xFF) {
func_80185968(sramCtx->saveBuf, D_801C67C8[0], D_801C67F0[0]);
} else if (fileChooseCtx->unk_2446A[gSaveContext.fileNum] != 0) {
} else if (fileSelect->unk_2446A[gSaveContext.fileNum] != 0) {
phi_t1 = gSaveContext.fileNum + 2;
phi_t1 *= 2;
@@ -1079,8 +1079,8 @@ void func_80145698(SramContext* sramCtx) {
// Verifies save and use backup if corrupted?
#ifdef NON_EQUIVALENT
void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
FileChooseContext* fileChooseCtx = fileChooseCtx2;
void func_801457CC(FileSelectState* fileSelect2, SramContext* sramCtx) {
FileSelectState* fileSelect = fileSelect2;
u16 sp7A;
// u16 sp78;
u16 sp76;
@@ -1119,7 +1119,7 @@ void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
}
if (sp76 < 2) {
fileChooseCtx->unk_24468[sp76] = 0;
fileSelect->unk_24468[sp76] = 0;
if (phi_s2) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]);
@@ -1157,34 +1157,33 @@ void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed?
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.newf); sp7A++) {
fileChooseCtx->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A];
fileSelect->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A];
}
if (!CHECK_NEWF(fileChooseCtx->newf[sp76])) {
fileChooseCtx->unk_2440C[sp76] = gSaveContext.save.playerData.deaths;
if (!CHECK_NEWF(fileSelect->newf[sp76])) {
fileSelect->unk_2440C[sp76] = gSaveContext.save.playerData.deaths;
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.playerName); sp7A++) {
fileChooseCtx->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A];
fileSelect->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A];
}
fileChooseCtx->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity;
fileChooseCtx->health[sp76] = gSaveContext.save.playerData.health;
fileChooseCtx->unk_24454[sp76] = gSaveContext.save.inventory.defenseHearts;
fileChooseCtx->unk_24444[sp76] = gSaveContext.save.inventory.questItems;
fileChooseCtx->unk_24458[sp76] = gSaveContext.save.time;
fileChooseCtx->unk_24460[sp76] = gSaveContext.save.day;
fileChooseCtx->unk_24468[sp76] = gSaveContext.save.isOwlSave;
fileChooseCtx->rupees[sp76] = gSaveContext.save.playerData.rupees;
fileChooseCtx->unk_24474[sp76] = CUR_UPG_VALUE(4);
fileSelect->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity;
fileSelect->health[sp76] = gSaveContext.save.playerData.health;
fileSelect->unk_24454[sp76] = gSaveContext.save.inventory.defenseHearts;
fileSelect->unk_24444[sp76] = gSaveContext.save.inventory.questItems;
fileSelect->unk_24458[sp76] = gSaveContext.save.time;
fileSelect->unk_24460[sp76] = gSaveContext.save.day;
fileSelect->unk_24468[sp76] = gSaveContext.save.isOwlSave;
fileSelect->rupees[sp76] = gSaveContext.save.playerData.rupees;
fileSelect->unk_24474[sp76] = CUR_UPG_VALUE(4);
for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) {
if (gSaveContext.save.inventory.items[sp7A + 24] != 0xFF) {
phi_a0++;
}
}
fileChooseCtx->maskCount[sp76] = phi_a0;
fileChooseCtx->heartPieceCount[sp76] =
((gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C);
fileSelect->maskCount[sp76] = phi_a0;
fileSelect->heartPieceCount[sp76] = ((gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C);
}
if (sp6E == 1) {
@@ -1209,9 +1208,9 @@ void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
}
}
} else if (sp76 < 4) {
fileChooseCtx->unk_24468[sp76] = 0;
fileSelect->unk_24468[sp76] = 0;
if (!CHECK_NEWF(fileChooseCtx->newf2[(s32)sp76])) { // TODO: Needed?
if (!CHECK_NEWF(fileSelect->newf2[(s32)sp76])) { // TODO: Needed?
if (phi_s2) {
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf,
@@ -1251,34 +1250,34 @@ void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed?
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.newf); sp7A++) {
fileChooseCtx->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A];
fileSelect->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A];
}
if (!CHECK_NEWF(fileChooseCtx->newf[sp76])) {
fileChooseCtx->unk_2440C[sp76] = gSaveContext.save.playerData.deaths;
if (!CHECK_NEWF(fileSelect->newf[sp76])) {
fileSelect->unk_2440C[sp76] = gSaveContext.save.playerData.deaths;
for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.playerName); sp7A++) {
phi_s2 += 0; // TODO: Needed?
fileChooseCtx->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A];
fileSelect->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A];
}
fileChooseCtx->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity;
fileChooseCtx->health[sp76] = gSaveContext.save.playerData.health;
fileChooseCtx->unk_24454[sp76] = gSaveContext.save.inventory.defenseHearts;
fileChooseCtx->unk_24444[sp76] = gSaveContext.save.inventory.questItems;
fileChooseCtx->unk_24458[sp76] = gSaveContext.save.time;
fileChooseCtx->unk_24460[sp76] = gSaveContext.save.day;
fileChooseCtx->unk_24468[sp76] = gSaveContext.save.isOwlSave;
fileChooseCtx->rupees[sp76] = gSaveContext.save.playerData.rupees;
fileChooseCtx->unk_24474[sp76] = CUR_UPG_VALUE(4);
fileSelect->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity;
fileSelect->health[sp76] = gSaveContext.save.playerData.health;
fileSelect->unk_24454[sp76] = gSaveContext.save.inventory.defenseHearts;
fileSelect->unk_24444[sp76] = gSaveContext.save.inventory.questItems;
fileSelect->unk_24458[sp76] = gSaveContext.save.time;
fileSelect->unk_24460[sp76] = gSaveContext.save.day;
fileSelect->unk_24468[sp76] = gSaveContext.save.isOwlSave;
fileSelect->rupees[sp76] = gSaveContext.save.playerData.rupees;
fileSelect->unk_24474[sp76] = CUR_UPG_VALUE(4);
for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) {
if (gSaveContext.save.inventory.items[sp7A + 24] != 0xFF) {
phi_a0++;
}
}
fileChooseCtx->maskCount[sp76] = phi_a0;
fileChooseCtx->heartPieceCount[sp76] =
fileSelect->maskCount[sp76] = phi_a0;
fileSelect->heartPieceCount[sp76] =
((gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C);
}
@@ -1342,14 +1341,14 @@ void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_801457CC.s")
#endif
void func_80146580(FileChooseContext* fileChooseCtx2, SramContext* sramCtx, s32 fileNum) {
FileChooseContext* fileChooseCtx = fileChooseCtx2;
void func_80146580(FileSelectState* fileSelect2, SramContext* sramCtx, s32 fileNum) {
FileSelectState* fileSelect = fileSelect2;
s32 pad;
if (gSaveContext.unk_3F3F) {
if (fileChooseCtx->unk_2446A[fileNum]) {
if (fileSelect->unk_2446A[fileNum]) {
func_80147314(sramCtx, fileNum);
fileChooseCtx->unk_2446A[fileNum] = 0;
fileSelect->unk_2446A[fileNum] = 0;
}
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save));
@@ -1361,30 +1360,30 @@ void func_80146580(FileChooseContext* fileChooseCtx2, SramContext* sramCtx, s32
#ifdef NON_MATCHING
// v0/v1
void func_80146628(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
FileChooseContext* fileChooseCtx = fileChooseCtx2;
void func_80146628(FileSelectState* fileSelect2, SramContext* sramCtx) {
FileSelectState* fileSelect = fileSelect2;
u16 i;
s16 maskCount;
if (gSaveContext.unk_3F3F) {
if (fileChooseCtx->unk_2446A[fileChooseCtx->unk_2448E]) {
func_80147414(sramCtx, fileChooseCtx->unk_2448E, fileChooseCtx->fileNum);
fileChooseCtx->unk_24410[fileChooseCtx->fileNum] = gSaveContext.save.playerData.deaths;
if (fileSelect->unk_2446A[fileSelect->unk_2448E]) {
func_80147414(sramCtx, fileSelect->unk_2448E, fileSelect->fileNum);
fileSelect->unk_24410[fileSelect->fileNum] = gSaveContext.save.playerData.deaths;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) {
fileChooseCtx->unk_24424[fileChooseCtx->fileNum][i] = gSaveContext.save.playerData.playerName[i];
fileSelect->unk_24424[fileSelect->fileNum][i] = gSaveContext.save.playerData.playerName[i];
}
fileChooseCtx->unk_24438[fileChooseCtx->fileNum] = gSaveContext.save.playerData.healthCapacity;
fileChooseCtx->unk_24440[fileChooseCtx->fileNum] = gSaveContext.save.playerData.health;
fileChooseCtx->unk_24456[fileChooseCtx->fileNum] = gSaveContext.save.inventory.defenseHearts;
fileChooseCtx->unk_2444C[fileChooseCtx->fileNum] = gSaveContext.save.inventory.questItems;
fileChooseCtx->unk_2445C[fileChooseCtx->fileNum] = gSaveContext.save.time;
fileChooseCtx->unk_24464[fileChooseCtx->fileNum] = gSaveContext.save.day;
fileChooseCtx->unk_2446A[fileChooseCtx->fileNum] = gSaveContext.save.isOwlSave;
fileChooseCtx->unk_24470[fileChooseCtx->fileNum] = gSaveContext.save.playerData.rupees;
fileSelect->unk_24438[fileSelect->fileNum] = gSaveContext.save.playerData.healthCapacity;
fileSelect->unk_24440[fileSelect->fileNum] = gSaveContext.save.playerData.health;
fileSelect->unk_24456[fileSelect->fileNum] = gSaveContext.save.inventory.defenseHearts;
fileSelect->unk_2444C[fileSelect->fileNum] = gSaveContext.save.inventory.questItems;
fileSelect->unk_2445C[fileSelect->fileNum] = gSaveContext.save.time;
fileSelect->unk_24464[fileSelect->fileNum] = gSaveContext.save.day;
fileSelect->unk_2446A[fileSelect->fileNum] = gSaveContext.save.isOwlSave;
fileSelect->unk_24470[fileSelect->fileNum] = gSaveContext.save.playerData.rupees;
// = CUR_UPG_VALUE(UPG_WALLET);
fileChooseCtx->unk_24476[fileChooseCtx->fileNum] =
fileSelect->unk_24476[fileSelect->fileNum] =
(gSaveContext.save.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4];
for (i = 0, maskCount = 0; i < 24; i++) {
@@ -1393,41 +1392,39 @@ void func_80146628(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
}
}
fileChooseCtx->unk_2447A[fileChooseCtx->fileNum] = maskCount;
fileChooseCtx->unk_2447E[fileChooseCtx->fileNum] =
(gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C;
fileSelect->unk_2447A[fileSelect->fileNum] = maskCount;
fileSelect->unk_2447E[fileSelect->fileNum] = (gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C;
}
// clear buffer
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
// read to buffer
func_80185968(sramCtx->saveBuf, D_801C67C8[fileChooseCtx->unk_2448E * 2],
D_801C67F0[fileChooseCtx->unk_2448E * 2]);
func_80185968(sramCtx->saveBuf, D_801C67C8[fileSelect->unk_2448E * 2], D_801C67F0[fileSelect->unk_2448E * 2]);
if (1) {}
func_80185968(&sramCtx->saveBuf[0x2000], D_801C67C8[fileChooseCtx->unk_2448E * 2 + 1],
D_801C67F0[fileChooseCtx->unk_2448E * 2 + 1]);
func_80185968(&sramCtx->saveBuf[0x2000], D_801C67C8[fileSelect->unk_2448E * 2 + 1],
D_801C67F0[fileSelect->unk_2448E * 2 + 1]);
if (1) {}
// copy buffer to save context
Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save));
fileChooseCtx->unk_2440C[fileChooseCtx->fileNum] = gSaveContext.save.playerData.deaths;
fileSelect->unk_2440C[fileSelect->fileNum] = gSaveContext.save.playerData.deaths;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) {
fileChooseCtx->unk_24414[fileChooseCtx->fileNum][i] = gSaveContext.save.playerData.playerName[i];
fileSelect->unk_24414[fileSelect->fileNum][i] = gSaveContext.save.playerData.playerName[i];
}
fileChooseCtx->healthCapacity[fileChooseCtx->fileNum] = gSaveContext.save.playerData.healthCapacity;
fileChooseCtx->health[fileChooseCtx->fileNum] = gSaveContext.save.playerData.health;
fileChooseCtx->unk_24454[fileChooseCtx->fileNum] = gSaveContext.save.inventory.defenseHearts;
fileChooseCtx->unk_24444[fileChooseCtx->fileNum] = gSaveContext.save.inventory.questItems;
fileChooseCtx->unk_24458[fileChooseCtx->fileNum] = gSaveContext.save.time;
fileChooseCtx->unk_24460[fileChooseCtx->fileNum] = gSaveContext.save.day;
fileChooseCtx->unk_24468[fileChooseCtx->fileNum] = gSaveContext.save.isOwlSave;
fileChooseCtx->rupees[fileChooseCtx->fileNum] = gSaveContext.save.playerData.rupees;
fileSelect->healthCapacity[fileSelect->fileNum] = gSaveContext.save.playerData.healthCapacity;
fileSelect->health[fileSelect->fileNum] = gSaveContext.save.playerData.health;
fileSelect->unk_24454[fileSelect->fileNum] = gSaveContext.save.inventory.defenseHearts;
fileSelect->unk_24444[fileSelect->fileNum] = gSaveContext.save.inventory.questItems;
fileSelect->unk_24458[fileSelect->fileNum] = gSaveContext.save.time;
fileSelect->unk_24460[fileSelect->fileNum] = gSaveContext.save.day;
fileSelect->unk_24468[fileSelect->fileNum] = gSaveContext.save.isOwlSave;
fileSelect->rupees[fileSelect->fileNum] = gSaveContext.save.playerData.rupees;
// = CUR_UPG_VALUE(UPG_WALLET);
fileChooseCtx->unk_24474[fileChooseCtx->fileNum] =
fileSelect->unk_24474[fileSelect->fileNum] =
(gSaveContext.save.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4];
for (i = 0, maskCount = 0; i < 24; i++) {
@@ -1436,8 +1433,8 @@ void func_80146628(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
}
}
fileChooseCtx->maskCount[fileChooseCtx->fileNum] = maskCount;
fileChooseCtx->heartPieceCount[fileChooseCtx->fileNum] =
fileSelect->maskCount[fileSelect->fileNum] = maskCount;
fileSelect->heartPieceCount[fileSelect->fileNum] =
(gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C;
}
@@ -1448,21 +1445,20 @@ void func_80146628(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146628.s")
#endif
void Sram_InitSave(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
void Sram_InitSave(FileSelectState* fileSelect2, SramContext* sramCtx) {
s32 phi_v0;
u16 i;
FileChooseContext* fileChooseCtx = fileChooseCtx2;
FileSelectState* fileSelect = fileSelect2;
s16 maskCount;
if (gSaveContext.unk_3F3F) {
Sram_InitNewSave();
if (fileChooseCtx->unk_24480 == 0) {
if (fileSelect->unk_24480 == 0) {
gSaveContext.save.cutscene = 0xFFF0;
}
for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(gSaveContext.save.playerData.playerName); phi_v0++) {
gSaveContext.save.playerData.playerName[phi_v0] =
fileChooseCtx->unk_24414[fileChooseCtx->unk_24480][phi_v0];
gSaveContext.save.playerData.playerName[phi_v0] = fileSelect->unk_24414[fileSelect->unk_24480][phi_v0];
}
gSaveContext.save.playerData.newf[0] = 'Z';
@@ -1478,24 +1474,24 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save));
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.newf); i++) {
fileChooseCtx->newf[fileChooseCtx->unk_24480][i] = gSaveContext.save.playerData.newf[i];
fileSelect->newf[fileSelect->unk_24480][i] = gSaveContext.save.playerData.newf[i];
}
fileChooseCtx->unk_2440C[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.deaths;
fileSelect->unk_2440C[fileSelect->unk_24480] = gSaveContext.save.playerData.deaths;
for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) {
fileChooseCtx->unk_24414[fileChooseCtx->unk_24480][i] = gSaveContext.save.playerData.playerName[i];
fileSelect->unk_24414[fileSelect->unk_24480][i] = gSaveContext.save.playerData.playerName[i];
}
fileChooseCtx->healthCapacity[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.healthCapacity;
fileChooseCtx->health[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.health;
fileChooseCtx->unk_24454[fileChooseCtx->unk_24480] = gSaveContext.save.inventory.defenseHearts;
fileChooseCtx->unk_24444[fileChooseCtx->unk_24480] = gSaveContext.save.inventory.questItems;
fileChooseCtx->unk_24458[fileChooseCtx->unk_24480] = gSaveContext.save.time;
fileChooseCtx->unk_24460[fileChooseCtx->unk_24480] = gSaveContext.save.day;
fileChooseCtx->unk_24468[fileChooseCtx->unk_24480] = gSaveContext.save.isOwlSave;
fileChooseCtx->rupees[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.rupees;
fileChooseCtx->unk_24474[fileChooseCtx->unk_24480] = CUR_UPG_VALUE(UPG_WALLET);
fileSelect->healthCapacity[fileSelect->unk_24480] = gSaveContext.save.playerData.healthCapacity;
fileSelect->health[fileSelect->unk_24480] = gSaveContext.save.playerData.health;
fileSelect->unk_24454[fileSelect->unk_24480] = gSaveContext.save.inventory.defenseHearts;
fileSelect->unk_24444[fileSelect->unk_24480] = gSaveContext.save.inventory.questItems;
fileSelect->unk_24458[fileSelect->unk_24480] = gSaveContext.save.time;
fileSelect->unk_24460[fileSelect->unk_24480] = gSaveContext.save.day;
fileSelect->unk_24468[fileSelect->unk_24480] = gSaveContext.save.isOwlSave;
fileSelect->rupees[fileSelect->unk_24480] = gSaveContext.save.playerData.rupees;
fileSelect->unk_24474[fileSelect->unk_24480] = CUR_UPG_VALUE(UPG_WALLET);
for (i = 0, maskCount = 0; i < 24; i++) {
if (gSaveContext.save.inventory.items[i + 24] != ITEM_NONE) {
@@ -1503,8 +1499,8 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) {
}
}
fileChooseCtx->maskCount[fileChooseCtx->unk_24480] = maskCount;
fileChooseCtx->heartPieceCount[fileChooseCtx->unk_24480] =
fileSelect->maskCount[fileSelect->unk_24480] = maskCount;
fileSelect->heartPieceCount[fileSelect->unk_24480] =
(gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C;
}
@@ -1526,9 +1522,9 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
func_801A3D98(gSaveContext.options.audioSetting);
}
void Sram_Alloc(GameState* gamestate, SramContext* sramCtx) {
void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
if (gSaveContext.unk_3F3F) {
sramCtx->saveBuf = THA_AllocEndAlign16(&gamestate->heap, SAVE_BUFFER_SIZE);
sramCtx->saveBuf = THA_AllocEndAlign16(&gameState->heap, SAVE_BUFFER_SIZE);
sramCtx->status = 0;
}
}