Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion base-hack/asm/functions/media.asm
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@
.definelabel RainbowCoinFTT, 0x806F5498
.definelabel wipeTurnedInArray, 0x806C7B00
.definelabel alCSPSetTempo, 0x80738320
.definelabel getSongTempo, 0x807383B0
.definelabel getSongTempo, 0x807383B0
.definelabel getNextFreeSynthUpdate, 0x80739C88
.definelabel SetParam, 0x8073F1E4
24 changes: 24 additions & 0 deletions base-hack/asm/hookcode/io.asm
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,30 @@ dynflagcheck_3:
j 0x80631E44
nop

stopVoiceFail:
lw $t8, 0x8 ($a0)
addiu $v0, $zero, 0x1
j 0x8073B740
sb $v0, 0x88 ($t8) ;byte 1 offset

stopVoiceFail2:
bne $t9, $zero, stopVoiceNotFail
nop
lw $t8, 0x24 ($sp)
addiu $v0, $zero, 0x1
j 0x8073CC48
sb $v0, 0x88 ($t8) ;byte 1 offset

stopVoiceNotFail:
j 0x8073CBF8
nop

freeVoiceFail:
lw $t2, 0x8 ($a0)
addiu $t4, $zero, 0x2
j 0x8073B814
sb $t4, 0x89 ($t2) ;byte 2 offset

pleaseDontStopIslesMusic:
addiu $at, $at, 0xA0A8 ; currentMap pointer
lw $a0, 0x0 ($at)
Expand Down
1 change: 1 addition & 0 deletions base-hack/asm/symbols.asm
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
.definelabel MusicTrackChannels, 0x807458DC
.definelabel BoatSpeeds, 0x8075A04C
.definelabel textParameter, 0x80750AC8
.definelabel synthesizer, 0x8076D708

.definelabel collisionType, 0x807FBD70
.definelabel collisionActive, 0x807FBB85
Expand Down
25 changes: 24 additions & 1 deletion base-hack/include/common_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2396,4 +2396,27 @@ typedef struct warp_info_data {
typedef struct coinHUDStruct {
/* 0x000 */ unsigned short map_id;
/* 0x004 */ unsigned short requirement;
} coinHUDStruct;
} coinHUDStruct;

typedef struct ALParam_s {
/* 0x000 */ struct ALParam_s* next;
/* 0x004 */ int delta;
/* 0x008 */ short updateType;
/* 0x00A */ short unity;
/* 0x00C */ int pitch;
/* 0x010 */ short volume;
/* 0x012 */ char pan;
/* 0x013 */ char fxmix;
/* 0x014 */ char unk_14[0x1C-0x14];
/* 0x01C */ int samples;
/* 0x020 */ struct ALWaveTable_s* wave;
} ALParam;

// This is ugly, but gets very bloated and hard to read otherwise
typedef struct PVoice {
/* 0x000 */ struct ALLink_s node;
/* 0x008 */ char unk_04[0x88-0x08];
/* 0x088 */ char debug1;
/* 0x089 */ char debug2;
/* 0x08A */ short delay;
} PVoice;
4 changes: 4 additions & 0 deletions base-hack/include/dk64.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,9 @@ extern void customDamageCode(void);
extern void unkSoundFunction(void *actor, int unk);
extern int isModelTwoTiedFlagSet(maps map, int id);

extern ALParam* getNextFreeSynthUpdate(void);
extern void SetParam(PVoice* pvoice, short type, ALParam* param);

//vanilla data
extern OSThread* __osActiveQueue;
extern float TransitionSpeed;
Expand Down Expand Up @@ -718,6 +721,7 @@ extern unsigned char SongInWriteSlot[4];
extern short songVolumes[SONG_COUNT];
extern ALCSPlayer* compactSequencePlayers[4];
extern ALCMidiHdr* musicStorage[4];
extern ALSynth synthesizer;
extern unsigned int DKTVData[5];

extern void* ExitPointer;
Expand Down
1 change: 1 addition & 0 deletions base-hack/include/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ extern void handleCrownTimerInternal(void);
extern void initSongDisplay(int song);
extern Gfx* displaySongNameHandler(Gfx* dl);
extern void resetDisplayedMusic(void);
extern char postSynUpdate(PVoice* pVoice, int delta, short type);

extern enum_bonus_skin getBarrelSkinIndex(int actor);
extern enum_bonus_skin getShopSkinIndex(item_packet *data);
Expand Down
50 changes: 49 additions & 1 deletion base-hack/src/misc/music_text.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,52 @@ Gfx* displaySongNameHandler(Gfx* dl) {
gSPPopMatrix(dl++, G_MTX_MODELVIEW);
}
return dl;
}
}

