mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 00:09:24 +01:00
Zelda UCode: Synth fixes and some RE. (Why does it still sound awful?)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3707 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
47ea4936b3
commit
25b77d4654
@ -221,7 +221,8 @@ private:
|
|||||||
|
|
||||||
// Voice formats
|
// Voice formats
|
||||||
void RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
void RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
void RenderSynth_Waveform(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
void RenderSynth_RectWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
|
void RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size);
|
||||||
void RenderVoice_PCM16(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
void RenderVoice_PCM16(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
||||||
void RenderVoice_AFC(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
void RenderVoice_AFC(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
||||||
void RenderVoice_Raw(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
void RenderVoice_Raw(ZeldaVoicePB& PB, s32* _Buffer, int _Size);
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
#include "Mixer.h"
|
#include "Mixer.h"
|
||||||
|
|
||||||
void CUCode_Zelda::RenderSynth_Waveform(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
void CUCode_Zelda::RenderSynth_RectWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||||
{
|
{
|
||||||
float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
|
float ratioFactor = 32000.0f / (float)soundStream->GetMixer()->GetSampleRate();
|
||||||
u32 _ratio = (PB.RatioInt << 16);
|
u32 _ratio = (PB.RatioInt << 16);
|
||||||
s64 ratio = (_ratio * ratioFactor) * 16;
|
s64 ratio = (_ratio * ratioFactor) * 16;
|
||||||
s64 TrueSamplePosition = (s64)(PB.Length - PB.RemLength) << 16;
|
s64 TrueSamplePosition = PB.CurSampleFrac;
|
||||||
TrueSamplePosition += PB.CurSampleFrac;
|
|
||||||
|
|
||||||
|
// PB.Format == 0x3 -> Rectangular Wave, 0x0 -> Square Wave
|
||||||
int mask = PB.Format ? 3 : 1, shift = PB.Format ? 2 : 1;
|
int mask = PB.Format ? 3 : 1, shift = PB.Format ? 2 : 1;
|
||||||
|
|
||||||
u32 pos[2] = {0, 0};
|
u32 pos[2] = {0, 0};
|
||||||
@ -93,6 +93,19 @@ _lRestart:
|
|||||||
PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
|
PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CUCode_Zelda::RenderSynth_SawWave(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||||
|
{
|
||||||
|
s32 ratio = PB.RatioInt * 2;
|
||||||
|
s64 pos = PB.CurSampleFrac;
|
||||||
|
|
||||||
|
for(int i = 0; i < 0x50; i++) {
|
||||||
|
pos += ratio;
|
||||||
|
|
||||||
|
_Buffer[i] = pos & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
PB.CurSampleFrac = pos & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
void CUCode_Zelda::RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
void CUCode_Zelda::RenderSynth_Constant(ZeldaVoicePB &PB, s32* _Buffer, int _Size)
|
||||||
{
|
{
|
||||||
|
@ -386,9 +386,13 @@ void CUCode_Zelda::RenderAddVoice(ZeldaVoicePB &PB, s32* _LeftBuffer, s32* _Righ
|
|||||||
{
|
{
|
||||||
// Synthesized sounds
|
// Synthesized sounds
|
||||||
case 0x0000: // Example: Magic meter filling up in ZWW
|
case 0x0000: // Example: Magic meter filling up in ZWW
|
||||||
|
case 0x0003:
|
||||||
|
RenderSynth_RectWave(PB, m_TempBuffer, _Size);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x0001: // Example: "Denied" sound when trying to pull out a sword
|
case 0x0001: // Example: "Denied" sound when trying to pull out a sword
|
||||||
// indoors in ZWW
|
// indoors in ZWW
|
||||||
RenderSynth_Waveform(PB, m_TempBuffer, _Size);
|
RenderSynth_SawWave(PB, m_TempBuffer, _Size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0006:
|
case 0x0006:
|
||||||
|
@ -2876,27 +2876,37 @@ void 07eb_AFCDecoder(_numberOfSample(AC0.M))
|
|||||||
//////////////////////////////////////////// DEFAULT DECODER
|
//////////////////////////////////////////// DEFAULT DECODER
|
||||||
void 087c_DefaultDecoder()
|
void 087c_DefaultDecoder()
|
||||||
{
|
{
|
||||||
087c 8100 clr $ACC0
|
// 087c 8100 clr $ACC0
|
||||||
087c 8100 clr $ACC0 // ACC0 = 0
|
// 087d 1f5e mrr $AX0.H, $AC0.M
|
||||||
087d 1f5e mrr $AX0.H, $AC0.M
|
// 087e 00d8 0402 lr $AX0.L, @0x0402
|
||||||
087e 00d8 0402 lr $AX0.L, @0x0402 // AX0.L = PB.RatioInt
|
|
||||||
|
ACC0 = 0;
|
||||||
|
AX0.L = *0x0402; // == PB.RatioInt
|
||||||
|
|
||||||
// Sample fraction is stored in a common way, but sample position is not, so
|
// Sample fraction is stored in a common way, but sample position is not, so
|
||||||
// it's in the individual decoders. Some decoders, like square wave, only care about
|
// it's in the individual decoders. Some decoders, like square wave, only care about
|
||||||
// fractional sample position. So here we just load up the fractional sample
|
// fractional sample position. So here we just load up the fractional sample
|
||||||
// position before handing control over.
|
// position before handing control over.
|
||||||
0880 00dc 0430 lr $AC0.L, @0x0430 // AC0.L = PB.CurSampleFrac
|
// 0880 00dc 0430 lr $AC0.L, @0x0430
|
||||||
0882 0080 0520 lri $AR0, #0x0520 // AR0 = 0x0520
|
// 0882 0080 0520 lri $AR0, #0x0520
|
||||||
|
|
||||||
|
AC0.L = *0x430; // == PB.CurSampleFrac
|
||||||
|
AR0 = 0x0520;
|
||||||
|
|
||||||
// 0884 00df 0480 lr $AC1.M, @0x0480
|
// 0884 00df 0480 lr $AC1.M, @0x0480
|
||||||
// 0886 1501 lsl $ACC1, #1 // AC1.M = (PB.Format << 1)
|
// 0886 1501 lsl $ACC1, #1
|
||||||
// 0887 0340 007e andi $AC1.M, #0x007e // AC1.M &= 0x007e
|
// 0887 0340 007e andi $AC1.M, #0x007e
|
||||||
// 0889 0300 0891 addi $AC1.M, #0x0891 // AC1.M += 0x0891
|
// 0889 0300 0891 addi $AC1.M, #0x0891
|
||||||
// 088b 1c5f mrr $AR2, $AC1.M // AR2 = AC1.M
|
// 088b 1c5f mrr $AR2, $AC1.M
|
||||||
// 088c 175f callr $AR2 // (*$AR2)() <-- See jump table at 0x0891
|
// 088c 175f callr $AR2 // (*$AR2)() <-- See jump table at 0x0891
|
||||||
|
|
||||||
|
AC1.M = ((*0x480 * 2) & 0x007e) + 0x0891; // == ((PB.Format * 2) & 0x007e) + 0x0891
|
||||||
|
AR2 = AC1.M;
|
||||||
|
|
||||||
JumpTable0891(PB.Format);
|
JumpTable0891(PB.Format);
|
||||||
|
|
||||||
088d 00fc 0430 sr @0x0430, $AC0.L // PB.CurSampleFrac = AC0.L
|
//088d 00fc 0430 sr @0x0430, $AC0.L
|
||||||
|
*0x430 = AC0.L; // *0x430 == PB.CurSampleFrac
|
||||||
|
|
||||||
// 088f 029f 02d8 jmp 0x02d8
|
// 088f 029f 02d8 jmp 0x02d8
|
||||||
GOTO ContinueWithBlock: // in SyncFrame
|
GOTO ContinueWithBlock: // in SyncFrame
|
||||||
@ -2923,7 +2933,7 @@ void 087c_DefaultDecoder()
|
|||||||
08af 029f 08b1 jmp 0x08b1 // case 0xf (unused)
|
08af 029f 08b1 jmp 0x08b1 // case 0xf (unused)
|
||||||
08b1 02df ret
|
08b1 02df ret
|
||||||
|
|
||||||
void 08b2_Decoder0x0_SquareWave() {
|
void 08b2_Decoder0x0_SquareWave(ACC0, AR0, AX0.L) {
|
||||||
08b2 1401 lsl $ACC0, #1 // t = samplePosition * 2
|
08b2 1401 lsl $ACC0, #1 // t = samplePosition * 2
|
||||||
|
|
||||||
// Set up sound buffers
|
// Set up sound buffers
|
||||||
@ -2949,7 +2959,7 @@ void 08b2_Decoder0x0_SquareWave() {
|
|||||||
// 08c1 02df ret
|
// 08c1 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
void 08c2_Decoder0x3_RectangleWave() {
|
void 08c2_Decoder0x3_RectangleWave(ACC0, AR0, AX0.L) {
|
||||||
08c2 1402 lsl $ACC0, #2 // t = PB.CurSampleFrac * 4
|
08c2 1402 lsl $ACC0, #2 // t = PB.CurSampleFrac * 4
|
||||||
08c3 8900 clr $ACC1 // ACC1 = 0
|
08c3 8900 clr $ACC1 // ACC1 = 0
|
||||||
08c4 1fb8 mrr $AC1.L, $AX0.L // AC1.L = PB.RatioInt
|
08c4 1fb8 mrr $AC1.L, $AX0.L // AC1.L = PB.RatioInt
|
||||||
@ -2976,7 +2986,7 @@ void 08c2_Decoder0x3_RectangleWave() {
|
|||||||
// 08d4 02df ret
|
// 08d4 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
void 08d5_Decoder0x2_SquareSaw() {
|
void 08d5_Decoder0x2_SquareSaw(ACC0, AR0, AX0.L) {
|
||||||
08d5 1401 lsl $ACC0, #1
|
08d5 1401 lsl $ACC0, #1
|
||||||
08d6 0081 0ca0 lri $AR1, #0x0ca0
|
08d6 0081 0ca0 lri $AR1, #0x0ca0
|
||||||
08d8 009b c000 lri $AX1.H, #0xc000
|
08d8 009b c000 lri $AX1.H, #0xc000
|
||||||
@ -2997,12 +3007,24 @@ void 08d5_Decoder0x2_SquareSaw() {
|
|||||||
// 08ec 02df ret
|
// 08ec 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
void 08ed_Decoder0x1_SawWave() {
|
void 08ed_Decoder0x1_SawWave(ACC0, AR0, AX0.L) {
|
||||||
08ed 8900 clr $ACC1
|
// 08ed 8900 clr $ACC1
|
||||||
08ee 1fb8 mrr $AC1.L, $AX0.L
|
// 08ee 1fb8 mrr $AC1.L, $AX0.L
|
||||||
08ef 157f lsr $ACC1, #-1
|
// 08ef 157f lsr $ACC1, #-1
|
||||||
08f0 1050 loopi #0x50
|
|
||||||
08f1 4c20 add's $ACC0, $AC1.L : @$AR0, $AC0.L
|
// At this point AX0.L is PB.RatioInt and AC0.L is PB.CurSampleFrac
|
||||||
|
ACC1 = 0;
|
||||||
|
AC1.L = AX0.L * 2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 08f0 1050 loopi #0x50
|
||||||
|
for(int i = 0; i < 0x50; i++) {
|
||||||
|
// 08f1 4c20 add's $ACC0, $AC1.L : @$AR0, $AC0.L
|
||||||
|
ACC0 += AC1.L;
|
||||||
|
|
||||||
|
*$AR0++ = AC0.L;
|
||||||
|
}
|
||||||
// 08f2 02df ret
|
// 08f2 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3038,7 +3060,7 @@ void 08f3_Unk() {
|
|||||||
// 0918 02df ret
|
// 0918 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
void 0919_Decoder0x6() {
|
void 0919_Decoder0x6(AR0, AX0.L) {
|
||||||
// case 0x6: Fills the buffer with PB.RatioInt (zero?)
|
// case 0x6: Fills the buffer with PB.RatioInt (zero?)
|
||||||
|
|
||||||
0919 1050 loopi #0x50
|
0919 1050 loopi #0x50
|
||||||
@ -3046,7 +3068,7 @@ void 0919_Decoder0x6() {
|
|||||||
091b 02df ret
|
091b 02df ret
|
||||||
}
|
}
|
||||||
|
|
||||||
void 091c_Decoder0x7_WaveTable() {
|
void 091c_Decoder0x7_WaveTable(ACC0, AR0, AX0.L) {
|
||||||
091c 0082 0100 lri $AR2, #0x0100
|
091c 0082 0100 lri $AR2, #0x0100
|
||||||
091e 008a 003f lri $WR2, #0x003f
|
091e 008a 003f lri $WR2, #0x003f
|
||||||
0920 0086 0000 lri $IX2, #0x0000
|
0920 0086 0000 lri $IX2, #0x0000
|
||||||
|
Loading…
x
Reference in New Issue
Block a user