diff --git a/Source/Core/Core/Src/HW/AudioInterface.cpp b/Source/Core/Core/Src/HW/AudioInterface.cpp index 8f18bdd8d6..424fb58599 100644 --- a/Source/Core/Core/Src/HW/AudioInterface.cpp +++ b/Source/Core/Core/Src/HW/AudioInterface.cpp @@ -53,14 +53,14 @@ union AICR AICR(u32 _hex) { hex = _hex;} struct { - unsigned PSTAT : 1; // sample counter/playback enable - unsigned AFR : 1; // 0=32khz 1=48khz - unsigned AIINTMSK : 1; // 0=interrupt masked 1=interrupt enabled - unsigned AIINT : 1; // audio interrupt status - unsigned AIINTVLD : 1; // This bit controls whether AIINT is affected by the AIIT register - // matching AISLRCNT. Once set, AIINT will hold - unsigned SCRESET : 1; // write to reset counter - unsigned DSPFR : 1; // DSP Frequency (0=32khz 1=48khz) + unsigned PSTAT : 1; // sample counter/playback enable + unsigned AFR : 1; // 0=32khz 1=48khz + unsigned AIINTMSK : 1; // 0=interrupt masked 1=interrupt enabled + unsigned AIINT : 1; // audio interrupt status + unsigned AIINTVLD : 1; // This bit controls whether AIINT is affected by the AIIT register + // matching AISLRCNT. Once set, AIINT will hold + unsigned SCRESET : 1; // write to reset counter + unsigned DSPFR : 1; // DSP Frequency (0=32khz 1=48khz) unsigned :25; }; u32 hex; @@ -96,6 +96,7 @@ void ReadStreamBlock(short* _pPCM); static u64 g_LastCPUTime = 0; static int g_SampleRate = 32000; +static int g_DSPSampleRate = 32000; static u64 g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL; void Init() @@ -116,6 +117,7 @@ void Read32(u32& _rReturnValue, const u32 _Address) case AI_CONTROL_REGISTER: //0x6C00 LOG(AUDIO_INTERFACE, "AudioInterface(R) 0x%08x", _Address); _rReturnValue = g_AudioRegister.m_Control.hex; + return; // Sample Rate (AIGetDSPSampleRate) @@ -164,7 +166,10 @@ void Write32(const u32 _Value, const u32 _Address) g_AudioRegister.m_Control.AFR = tmpAICtrl.AFR; } - g_SampleRate = g_AudioRegister.m_Control.AFR ? 48000 : 32000; + g_SampleRate = tmpAICtrl.AFR ? 32000 : 48000; + g_DSPSampleRate = tmpAICtrl.DSPFR ? 32000 : 48000; +// PanicAlert("Sample rate %i %i", g_Aui, g_SampleRate); + g_CPUCyclesPerSample = SystemTimers::GetTicksPerSecond() / g_SampleRate; // Streaming counter @@ -195,6 +200,8 @@ void Write32(const u32 _Value, const u32 _Address) g_LastCPUTime = CoreTiming::GetTicks(); } + g_AudioRegister.m_Control = tmpAICtrl; + UpdateInterrupts(); } break; @@ -316,11 +323,16 @@ void IncreaseSampleCount(const u32 _iAmount) } } -u32 GetRate() +u32 GetAISampleRate() { return g_SampleRate; } +u32 GetDSPSampleRate() +{ + return g_DSPSampleRate; +} + void Update() { // update timer diff --git a/Source/Core/Core/Src/HW/AudioInterface.h b/Source/Core/Core/Src/HW/AudioInterface.h index 4b5e759550..85ca1a4231 100644 --- a/Source/Core/Core/Src/HW/AudioInterface.h +++ b/Source/Core/Core/Src/HW/AudioInterface.h @@ -42,7 +42,8 @@ void HWCALL Read32(u32& _uReturnValue, const u32 _iAddress); void HWCALL Write32(const u32 _iValue, const u32 _iAddress); // Get the Audio Rate (48000 or 32000) -u32 GetRate(); +u32 GetAISampleRate(); +u32 GetDSPSampleRate(); } // end of namespace AudioInterface diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index c941f07507..db49f62839 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -179,11 +179,6 @@ void WriteARAM(u8 _iValue, u32 _iAddress); bool Update_DSP_ReadRegister(); void Update_DSP_WriteRegister(); -int GetDSPSampleRate() -{ - return 32000; // TODO - can also be 48000 -} - void Init() { g_ARAM = (u8 *)AllocateMemoryPages(ARAM_SIZE); @@ -414,7 +409,7 @@ void Write16(const u16 _Value, const u32 _Address) g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; GenerateDSPInterrupt(DSP::INT_AID); - LOG(DSP, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); + LOG(DSPINTERFACE, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); } break; } @@ -432,8 +427,12 @@ void Write16(const u16 _Value, const u32 _Address) void UpdateAudioDMA() { if (g_audioDMA.AudioDMAControl.Enabled && g_audioDMA.BlocksLeft) { - // TODO : Read audio at g_audioDMA.ReadAddress in RAM and push onto an external audio fifo in the emulator, - // to be mixed with the disc streaming output. If that audio queue fills up, we have to delay the emulator. + // Read audio at g_audioDMA.ReadAddress in RAM and push onto an external audio fifo in the emulator, + // to be mixed with the disc streaming output. If that audio queue fills up, we delay the emulator. + + // TO RESTORE OLD BEHAVIOUR, COMMENT OUT THIS LINE + PluginDSP::DSP_SendAIBuffer(g_audioDMA.ReadAddress, AudioInterface::GetDSPSampleRate()); + g_audioDMA.ReadAddress += 32; g_audioDMA.BlocksLeft--; if (!g_audioDMA.BlocksLeft) { @@ -444,6 +443,10 @@ void UpdateAudioDMA() g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; GenerateDSPInterrupt(DSP::INT_AID); } + } else { + // Send silence. Yeah, it's a bit of a waste to sample rate convert silence. + // or hm. Maybe we shouldn't do this :) + // PluginDSP::DSP_SendAIBuffer(0, AudioInterface::GetDSPSampleRate()); } } diff --git a/Source/Core/Core/Src/HW/DSP.h b/Source/Core/Core/Src/HW/DSP.h index c20cb9f12d..a139c9bef6 100644 --- a/Source/Core/Core/Src/HW/DSP.h +++ b/Source/Core/Core/Src/HW/DSP.h @@ -50,7 +50,6 @@ u8 ReadARAM(const u32 _uAddress); u8* GetARAMPtr(); void UpdateAudioDMA(); -int GetDSPSampleRate(); }// end of namespace DSP diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index b079957b46..2c02fa2f60 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -92,15 +92,14 @@ void AICallback(u64 userdata, int cyclesLate) void DSPCallback(u64 userdata, int cyclesLate) { - // Poke the DSP, make it do stuff. This should eventually be replaced with dsp->RunCycles(1000) or whatever, // ~1/6th as many cycles as the period PPC-side. - PluginDSP::DSP_Update(); + PluginDSP::DSP_Update(DSP_PERIOD / 6); CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, &DSPCallback, "DSPCallback"); } void AudioFifoCallback(u64 userdata, int cyclesLate) { - int period = CPU_CORE_CLOCK / (DSP::GetDSPSampleRate() * 4 / 32); + int period = CPU_CORE_CLOCK / (AudioInterface::GetDSPSampleRate() * 4 / 32); DSP::UpdateAudioDMA(); // Push audio to speakers. CoreTiming::ScheduleEvent(period - cyclesLate, &AudioFifoCallback, "AudioFifoCallback"); @@ -140,7 +139,7 @@ void DecrementerSet() u32 decValue = PowerPC::ppcState.spr[SPR_DEC]; fakeDec = decValue*TIMER_RATIO; CoreTiming::RemoveEvent(DecrementerCallback); - CoreTiming::ScheduleEvent(decValue*TIMER_RATIO, DecrementerCallback, "DecCallback"); + CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, DecrementerCallback, "DecCallback"); } void AdvanceCallback(int cyclesExecuted) diff --git a/Source/Core/Core/Src/Plugins/Plugin_DSP.cpp b/Source/Core/Core/Src/Plugins/Plugin_DSP.cpp index b2c4b20ffe..a264374166 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_DSP.cpp +++ b/Source/Core/Core/Src/Plugins/Plugin_DSP.cpp @@ -31,8 +31,8 @@ typedef void (__cdecl* TDSP_WriteMailBox)(BOOL _CPUMailbox, unsigned short); typedef unsigned short (__cdecl* TDSP_ReadMailBox)(BOOL _CPUMailbox); typedef unsigned short (__cdecl* TDSP_ReadControlRegister)(); typedef unsigned short (__cdecl* TDSP_WriteControlRegister)(unsigned short); -typedef void (__cdecl* TDSP_Update)(); -typedef void (__cdecl* TDSP_SendAIBuffer)(unsigned int _Address, unsigned int _Size); +typedef void (__cdecl* TDSP_Update)(int cycles); +typedef void (__cdecl* TDSP_SendAIBuffer)(unsigned int address, int sample_rate); //! Function Pointer TGetDllInfo g_GetDllInfo = 0; @@ -217,16 +217,16 @@ unsigned short DSP_ReadControlRegister() // __________________________________________________________________________________________________ // -void DSP_Update() +void DSP_Update(int cycles) { - g_DSP_Update(); + g_DSP_Update(cycles); } // __________________________________________________________________________________________________ // -void DSP_SendAIBuffer(unsigned int _Address, unsigned int _Size) +void DSP_SendAIBuffer(unsigned int address, int sample_rate) { - g_DSP_SendAIBuffer(_Address, _Size); + g_DSP_SendAIBuffer(address, sample_rate); } } diff --git a/Source/Core/Core/Src/Plugins/Plugin_DSP.h b/Source/Core/Core/Src/Plugins/Plugin_DSP.h index b83142b489..21427e984e 100644 --- a/Source/Core/Core/Src/Plugins/Plugin_DSP.h +++ b/Source/Core/Core/Src/Plugins/Plugin_DSP.h @@ -42,8 +42,8 @@ void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value); void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value); unsigned short DSP_WriteControlRegister(unsigned short _Flags); unsigned short DSP_ReadControlRegister(); -void DSP_Update(); -void DSP_SendAIBuffer(unsigned int _Address, unsigned int _Size); +void DSP_Update(int cycles); +void DSP_SendAIBuffer(unsigned int address, int sample_rate); } // end of namespace PluginDSP diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 84d7f6a20b..02e392b87d 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -353,7 +353,8 @@ namespace Jit64 const u8* DoJit(u32 emaddress, JitBlock &b) { - _assert_msg_(DYNA_REC, emaddress != 0, "ERROR - Trying to compile at 0. LR=%08x",LR); + if (emaddress == 0) + PanicAlert("ERROR : Trying to compile at 0. LR=%08x", LR); u32 size; js.isLastInstruction = false; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp index 33e24ad427..f6ff05f222 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Branch.cpp @@ -87,12 +87,14 @@ namespace Jit64 if (inst.LK) AND(32, M(&CR), Imm32(~(0xFF000000))); #endif - //if (destination == js.compilerPC) - //{ + if (destination == js.compilerPC) + { //PanicAlert("Idle loop detected at %08x", destination); // CALL(ProtectFunction(&CoreTiming::Idle, 0)); // JMP(Asm::testExceptions, true); - //} + // make idle loops go faster + js.downcountAmount += 8; + } WriteExit(destination, 0); } else { diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index d2369bc7dd..f36a7dd426 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -99,9 +99,6 @@ u32 PPCAnalyst::EvaluateBranchTarget(UGeckoInstruction instr, u32 pc) u32 PPCAnalyst::AnalyzeFunction(u32 startAddr, SFunction &func) { - //if (startAddr <0x80000008 || startAddr>0x80000000+Memory::RAM_MASK) - // return 0; - func.name = StringFromFormat("zzz_%08x ??", startAddr); func.calls.clear(); func.callers.clear(); diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp index 209aab2584..c0ecd1a6f0 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp @@ -262,9 +262,8 @@ inline void decodebytesARGB8pass1(u32 *dst, u16 *src, int numpixels) for (int x = 0; x < numpixels; x++) { int val = Common::swap16(src[x]); - int a=val&0xFF; - val>>=8; - + int a = val & 0xFF; + val >>= 8; *dst++ = (a<<16) | (val<<24); } } @@ -274,9 +273,8 @@ inline void decodebytesARGB8pass2(u32 *dst, u16 *src, int numpixels) for (int x = 0; x < numpixels; x++) { int val = Common::swap16(src[x]); - int a=val&0xFF; - val>>=8; - + int a = val & 0xFF; + val >>= 8; *dst++ |= (val<<8) | (a<<0); } } @@ -419,9 +417,9 @@ PC_TexFormat TexDecoder_Decode(u8 *dst, u8 *src, int width, int height, int texf for (int x = 0; x < width; x += 4) { for (int iy = 0; iy < 4; iy++, src += 8) - decodebytesARGB8pass1((u32*)dst+(y+iy)*width+x, (u16*)src, 4); + decodebytesARGB8pass1((u32*)dst + (y+iy)*width + x, (u16*)src, 4); for (int iy = 0; iy < 4; iy++, src += 8) - decodebytesARGB8pass2((u32*)dst+(y+iy)*width+x, (u16*)src, 4); + decodebytesARGB8pass2((u32*)dst + (y+iy)*width + x, (u16*)src, 4); } } return PC_TEX_FMT_BGRA32; diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index bd097c1464..74c7d9df28 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -3,16 +3,16 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core\Core\Core.vcproj", "{F0B874CB-4476-4199-9315-8343D05AE684}" ProjectSection(ProjectDependencies) = postProject - {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoDX9", "Plugins\Plugin_VideoDX9\Plugin_VideoDX9.vcproj", "{636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18}" ProjectSection(ProjectDependencies) = postProject - {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} - {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} + {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_PadSimple", "Plugins\Plugin_PadSimple\Plugin_PadSimple.vcproj", "{9A183B48-ECC2-4121-876A-9B3793686073}" @@ -33,24 +33,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiscIO", "Core\DiscIO\DiscI EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_VideoOGL", "Plugins\Plugin_VideoOGL\Plugin_VideoOGL.vcproj", "{CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160}" ProjectSection(ProjectDependencies) = postProject - {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} - {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} - {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} = {E5D1F0C0-AA07-4841-A4EB-4CF4DAA6B0FA} + {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Common.vcproj", "{C573CAF7-EE6A-458E-8049-16C0BF34C2E9}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DolphinWX", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}" ProjectSection(ProjectDependencies) = postProject - {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} - {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684} - {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} = {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} - {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} - {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} - {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} + {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} + {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} + {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} = {4D3CD4C5-412B-4B49-9B1B-A68A2A129C77} + {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} = {B7F1A9FB-BEA8-416E-9460-AE35A6A5165C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxBase28", "..\Externals\wxWidgets\build\msw\wx_base.vcproj", "{48AD7E0A-25B1-4974-A1E3-03F8C438D34F}" @@ -59,11 +59,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxCore28", "..\Externals\wx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DebuggerWX", "Core\DebuggerWX\DebuggerWX.vcproj", "{4D3CD4C5-412B-4B49-9B1B-A68A2A129C77}" ProjectSection(ProjectDependencies) = postProject - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} - {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684} - {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} - {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} + {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} = {29C2ABC1-ADA5-42CD-A5FC-96022D52A510} + {F0B874CB-4476-4199-9315-8343D05AE684} = {F0B874CB-4476-4199-9315-8343D05AE684} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_DSP_NULL", "Plugins\Plugin_DSP_NULL\Plugin_DSP_NULL.vcproj", "{9AC65CBE-7854-4A86-AA10-D73FF9E5D61F}" @@ -80,9 +80,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_PadDX9", "Plugins\Pl EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_nJoy_SDL", "Plugins\Plugin_nJoy_SDL\Plugin_nJoy_SDL.vcproj", "{521498BE-6089-4780-8223-E67C22F4E068}" ProjectSection(ProjectDependencies) = postProject - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} - {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} {0318BA30-EF48-441A-9E10-DC85EFAE39F0} = {0318BA30-EF48-441A-9E10-DC85EFAE39F0} + {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} = {48AD7E0A-25B1-4974-A1E3-03F8C438D34F} + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Plugin_DSP_HLE", "Plugins\Plugin_DSP_HLE\Plugin_DSP_HLE.vcproj", "{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}" + ProjectSection(ProjectDependencies) = postProject + {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} EndProjectSection EndProject Global @@ -299,6 +304,18 @@ Global {521498BE-6089-4780-8223-E67C22F4E068}.Release|Win32.Build.0 = Release|Win32 {521498BE-6089-4780-8223-E67C22F4E068}.Release|x64.ActiveCfg = Release|x64 {521498BE-6089-4780-8223-E67C22F4E068}.Release|x64.Build.0 = Release|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|Win32.ActiveCfg = Debug|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|Win32.Build.0 = Debug|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|x64.ActiveCfg = Debug|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Debug|x64.Build.0 = Debug|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.DebugFast|Win32.ActiveCfg = DebugFast|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.DebugFast|Win32.Build.0 = DebugFast|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.DebugFast|x64.Build.0 = DebugFast|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.ActiveCfg = Release|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|Win32.Build.0 = Release|Win32 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.ActiveCfg = Release|x64 + {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Source/PluginSpecs/pluginspecs_dsp.h b/Source/PluginSpecs/pluginspecs_dsp.h index 5d99663789..a6fa868860 100644 --- a/Source/PluginSpecs/pluginspecs_dsp.h +++ b/Source/PluginSpecs/pluginspecs_dsp.h @@ -151,18 +151,18 @@ EXPORT unsigned short CALL DSP_ReadControlRegister(void); // __________________________________________________________________________________________________ // Function: DSP_Update // Purpose: This function is called from time to time from the core. -// input: flag (DSP_FLAG_RESET, DSP_FLAG_ASSERT_INT, ...) +// input: cycles - run this number of DSP clock cycles. // output: TRUE if the flag is set, else FALSE // -EXPORT void CALL DSP_Update(void); +EXPORT void CALL DSP_Update(int cycles); // __________________________________________________________________________________________________ // Function: DSP_SendAIBuffer // Purpose: This function sends the current AI Buffer to the DSP plugin // input: _Address : Memory-Address -// input: _Size : Size of the Buffer +// input: _Size : Size of the Buffer (always 32) // -EXPORT void CALL DSP_SendAIBuffer(unsigned int _Address, unsigned int _Size); +EXPORT void CALL DSP_SendAIBuffer(unsigned int address, int sample_rate); #undef CALL #if defined(__cplusplus) } diff --git a/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj new file mode 100644 index 0000000000..3a6b0c6fe9 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj @@ -0,0 +1,809 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.cpp new file mode 100644 index 0000000000..2e3177409e --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "resource.h" + +#include "AboutDlg.h" + +LRESULT +CAboutDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + CenterWindow(GetParent()); + return(TRUE); +} + +LRESULT +CAboutDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + EndDialog(wID); + return(0); +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.h b/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.h new file mode 100644 index 0000000000..e1c136907a --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/AboutDlg.h @@ -0,0 +1,41 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +class CAboutDlg + : public CDialogImpl +{ + public: + + enum { IDD = IDD_ABOUT }; + + BEGIN_MSG_MAP(CAboutDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnCloseCmd) + COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd) + END_MSG_MAP() + +// Handler prototypes (uncomment arguments if needed): +// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/); + + LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/); +}; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp new file mode 100644 index 0000000000..1ccdd4ff87 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Config.cpp @@ -0,0 +1,75 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "IniFile.h" +#include "Config.h" + +CConfig g_Config; + +CConfig::CConfig() +{ + Load(); +} + +void CConfig::LoadDefaults() +{ + m_EnableHLEAudio = true; + m_EnableDTKMusic = true; + m_Interpolation = true; + m_DumpSampleMinLength = true; + m_DumpSamples = false; + m_AntiGap = false; +} + +void CConfig::Load() +{ + // first load defaults + LoadDefaults(); + + IniFile file; + file.Load("DSP.ini"); + file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, true); + file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true); + file.Get("Config", "Interpolation", &m_Interpolation, true); + file.Get("Config", "DumpSamples", &m_DumpSamples, false); + file.Get("Config", "DumpSampleMinLength", &m_DumpSampleMinLength, true); +#ifdef _WIN32 + file.Get("Config", "DumpSamplePath", &m_szSamplePath, "C:\\"); +#else + file.Get("Config", "DumpSamplePath", &m_szSamplePath, "/dev/null/"); +#endif + file.Get("Config", "AntiGap", &m_AntiGap, false); +} + +void CConfig::Save() +{ + IniFile file; + file.Load("DSP.ini"); + file.Set("Config", "EnableHLEAudio", m_EnableHLEAudio); + file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic); + file.Set("Config", "Interpolation", m_Interpolation); + file.Set("Config", "DumpSamples", m_DumpSamples); + file.Set("Config", "DumpSampleMinLength", m_DumpSampleMinLength); +#ifdef _WIN32 + file.Set("Config", "DumpSamplePath", m_szSamplePath); +#else + file.Set("Config", "DumpSamplePath", m_szSamplePath); +#endif + file.Set("Config", "AntiGap", m_AntiGap); + file.Save("DSP.ini"); +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Config.h b/Source/Plugins/Plugin_DSP_HLE/Src/Config.h new file mode 100644 index 0000000000..6ee9b31895 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Config.h @@ -0,0 +1,46 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _CONFIG_H +#define _CONFIG_H + +#include + +struct CConfig +{ + bool m_AntiGap; + bool m_EnableHLEAudio; + bool m_EnableDTKMusic; + bool m_Interpolation; + bool m_DumpSamples; + std::string m_szSamplePath; + int m_SampleRate; + bool m_DumpSampleMinLength; + + CConfig(); + + void LoadDefaults(); + + void Load(); + + void Save(); +}; + +extern CConfig g_Config; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.cpp new file mode 100644 index 0000000000..2dca38c5c1 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "resource.h" + +#include "Config.h" +#include "ConfigDlg.h" + +LRESULT +CConfigDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) +{ + g_Config.Load(); + //CenterWindow(this->GetParent()); + CenterWindow(GetParent()); + m_buttonEnableHLEAudio = GetDlgItem(IDC_ENABLE_HLE_AUDIO); + m_buttonEnableDTKMusic = GetDlgItem(IDC_ENABLE_DTK_MUSIC); + m_buttonAntiGap = GetDlgItem(IDC_ANTIGAP); + m_buttonDumpSamples = GetDlgItem(IDC_DUMPSAMPLES); + m_editDumpSamplePath = GetDlgItem(IDC_SAMPLEDUMPPATH); + m_comboSampleRate = GetDlgItem(IDC_SAMPLERATE); + + m_buttonEnableHLEAudio.SetCheck(g_Config.m_EnableHLEAudio ? BST_CHECKED : BST_UNCHECKED); + m_buttonEnableDTKMusic.SetCheck(g_Config.m_EnableDTKMusic ? BST_CHECKED : BST_UNCHECKED); + m_buttonAntiGap.SetCheck(g_Config.m_AntiGap ? BST_CHECKED : BST_UNCHECKED); + m_buttonDumpSamples.SetCheck(g_Config.m_DumpSamples ? BST_CHECKED : BST_UNCHECKED); + m_editDumpSamplePath.SetWindowText(g_Config.m_szSamplePath.c_str()); + m_comboSampleRate.AddString("44100"); + m_comboSampleRate.AddString("48000"); + m_comboSampleRate.SetCurSel(g_Config.m_SampleRate == 44100 ? 0 : 1); + + return(TRUE); +} + + +LRESULT +CConfigDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + if (wID == IDOK) + { + g_Config.m_EnableHLEAudio = (m_buttonEnableHLEAudio.GetCheck() == BST_CHECKED) ? true : false; + g_Config.m_EnableDTKMusic = (m_buttonEnableDTKMusic.GetCheck() == BST_CHECKED) ? true : false; + g_Config.m_DumpSamples = (m_buttonDumpSamples.GetCheck() == BST_CHECKED) ? true : false; + g_Config.m_AntiGap = (m_buttonAntiGap.GetCheck() == BST_CHECKED) ? true : false; + char temp[MAX_PATH]; + m_editDumpSamplePath.GetWindowText(temp, MAX_PATH); + g_Config.m_szSamplePath = temp; + g_Config.m_SampleRate = (m_comboSampleRate.GetCurSel() == 0 ? 44100 : 48000); + g_Config.Save(); + } + + EndDialog(wID); + g_Config.Save(); + return(0); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.h b/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.h new file mode 100644 index 0000000000..c170a68d6e --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/ConfigDlg.h @@ -0,0 +1,49 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +class CConfigDlg + : public CDialogImpl +{ + public: + + enum { IDD = IDD_SETTINGS }; + + BEGIN_MSG_MAP(CConfigDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnCloseCmd) + COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd) + END_MSG_MAP() + + private: + + CButton m_buttonEnableHLEAudio; + CButton m_buttonEnableDTKMusic; + CButton m_buttonDumpSamples; + CButton m_buttonAntiGap; + CEdit m_editDumpSamplePath; + CComboBox m_comboSampleRate; + + // Handler prototypes (uncomment arguments if needed): + // LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + // LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + // LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL & /*bHandled*/); + LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL & /*bHandled*/); +}; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.cpp new file mode 100644 index 0000000000..1687202e8a --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.cpp @@ -0,0 +1,95 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifdef _WIN32 +#include "PCHW/DSoundStream.h" +#endif + +#include "DSPHandler.h" + +CDSPHandler* CDSPHandler::m_pInstance = NULL; + +CDSPHandler::CDSPHandler() + : m_pUCode(NULL), + m_bHalt(false), + m_bAssertInt(false) +{ + SetUCode(UCODE_ROM); + m_DSPControl.DSPHalt = 1; + m_DSPControl.DSPInit = 1; +} + +CDSPHandler::~CDSPHandler() +{ + delete m_pUCode; + m_pUCode = NULL; +} + +void CDSPHandler::Update() +{ + if (m_pUCode != NULL) + { + m_pUCode->Update(); + } +} + +unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value) +{ + UDSPControl Temp(_Value); + if (Temp.DSPReset) + { + SetUCode(UCODE_ROM); + Temp.DSPReset = 0; + } + if (Temp.DSPInit == 0) + { + // copy 128 byte from ARAM 0x000000 to IMEM + SetUCode(UCODE_INIT_AUDIO_SYSTEM); + Temp.DSPInitCode = 0; + // MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK); + } + + m_DSPControl.Hex = Temp.Hex; + + return(m_DSPControl.Hex); +} + +unsigned short CDSPHandler::ReadControlRegister() +{ + return(m_DSPControl.Hex); +} + +void CDSPHandler::SendMailToDSP(u32 _uMail) +{ + if (m_pUCode != NULL) + { + m_pUCode->HandleMail(_uMail); + } +} + +IUCode* CDSPHandler::GetUCode() +{ + return(m_pUCode); +} + +void CDSPHandler::SetUCode(u32 _crc) +{ + delete m_pUCode; + + m_MailHandler.Clear(); + m_pUCode = UCodeFactory(_crc, m_MailHandler); +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.h b/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.h new file mode 100644 index 0000000000..e183a75649 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/DSPHandler.h @@ -0,0 +1,101 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _DSPHANDLER_H +#define _DSPHANDLER_H + +#include "Common.h" +#include "MailHandler.h" +#include "UCodes/UCodes.h" + +class CDSPHandler +{ +public: + void Update(); + unsigned short WriteControlRegister(unsigned short _Value); + unsigned short ReadControlRegister(); + void SendMailToDSP(u32 _uMail); + IUCode* GetUCode(); + void SetUCode(u32 _crc); + + CMailHandler& AccessMailHandler() {return(m_MailHandler);} + + static CDSPHandler& GetInstance() + { + return(*m_pInstance); + } + + static void Destroy() + { + delete m_pInstance; + m_pInstance = NULL; + } + + static CDSPHandler& CreateInstance() + { + if (!m_pInstance) + { + m_pInstance = new CDSPHandler(); + } + + return(*m_pInstance); + } + +private: + CDSPHandler(); + ~CDSPHandler(); + + // UDSPControl + union UDSPControl + { + u16 Hex; + struct + { + unsigned DSPReset : 1; // Write 1 to reset and waits for 0 + unsigned DSPAssertInt : 1; + unsigned DSPHalt : 1; + + unsigned AI : 1; + unsigned AI_mask : 1; + unsigned ARAM : 1; + unsigned ARAM_mask : 1; + unsigned DSP : 1; + unsigned DSP_mask : 1; + + unsigned ARAM_DMAState : 1; // DSPGetDMAStatus() uses this flag + unsigned DSPInitCode : 1; + unsigned DSPInit : 1; // DSPInit() writes to this flag + unsigned pad : 4; + }; + + UDSPControl(u16 _Hex = 0) + : Hex(_Hex) + {} + }; + + // singleton instance + static CDSPHandler* m_pInstance; + + IUCode* m_pUCode; + UDSPControl m_DSPControl; + CMailHandler m_MailHandler; + + bool m_bHalt; + bool m_bAssertInt; +}; + +#endif diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp new file mode 100644 index 0000000000..fe9266e0f9 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include "Common.h" +#include "Globals.h" + +void DebugLog(const char* _fmt, ...) +{ +#ifdef _DEBUG + char Msg[512]; + va_list ap; + + va_start(ap, _fmt); + vsprintf(Msg, _fmt, ap); + va_end(ap); + + g_dspInitialize.pLog(Msg); +#endif +} + +extern u8* g_pMemory; + +// TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM. +#define RAM_MASK 0x1FFFFFF + +u8 Memory_Read_U8(u32 _uAddress) +{ + _uAddress &= RAM_MASK; + return g_pMemory[_uAddress]; +} + +u16 Memory_Read_U16(u32 _uAddress) +{ + _uAddress &= RAM_MASK; + return Common::swap16(*(u16*)&g_pMemory[_uAddress]); +} + +u32 Memory_Read_U32(u32 _uAddress) +{ + _uAddress &= RAM_MASK; + return Common::swap32(*(u32*)&g_pMemory[_uAddress]); +} + +float Memory_Read_Float(u32 _uAddress) +{ + u32 uTemp = Memory_Read_U32(_uAddress); + return *(float*)&uTemp; +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h new file mode 100644 index 0000000000..cb514eb5a1 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/Globals.h @@ -0,0 +1,17 @@ +#ifndef _GLOBALS_H +#define _GLOBALS_H + +#include "Common.h" +#include "pluginspecs_dsp.h" + +extern DSPInitialize g_dspInitialize; +void DebugLog(const char* _fmt, ...); + +u8 Memory_Read_U8(u32 _uAddress); +u16 Memory_Read_U16(u32 _uAddress); +u32 Memory_Read_U32(u32 _uAddress); +float Memory_Read_Float(u32 _uAddress); + + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp new file mode 100644 index 0000000000..2cb4685b56 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "MailHandler.h" + +CMailHandler::CMailHandler() +{} + +CMailHandler::~CMailHandler() +{ + Clear(); +} + +void CMailHandler::PushMail(u32 _Mail) +{ + m_Mails.push(_Mail); + + Update(); +} + +u16 CMailHandler::ReadDSPMailboxHigh() +{ + // check if we have a mail for the core + if (!m_Mails.empty()) + { + u16 result = (m_Mails.front() >> 16) & 0xFFFF; + + Update(); + + return(result); + } + + return(0x00); +} + +u16 CMailHandler::ReadDSPMailboxLow() +{ + // check if we have a mail for the core + if (!m_Mails.empty()) + { + u16 result = m_Mails.front() & 0xFFFF; + m_Mails.pop(); + + Update(); + + return(result); + } + + return(0x00); +} + +void CMailHandler::Clear() +{ + while (!m_Mails.empty()) + { + m_Mails.pop(); + } +} + +bool CMailHandler::IsEmpty() +{ + return(m_Mails.empty()); +} + +void CMailHandler::Halt(bool _Halt) +{ + if (_Halt) + { + Clear(); + m_Mails.push(0x80544348); + } + + Update(); +} + +void CMailHandler::Update() +{ + if (!IsEmpty()) + { + // g_dspInitialize.pGenerateDSPInterrupt(); + } +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h new file mode 100644 index 0000000000..c1858fa733 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h @@ -0,0 +1,46 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _MAILHANDLER_H +#define _MAILHANDLER_H + +#include + +#include "Common.h" + +class CMailHandler +{ +public: + CMailHandler(); + ~CMailHandler(); + + void PushMail(u32 _Mail); + void Clear(); + void Halt(bool _Halt); + bool IsEmpty(); + + u16 ReadDSPMailboxHigh(); + u16 ReadDSPMailboxLow(); + void Update(); + +private: + // mail handler + std::queue m_Mails; +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.cpp new file mode 100644 index 0000000000..fb9171deb2 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.cpp @@ -0,0 +1,127 @@ +#include +#include +#include "AOSoundStream.h" + +namespace AOSound +{ + pthread_t thread; + StreamCallback callback; + + char *buffer; + int buf_size; + + ao_device *device; + ao_sample_format format; + int default_driver; + + int bufferSize; + int totalRenderedBytes; + int sampleRate; + volatile int threadData; + int currentPos; + int lastPos; + short realtimeBuffer[1024 * 1024]; + int AOSound_GetSampleRate() + { + return sampleRate; + } + bool WriteDataToBuffer(int dwOffset,char* soundData, int dwSoundBytes) + { + //void* ptr1, * ptr2; + //DWORD numBytes1, numBytes2; + // Obtain memory address of write block. This will be in two parts if the block wraps around. + //HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); + + // If the buffer was lost, restore and retry lock. + /*if (DSERR_BUFFERLOST == hr) + { + dsBuffer->Restore(); + hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); + } + + if (SUCCEEDED(hr)) + { + memcpy(ptr1, soundData, numBytes1); + + if (ptr2 != 0) + { + memcpy(ptr2, soundData + numBytes1, numBytes2); + } + + // Release the data back to DirectSound. + dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); + return(true); + } + + return(false);*/ + if(soundData[0] != 0) + ao_play(device, soundData, dwSoundBytes); + return true; + + } + + void* soundThread(void*) + { + currentPos = 0; + lastPos = 0; + + // Prefill buffer? + //writeDataToBuffer(0,realtimeBuffer,bufferSize); + // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); + //dsBuffer->Play(0, 0, DSBPLAY_LOOPING); + + while (!threadData) + { + // No blocking inside the csection + //dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0); + int numBytesToRender = 256; + + if (numBytesToRender >= 256) + { + (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2); + + WriteDataToBuffer(0, (char*)realtimeBuffer, numBytesToRender); + //currentPos = ModBufferSize(lastPos + numBytesToRender); + //totalRenderedBytes += numBytesToRender; + + //lastPos = currentPos; + } + + //WaitForSingleObject(soundSyncEvent, MAXWAIT); + } + + //dsBuffer->Stop(); + return(0); //hurra! + } + bool AOSound_StartSound(int _sampleRate, StreamCallback _callback) + { + callback = _callback; + threadData = 0; + sampleRate = _sampleRate; + + //no security attributes, automatic resetting, init state nonset, untitled + //soundSyncEvent = CreateEvent(0, false, false, 0); + ao_initialize(); + default_driver = ao_default_driver_id(); + format.bits = 16; + format.channels = 2; + format.rate = sampleRate; + format.byte_format = AO_FMT_LITTLE; + + //vi vill ha access till DSOUND sÃ¥... + device = ao_open_live(default_driver, &format, NULL /* no options */); + if (device == NULL) { + fprintf(stderr, "Error opening device.\n"); + return 1; + } + buf_size = format.bits/8 * format.channels * format.rate; + buffer = (char*)calloc(buf_size, sizeof(char)); + pthread_create(&thread, NULL, soundThread, (void *)NULL); + return(true); + } + void AOSound_StopSound() + { + ao_close(device); + ao_shutdown(); + } +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.h b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.h new file mode 100644 index 0000000000..dfef628e0c --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/AOSoundStream.h @@ -0,0 +1,35 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __AOSOUNDSTREAM_H__ +#define __AOSOUNDSTREAM_H__ + +namespace AOSound +{ +typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels); + +bool AOSound_StartSound(int sampleRate, StreamCallback _callback); +void AOSound_UpdateSound(); +void AOSound_StopSound(); + +float AOSound_GetTimer(); +int AOSound_GetCurSample(); +int AOSound_GetSampleRate(); +} + + +#endif //__AOSOUNDSTREAM_H__ diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp new file mode 100644 index 0000000000..639150ed27 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.cpp @@ -0,0 +1,254 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "stdafx.h" + +#include +#include + +#include "dsoundstream.h" + +namespace DSound +{ +#define BUFSIZE 32768 +#define MAXWAIT 70 //ms + +CRITICAL_SECTION soundCriticalSection; +HANDLE soundSyncEvent; +HANDLE hThread; + +StreamCallback callback; + +//lite mojs +IDirectSound8* ds; +IDirectSoundBuffer* dsBuffer; + +//tja.. behövs +int bufferSize; //i bytes +int totalRenderedBytes; +int sampleRate; + +//med den här synkar vi stängning.. +//0=vi spelar oväsen, 1=stäng tråden NU! +volatile int threadData; + +inline int FIX128(int x) +{ + return(x & (~127)); +} + + +int DSound_GetSampleRate() +{ + return(sampleRate); +} + + +bool CreateBuffer() +{ + PCMWAVEFORMAT pcmwf; + DSBUFFERDESC dsbdesc; + + memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); + memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); + + pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; + pcmwf.wf.nChannels = 2; + pcmwf.wf.nSamplesPerSec = sampleRate; + pcmwf.wf.nBlockAlign = 4; + pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; + pcmwf.wBitsPerSample = 16; + + //buffer description + dsbdesc.dwSize = sizeof(DSBUFFERDESC); + dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; + dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; + dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf; + + if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL))) + { + dsBuffer->SetCurrentPosition(0); + return(true); + } + else + { + // Failed. + dsBuffer = NULL; + return(false); + } +} + + +bool WriteDataToBuffer(DWORD dwOffset, // Our own write cursor. + char* soundData, // Start of our data. + DWORD dwSoundBytes) // Size of block to copy. +{ + void* ptr1, * ptr2; + DWORD numBytes1, numBytes2; + // Obtain memory address of write block. This will be in two parts if the block wraps around. + HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); + + // If the buffer was lost, restore and retry lock. + if (DSERR_BUFFERLOST == hr) + { + dsBuffer->Restore(); + hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); + } + + if (SUCCEEDED(hr)) + { + memcpy(ptr1, soundData, numBytes1); + + if (ptr2 != 0) + { + memcpy(ptr2, soundData + numBytes1, numBytes2); + } + + // Release the data back to DirectSound. + dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); + return(true); + } + + return(false); +} + + +inline int ModBufferSize(int x) +{ + return((x + bufferSize) % bufferSize); +} + + +int currentPos; +int lastPos; +short realtimeBuffer[1024 * 1024]; + +//Själva tråden +DWORD WINAPI soundThread(void*) +{ + currentPos = 0; + lastPos = 0; + + // Prefill buffer? + //writeDataToBuffer(0,realtimeBuffer,bufferSize); + // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); + dsBuffer->Play(0, 0, DSBPLAY_LOOPING); + + while (!threadData) + { + // No blocking inside the csection + EnterCriticalSection(&soundCriticalSection); + dsBuffer->GetCurrentPosition((DWORD*)¤tPos, 0); + int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos)); + + if (numBytesToRender >= 256) + { + (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2); + + WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); + currentPos = ModBufferSize(lastPos + numBytesToRender); + totalRenderedBytes += numBytesToRender; + + lastPos = currentPos; + } + + LeaveCriticalSection(&soundCriticalSection); + WaitForSingleObject(soundSyncEvent, MAXWAIT); + } + + dsBuffer->Stop(); + return(0); //hurra! +} + + +bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback) +{ + callback = _callback; + threadData = 0; + sampleRate = _sampleRate; + + //no security attributes, automatic resetting, init state nonset, untitled + soundSyncEvent = CreateEvent(0, false, false, 0); + + //vi initierar den........... + InitializeCriticalSection(&soundCriticalSection); + + //vi vill ha access till DSOUND så... + if (FAILED(DirectSoundCreate8(0, &ds, 0))) + { + return(false); + } + + ds->SetCooperativeLevel(window, DSSCL_NORMAL); + + if (!CreateBuffer()) + { + return(false); + } + + DWORD num1; + short* p1; + dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0); + memset(p1, 0, num1); + dsBuffer->Unlock(p1, num1, 0, 0); + totalRenderedBytes = -bufferSize; + DWORD h; + hThread = CreateThread(0, 0, soundThread, 0, 0, &h); + SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); + return(true); +} + + +void DSound_UpdateSound() +{ + SetEvent(soundSyncEvent); +} + + +void DSound_StopSound() +{ + EnterCriticalSection(&soundCriticalSection); + threadData = 1; + //kick the thread if it's waiting + SetEvent(soundSyncEvent); + LeaveCriticalSection(&soundCriticalSection); + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + + dsBuffer->Release(); + ds->Release(); + + CloseHandle(soundSyncEvent); +} + + +int DSound_GetCurSample() +{ + EnterCriticalSection(&soundCriticalSection); + int playCursor; + dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0); + playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes; + LeaveCriticalSection(&soundCriticalSection); + return(playCursor); +} + + +float DSound_GetTimer() +{ + return((float)DSound_GetCurSample() * (1.0f / (4.0f * sampleRate))); +} +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.h b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.h new file mode 100644 index 0000000000..f27293c997 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/DSoundStream.h @@ -0,0 +1,35 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __SOUNDSTREAM_H__ +#define __SOUNDSTREAM_H__ + +namespace DSound +{ +typedef void (*StreamCallback)(short* buffer, int numSamples, int bits, int rate, int channels); + +bool DSound_StartSound(HWND window, int sampleRate, StreamCallback _callback); +void DSound_UpdateSound(); +void DSound_StopSound(); + +float DSound_GetTimer(); +int DSound_GetCurSample(); +int DSound_GetSampleRate(); +} + + +#endif //__SOUNDSTREAM_H__ diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp new file mode 100644 index 0000000000..e2745d1bbf --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// This queue solution is temporary. I'll implement something more efficient later. + +#include +#include "../Config.h" +#include "../Globals.h" +#include "../DSPHandler.h" +#include "Thread.h" +#include "Mixer.h" +#ifdef _WIN32 +#include "../PCHW/DSoundStream.h" +#endif + +namespace { +Common::CriticalSection push_sync; + +// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so... +int queue_maxlength = 1024 * 8; +std::queue sample_queue; +} // namespace + +volatile bool mixer_HLEready = false; +volatile int queue_size = 0; + +void Mixer(short *buffer, int numSamples, int bits, int rate, int channels) +{ + // silence + memset(buffer, 0, numSamples * 2 * sizeof(short)); + + // first get th DTK Music + if (g_Config.m_EnableDTKMusic) + { + g_dspInitialize.pGetAudioStreaming(buffer, numSamples); + } + + //if this was called directly from the HLE, and not by timeout + if (g_Config.m_EnableHLEAudio && (mixer_HLEready || g_Config.m_AntiGap)) + { + IUCode* pUCode = CDSPHandler::GetInstance().GetUCode(); + if (pUCode != NULL) + pUCode->MixAdd(buffer, numSamples); + } + + push_sync.Enter(); + int count = 0; + while (sample_queue.size() && count < numSamples * 2) { + int x = buffer[count]; + short sample = sample_queue.front(); + x += sample_queue.front(); + if (x > 32767) x = 32767; + if (x < -32767) x = -32767; + buffer[count] = x; + count++; + sample_queue.pop(); + queue_size--; + } + push_sync.Leave(); +} + +void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) { +// static FILE *f; +// if (!f) +// f = fopen("d:\\hello.raw", "wb"); +// fwrite(buffer, num_stereo_samples * 4, 1, f); + static int fraction = 0; + + while (queue_size > queue_maxlength / 2) { +#ifdef _WIN32 + DSound::DSound_UpdateSound(); +#endif + Sleep(0); + } + push_sync.Enter(); + for (int i = 0; i < num_stereo_samples * 2; i++) { + while (fraction < 65536) { + sample_queue.push(buffer[i]); + queue_size++; + fraction += (65536ULL * sample_rate) / 48000; + } + fraction &= 0xFFFF; + } + push_sync.Leave(); +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h new file mode 100644 index 0000000000..a3340845c6 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/PCHW/Mixer.h @@ -0,0 +1,30 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _MIXER_H +#define _MIXER_H + +extern volatile bool mixer_HLEready; + +// Called from audio threads +void Mixer(short* buffer, int numSamples, int bits, int rate, int channels); + +// Called from main thread +void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate); + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/SConscript b/Source/Plugins/Plugin_DSP_HLE/Src/SConscript new file mode 100644 index 0000000000..ced5609cb2 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/SConscript @@ -0,0 +1,24 @@ +Import('env') +import sys + +files = ["DSPHandler.cpp", + "MailHandler.cpp", + "main.cpp", + "Config.cpp", + "Globals.cpp", + "PCHW/AOSoundStream.cpp", + "PCHW/Mixer.cpp", + "UCodes/UCode_AX.cpp", + "UCodes/UCode_CARD.cpp", + "UCodes/UCode_InitAudioSystem.cpp", + "UCodes/UCode_Jac.cpp", + "UCodes/UCode_ROM.cpp", + "UCodes/UCodes.cpp", + "UCodes/UCode_Zelda.cpp", + ] +dspenv=env.Copy(LINKFLAGS = "`pkg-config --libs ao` ") + +if sys.platform == 'darwin': + dspenv.SharedLibrary("../../../../Binary/mac/Plugins/dsphle.so", files, LIBS = ["common"]) +else: + dspenv.SharedLibrary("../../../../Binary/linux/Plugins/dsphle.so", files, LIBS = ["common"]) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp new file mode 100644 index 0000000000..d566968a5d --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.cpp @@ -0,0 +1,514 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" + +#ifdef _WIN32 +#include "../PCHW/DSoundStream.h" +#endif +#include "../PCHW/Mixer.h" +#include "../MailHandler.h" + +#include "UCodes.h" +#include "UCode_AXStructs.h" +#include "UCode_AX.h" + +CUCode_AX::CUCode_AX(CMailHandler& _rMailHandler, bool wii) + : IUCode(_rMailHandler) + , m_addressPBs(0xFFFFFFFF) + , wii_mode(wii) +{ + // we got loaded + m_rMailHandler.PushMail(0xDCD10000); + m_rMailHandler.PushMail(0x80000000); // handshake ??? only (crc == 0xe2136399) needs it ... + + templbuffer = new int[1024 * 1024]; + temprbuffer = new int[1024 * 1024]; +} + +CUCode_AX::~CUCode_AX() +{ + m_rMailHandler.Clear(); + delete [] templbuffer; + delete [] temprbuffer; +} + +void CUCode_AX::HandleMail(u32 _uMail) +{ + if ((_uMail & 0xFFFF0000) == MAIL_AX_ALIST) + { + // a new List + } + else + { + AXTask(_uMail); + } +} + +s16 CUCode_AX::ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac) +{ + PBADPCMInfo &adpcm = pb.adpcm; + + while (samplePos < newSamplePos) + { + if ((samplePos & 15) == 0) + { + adpcm.pred_scale = g_dspInitialize.pARAM_Read_U8((samplePos & ~15) >> 1); + samplePos += 2; + newSamplePos += 2; + } + + int scale = 1 << (adpcm.pred_scale & 0xF); + int coef_idx = adpcm.pred_scale >> 4; + + s32 coef1 = adpcm.coefs[coef_idx * 2 + 0]; + s32 coef2 = adpcm.coefs[coef_idx * 2 + 1]; + + int temp = (samplePos & 1) ? + (g_dspInitialize.pARAM_Read_U8(samplePos >> 1) & 0xF) : + (g_dspInitialize.pARAM_Read_U8(samplePos >> 1) >> 4); + + if (temp >= 8) + temp -= 16; + + // 0x400 = 0.5 in 11-bit fixed point + int val = (scale * temp) + ((0x400 + coef1 * adpcm.yn1 + coef2 * adpcm.yn2) >> 11); + + if (val > 0x7FFF) + val = 0x7FFF; + else if (val < -0x7FFF) + val = -0x7FFF; + + adpcm.yn2 = adpcm.yn1; + adpcm.yn1 = val; + + samplePos++; + } + + return adpcm.yn1; +} + +void ADPCM_Loop(AXParamBlock& pb) +{ + if (!pb.is_stream) + { + pb.adpcm.yn1 = pb.adpcm_loop_info.yn1; + pb.adpcm.yn2 = pb.adpcm_loop_info.yn2; + pb.adpcm.pred_scale = pb.adpcm_loop_info.pred_scale; + } + //else stream and we should not attempt to replace values +} + +void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) +{ + AXParamBlock PBs[NUMBER_OF_PBS]; + + if (_iSize > 1024 * 1024) + _iSize = 1024 * 1024; + + memset(templbuffer, 0, _iSize * sizeof(int)); + memset(temprbuffer, 0, _iSize * sizeof(int)); + // read out pbs + int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS); +#ifdef _WIN32 + float ratioFactor = 32000.0f / (float)DSound::DSound_GetSampleRate(); +#else + float ratioFactor = 32000.0f / 44100.0f; +#endif + + for (int i = 0; i < numberOfPBs; i++) + { + AXParamBlock& pb = PBs[i]; + + if (pb.running) + { + //constants + const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo; + const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo; + const u32 ratio = (u32)(((pb.src.ratio_hi << 16) + pb.src.ratio_lo) * ratioFactor); + + //variables + u32 samplePos = (pb.audio_addr.cur_addr_hi << 16) | pb.audio_addr.cur_addr_lo; + u32 frac = pb.src.cur_addr_frac; + + for (int s = 0; s < _iSize; s++) + { + int sample = 0; + frac += ratio; + u32 newSamplePos = samplePos + (frac >> 16); //whole number of frac + + switch (pb.audio_addr.sample_format) + { + case AUDIOFORMAT_PCM8: + pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample + pb.adpcm.yn1 = ((s8)g_dspInitialize.pARAM_Read_U8(samplePos)) << 8; + + if (pb.src_type == SRCTYPE_NEAREST) + { + sample = pb.adpcm.yn1; + } + else //linear interpolation + { + sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; + } + + samplePos = newSamplePos; + break; + + case AUDIOFORMAT_PCM16: + pb.adpcm.yn2 = pb.adpcm.yn1; //save last sample + pb.adpcm.yn1 = (s16)(u16)((g_dspInitialize.pARAM_Read_U8(samplePos * 2) << 8) | (g_dspInitialize.pARAM_Read_U8((samplePos * 2 + 1)))); + if (pb.src_type == SRCTYPE_NEAREST) + sample = pb.adpcm.yn1; + else //linear interpolation + sample = (pb.adpcm.yn1 * (u16)frac + pb.adpcm.yn2 * (u16)(0xFFFF - frac)) >> 16; + + samplePos = newSamplePos; + break; + + case AUDIOFORMAT_ADPCM: + sample = ADPCM_Step(pb, samplePos, newSamplePos, frac); + break; + + default: + break; + } + + frac &= 0xffff; + + int vol = pb.vol_env.cur_volume >> 9; + sample = sample * vol >> 8; + + if (pb.mixer_control & MIXCONTROL_RAMPING) + { + int x = pb.vol_env.cur_volume; + x += pb.vol_env.cur_volume_delta; + if (x < 0) x = 0; + if (x >= 0x7fff) x = 0x7fff; + pb.vol_env.cur_volume = x; // maybe not per sample?? :P + } + + int leftmix = pb.mixer.volume_left >> 5; + int rightmix = pb.mixer.volume_right >> 5; + + int left = sample * leftmix >> 8; + int right = sample * rightmix >> 8; + + //adpcm has to walk from oldSamplePos to samplePos here + templbuffer[s] += left; + temprbuffer[s] += right; + + if (samplePos >= sampleEnd) + { + if (pb.audio_addr.looping == 1) + { + samplePos = loopPos; + if (pb.audio_addr.sample_format == AUDIOFORMAT_ADPCM) + ADPCM_Loop(pb); + } + else + { + pb.running = 0; + break; + } + } + } + + pb.src.cur_addr_frac = (u16)frac; + pb.audio_addr.cur_addr_hi = samplePos >> 16; + pb.audio_addr.cur_addr_lo = (u16)samplePos; + } + } + + for (int i = 0; i < _iSize; i++) + { + // Clamp into 16-bit. Maybe we should add a volume compressor here. + int left = templbuffer[i]; + int right = temprbuffer[i]; + if (left < -32767) left = -32767; + if (left > 32767) left = 32767; + if (right < -32767) right = -32767; + if (right > 32767) right = 32767; + *_pBuffer++ += left; + *_pBuffer++ += right; + } + + // write back out pbs + WriteBackPBs(PBs, numberOfPBs); +} + +void CUCode_AX::Update() +{ + // check if we have to sent something + if (!m_rMailHandler.IsEmpty()) + { + g_dspInitialize.pGenerateDSPInterrupt(); + } +} + +// AX seems to bootup one task only and waits for resume-callbacks +// everytime the DSP has "spare time" it sends a resume-mail to the CPU +// and the __DSPHandler calls a AX-Callback which generates a new AXFrame +bool CUCode_AX::AXTask(u32& _uMail) +{ + u32 uAddress = _uMail; + DebugLog("AXTask - AXCommandList-Addr: 0x%08x", uAddress); + + u32 Addr__AXStudio; + u32 Addr__AXOutSBuffer; + u32 Addr__AXOutSBuffer_1; + u32 Addr__AXOutSBuffer_2; + u32 Addr__A; + u32 Addr__12; + u32 Addr__4_1; + u32 Addr__4_2; + u32 Addr__5_1; + u32 Addr__5_2; + u32 Addr__6; + u32 Addr__9; + + bool bExecuteList = true; + + while (bExecuteList) + { + static int last_valid_command = 0; + u16 iCommand = Memory_Read_U16(uAddress); + uAddress += 2; + switch (iCommand) + { + case AXLIST_STUDIOADDR: //00 + Addr__AXStudio = Memory_Read_U32(uAddress); + uAddress += 4; + if (wii_mode) + uAddress += 6; + DebugLog("AXLIST studio address: %08x", Addr__AXStudio); + break; + + case 0x001: + { + u32 address = Memory_Read_U32(uAddress); + uAddress += 4; + u16 param1 = Memory_Read_U16(uAddress); + uAddress += 2; + u16 param2 = Memory_Read_U16(uAddress); + uAddress += 2; + u16 param3 = Memory_Read_U16(uAddress); + uAddress += 2; + DebugLog("AXLIST 1: %08x, %04x, %04x, %04x", address, param1, param2, param3); + } + break; + + // + // Somewhere we should be getting a bitmask of AX_SYNC values + // that tells us what has been updated + // Dunno if important + // + case AXLIST_PBADDR: //02 + { + m_addressPBs = Memory_Read_U32(uAddress); + uAddress += 4; + + mixer_HLEready = true; + DebugLog("AXLIST PB address: %08x", m_addressPBs); +#ifdef _WIN32 + DebugLog("Update the SoundThread to be in sync"); + DSound::DSound_UpdateSound(); //do it in this thread to avoid sync problems +#endif + } + break; + + case 0x0003: + DebugLog("AXLIST command 0x0003 ????"); + break; + + case 0x0004: + Addr__4_1 = Memory_Read_U32(uAddress); + uAddress += 4; + Addr__4_2 = Memory_Read_U32(uAddress); + uAddress += 4; + DebugLog("AXLIST 4_1 4_2 addresses: %08x %08x", Addr__4_1, Addr__4_2); + break; + + case 0x0005: + Addr__5_1 = Memory_Read_U32(uAddress); + uAddress += 4; + Addr__5_2 = Memory_Read_U32(uAddress); + uAddress += 4; + DebugLog("AXLIST 5_1 5_2 addresses: %08x %08x", Addr__5_1, Addr__5_2); + break; + + case 0x0006: + Addr__6 = Memory_Read_U32(uAddress); + uAddress += 4; + DebugLog("AXLIST 6 address: %08x", Addr__6); + break; + + case AXLIST_SBUFFER: + // Hopefully this is where in main ram to write. + Addr__AXOutSBuffer = Memory_Read_U32(uAddress); + uAddress += 4; + if (wii_mode) { + uAddress += 12; + } + DebugLog("AXLIST OutSBuffer address: %08x", Addr__AXOutSBuffer); + break; + + case 0x0009: + Addr__9 = Memory_Read_U32(uAddress); + uAddress += 4; + DebugLog("AXLIST 6 address: %08x", Addr__9); + break; + + case AXLIST_COMPRESSORTABLE: // 0xa + Addr__A = Memory_Read_U32(uAddress); + uAddress += 4; + if (wii_mode) { + // There's one more here. +// uAddress += 4; + } + DebugLog("AXLIST CompressorTable address: %08x", Addr__A); + break; + + case 0x000e: + Addr__AXOutSBuffer_1 = Memory_Read_U32(uAddress); + uAddress += 4; + Addr__AXOutSBuffer_2 = Memory_Read_U32(uAddress); + uAddress += 4; + DebugLog("AXLIST sbuf2 addresses: %08x %08x", Addr__AXOutSBuffer_1, Addr__AXOutSBuffer_2); + break; + + case AXLIST_END: + bExecuteList = false; + DebugLog("AXLIST end"); + break; + + case 0x0010: //Super Monkey Ball 2 + DebugLog("AXLIST unknown"); + //should probably read/skip stuff here + uAddress += 8; + break; + + case 0x0011: + uAddress += 4; + break; + + case 0x0012: + Addr__12 = Memory_Read_U16(uAddress); + uAddress += 2; + break; + + case 0x0013: + uAddress += 6 * 4; // 6 Addresses. + break; + + case 0x000d: + if (wii_mode) { + uAddress += 4 * 4; // 4 addresses. another aux? + break; + } + // non-wii : fall through + + case 0x000b: + if (wii_mode) { + uAddress += 2; // one 0x8000 in rabbids + uAddress += 4 * 2; // then two RAM addressses + break; + } + // non-wii : fall through + + default: + { + static bool bFirst = true; + if (bFirst == true) + { + char szTemp[2048]; + sprintf(szTemp, "Unknown AX-Command 0x%x (address: 0x%08x). Last valid: %02x\n", + iCommand, uAddress - 2, last_valid_command); + int num = -32; + while (num < 64+32) + { + char szTemp2[128] = ""; + sprintf(szTemp2, "%s0x%04x\n", num == 0 ? ">>" : " ", Memory_Read_U16(uAddress + num)); + strcat(szTemp, szTemp2); + num += 2; + } + + PanicAlert(szTemp); + bFirst = false; + } + + // unknown command so stop the execution of this TaskList + bExecuteList = false; + } + break; + } + if (bExecuteList) + last_valid_command = iCommand; + } + DebugLog("AXTask - done, send resume"); + + // i hope resume is okay AX + m_rMailHandler.PushMail(0xDCD10001); + return true; +} + +int CUCode_AX::ReadOutPBs(AXParamBlock* _pPBs, int _num) +{ + int count = 0; + u32 blockAddr = m_addressPBs; + + // reading and 'halfword' swap + for (int i = 0; i < _num; i++) + { + const short *pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr); + if (pSrc != NULL) + { + short *pDest = (short *)&_pPBs[i]; + for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) + { + pDest[p] = Common::swap16(pSrc[p]); + } + blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo; + count++; + } + else + break; + } + + // return the number of readed PBs + return count; +} + +void CUCode_AX::WriteBackPBs(AXParamBlock* _pPBs, int _num) +{ + u32 blockAddr = m_addressPBs; + + // write back and 'halfword'swap + for (int i = 0; i < _num; i++) + { + short* pSrc = (short*)&_pPBs[i]; + short* pDest = (short*)g_dspInitialize.pGetMemoryPointer(blockAddr); + for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) + { + pDest[p] = Common::swap16(pSrc[p]); + } + + // next block + blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo; + } +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h new file mode 100644 index 0000000000..7f8aedfda6 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX.h @@ -0,0 +1,67 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_AX +#define _UCODE_AX + +#include "UCode_AXStructs.h" + +class CUCode_AX : public IUCode +{ +public: + CUCode_AX(CMailHandler& _rMailHandler, bool wii = false); + virtual ~CUCode_AX(); + + void HandleMail(u32 _uMail); + void MixAdd(short* _pBuffer, int _iSize); + void Update(); + +private: + + enum + { + NUMBER_OF_PBS = 64 + }; + + enum + { + MAIL_AX_ALIST = 0xBABE0000, + AXLIST_STUDIOADDR = 0x0000, + AXLIST_PBADDR = 0x0002, + AXLIST_SBUFFER = 0x0007, + AXLIST_COMPRESSORTABLE = 0x000A, + AXLIST_END = 0x000F + }; + + // PBs + u32 m_addressPBs; + + int *templbuffer; + int *temprbuffer; + + bool wii_mode; + + // ax task message handler + bool AXTask(u32& _uMail); + + void SendMail(u32 _uMail); + int ReadOutPBs(AXParamBlock *_pPBs, int _num); + void WriteBackPBs(AXParamBlock *_pPBs, int _num); + s16 ADPCM_Step(AXParamBlock& pb, u32& samplePos, u32 newSamplePos, u16 frac); +}; + +#endif // _UCODE_AX diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h new file mode 100644 index 0000000000..207e8d932c --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h @@ -0,0 +1,141 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef UCODE_AX_STRUCTS +#define UCODE_AX_STRUCTS + +struct PBMixer +{ + u16 volume_left; + u16 unknown; + u16 volume_right; + u16 unknown2; + + u16 unknown3[8]; + u16 unknown4[6]; +}; + +struct PBInitialTimeDelay +{ + u16 unknown[7]; +}; + +// Update data - read these each 1ms subframe and use them! +// It seems that to provide higher time precisions for MIDI events, some games +// use this thing to update the parameter blocks per 1ms sub-block (a block is 5ms). +// Using this data should fix games that are missing MIDI notes. +struct PBUpdates +{ + u16 num_updates[5]; + u16 data_hi; // These point to main RAM. Not sure about the structure of the data. + u16 data_lo; +}; + +struct PBUnknown +{ + s16 unknown[9]; +}; + +struct PBVolumeEnvelope +{ + u16 cur_volume; + s16 cur_volume_delta; +}; + +struct PBUnknown2 +{ + u16 unknown_reserved[3]; +}; + +struct PBAudioAddr +{ + u16 looping; + u16 sample_format; + u16 loop_addr_hi; // Start of loop (this will point to a shared "zero" buffer if one-shot mode is active) + u16 loop_addr_lo; + u16 end_addr_hi; // End of sample (and loop), inclusive + u16 end_addr_lo; + u16 cur_addr_hi; + u16 cur_addr_lo; +}; + +struct PBADPCMInfo +{ + s16 coefs[16]; + u16 unknown; + u16 pred_scale; + s16 yn1; + s16 yn2; +}; + +struct PBSampleRateConverter +{ + u16 ratio_hi; + u16 ratio_lo; + u16 cur_addr_frac; + u16 last_samples[4]; +}; + +struct PBADPCMLoopInfo +{ + u16 pred_scale; + u16 yn1; + u16 yn2; +}; + +struct AXParamBlock +{ + u16 next_pb_hi; + u16 next_pb_lo; + + u16 this_pb_hi; + u16 this_pb_lo; + + u16 src_type; // Type of sample rate converter (none, ?, linear) + u16 unknown1; + + u16 mixer_control; + u16 running; // 1=RUN 0=STOP + u16 is_stream; // 1 = stream, 0 = one shot + + PBMixer mixer; + PBInitialTimeDelay initial_time_delay; + PBUpdates updates; + PBUnknown unknown2; + PBVolumeEnvelope vol_env; + PBUnknown2 unknown3; + PBAudioAddr audio_addr; + PBADPCMInfo adpcm; + PBSampleRateConverter src; + PBADPCMLoopInfo adpcm_loop_info; + u16 unknown_maybe_padding[3]; +}; + +enum { + AUDIOFORMAT_ADPCM = 0, + AUDIOFORMAT_PCM8 = 0x19, + AUDIOFORMAT_PCM16 = 0xA, +}; + +enum { + SRCTYPE_LINEAR = 1, + SRCTYPE_NEAREST = 2, + MIXCONTROL_RAMPING = 8, +}; + + +#endif diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.cpp new file mode 100644 index 0000000000..de9e919946 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.cpp @@ -0,0 +1,63 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" +#include "../DSPHandler.h" +#include "UCodes.h" +#include "UCode_CARD.h" + + +CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler) + : IUCode(_rMailHandler) +{ + DebugLog("CUCode_CARD - initialized"); + m_rMailHandler.PushMail(DSP_INIT); +} + + +CUCode_CARD::~CUCode_CARD() +{ + m_rMailHandler.Clear(); +} + + +void CUCode_CARD::Update() +{ + // check if we have to sent something + if (!m_rMailHandler.IsEmpty()) + { + g_dspInitialize.pGenerateDSPInterrupt(); + } +} + +void CUCode_CARD::HandleMail(u32 _uMail) +{ + if (_uMail == 0xFF000000) // unlock card + { + // m_Mails.push(0x00000001); // ACK (actualy anything != 0) + } + else + { + DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail); + } + + m_rMailHandler.PushMail(DSP_DONE); + CDSPHandler::GetInstance().SetUCode(UCODE_ROM); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.h new file mode 100644 index 0000000000..528a5672f8 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_CARD.h @@ -0,0 +1,45 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_CARD_H +#define _UCODE_CARD_H + +#include "UCodes.h" + +class CUCode_CARD : public IUCode +{ +private: + enum EDSP_Codes + { + DSP_INIT = 0xDCD10000, + DSP_RESUME = 0xDCD10001, + DSP_YIELD = 0xDCD10002, + DSP_DONE = 0xDCD10003, + DSP_SYNC = 0xDCD10004, + DSP_UNKN = 0xDCD10005, + }; + +public: + CUCode_CARD(CMailHandler& _rMailHandler); + virtual ~CUCode_CARD(); + + void HandleMail(u32 _uMail); + void Update(); +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.cpp new file mode 100644 index 0000000000..741fd446f2 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" +#include "../DSPHandler.h" +#include "UCodes.h" +#include "UCode_InitAudioSystem.h" + +CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler) + : IUCode(_rMailHandler) + , m_BootTask_numSteps(0) + , m_NextParameter(0) + , IsInitialized(false) +{ + DebugLog("CUCode_InitAudioSystem - initialized"); +} + + +CUCode_InitAudioSystem::~CUCode_InitAudioSystem() +{} + + +void CUCode_InitAudioSystem::Init() +{} + + +void CUCode_InitAudioSystem::Update() +{ + if (m_rMailHandler.IsEmpty()) + { + m_rMailHandler.PushMail(0x80544348); + // HALT + } +} + +void CUCode_InitAudioSystem::HandleMail(u32 _uMail) +{} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.h new file mode 100644 index 0000000000..24231f7628 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_InitAudioSystem.h @@ -0,0 +1,54 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_INITAUDIOSYSTEM +#define _UCODE_INITAUDIOSYSTEM + +#include "UCodes.h" + +class CUCode_InitAudioSystem : public IUCode +{ +public: + CUCode_InitAudioSystem(CMailHandler& _rMailHandler); + virtual ~CUCode_InitAudioSystem(); + + void HandleMail(u32 _uMail); + void Update(); + void Init(); + +private: + struct SUCode + { + u32 m_RAMAddress; + u32 m_Length; + u32 m_IMEMAddress; + u32 m_Unk; + u32 m_StartPC; + }; + + SUCode m_CurrentUCode; + int m_BootTask_numSteps; + + u32 m_NextParameter; + + bool IsInitialized; + + void BootUCode(); +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.cpp new file mode 100644 index 0000000000..a1f6ff3544 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.cpp @@ -0,0 +1,162 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" +#include "UCodes.h" +#include "UCode_Jac.h" +#include "../MailHandler.h" + +CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler) + : IUCode(_rMailHandler) + , m_bListInProgress(false) +{ + DebugLog("CUCode_Jac: init"); + m_rMailHandler.PushMail(0xDCD10000); + m_rMailHandler.PushMail(0x80000000); +} + + +CUCode_Jac::~CUCode_Jac() +{ + m_rMailHandler.Clear(); +} + + +void CUCode_Jac::HandleMail(u32 _uMail) +{ + // this is prolly totally bullshit and should work like the zelda one... + // but i am to lazy to change it atm + + if (m_bListInProgress == false) + { + // get the command to find out how much steps it has + switch (_uMail & 0xFFFF) + { + // release halt + case 0x00: + // m_Mails.push(0x80000000); + g_dspInitialize.pGenerateDSPInterrupt(); + break; + + case 0x40: + m_step = 0; + ((u32*)m_Buffer)[m_step++] = _uMail; + m_bListInProgress = true; + m_numSteps = 5; + break; + + case 0x2000: + case 0x4000: + m_step = 0; + ((u32*)m_Buffer)[m_step++] = _uMail; + m_bListInProgress = true; + m_numSteps = 3; + break; + + default: + PanicAlert("UCode Jac"); + DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF); + break; + } + } + else + { + ((u32*)m_Buffer)[m_step] = _uMail; + m_step++; + + if (m_step == m_numSteps) + { + ExecuteList(); + m_bListInProgress = false; + } + } +} + + +void CUCode_Jac::Update() +{ + // check if we have to sent something +/* if (!g_MailHandler.empty()) + { + g_dspInitialize.pGenerateDSPInterrupt(); + }*/ +} + + +void CUCode_Jac::ExecuteList() +{ + // begin with the list + m_readOffset = 0; + + u16 cmd = Read16(); + u16 sync = Read16(); + + DebugLog("=============================================================================="); + DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync); + + switch (cmd) + { + // ============================================================================== + // DsetupTable + // ============================================================================== + case 0x40: + { + u32 tmp[4]; + tmp[0] = Read32(); + tmp[1] = Read32(); + tmp[2] = Read32(); + tmp[3] = Read32(); + + DebugLog("DsetupTable"); + DebugLog("???: 0x%08x", tmp[0]); + DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); + DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); + DebugLog("???: 0x%08x", tmp[3]); + } + break; + + // ============================================================================== + // UpdateDSPChannel + // ============================================================================== + case 0x2000: + case 0x4000: // animal crossing + { + u32 tmp[3]; + tmp[0] = Read32(); + tmp[1] = Read32(); + tmp[2] = Read32(); + + DebugLog("UpdateDSPChannel"); + DebugLog("audiomemory: 0x%08x", tmp[0]); + DebugLog("audiomemory: 0x%08x", tmp[1]); + DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]); + } + break; + + default: + PanicAlert("UCode Jac unknown cmd: %s (size %)", cmd, m_numSteps); + DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps); + break; + } + + // sync, we are rdy + m_rMailHandler.PushMail(DSP_SYNC); + m_rMailHandler.PushMail(0xF3550000 | sync); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.h new file mode 100644 index 0000000000..1a8a02acd4 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Jac.h @@ -0,0 +1,74 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_JAC +#define _UCODE_JAC + +#include "UCodes.h" + +class CUCode_Jac : public IUCode +{ +private: + + enum EDSP_Codes + { + DSP_INIT = 0xDCD10000, + DSP_RESUME = 0xDCD10001, + DSP_YIELD = 0xDCD10002, + DSP_DONE = 0xDCD10003, + DSP_SYNC = 0xDCD10004, + DSP_UNKN = 0xDCD10005, + }; + + bool m_bListInProgress; + int m_numSteps; + int m_step; + u8 m_Buffer[1024]; + void ExecuteList(); + + u32 m_readOffset; + + u8 Read8() + { + return(m_Buffer[m_readOffset++]); + } + + // Hmm, don't these need bswaps? + u16 Read16() + { + u16 res = *(u16*)&m_Buffer[m_readOffset]; + m_readOffset += 2; + return(res); + } + + u32 Read32() + { + u32 res = *(u32*)&m_Buffer[m_readOffset]; + m_readOffset += 4; + return(res); + } + +public: + CUCode_Jac(CMailHandler& _rMailHandler); + virtual ~CUCode_Jac(); + + void HandleMail(u32 _uMail); + void Update(); +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.cpp new file mode 100644 index 0000000000..71b54c8c02 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.cpp @@ -0,0 +1,117 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" +#include "../DSPHandler.h" +#include "UCodes.h" +#include "UCode_ROM.h" + + +CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler) + : IUCode(_rMailHandler) + , m_BootTask_numSteps(0) + , m_NextParameter(0) +{ + DebugLog("UCode_Rom - initialized"); + m_rMailHandler.Clear(); + m_rMailHandler.PushMail(0x8071FEED); +} + + +CUCode_Rom::~CUCode_Rom() +{} + + +void CUCode_Rom::Update() +{} + + +void CUCode_Rom::HandleMail(u32 _uMail) +{ + if (m_NextParameter == 0) + { + // wait for beginning of UCode + if ((_uMail & 0xFFFF0000) != 0x80F30000) + { + u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF); + m_rMailHandler.PushMail(Message); + } + else + { + m_NextParameter = _uMail; + } + } + else + { + switch (m_NextParameter) + { + case 0x80F3A001: + m_CurrentUCode.m_RAMAddress = _uMail; + break; + + case 0x80F3A002: + m_CurrentUCode.m_Length = _uMail; + break; + + case 0x80F3C002: + m_CurrentUCode.m_IMEMAddress = _uMail; + break; + + case 0x80F3B002: + m_CurrentUCode.m_Unk = _uMail; + break; + + case 0x80F3D001: + { + m_CurrentUCode.m_StartPC = _uMail; + BootUCode(); + } + break; + } + + m_NextParameter = 0; + } +} + + +void +CUCode_Rom::BootUCode() +{ + // simple non-scientific crc invented by ector :P + // too annoying to change now, and probably good enough anyway + u32 crc = 0; + + for (u32 i = 0; i < m_CurrentUCode.m_Length; i++) + { + crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i); + //let's rol + crc = (crc << 3) | (crc >> 29); + } + + DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress); + DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length); + DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress); + DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk); + DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC); + DebugLog("CurrentUCode CRC: 0x%08x", crc); + DebugLog("BootTask - done"); + + CDSPHandler::GetInstance().SetUCode(crc); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.h new file mode 100644 index 0000000000..82d438485b --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_ROM.h @@ -0,0 +1,51 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_ROM +#define _UCODE_ROM + +#include "UCodes.h" + +class CUCode_Rom : public IUCode +{ +public: + CUCode_Rom(CMailHandler& _rMailHandler); + virtual ~CUCode_Rom(); + + void HandleMail(u32 _uMail); + void Update(); + +private: + struct SUCode + { + u32 m_RAMAddress; + u32 m_Length; + u32 m_IMEMAddress; + u32 m_Unk; + u32 m_StartPC; + }; + + SUCode m_CurrentUCode; + int m_BootTask_numSteps; + + u32 m_NextParameter; + + void BootUCode(); +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp new file mode 100644 index 0000000000..c7a223e519 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp @@ -0,0 +1,163 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// Games that uses this UCode: +// Zelda: The Windwaker, Mario Sunshine, Mario Kart + +#include "Common.h" +#include "../Globals.h" +#include "UCodes.h" +#include "UCode_Zelda.h" +#include "../MailHandler.h" + + +CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler) + : IUCode(_rMailHandler) + , m_numSteps(0) + , m_bListInProgress(false) +{ + DebugLog("UCode_Zelda - add boot mails for handshake"); + m_rMailHandler.PushMail(DSP_INIT); + m_rMailHandler.PushMail(0x80000000); // handshake +} + + +CUCode_Zelda::~CUCode_Zelda() +{ + m_rMailHandler.Clear(); +} + + +void CUCode_Zelda::Update() +{ + // check if we have to sent something + if (!m_rMailHandler.IsEmpty()) + { + g_dspInitialize.pGenerateDSPInterrupt(); + } +} + + +void CUCode_Zelda::HandleMail(u32 _uMail) +{ + if (m_bListInProgress == false) + { + m_bListInProgress = true; + m_numSteps = _uMail; + m_step = 0; + } + else + { + ((u32*)m_Buffer)[m_step] = _uMail; + m_step++; + + if (m_step == m_numSteps) + { + ExecuteList(); + m_bListInProgress = false; + } + } +} + + +void CUCode_Zelda::ExecuteList() +{ + // begin with the list + m_readOffset = 0; + + u32 Temp = Read32(); + u32 Command = (Temp >> 24) & 0x7f; + u32 Sync = Temp >> 16; + + DebugLog("=============================================================================="); + DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync); + + switch (Command) + { + // DsetupTable ... zelda ww jumps to 0x0095 + case 0x01: + { + u32 tmp[4]; + tmp[0] = Read32(); + tmp[1] = Read32(); + tmp[2] = Read32(); + tmp[3] = Read32(); + + DebugLog("DsetupTable"); + DebugLog("???: 0x%08x", tmp[0]); + DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); + DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); + DebugLog("???: 0x%08x", tmp[3]); + } + break; + + // SyncFrame ... zelda ww jumps to 0x0243 + case 0x02: + { + u32 tmp[3]; + tmp[0] = Read32(); + tmp[1] = Read32(); + tmp[2] = Read32(); + + DebugLog("DsyncFrame"); + DebugLog("???: 0x%08x", tmp[0]); + DebugLog("???: 0x%08x", tmp[1]); + DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); + } + break; + +/* + case 0x03: break; // dunno ... zelda ww jmps to 0x0073 + case 0x04: break; // dunno ... zelda ww jmps to 0x0580 + case 0x05: break; // dunno ... zelda ww jmps to 0x0592 + case 0x06: break; // dunno ... zelda ww jmps to 0x0469 + + case 0x07: break; // dunno ... zelda ww jmps to 0x044d + case 0x08: break; // Mixer ... zelda ww jmps to 0x0485 + case 0x09: break; // dunno ... zelda ww jmps to 0x044d + */ + + // DsetDolbyDelay ... zelda ww jumps to 0x00b2 + case 0x0d: + { + u32 tmp[2]; + tmp[0] = Read32(); + tmp[1] = Read32(); + + DebugLog("DSetDolbyDelay"); + DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]); + DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]); + } + break; + + // Set VARAM + case 0x0e: +// MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK); + break; + + // default ... zelda ww jumps to 0x0043 + default: + PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps); + break; + } + + // sync, we are rdy + m_rMailHandler.PushMail(DSP_SYNC); + m_rMailHandler.PushMail(0xF3550000 | Sync); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h new file mode 100644 index 0000000000..e9168fd52e --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h @@ -0,0 +1,74 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODE_ZELDA_H +#define _UCODE_ZELDA_H + +#include "Common.h" +#include "UCodes.h" + +class CUCode_Zelda : public IUCode +{ +private: + enum EDSP_Codes + { + DSP_INIT = 0xDCD10000, + DSP_RESUME = 0xDCD10001, + DSP_YIELD = 0xDCD10002, + DSP_DONE = 0xDCD10003, + DSP_SYNC = 0xDCD10004, + DSP_UNKN = 0xDCD10005, + }; + + // List in progress + int m_numSteps; + bool m_bListInProgress; + int m_step; + u8 m_Buffer[1024]; + void ExecuteList(); + + u32 m_readOffset; + + u8 Read8() + { + return(m_Buffer[m_readOffset++]); + } + + u16 Read16() + { + u16 res = *(u16*)&m_Buffer[m_readOffset]; + m_readOffset += 2; + return(res); + } + + u32 Read32() + { + u32 res = *(u32*)&m_Buffer[m_readOffset]; + m_readOffset += 4; + return(res); + } +public: + + CUCode_Zelda(CMailHandler& _rMailHandler); + virtual ~CUCode_Zelda(); + + void HandleMail(u32 _uMail); + void Update(); +}; + +#endif + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.cpp new file mode 100644 index 0000000000..508bd648c0 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "../Globals.h" + +#include "UCodes.h" + +#include "UCode_AX.h" +#include "UCode_Zelda.h" +#include "UCode_Jac.h" +#include "UCode_ROM.h" +#include "UCode_CARD.h" +#include "UCode_InitAudioSystem.h" + +IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler) +{ + switch (_CRC) + { + case UCODE_ROM: + return(new CUCode_Rom(_rMailHandler)); + + case UCODE_INIT_AUDIO_SYSTEM: + return(new CUCode_InitAudioSystem(_rMailHandler)); + + case 0x65d6cc6f: // CARD + return(new CUCode_CARD(_rMailHandler)); + + case 0x088e38a5: // IPL - JAP + case 0xd73338cf: // IPL + case 0x42f64ac4: // Luigi (after fix) + case 0x4be6a5cb: // AC, Pikmin (after fix) + DebugLog("JAC ucode chosen"); + return(new CUCode_Jac(_rMailHandler)); + + case 0x3ad3b7ac: // Naruto3 + case 0x3daf59b9: // Alien Hominid + case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario, + // capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat, + // smugglers run warzone, smash brothers, sonic mega collection, ZooCube + // nddemo, starfox + case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2, + // Zelda:OOT, Tony hawk, viewtiful joe + case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080 + DebugLog("AX ucode chosen, yay!"); + return(new CUCode_AX(_rMailHandler)); + + case 0x6CA33A6D: // DK Jungle Beat + case 0x86840740: // zelda + case 0x56d36052: // mario + case 0x2fcdf1ec: // mariokart, zelda 4 swords + DebugLog("Zelda ucode chosen"); + return(new CUCode_Zelda(_rMailHandler)); + + // WII CRCs + case 0x6c3f6f94: // zelda - PAL + case 0xd643001f: // mario galaxy - PAL + DebugLog("Zelda Wii ucode chosen"); + return(new CUCode_Zelda(_rMailHandler)); + + case 0x347112ba: // raving rabbits + DebugLog("Wii - AX chosen"); + return(new CUCode_AX(_rMailHandler, true)); + + default: + PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC); + return(new CUCode_AX(_rMailHandler)); + } + + return(NULL); +} + + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.h new file mode 100644 index 0000000000..f7c2787e49 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCodes.h @@ -0,0 +1,47 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _UCODES_H +#define _UCODES_H + +#include "Common.h" + +#define UCODE_ROM 0x0000000 +#define UCODE_INIT_AUDIO_SYSTEM 0x0000001 + +class CMailHandler; +class IUCode +{ +public: + IUCode(CMailHandler& _rMailHandler) + : m_rMailHandler(_rMailHandler) + {} + + virtual ~IUCode() + {} + + virtual void HandleMail(u32 _uMail) = 0; + virtual void Update(void) = 0; + virtual void MixAdd(short* buffer, int size) {} + +protected: + CMailHandler& m_rMailHandler; +}; + +extern IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler); + +#endif diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp new file mode 100644 index 0000000000..00a2d8d7cd --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp @@ -0,0 +1,237 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Globals.h" +#include "resource.h" + +#ifdef _WIN32 +#include "PCHW/DSoundStream.h" +#include "AboutDlg.h" +#include "ConfigDlg.h" +#else +#include "PCHW/AOSoundStream.h" +#endif + +#include "PCHW/Mixer.h" + +#include "DSPHandler.h" +#include "Config.h" + +DSPInitialize g_dspInitialize; +u8* g_pMemory; + +#ifdef _WIN32 +HINSTANCE g_hInstance = NULL; + +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle + DWORD dwReason, // reason called + LPVOID lpvReserved) // reserved +{ + switch (dwReason) + { + case DLL_PROCESS_ATTACH: + break; + + case DLL_PROCESS_DETACH: + break; + + default: + break; + } + + g_hInstance = hinstDLL; + return(TRUE); +} + +#endif + +void GetDllInfo(PLUGIN_INFO* _PluginInfo) +{ + _PluginInfo->Version = 0x0100; + _PluginInfo->Type = PLUGIN_TYPE_DSP; +#ifndef _DEBUG + sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin"); +#else + sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin Debug"); +#endif +} + +void DllAbout(HWND _hParent) +{ +#ifdef _WIN32 + CAboutDlg aboutDlg; + aboutDlg.DoModal(_hParent); +#endif +} + +void DllConfig(HWND _hParent) +{ +#ifdef _WIN32 + CConfigDlg configDlg; + configDlg.DoModal(_hParent); +#endif +} + +void DSP_Initialize(DSPInitialize _dspInitialize) +{ + g_Config.LoadDefaults(); + g_Config.Load(); + + g_dspInitialize = _dspInitialize; + + g_pMemory = g_dspInitialize.pGetMemoryPointer(0); + + CDSPHandler::CreateInstance(); + +#ifdef _WIN32 + DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); +#else + AOSound::AOSound_StartSound(48000, Mixer); +#endif +} + +void DSP_Shutdown() +{ + // delete the UCodes +#ifdef _WIN32 + DSound::DSound_StopSound(); +#else + AOSound::AOSound_StopSound(); +#endif + CDSPHandler::Destroy(); +} + +struct DSPState +{ + u32 CPUMailbox; + bool CPUMailbox_Written[2]; + + u32 DSPMailbox; + bool DSPMailbox_Read[2]; + + DSPState() + { + CPUMailbox = 0x00000000; + CPUMailbox_Written[0] = false; + CPUMailbox_Written[1] = false; + + DSPMailbox = 0x00000000; + DSPMailbox_Read[0] = true; + DSPMailbox_Read[1] = true; + } +}; +DSPState g_dspState; + +unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) +{ + if (_CPUMailbox) + { + return((g_dspState.CPUMailbox >> 16) & 0xFFFF); + } + else + { + return(CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh()); + } +} + +unsigned short DSP_ReadMailboxLow(bool _CPUMailbox) +{ + if (_CPUMailbox) + { + return(g_dspState.CPUMailbox & 0xFFFF); + } + else + { + return(CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow()); + } +} + +void Update_DSP_WriteRegister() +{ + // check if the whole message is complete and if we can send it + if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1]) + { + CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox); + g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false; + g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed + } +} + +void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value) +{ + if (_CPUMailbox) + { + g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16); + g_dspState.CPUMailbox_Written[0] = true; + + Update_DSP_WriteRegister(); + } + else + { + PanicAlert("CPU can't write %08x to DSP mailbox", _Value); + } +} + +void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value) +{ + if (_CPUMailbox) + { + g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value; + g_dspState.CPUMailbox_Written[1] = true; + + Update_DSP_WriteRegister(); + } + else + { + PanicAlert("CPU can't write %08x to DSP mailbox", _Value); + } +} + +unsigned short DSP_WriteControlRegister(unsigned short _Value) +{ + return CDSPHandler::GetInstance().WriteControlRegister(_Value); +} + +unsigned short DSP_ReadControlRegister() +{ + return CDSPHandler::GetInstance().ReadControlRegister(); +} + +void DSP_Update(int cycles) +{ + CDSPHandler::GetInstance().Update(); +} + +void DSP_SendAIBuffer(unsigned int address, int sample_rate) +{ + short samples[16] = {0}; // interleaved stereo + if (address) { + for (int i = 0; i < 16; i++) { + samples[i] = Memory_Read_U16(address + i * 2); + } + } + Mixer_PushSamples(samples, 32 / 4, sample_rate); + + static int counter = 0; + counter++; +#ifdef _WIN32 + if ((counter & 255) == 0) + DSound::DSound_UpdateSound(); +#endif + +} diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/resource.h b/Source/Plugins/Plugin_DSP_HLE/Src/resource.h new file mode 100644 index 0000000000..9188e4df98 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/resource.h @@ -0,0 +1,32 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_SETTINGS 101 +#define IDD_DIALOG2 102 +#define IDD_ABOUT 102 +#define IDC_COMBO1 1001 +#define IDC_SAMPLERATE 1001 +#define IDC_EDIT1 1002 +#define IDC_SAMPLEDUMPPATH 1002 +#define IDC_CHECK1 1003 +#define IDC_ENABLE_AUDIO 1003 +#define IDC_ENABLE_HLE_AUDIO 1003 +#define IDC_CHECK2 1004 +#define IDC_ENABLE_DTK_MUSIC 1004 +#define IDC_DUMPSAMPLES 1005 +#define IDC_SAMPLEMINLENGTH 1006 +#define IDC_BROWSE 1007 +#define IDC_ANTIGAP 1009 +#define IDC_CHECK3 1010 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/resource.rc b/Source/Plugins/Plugin_DSP_HLE/Src/resource.rc new file mode 100644 index 0000000000..33bc63a084 --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/resource.rc @@ -0,0 +1,130 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SETTINGS DIALOGEX 0, 0, 241, 138 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dolphin DSP-HLE Plugin Settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,116,50,14 + PUSHBUTTON "Cancel",IDCANCEL,184,116,50,14 + GROUPBOX "&Sound settings",IDC_STATIC,7,7,227,45 + EDITTEXT IDC_SAMPLEDUMPPATH,13,89,155,13,ES_AUTOHSCROLL | WS_DISABLED + CONTROL "&Enable HLE Audio",IDC_ENABLE_HLE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,22,84,8 + GROUPBOX "Sample d&umping",IDC_STATIC,7,59,227,51 + CONTROL "Enab&le DTK Music",IDC_ENABLE_DTK_MUSIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,36,102,8 + CONTROL "&Dump all samples longer than",IDC_DUMPSAMPLES,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,13,73,105,9 + EDITTEXT IDC_SAMPLEMINLENGTH,122,71,47,12,ES_AUTOHSCROLL | WS_DISABLED + LTEXT "seconds to:",IDC_STATIC,173,73,40,10 + PUSHBUTTON "&Browse...",IDC_BROWSE,173,89,54,14 + CONTROL "&Anti-gap (dangerous!)",IDC_ANTIGAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,122,22,96,9 + CONTROL "&Reverb",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,122,36,89,10 +END + +IDD_ABOUT DIALOGEX 0, 0, 184, 65 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Dolphin DSP-HLE Plugin" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,127,44,50,14 + LTEXT "Coded by ector and F|RES",IDC_STATIC,51,25,104,14 + LTEXT "Dolphin DSP-HLE plugin",IDC_STATIC,51,7,104,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SETTINGS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 234 + VERTGUIDE, 13 + VERTGUIDE, 122 + VERTGUIDE, 168 + TOPMARGIN, 7 + BOTTOMMARGIN, 131 + HORZGUIDE, 31 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 177 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.cpp new file mode 100644 index 0000000000..5d19def11f --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "stdafx.h" + diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.h b/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.h new file mode 100644 index 0000000000..6e2672e1cd --- /dev/null +++ b/Source/Plugins/Plugin_DSP_HLE/Src/stdafx.h @@ -0,0 +1,35 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define _CRT_SECURE_NO_DEPRECATE 1 + +// Windows Header Files: +#include +#include + +// WTL +#include +#include +#include +#include + +#endif diff --git a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj index 15e492003a..8959b00d5e 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj +++ b/Source/Plugins/Plugin_DSP_LLE/Plugin_DSP_LLE.vcproj @@ -715,6 +715,10 @@ RelativePath=".\Src\main.cpp" > + + diff --git a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp index a530eb04fc..7a84e0e150 100644 --- a/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE/Src/main.cpp @@ -163,32 +163,29 @@ void Mixer(short* buffer, int numSamples, int bits, int rate, int channels) void DSP_Initialize(DSPInitialize _dspInitialize) { + g_dspInitialize = _dspInitialize; + + gdsp_init(); + g_dsp.step_counter = 0; + g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); + g_dsp.irq_request = dspi_req_dsp_irq; + gdsp_reset(); + + if (!gdsp_load_rom("data\\dsp_rom.bin")) { - g_dspInitialize = _dspInitialize; - - gdsp_init(); - g_dsp.step_counter = 0; - g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); - g_dsp.irq_request = dspi_req_dsp_irq; - gdsp_reset(); - - if (!gdsp_load_rom("data\\dsp_rom.bin")) - { - ErrorLog("Cannot load DSP ROM\n"); - } - - if (!gdsp_load_coef("data\\dsp_coef.bin")) - { - ErrorLog("Cannot load DSP COEF\n"); - } + ErrorLog("Cannot load DSP ROM\n"); + } + if (!gdsp_load_coef("data\\dsp_coef.bin")) + { + ErrorLog("Cannot load DSP COEF\n"); + } /* Dump UCode to file... FILE* t = fopen("e:\\hmm.txt", "wb"); gd_globals_t gdg; gd_dis_file(&gdg, "D:\\DSP_UCode.bin", t); fclose(t); */ - } #ifdef _WIN32 #if _DEBUG @@ -200,13 +197,12 @@ void DSP_Initialize(DSPInitialize _dspInitialize) pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL); #endif - - #ifdef _WIN32 - InitializeCriticalSection(&g_CriticalSection); - DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 32000, Mixer); - #else - AOSound::AOSound_StartSound(32000, Mixer); - #endif +#ifdef _WIN32 + InitializeCriticalSection(&g_CriticalSection); + DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); +#else + AOSound::AOSound_StartSound(48000, Mixer); +#endif } @@ -313,7 +309,7 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, short unsigned int _uLowMail) } -void DSP_Update() +void DSP_Update(int cycles) { if (g_hDSPThread) { @@ -322,19 +318,19 @@ void DSP_Update() #ifdef _WIN32 if (g_Dialog.CanDoStep()) { - gdsp_runx(100); + gdsp_runx(100); // cycles } #endif } #ifdef _WIN32 -void DSP_SendAIBuffer(unsigned __int32 _Address, unsigned __int32 _Size) +void DSP_SendAIBuffer(unsigned int address, int sample_rate) #else -void DSP_SendAIBuffer(unsigned int _Address, unsigned int _Size) +void DSP_SendAIBuffer(unsigned int address, int sample_rate) #endif { - uint32 Size = _Size * 16 * 2; // 16bit per sample, two channels + // uint32 Size = _Size * 16 * 2; // 16bit per sample, two channels - g_LastDMAAddress = _Address; - g_LastDMASize = Size; + g_LastDMAAddress = address; + g_LastDMASize = 32; } diff --git a/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj b/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj index 5d24e9663e..baf3643898 100644 --- a/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj +++ b/Source/Plugins/Plugin_DSP_NULL/Plugin_DSP_NULL.vcproj @@ -741,6 +741,10 @@ RelativePath=".\Src\main.cpp" > + + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 514de0c048..c86aaf9e2e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -18,6 +18,8 @@ #include "Globals.h" #include +#include + #include "GLInit.h" #include "Render.h" #include "OpcodeDecoding.h" @@ -355,7 +357,7 @@ bool Renderer::Initialize() void Renderer::AddMessage(const char* pstr, u32 ms) { - s_listMsgs.push_back(MESSAGE(pstr, timeGetTime()+ms)); + s_listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms)); } void Renderer::ProcessMessages()