From dcd5ffeb7ad0216b5d9a90f59c23c54208e2bdde Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 16 Aug 2008 10:49:08 +0000 Subject: [PATCH] More accurate audio interrupts (preparation for homebrew audio support). some minor cleanup in gl plugin. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@226 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/AudioInterface.cpp | 29 ++++-- Source/Core/Core/Src/HW/AudioInterface.h | 3 + Source/Core/Core/Src/HW/DSP.cpp | 88 ++++++++++++++----- Source/Core/Core/Src/HW/DSP.h | 4 +- Source/Core/Core/Src/HW/GPFifo.cpp | 4 + Source/Core/Core/Src/HW/GPFifo.h | 2 + Source/Core/Core/Src/HW/SystemTimers.cpp | 65 ++++++++------ .../Interpreter_SystemRegisters.cpp | 18 ++-- .../Src/PowerPC/Jit64/Jit_SystemRegisters.cpp | 4 +- .../Plugin_VideoOGL/Plugin_VideoOGL.vcproj | 4 + .../Plugins/Plugin_VideoOGL/Src/Globals.cpp | 7 ++ Source/Plugins/Plugin_VideoOGL/Src/Globals.h | 23 +---- .../Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp | 9 ++ .../Src/PixelShaderManager.cpp | 9 +- .../Plugin_VideoOGL/Src/TextureMngr.cpp | 7 +- .../Plugin_VideoOGL/Src/VertexLoader.cpp | 2 +- 16 files changed, 177 insertions(+), 101 deletions(-) diff --git a/Source/Core/Core/Src/HW/AudioInterface.cpp b/Source/Core/Core/Src/HW/AudioInterface.cpp index 89a826cc99..8f18bdd8d6 100644 --- a/Source/Core/Core/Src/HW/AudioInterface.cpp +++ b/Source/Core/Core/Src/HW/AudioInterface.cpp @@ -15,6 +15,13 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +// This file is ONLY about disc streaming. It's a bit unfortunately named. +// For the rest of the audio stuff, including the "real" AI, see DSP.cpp/h. + +// AI disc streaming is handled completely separately from the rest of the +// audio processing. In short, it simply streams audio directly from disc +// out through the speakers. + #include "Common.h" #include "StreamADPCM.H" @@ -125,13 +132,15 @@ void Read32(u32& _rReturnValue, const u32 _Address) return; case AI_INTERRUPT_TIMING: + // When sample counter reaches the value of this register, the interrupt AIINT should + // fire. LOG(AUDIO_INTERFACE, "AudioInterface(R) 0x%08x", _Address); _rReturnValue = g_AudioRegister.m_InterruptTiming; return; default: LOG(AUDIO_INTERFACE, "AudioInterface(R) 0x%08x", _Address); - _dbg_assert_msg_(AUDIO_INTERFACE,0,"AudioInterface - Read from ???"); + _dbg_assert_msg_(AUDIO_INTERFACE, 0, "AudioInterface - Read from ???"); _rReturnValue = 0; return; } @@ -196,7 +205,8 @@ void Write32(const u32 _Value, const u32 _Address) break; case AI_SAMPLE_COUNTER: - _dbg_assert_msg_(AUDIO_INTERFACE,0,"AudioInterface - m_SampleCounter is Read only"); + // _dbg_assert_msg_(AUDIO_INTERFACE, 0, "AudioInterface - m_SampleCounter is Read only"); + g_AudioRegister.m_SampleCounter = _Value; break; case AI_INTERRUPT_TIMING: @@ -229,7 +239,7 @@ void GenerateAudioInterrupt() UpdateInterrupts(); } -// Callback for the DSP streaming +// Callback for the disc streaming // WARNING - called from audio thread unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _numSamples) { @@ -240,9 +250,9 @@ unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _nu const int lvolume = g_AudioRegister.m_Volume.leftVolume; const int rvolume = g_AudioRegister.m_Volume.rightVolume; - for (unsigned int i=0; i<_numSamples; i++) + for (unsigned int i = 0; i < _numSamples; i++) { - if (pos==0) + if (pos == 0) { ReadStreamBlock(pcm); } @@ -253,13 +263,13 @@ unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _nu pos++; if (pos == 28) { - pos=0; + pos = 0; } } } else { - for (unsigned int i=0; i<_numSamples*2; i++) + for (unsigned int i = 0; i < _numSamples * 2; i++) { _pDestBuffer[i] = 0; //silence! } @@ -269,7 +279,7 @@ unsigned __int32 Callback_GetStreaming(short* _pDestBuffer, unsigned __int32 _nu } // WARNING - called from audio thread -void ReadStreamBlock(short* _pPCM) +void ReadStreamBlock(short *_pPCM) { char tempADPCM[32]; if (DVDInterface::DVDReadADPCM((u8*)tempADPCM, 32)) @@ -289,6 +299,7 @@ void ReadStreamBlock(short* _pPCM) // our whole streaming code is "faked" ... so it shouldn't increase the sample counter // streaming will never work correctly this way, but at least the program will think all is alright. + // This call must not be done wihout going through CoreTiming's threadsafe option. // IncreaseSampleCount(28); } @@ -298,7 +309,7 @@ void IncreaseSampleCount(const u32 _iAmount) { g_AudioRegister.m_SampleCounter += _iAmount; if (g_AudioRegister.m_Control.AIINTVLD && - (g_AudioRegister.m_SampleCounter > g_AudioRegister.m_InterruptTiming)) + (g_AudioRegister.m_SampleCounter >= g_AudioRegister.m_InterruptTiming)) { GenerateAudioInterrupt(); } diff --git a/Source/Core/Core/Src/HW/AudioInterface.h b/Source/Core/Core/Src/HW/AudioInterface.h index 2e8da4b33c..4b5e759550 100644 --- a/Source/Core/Core/Src/HW/AudioInterface.h +++ b/Source/Core/Core/Src/HW/AudioInterface.h @@ -14,6 +14,9 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ + +// See CPP file for comments. + #ifndef _AUDIOINTERFACE_H #define _AUDIOINTERFACE_H diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 6126128db3..c941f07507 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -15,6 +15,22 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +// AID / AUDIO_DMA controls pushing audio out to the SRC and then the speakers. +// The audio DMA pushes audio through a small FIFO 32 bytes at a time, as needed. +// Since the SRC behind the fifo eats stereo 16-bit data at a sample rate of 32khz, +// that is, 4 bytes at 32 khz, which is 32 bytes at 4 khz. We should thus schedule an +// event that runs at 4khz, that eats audio from the fifo, and all the rest will follow. +// Then we will have homebrew audio. + +// The AID interrupt is set when the fifo STARTS a transfer. It latches address and count +// into internal registers and starts copying. This means that the interrupt handler can simply +// set the registers to where the next buffer is, and start filling it. When the DMA is complete, +// it will automatically relatch and fire a new interrupt. + +// Then there's the DSP... what likely happens is that the fifo-latched-interrupt handler +// kicks off the DSP, requesting it to fill up the just used buffer through the AXList (or +// whatever it might be called in Nintendo games). + #include "DSP.h" #include "../CoreTiming.h" @@ -80,8 +96,8 @@ union UDSPControl unsigned DSPAssertInt : 1; unsigned DSPHalt : 1; - unsigned AI : 1; - unsigned AI_mask : 1; + unsigned AID : 1; + unsigned AID_mask : 1; unsigned ARAM : 1; unsigned ARAM_mask : 1; unsigned DSP : 1; @@ -107,14 +123,14 @@ struct DSPState } }; -// UDSPControl +// Blocks are 32 bytes. union UAudioDMAControl { u16 Hex; struct { - unsigned NumSamples : 15; - unsigned Enabled : 1; + unsigned NumBlocks : 15; + unsigned Enabled : 1; }; UAudioDMAControl(u16 _Hex = 0) : Hex(_Hex) @@ -125,8 +141,9 @@ union UAudioDMAControl struct AudioDMA { u32 SourceAddress; + u32 ReadAddress; UAudioDMAControl AudioDMAControl; - u32 SamplesLeft; + int BlocksLeft; }; // ARDMA @@ -162,6 +179,11 @@ 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); @@ -236,7 +258,8 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // DMA_REGS 0x5030+ // ================================================================================== case AUDIO_DMA_BYTES_LEFT: - _uReturnValue = g_audioDMA.SamplesLeft; + // Hmm. Would be stupid to ask for bytes left. Assume it wants blocks left. + _uReturnValue = g_audioDMA.BlocksLeft; return; case AUDIO_DMA_START_LO: @@ -305,12 +328,12 @@ void Write16(const u16 _Value, const u32 _Address) g_dspState.DSPControl.DSPInit = tmpControl.DSPInit; // Interrupt (mask) - g_dspState.DSPControl.AI_mask = tmpControl.AI_mask; + g_dspState.DSPControl.AID_mask = tmpControl.AID_mask; g_dspState.DSPControl.ARAM_mask = tmpControl.ARAM_mask; g_dspState.DSPControl.DSP_mask = tmpControl.DSP_mask; // Interrupt - if (tmpControl.AI) g_dspState.DSPControl.AI = 0; + if (tmpControl.AID) g_dspState.DSPControl.AID = 0; if (tmpControl.ARAM) g_dspState.DSPControl.ARAM = 0; if (tmpControl.DSP) g_dspState.DSPControl.DSP = 0; @@ -332,6 +355,7 @@ void Write16(const u16 _Value, const u32 _Address) // ================================================================================== // AR_REGS 0x501x+ + // DMA back and forth between ARAM and RAM // ================================================================================== case 0x5012: @@ -369,6 +393,7 @@ void Write16(const u16 _Value, const u32 _Address) // ================================================================================== // Audio DMA_REGS 0x5030+ + // This is the DMA that goes straight out the speaker. // ================================================================================== case AUDIO_DMA_START_HI: g_audioDMA.SourceAddress = (g_audioDMA.SourceAddress & 0xFFFF) | (_Value<<16); @@ -379,16 +404,20 @@ void Write16(const u16 _Value, const u32 _Address) break; case AUDIO_DMA_CONTROL_LEN: // called by AIStartDMA() - g_audioDMA.AudioDMAControl.Hex = _Value; - g_audioDMA.SamplesLeft = g_audioDMA.AudioDMAControl.NumSamples; - - if (g_audioDMA.AudioDMAControl.Enabled) { - PluginDSP::DSP_SendAIBuffer(g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumSamples); - g_audioDMA.SamplesLeft = 0; + UAudioDMAControl old_control = g_audioDMA.AudioDMAControl; + g_audioDMA.AudioDMAControl.Hex = _Value; + + if (!old_control.Enabled && g_audioDMA.AudioDMAControl.Enabled) + { + // Enabled bit was flipped to true, let's latch address & length and call the interrupt. + 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); } break; - + } case AUDIO_DMA_BYTES_LEFT: _dbg_assert_(DSPINTERFACE,0); break; @@ -399,6 +428,25 @@ void Write16(const u16 _Value, const u32 _Address) } } +// This happens at 4 khz, since 32 bytes at 4khz = 4 bytes at 32 khz (16bit stereo pcm) +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. + g_audioDMA.ReadAddress += 32; + g_audioDMA.BlocksLeft--; + if (!g_audioDMA.BlocksLeft) { + // No need to turn off the DMA - we can only get here if we had blocks left when we + // entered this function, and no longer have any. + // Latch new parameters + g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; + g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; + GenerateDSPInterrupt(DSP::INT_AID); + } + } +} + void Read32(u32& _uReturnValue, const u32 _iAddress) { LOG(DSPINTERFACE, "DSPInterface(r) 0x%08x", _iAddress); @@ -450,7 +498,7 @@ void Write32(const u32 _iValue, const u32 _iAddress) // void UpdateInterrupts() { - if ((g_dspState.DSPControl.AI & g_dspState.DSPControl.AI_mask) || + if ((g_dspState.DSPControl.AID & g_dspState.DSPControl.AID_mask) || (g_dspState.DSPControl.ARAM & g_dspState.DSPControl.ARAM_mask) || (g_dspState.DSPControl.DSP & g_dspState.DSPControl.DSP_mask)) { @@ -468,7 +516,7 @@ void GenerateDSPInterrupt(DSPInterruptType type, bool _bSet) { case INT_DSP: g_dspState.DSPControl.DSP = _bSet ? 1 : 0; break; case INT_ARAM: g_dspState.DSPControl.ARAM = _bSet ? 1 : 0; break; - case INT_AI: g_dspState.DSPControl.AI = _bSet ? 1 : 0; break; + case INT_AID: g_dspState.DSPControl.AID = _bSet ? 1 : 0; break; } UpdateInterrupts(); @@ -504,7 +552,7 @@ void Update_ARAM_DMA() u32 iARAMAddress = g_arDMA.ARAddr; // TODO(??): sanity check instead of writing bogus data? - for (u32 i=0; iRunCycles(1000) or whatever, + // ~1/6th as many cycles as the period PPC-side. + PluginDSP::DSP_Update(); + CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, &DSPCallback, "DSPCallback"); +} + +void AudioFifoCallback(u64 userdata, int cyclesLate) +{ + int period = CPU_CORE_CLOCK / (DSP::GetDSPSampleRate() * 4 / 32); + DSP::UpdateAudioDMA(); // Push audio to speakers. + + CoreTiming::ScheduleEvent(period - cyclesLate, &AudioFifoCallback, "AudioFifoCallback"); +} + void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate) { WII_IPC_HLE_Interface::Update(); @@ -100,18 +127,6 @@ void SICallback(u64 userdata, int cyclesLate) CoreTiming::ScheduleEvent(SI_PERIOD-cyclesLate, &SICallback, "SICallback"); } -void DSPCallback(u64 userdata, int cyclesLate) -{ - PluginDSP::DSP_Update(); - CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, &DSPCallback, "DSPCallback"); -} - -void DSPInterruptCallback(u64 userdata, int cyclesLate) -{ - DSP::GenerateDSPInterrupt(DSP::INT_AI); - CoreTiming::ScheduleEvent(DSPINT_PERIOD-cyclesLate, &DSPInterruptCallback, "DSPInterruptCallback"); -} - void DecrementerCallback(u64 userdata, int cyclesLate) { //Why is fakeDec too big here? @@ -122,7 +137,6 @@ void DecrementerCallback(u64 userdata, int cyclesLate) void DecrementerSet() { - // MessageBox(0, "dec set",0,0); u32 decValue = PowerPC::ppcState.spr[SPR_DEC]; fakeDec = decValue*TIMER_RATIO; CoreTiming::RemoveEvent(DecrementerCallback); @@ -131,10 +145,7 @@ void DecrementerSet() void AdvanceCallback(int cyclesExecuted) { - //int oldFakeDec = fakeDec; fakeDec -= cyclesExecuted; - //if (fakeDec < 0 && oldFakeDec > 0) - // fakeDec = TIMER_RATIO; u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO; //works since we are little endian and TL comes first :) *(u64*)&TL = timebase_ticks; if (fakeDec >= 0) @@ -185,26 +196,24 @@ void Init() if (Core::GetStartupParameter().bWii) { CPU_CORE_CLOCK = 721000000; - VI_PERIOD = GetTicksPerSecond() / (60*120), - SI_PERIOD = GetTicksPerSecond() / 60, //once a frame is good for controllers + VI_PERIOD = GetTicksPerSecond() / (60*120); + SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers // These are the big question marks IMHO :) - AI_PERIOD = GetTicksPerSecond() / 80, - DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f), - DSPINT_PERIOD = (int)(GetTicksPerSecond() * 0.003f); + AI_PERIOD = GetTicksPerSecond() / 80; + DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f); HLE_IPC_PERIOD = (int)(GetTicksPerSecond() * 0.003f); } else { CPU_CORE_CLOCK = 486000000; - VI_PERIOD = GetTicksPerSecond() / (60*120), - SI_PERIOD = GetTicksPerSecond() / 60, //once a frame is good for controllers + VI_PERIOD = GetTicksPerSecond() / (60*120); + SI_PERIOD = GetTicksPerSecond() / 60; // once a frame is good for controllers // These are the big question marks IMHO :) - AI_PERIOD = GetTicksPerSecond() / 80, - DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f), - DSPINT_PERIOD = (int)(GetTicksPerSecond() *0.005f); + AI_PERIOD = GetTicksPerSecond() / 80; + DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f); } Common::Timer::IncreaseResolution(); memset(timeHistory, 0, sizeof(timeHistory)); @@ -216,7 +225,7 @@ void Init() CoreTiming::ScheduleEvent(VI_PERIOD, &VICallback, "VICallback"); CoreTiming::ScheduleEvent(DSP_PERIOD, &DSPCallback, "DSPCallback"); CoreTiming::ScheduleEvent(SI_PERIOD, &SICallback, "SICallback"); - CoreTiming::ScheduleEvent(DSPINT_PERIOD, &DSPInterruptCallback, "DSPInterruptCallback"); + CoreTiming::ScheduleEvent(CPU_CORE_CLOCK / (32000 * 4 / 32), &AudioFifoCallback, "AudioFifoCallback"); if (!Core::GetStartupParameter().bUseDualCore) CoreTiming::ScheduleEvent(GPU_PERIOD, &RunGPUCallback, "RunGPUCallback"); diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 7aa4f09f33..73d23191eb 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -234,11 +234,11 @@ void CInterpreter::mftb(UGeckoInstruction _inst) void CInterpreter::mfspr(UGeckoInstruction _inst) { - u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5)&0x1F); + u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F); //TODO - check processor privilege level - many of these require privilege //XER LR CTR are the only ones available in user mode, time base can be read too. - //Not that gamecube games usually run user mode, but hey.... + //Gamecube games always run in superuser mode, but hey.... switch (iIndex) { @@ -247,11 +247,8 @@ void CInterpreter::mfspr(UGeckoInstruction _inst) // break; case SPR_WPAR: { - //There's supposed to be a bit here that indicates whether there is any data in the wp - //(or if it's full, not sure) - //MessageBox(NULL, "Read from SPR_WPAR", "????", MB_OK); - //Paper Mario reads here, this should be investigated ... TODO(ector) - bool wpar_empty = true; + // If wpar_empty ever is false, Paper Mario hangs. Strange. + bool wpar_empty = true; //GPFifo::IsEmpty(); if (!wpar_empty) rSPR(iIndex) |= 1; // BNE = buffer not empty else @@ -268,9 +265,9 @@ void CInterpreter::mtspr(UGeckoInstruction _inst) u32 oldValue = rSPR(iIndex); rSPR(iIndex) = m_GPR[_inst.RD]; - //TODO(ector) - check processor privilege level - many of these require privilege - //XER LR CTR are the only ones available in user mode - //Not that gamecube games usually run user mode, but hey.... + //TODO - check processor privilege level - many of these require privilege + //XER LR CTR are the only ones available in user mode, time base can be read too. + //Gamecube games always run in superuser mode, but hey.... //Our DMA emulation is highly inaccurate - instead of properly emulating the queue //and so on, we simply make all DMA:s complete instantaneously. @@ -306,7 +303,6 @@ void CInterpreter::mtspr(UGeckoInstruction _inst) //TODO(ector): Protect LC memory if LCE is false. //TODO(ector): Honor PSE. - // //_assert_msg_(GEKKO, WriteGatherPipeEnable, "Write gather pipe not enabled!"); //if ((HID2.PSE == 0)) // MessageBox(NULL, "PSE in HID2 is set", "Warning", MB_OK); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index 4ce970def6..8b3bab2b1a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -77,7 +77,9 @@ namespace Jit64 int d = inst.RD; switch (iIndex) { - + case SPR_WPAR: + Default(inst); + return; // case SPR_DEC: //MessageBox(NULL, "Read from DEC", "????", MB_OK); //break; diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj index a9a31c11e4..fae04ccc98 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj @@ -1048,6 +1048,10 @@ RelativePath=".\Src\Render.h" > + + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp index 82c75bf7bd..9e160eebb6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp @@ -15,6 +15,13 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ + +#include +#include +#include +#include +#include + #include "Globals.h" #include "pluginspecs_video.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h index 98d9d89a74..11a38bb936 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h @@ -19,12 +19,6 @@ #ifndef _GLOBALS_H #define _GLOBALS_H -#include -#include -#include -#include -#include - #define LOGGING #include "Common.h" @@ -32,13 +26,6 @@ #ifdef _WIN32 -#include -#include -#include - -void OpenConsole(); -void CloseConsole(); - #define GLEW_STATIC #include "GLew/glew.h" @@ -97,16 +84,8 @@ struct RECT #define GL_DEPTH24_STENCIL8_EXT 0x88F0 #define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 #endif -extern float MValue; -// several macros -// PLEASE DO NOT USE THE FOLLOWING SAFE* -// They only encourage sloppy coding, and hide bugs. -#define SAFE_RELEASE_CGPROG(x) { if( (x) != NULL ) { cgDestroyProgram(x); x = NULL; } } -#define SAFE_RELEASE_PROG(x) { if( (x) != 0 ) { glDeleteProgramsARB(1, &(x)); x = 0; } } -#define SAFE_RELEASE_TEX(x) { if( (x) != 0 ) { glDeleteTextures(1, &(x)); x = 0; } } -#define SAFE_RELEASE_BUF(x) { if( (x) != 0 ) { glDeleteBuffers(1, &(x)); x = 0; } } -#define FORIT(it, v) for(it = (v).begin(); it != (v).end(); ++(it)) +extern float MValue; #define ERROR_LOG __Log diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp index f4c3a45e68..54e3f9e993 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp @@ -18,11 +18,20 @@ #include +#include +#include +#include +#include +#include + #include "../Globals.h" #include "../../Core/Src/Core.h" #include "Win32.h" +void OpenConsole(); +void CloseConsole(); + HINSTANCE g_hInstance; class wxDLLApp : public wxApp diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp index 63018f6fdc..2f4b43738a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderManager.cpp @@ -94,16 +94,17 @@ void PixelShaderMngr::Init() GL_REPORT_ERROR(); if( err != GL_NO_ERROR ) { ERROR_LOG("Failed to create color matrix fragment program\n"); - - SAFE_RELEASE_PROG(s_ColorMatrixProgram); + glDeleteProgramsARB(1, &s_ColorMatrixProgram); + s_ColorMatrixProgram = 0; } } void PixelShaderMngr::Shutdown() { - SAFE_RELEASE_PROG(s_ColorMatrixProgram); + glDeleteProgramsARB(1, &s_ColorMatrixProgram); + s_ColorMatrixProgram = 0; PSCache::iterator iter = pshaders.begin(); - for (;iter!=pshaders.end();iter++) + for (; iter != pshaders.end(); iter++) iter->second.Destroy(); pshaders.clear(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp index 37b868f615..ae4b672e3c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp @@ -80,14 +80,15 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0& newmode) void TextureMngr::TCacheEntry::Destroy() { - SAFE_RELEASE_TEX(texture); + glDeleteTextures(1, &texture); + texture = 0; } void TextureMngr::Init() { temp = (u8*)AllocateMemoryPages(TEMP_SIZE); nTex2DEnabled = nTexRECTEnabled = 0; - TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable,g_Config.bTexFmtOverlayCenter); + TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter); } void TextureMngr::Invalidate() @@ -96,7 +97,7 @@ void TextureMngr::Invalidate() for (;iter!=textures.end();iter++) iter->second.Destroy(); textures.clear(); - TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable,g_Config.bTexFmtOverlayCenter); + TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter); } void TextureMngr::Shutdown() diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp index eb89f5a642..1cf5224d1d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexLoader.cpp @@ -1087,7 +1087,7 @@ void VertexManager::Flush() int offset = 0; vector< pair >::iterator it; - FORIT (it, s_vStoredPrimitives) { + for (it = s_vStoredPrimitives.begin(); it != s_vStoredPrimitives.end(); ++it) { glDrawArrays(it->first, offset, it->second); offset += it->second; }