void fixBrokenVoices(ALSeqPlayer* seq_p) {
if(SongInWriteSlot[2] != 0x2B || MusicTrackChannels[8] == 0x12){
seq_p->state = 1;
return;
}
PVoice* pVoice = (PVoice*) 0x8076D714;
int* samples = *(int*) 0x8076D724;
int delta = * samples;
while(pVoice != 0){
// if stop voice update didn't come through
if (pVoice->debug1 == 0x01){
if(postSynUpdate(pVoice, (pVoice->delay + samples), 0xF) == 1){
pVoice->debug1 = 0;
}
}
// if stop voice update came through, but free voice update didn't come through
if (pVoice->debug1 == 0 && pVoice->debug2 == 0x02){
if(postSynUpdate(pVoice, (pVoice->delay + samples), 0) == 1){
pVoice->debug1 = 0;
pVoice->debug2 = 0;
}
}
pVoice = (PVoice*) (int*) pVoice->node.next;
}

// finally set the sequence player's state to 1 (playing), which is the code that this function overwrites
seq_p->state = 1;
}

char postSynUpdate(PVoice* pVoice, int delta, short type){
// Sends an update to the Synthesizer. type 0xF is for stopping voices and type 0x0 is for freeing voices
if(pVoice){
// Typical dk64 bureaucracy, everything goes through updates, very much similar to MIDI's events
// but yeah, we need one, so let's see if we can get one
ALParam* param = getNextFreeSynthUpdate();
if(param != 0){
param->delta = delta;
param->updateType = type;
param->pitch = (int*) pVoice;
// the "3" here signifies that we're adding an update to a pVoice.
// the exact function in dk64 is... a function of all time,
SetParam(pVoice, 3, param);
return 1;
}
}
return 0;
}
50 changes: 50 additions & 0 deletions randomizer/Patching/ASMPatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -1689,10 +1689,60 @@ def patchAssembly(ROM_COPY, spoiler):
writeFunction(ROM_COPY, 0x8061DD80, Overlay.Static, "pressSkipHandler", offset_dict) # Handler for press start to skip

# Music Fix
# Increase music resources to mitigate the music bug killing the audio engine
writeValue(ROM_COPY, 0x807452B0, Overlay.Static, 0xD00, offset_dict, 4)
writeValue(ROM_COPY, 0x80600DA2, Overlay.Static, 0x38, offset_dict)
writeValue(ROM_COPY, 0x80600DA6, Overlay.Static, 0x70, offset_dict)

# Repair the audio engine if damage did occur
# Write debug bytes to identify permanently damaged voices and what kind of damage they suffer from
writeHook(ROM_COPY, 0x8073B6E4, Overlay.Static, "stopVoiceFail", offset_dict)
writeHook(ROM_COPY, 0x8073B798, Overlay.Static, "freeVoiceFail", offset_dict)
# This particular hook is pretty ugly, but I don't see another way. It's probably
# explicitly not a function because of how deep this might be in the stack with handleMIDIEvents
writeHook(ROM_COPY, 0x8073CBF0, Overlay.Static, "stopVoiceFail2", offset_dict)

# Write function that fixes the permanently damaged voices
writeFunction(ROM_COPY, 0x80733750, Overlay.Static, "fixBrokenVoices", offset_dict)
writeValue(ROM_COPY, 0x80733754, Overlay.Static, 0x8FA40074, offset_dict, 4) # LW a0, 0x74 (sp)

# Accomodate for there being 2 new debug byte fields in a struct that didn't have them
# These are pairs of writes that change each command from LW to LH and increase the offset to
# compensate for the changed data type. This only affects read commands, because
# whenever the delay is set, the voice can't possibly be in a bad state in terms of this change.
writeValue(ROM_COPY, 0x8073B704, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073B707, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073B7B8, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073B7BB, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073B88C, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073B88F, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073B958, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073B95B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073BA08, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073BA0B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073BAB8, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073BABB, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073C878, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073C87B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073CE30, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073CE33, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073CF58, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073CF5B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073D008, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073D00B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

writeValue(ROM_COPY, 0x8073CD68, Overlay.Static, 0x85, offset_dict, 1) # LW -> LH
writeValue(ROM_COPY, 0x8073CD6B, Overlay.Static, 0x8A, offset_dict, 1) # 0x88 -> 0x8A

# Soundplayer Fix
writeValue(ROM_COPY, 0x80735C9E, Overlay.Static, 0xFFFF, offset_dict) # initSoundPlayer creates the event
writeValue(ROM_COPY, 0x80735D0E, Overlay.Static, 0xFFFF, offset_dict) # __sndpVoiceHandler checks for the event
Expand Down
Loading