Some compiler warnings and eol-style.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6418 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Soren Jorvang 2010-11-14 23:56:26 +00:00
parent 0da42fcca7
commit 62a7f101a7
7 changed files with 717 additions and 717 deletions

View File

@ -1,48 +1,48 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "AudioCommon.h" #include "AudioCommon.h"
#include "NullSoundStream.h" #include "NullSoundStream.h"
void NullSound::SoundLoop() void NullSound::SoundLoop()
{ {
} }
bool NullSound::Start() bool NullSound::Start()
{ {
return true; return true;
} }
void NullSound::SetVolume(int volume) void NullSound::SetVolume(int volume)
{ {
} }
void NullSound::Update() void NullSound::Update()
{ {
// This should equal AUDIO_DMA_PERIOD. TODO: Fix after DSP merge // This should equal AUDIO_DMA_PERIOD. TODO: Fix after DSP merge
int numBytesToRender = 32000 * 4 / 32; int numBytesToRender = 32000 * 4 / 32;
m_mixer->Mix(realtimeBuffer, numBytesToRender / 4); m_mixer->Mix(realtimeBuffer, numBytesToRender / 4);
} }
void NullSound::Clear(bool mute) void NullSound::Clear(bool mute)
{ {
m_muted = mute; m_muted = mute;
} }
void NullSound::Stop() void NullSound::Stop()
{ {
} }

View File

@ -1,48 +1,48 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _NULLSOUNDSTREAM_H_ #ifndef _NULLSOUNDSTREAM_H_
#define _NULLSOUNDSTREAM_H_ #define _NULLSOUNDSTREAM_H_
#include "SoundStream.h" #include "SoundStream.h"
#include "Thread.h" #include "Thread.h"
#define BUF_SIZE (48000 * 4 / 32) #define BUF_SIZE (48000 * 4 / 32)
class NullSound : public SoundStream class NullSound : public SoundStream
{ {
// playback position // playback position
short realtimeBuffer[BUF_SIZE / sizeof(short)]; short realtimeBuffer[BUF_SIZE / sizeof(short)];
public: public:
NullSound(CMixer *mixer, void *hWnd = NULL) NullSound(CMixer *mixer, void *hWnd = NULL)
: SoundStream(mixer) : SoundStream(mixer)
{} {}
virtual ~NullSound() {} virtual ~NullSound() {}
virtual bool Start(); virtual bool Start();
virtual void SoundLoop(); virtual void SoundLoop();
virtual void SetVolume(int volume); virtual void SetVolume(int volume);
virtual void Stop(); virtual void Stop();
virtual void Clear(bool mute); virtual void Clear(bool mute);
static bool isValid() { return true; } static bool isValid() { return true; }
virtual bool usesMixer() const { return true; } virtual bool usesMixer() const { return true; }
virtual void Update(); virtual void Update();
}; };
#endif //_NULLSOUNDSTREAM_H_ #endif //_NULLSOUNDSTREAM_H_

View File

@ -1,211 +1,211 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "AudioCommon.h" #include "AudioCommon.h"
#include "XAudio2Stream.h" #include "XAudio2Stream.h"
struct StreamingVoiceContext : public IXAudio2VoiceCallback struct StreamingVoiceContext : public IXAudio2VoiceCallback
{ {
IXAudio2SourceVoice* pSourceVoice; IXAudio2SourceVoice* pSourceVoice;
CMixer *m_mixer; CMixer *m_mixer;
Common::EventEx *soundSyncEvent; Common::EventEx *soundSyncEvent;
short *xaBuffer; short *xaBuffer;
StreamingVoiceContext(IXAudio2 *pXAudio2, CMixer *pMixer, Common::EventEx *pSyncEvent) StreamingVoiceContext(IXAudio2 *pXAudio2, CMixer *pMixer, Common::EventEx *pSyncEvent)
{ {
m_mixer = pMixer; m_mixer = pMixer;
soundSyncEvent = pSyncEvent; soundSyncEvent = pSyncEvent;
WAVEFORMATEXTENSIBLE wfx; WAVEFORMATEXTENSIBLE wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE)); memset(&wfx, 0, sizeof(WAVEFORMATEXTENSIBLE));
wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfx.Format.nSamplesPerSec = m_mixer->GetSampleRate(); wfx.Format.nSamplesPerSec = m_mixer->GetSampleRate();
wfx.Format.nChannels = 2; wfx.Format.nChannels = 2;
wfx.Format.wBitsPerSample = 16; wfx.Format.wBitsPerSample = 16;
wfx.Format.nBlockAlign = wfx.Format.nChannels*wfx.Format.wBitsPerSample/8; wfx.Format.nBlockAlign = wfx.Format.nChannels*wfx.Format.wBitsPerSample/8;
wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign;
wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
wfx.Samples.wValidBitsPerSample = 16; wfx.Samples.wValidBitsPerSample = 16;
wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
// create source voice // create source voice
HRESULT hr; HRESULT hr;
if(FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC, 1.0f, this))) if(FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC, 1.0f, this)))
PanicAlert("XAudio2 CreateSourceVoice failed: %#X", hr); PanicAlert("XAudio2 CreateSourceVoice failed: %#X", hr);
pSourceVoice->FlushSourceBuffers(); pSourceVoice->FlushSourceBuffers();
pSourceVoice->Start(); pSourceVoice->Start();
xaBuffer = new s16[NUM_BUFFERS * BUFFER_SIZE]; xaBuffer = new s16[NUM_BUFFERS * BUFFER_SIZE];
memset(xaBuffer, 0, NUM_BUFFERS * BUFFER_SIZE_BYTES); memset(xaBuffer, 0, NUM_BUFFERS * BUFFER_SIZE_BYTES);
//start buffers with silence //start buffers with silence
for(int i=0; i < NUM_BUFFERS; i++) for(int i=0; i < NUM_BUFFERS; i++)
{ {
XAUDIO2_BUFFER buf = {0}; XAUDIO2_BUFFER buf = {0};
buf.AudioBytes = BUFFER_SIZE_BYTES; buf.AudioBytes = BUFFER_SIZE_BYTES;
buf.pAudioData = (BYTE *) &xaBuffer[i * BUFFER_SIZE]; buf.pAudioData = (BYTE *) &xaBuffer[i * BUFFER_SIZE];
buf.pContext = (void *) buf.pAudioData; buf.pContext = (void *) buf.pAudioData;
pSourceVoice->SubmitSourceBuffer(&buf); pSourceVoice->SubmitSourceBuffer(&buf);
} }
} }
~StreamingVoiceContext() ~StreamingVoiceContext()
{ {
IXAudio2SourceVoice* temp = pSourceVoice; IXAudio2SourceVoice* temp = pSourceVoice;
pSourceVoice = NULL; pSourceVoice = NULL;
temp->FlushSourceBuffers(); temp->FlushSourceBuffers();
temp->DestroyVoice(); temp->DestroyVoice();
safe_delete_array(xaBuffer); safe_delete_array(xaBuffer);
} }
void StreamingVoiceContext::Stop() { void StreamingVoiceContext::Stop() {
if (pSourceVoice) if (pSourceVoice)
pSourceVoice->Stop(); pSourceVoice->Stop();
} }
void StreamingVoiceContext::Play() { void StreamingVoiceContext::Play() {
if (pSourceVoice) if (pSourceVoice)
pSourceVoice->Start(); pSourceVoice->Start();
} }
STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) {} STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) {}
STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {} STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {}
STDMETHOD_(void, OnVoiceProcessingPassEnd) () {} STDMETHOD_(void, OnVoiceProcessingPassEnd) () {}
STDMETHOD_(void, OnBufferStart) (void*) {} STDMETHOD_(void, OnBufferStart) (void*) {}
STDMETHOD_(void, OnLoopEnd) (void*) {} STDMETHOD_(void, OnLoopEnd) (void*) {}
STDMETHOD_(void, OnStreamEnd) () {} STDMETHOD_(void, OnStreamEnd) () {}
STDMETHOD_(void, OnBufferEnd) (void* context) STDMETHOD_(void, OnBufferEnd) (void* context)
{ // { //
// buffer end callback; gets SAMPLES_PER_BUFFER samples for a new buffer // buffer end callback; gets SAMPLES_PER_BUFFER samples for a new buffer
// //
if( !pSourceVoice || !context) return; if( !pSourceVoice || !context) return;
//soundSyncEvent->Init(); //soundSyncEvent->Init();
//soundSyncEvent->Wait(); //sync //soundSyncEvent->Wait(); //sync
//soundSyncEvent->Spin(); //or tight sync //soundSyncEvent->Spin(); //or tight sync
//if (!pSourceVoice) return; //if (!pSourceVoice) return;
m_mixer->Mix((short *)context, SAMPLES_PER_BUFFER); m_mixer->Mix((short *)context, SAMPLES_PER_BUFFER);
XAUDIO2_BUFFER buf = {0}; XAUDIO2_BUFFER buf = {0};
buf.AudioBytes = BUFFER_SIZE_BYTES; buf.AudioBytes = BUFFER_SIZE_BYTES;
buf.pAudioData = (byte*)context; buf.pAudioData = (byte*)context;
buf.pContext = context; buf.pContext = context;
pSourceVoice->SubmitSourceBuffer(&buf); pSourceVoice->SubmitSourceBuffer(&buf);
} }
}; };
StreamingVoiceContext* pVoiceContext = 0; StreamingVoiceContext* pVoiceContext = 0;
bool XAudio2::Start() bool XAudio2::Start()
{ {
//soundSyncEvent.Init(); //soundSyncEvent.Init();
// XAudio2 init // XAudio2 init
CoInitializeEx(NULL, COINIT_MULTITHREADED); CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr; HRESULT hr;
if(FAILED(hr = XAudio2Create(&pXAudio2, 0, XAUDIO2_ANY_PROCESSOR))) //callback dosent seem to run on a speecific cpu anyways if(FAILED(hr = XAudio2Create(&pXAudio2, 0, XAUDIO2_ANY_PROCESSOR))) //callback dosent seem to run on a speecific cpu anyways
{ {
PanicAlert("XAudio2 init failed: %#X", hr); PanicAlert("XAudio2 init failed: %#X", hr);
CoUninitialize(); CoUninitialize();
return false; return false;
} }
// XAudio2 master voice // XAudio2 master voice
// XAUDIO2_DEFAULT_CHANNELS instead of 2 for expansion? // XAUDIO2_DEFAULT_CHANNELS instead of 2 for expansion?
if(FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice, 2, m_mixer->GetSampleRate()))) if(FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasteringVoice, 2, m_mixer->GetSampleRate())))
{ {
PanicAlert("XAudio2 master voice creation failed: %#X", hr); PanicAlert("XAudio2 master voice creation failed: %#X", hr);
safe_release(pXAudio2); safe_release(pXAudio2);
CoUninitialize(); CoUninitialize();
return false; return false;
} }
// Volume // Volume
if (pMasteringVoice) if (pMasteringVoice)
pMasteringVoice->SetVolume(m_volume); pMasteringVoice->SetVolume(m_volume);
if (pXAudio2) if (pXAudio2)
pVoiceContext = new StreamingVoiceContext(pXAudio2, m_mixer, &soundSyncEvent); pVoiceContext = new StreamingVoiceContext(pXAudio2, m_mixer, &soundSyncEvent);
return true; return true;
} }
void XAudio2::SetVolume(int volume) void XAudio2::SetVolume(int volume)
{ {
//linear 1- .01 //linear 1- .01
m_volume = (float)volume / 100.0; m_volume = (float)volume / 100.0;
if (pMasteringVoice) if (pMasteringVoice)
pMasteringVoice->SetVolume(m_volume); pMasteringVoice->SetVolume(m_volume);
} }
//XAUDIO2_PERFORMANCE_DATA perfData; //XAUDIO2_PERFORMANCE_DATA perfData;
//int xi = 0; //int xi = 0;
void XAudio2::Update() void XAudio2::Update()
{ {
//soundSyncEvent.Set(); //soundSyncEvent.Set();
//xi++; //xi++;
//if (xi == 100000) { //if (xi == 100000) {
// xi = 0; // xi = 0;
// pXAudio2->GetPerformanceData(&perfData); // pXAudio2->GetPerformanceData(&perfData);
// NOTICE_LOG(DSPHLE, "XAudio2 latency (samples): %i",perfData.CurrentLatencyInSamples); // NOTICE_LOG(DSPHLE, "XAudio2 latency (samples): %i",perfData.CurrentLatencyInSamples);
// NOTICE_LOG(DSPHLE, "XAudio2 total glitches: %i",perfData.GlitchesSinceEngineStarted); // NOTICE_LOG(DSPHLE, "XAudio2 total glitches: %i",perfData.GlitchesSinceEngineStarted);
//} //}
} }
void XAudio2::Clear(bool mute) void XAudio2::Clear(bool mute)
{ {
m_muted = mute; m_muted = mute;
if (pVoiceContext) if (pVoiceContext)
{ {
if (m_muted) if (m_muted)
pVoiceContext->Stop(); pVoiceContext->Stop();
else else
pVoiceContext->Play(); pVoiceContext->Play();
} }
} }
void XAudio2::Stop() void XAudio2::Stop()
{ {
//soundSyncEvent.Set(); //soundSyncEvent.Set();
safe_delete(pVoiceContext); safe_delete(pVoiceContext);
pVoiceContext = NULL; pVoiceContext = NULL;
if(pMasteringVoice) if(pMasteringVoice)
pMasteringVoice->DestroyVoice(); pMasteringVoice->DestroyVoice();
safe_release(pXAudio2); safe_release(pXAudio2);
pMasteringVoice = NULL; pMasteringVoice = NULL;
CoUninitialize(); CoUninitialize();
//soundSyncEvent.Shutdown(); //soundSyncEvent.Shutdown();
} }

View File

@ -1,86 +1,86 @@
// Copyright (C) 2003 Dolphin Project. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _XAUDIO2STREAM_H_ #ifndef _XAUDIO2STREAM_H_
#define _XAUDIO2STREAM_H_ #define _XAUDIO2STREAM_H_
#include "SoundStream.h" #include "SoundStream.h"
#ifdef _WIN32 #ifdef _WIN32
#include "Thread.h" #include "Thread.h"
#include <xaudio2.h> #include <xaudio2.h>
const int NUM_BUFFERS = 3; const int NUM_BUFFERS = 3;
const int SAMPLES_PER_BUFFER = 96; const int SAMPLES_PER_BUFFER = 96;
const int NUM_CHANNELS = 2; const int NUM_CHANNELS = 2;
const int BUFFER_SIZE = SAMPLES_PER_BUFFER * NUM_CHANNELS; const int BUFFER_SIZE = SAMPLES_PER_BUFFER * NUM_CHANNELS;
const int BUFFER_SIZE_BYTES = BUFFER_SIZE * sizeof(s16); const int BUFFER_SIZE_BYTES = BUFFER_SIZE * sizeof(s16);
#ifndef safe_delete_array #ifndef safe_delete_array
#define safe_delete_array(p) { if(p) { delete[] (p); (p)=NULL; } } #define safe_delete_array(p) { if(p) { delete[] (p); (p)=NULL; } }
#endif #endif
#ifndef safe_delete #ifndef safe_delete
#define safe_delete(a) if( (a) != NULL ) delete (a); (a) = NULL; #define safe_delete(a) if( (a) != NULL ) delete (a); (a) = NULL;
#endif #endif
#ifndef safe_release #ifndef safe_release
#define safe_release(p) { if(p) { (p)->Release(); (p)=NULL; } } #define safe_release(p) { if(p) { (p)->Release(); (p)=NULL; } }
#endif #endif
#endif #endif
class XAudio2 : public SoundStream class XAudio2 : public SoundStream
{ {
#ifdef _WIN32 #ifdef _WIN32
IXAudio2 *pXAudio2; IXAudio2 *pXAudio2;
IXAudio2MasteringVoice *pMasteringVoice; IXAudio2MasteringVoice *pMasteringVoice;
IXAudio2SourceVoice *pSourceVoice; IXAudio2SourceVoice *pSourceVoice;
Common::EventEx soundSyncEvent; Common::EventEx soundSyncEvent;
float m_volume; float m_volume;
bool Init(); bool Init();
public: public:
XAudio2(CMixer *mixer) XAudio2(CMixer *mixer)
: SoundStream(mixer), : SoundStream(mixer),
pXAudio2(0), pXAudio2(0),
pMasteringVoice(0), pMasteringVoice(0),
pSourceVoice(0), pSourceVoice(0),
m_volume(1.0f) {} m_volume(1.0f) {}
virtual ~XAudio2() {} virtual ~XAudio2() {}
virtual bool Start(); virtual bool Start();
virtual void SetVolume(int volume); virtual void SetVolume(int volume);
virtual void Stop(); virtual void Stop();
virtual void Clear(bool mute); virtual void Clear(bool mute);
static bool isValid() { return true; } static bool isValid() { return true; }
virtual bool usesMixer() const { return true; } virtual bool usesMixer() const { return true; }
virtual void Update(); virtual void Update();
#else #else
public: public:
XAudio2(CMixer *mixer, void *hWnd = NULL) XAudio2(CMixer *mixer, void *hWnd = NULL)
: SoundStream(mixer) : SoundStream(mixer)
{} {}
#endif #endif
}; };
#endif //_XAUDIO2STREAM_H_ #endif //_XAUDIO2STREAM_H_

View File

@ -224,23 +224,23 @@ inline u64 CreateMapId(u32 address, u32 size)
inline u64 CreateVMapId(u8 VATUSED) inline u64 CreateVMapId(u8 VATUSED)
{ {
u64 vmat_id = 0; u64 vmap_id = 0;
for(int i = 0; i < 8 ; i++) for(int i = 0; i < 8 ; i++)
{ {
if(VATUSED & (1 << i)) if(VATUSED & (1 << i))
{ {
//vmat_id ^= GetHash64((u8*)(&g_VtxAttr[i].g0.),sizeof(VAT),0); //vmap_id ^= GetHash64((u8*)(&g_VtxAttr[i].g0.),sizeof(VAT),0);
if(vmat_id != 0) if(vmap_id != 0)
{ {
vmat_id ^= (((u64)g_VtxAttr[i].g0.Hex) | (((u64)g_VtxAttr[i].g1.Hex) << 32)) ^ (((u64)g_VtxAttr[i].g2.Hex) << 16); vmap_id ^= (((u64)g_VtxAttr[i].g0.Hex) | (((u64)g_VtxAttr[i].g1.Hex) << 32)) ^ (((u64)g_VtxAttr[i].g2.Hex) << 16);
} }
else else
{ {
vmat_id = (((u64)g_VtxAttr[i].g0.Hex) | (((u64)g_VtxAttr[i].g1.Hex) << 32)) ^ (((u64)g_VtxAttr[i].g2.Hex) << 16); vmap_id = (((u64)g_VtxAttr[i].g0.Hex) | (((u64)g_VtxAttr[i].g1.Hex) << 32)) ^ (((u64)g_VtxAttr[i].g2.Hex) << 16);
} }
} }
} }
return vmat_id; return vmap_id;
} }
typedef std::map<u64, CachedDisplayList> DLMap; typedef std::map<u64, CachedDisplayList> DLMap;
@ -689,7 +689,6 @@ bool HandleDisplayList(u32 address, u32 size)
if (Parentiter != DLCache::dl_map.end()) if (Parentiter != DLCache::dl_map.end())
{ {
vhash = DLCache::CreateVMapId(Parentiter->second.VATUsed); vhash = DLCache::CreateVMapId(Parentiter->second.VATUsed);
DLCache::VDlist &tvdl = Parentiter->second;
iter = Parentiter->second.dl_map.find(vhash); iter = Parentiter->second.dl_map.find(vhash);
childexist = iter != Parentiter->second.dl_map.end(); childexist = iter != Parentiter->second.dl_map.end();
} }

View File

@ -1,225 +1,226 @@
#include "FramebufferManagerBase.h" #include "FramebufferManagerBase.h"
#include "Render.h" #include "Render.h"
#include "VideoConfig.h" #include "VideoConfig.h"
FramebufferManagerBase *g_framebuffer_manager; FramebufferManagerBase *g_framebuffer_manager;
XFBSourceBase *FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB mode XFBSourceBase *FramebufferManagerBase::m_realXFBSource; // Only used in Real XFB mode
FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode FramebufferManagerBase::VirtualXFBListType FramebufferManagerBase::m_virtualXFBList; // Only used in Virtual XFB mode
const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB]; const XFBSourceBase* FramebufferManagerBase::m_overlappingXFBArray[MAX_VIRTUAL_XFB];
FramebufferManagerBase::FramebufferManagerBase() FramebufferManagerBase::FramebufferManagerBase()
{ {
m_realXFBSource = NULL; m_realXFBSource = NULL;
// can't hurt // can't hurt
memset(m_overlappingXFBArray, 0, sizeof(m_overlappingXFBArray)); memset(m_overlappingXFBArray, 0, sizeof(m_overlappingXFBArray));
} }
FramebufferManagerBase::~FramebufferManagerBase() FramebufferManagerBase::~FramebufferManagerBase()
{ {
VirtualXFBListType::iterator VirtualXFBListType::iterator
it = m_virtualXFBList.begin(), it = m_virtualXFBList.begin(),
vlend = m_virtualXFBList.end(); vlend = m_virtualXFBList.end();
for (; it != vlend; ++it) for (; it != vlend; ++it)
delete it->xfbSource; delete it->xfbSource;
m_virtualXFBList.clear(); m_virtualXFBList.clear();
delete m_realXFBSource; delete m_realXFBSource;
} }
const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) const XFBSourceBase* const* FramebufferManagerBase::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{ {
if (g_ActiveConfig.bUseRealXFB) if (g_ActiveConfig.bUseRealXFB)
return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); return GetRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
else else
return GetVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); return GetVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
} }
const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) const XFBSourceBase* const* FramebufferManagerBase::GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{ {
xfbCount = 1; xfbCount = 1;
if (!m_realXFBSource) if (!m_realXFBSource)
m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight); m_realXFBSource = g_framebuffer_manager->CreateXFBSource(fbWidth, fbHeight);
m_realXFBSource->srcAddr = xfbAddr; m_realXFBSource->srcAddr = xfbAddr;
m_realXFBSource->srcWidth = MAX_XFB_WIDTH; m_realXFBSource->srcWidth = MAX_XFB_WIDTH;
m_realXFBSource->srcHeight = MAX_XFB_HEIGHT; m_realXFBSource->srcHeight = MAX_XFB_HEIGHT;
m_realXFBSource->texWidth = fbWidth; m_realXFBSource->texWidth = fbWidth;
m_realXFBSource->texHeight = fbHeight; m_realXFBSource->texHeight = fbHeight;
// TODO: stuff only used by OGL... :/ // TODO: stuff only used by OGL... :/
// OpenGL texture coordinates originate at the lower left, which is why // OpenGL texture coordinates originate at the lower left, which is why
// sourceRc.top = fbHeight and sourceRc.bottom = 0. // sourceRc.top = fbHeight and sourceRc.bottom = 0.
m_realXFBSource->sourceRc.left = 0; m_realXFBSource->sourceRc.left = 0;
m_realXFBSource->sourceRc.top = fbHeight; m_realXFBSource->sourceRc.top = fbHeight;
m_realXFBSource->sourceRc.right = fbWidth; m_realXFBSource->sourceRc.right = fbWidth;
m_realXFBSource->sourceRc.bottom = 0; m_realXFBSource->sourceRc.bottom = 0;
// Decode YUYV data from GameCube RAM // Decode YUYV data from GameCube RAM
m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight); m_realXFBSource->DecodeToTexture(xfbAddr, fbWidth, fbHeight);
m_overlappingXFBArray[0] = m_realXFBSource; m_overlappingXFBArray[0] = m_realXFBSource;
return &m_overlappingXFBArray[0]; return &m_overlappingXFBArray[0];
} }
const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) const XFBSourceBase* const* FramebufferManagerBase::GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{ {
xfbCount = 0; xfbCount = 0;
if (m_virtualXFBList.empty()) // no Virtual XFBs available if (m_virtualXFBList.empty()) // no Virtual XFBs available
return NULL; return NULL;
u32 srcLower = xfbAddr; u32 srcLower = xfbAddr;
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight; u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
VirtualXFBListType::reverse_iterator VirtualXFBListType::reverse_iterator
it = m_virtualXFBList.rbegin(), it = m_virtualXFBList.rbegin(),
vlend = m_virtualXFBList.rend(); vlend = m_virtualXFBList.rend();
for (; it != vlend; ++it) for (; it != vlend; ++it)
{ {
VirtualXFB* vxfb = &*it; VirtualXFB* vxfb = &*it;
u32 dstLower = vxfb->xfbAddr; u32 dstLower = vxfb->xfbAddr;
u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight; u32 dstUpper = vxfb->xfbAddr + 2 * vxfb->xfbWidth * vxfb->xfbHeight;
if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
{ {
m_overlappingXFBArray[xfbCount] = vxfb->xfbSource; m_overlappingXFBArray[xfbCount] = vxfb->xfbSource;
++xfbCount; ++xfbCount;
} }
} }
return &m_overlappingXFBArray[0]; return &m_overlappingXFBArray[0];
} }
void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManagerBase::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{ {
if (g_ActiveConfig.bUseRealXFB) if (g_ActiveConfig.bUseRealXFB)
g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc); g_framebuffer_manager->CopyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
else else
CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); CopyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
} }
void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{ {
VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight); VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight);
if (m_virtualXFBList.end() == vxfb) if (m_virtualXFBList.end() == vxfb)
{ {
if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB) if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB)
{ {
// create a new Virtual XFB and place it at the front of the list // create a new Virtual XFB and place it at the front of the list
VirtualXFB v; VirtualXFB v;
m_virtualXFBList.push_front(v); memset(&v, 0, sizeof v);
vxfb = m_virtualXFBList.begin(); m_virtualXFBList.push_front(v);
} vxfb = m_virtualXFBList.begin();
else }
{ else
// Replace the last virtual XFB {
--vxfb; // Replace the last virtual XFB
} --vxfb;
} }
//else // replace existing virtual XFB }
//else // replace existing virtual XFB
// move this Virtual XFB to the front of the list.
if (m_virtualXFBList.begin() != vxfb) // move this Virtual XFB to the front of the list.
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb); if (m_virtualXFBList.begin() != vxfb)
m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb);
unsigned int target_width, target_height;
g_framebuffer_manager->GetTargetSize(&target_width, &target_height, sourceRc); unsigned int target_width, target_height;
g_framebuffer_manager->GetTargetSize(&target_width, &target_height, sourceRc);
// recreate if needed
if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height)) // recreate if needed
{ if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height))
//delete vxfb->xfbSource; {
//vxfb->xfbSource = NULL; //delete vxfb->xfbSource;
} //vxfb->xfbSource = NULL;
}
if (!vxfb->xfbSource)
{ if (!vxfb->xfbSource)
vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height); {
vxfb->xfbSource->texWidth = target_width; vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height);
vxfb->xfbSource->texHeight = target_height; vxfb->xfbSource->texWidth = target_width;
} vxfb->xfbSource->texHeight = target_height;
}
vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr;
vxfb->xfbSource->srcWidth = vxfb->xfbWidth = fbWidth; vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr;
vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight; vxfb->xfbSource->srcWidth = vxfb->xfbWidth = fbWidth;
vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight;
vxfb->xfbSource->sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
vxfb->xfbSource->sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
// keep stale XFB data from being used
ReplaceVirtualXFB(); // keep stale XFB data from being used
ReplaceVirtualXFB();
Renderer::ResetAPIState(); // reset any game specific settings
Renderer::ResetAPIState(); // reset any game specific settings
// Copy EFB data to XFB and restore render target again
vxfb->xfbSource->CopyEFB(); // Copy EFB data to XFB and restore render target again
vxfb->xfbSource->CopyEFB();
Renderer::RestoreAPIState();
} Renderer::RestoreAPIState();
}
FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
{ FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
const u32 srcLower = xfbAddr; {
const u32 srcUpper = xfbAddr + 2 * width * height; const u32 srcLower = xfbAddr;
const u32 srcUpper = xfbAddr + 2 * width * height;
VirtualXFBListType::iterator it = m_virtualXFBList.begin();
for (; it != m_virtualXFBList.end(); ++it) VirtualXFBListType::iterator it = m_virtualXFBList.begin();
{ for (; it != m_virtualXFBList.end(); ++it)
const u32 dstLower = it->xfbAddr; {
const u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; const u32 dstLower = it->xfbAddr;
const u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
if (dstLower >= srcLower && dstUpper <= srcUpper)
break; if (dstLower >= srcLower && dstUpper <= srcUpper)
} break;
}
return it;
} return it;
}
void FramebufferManagerBase::ReplaceVirtualXFB()
{ void FramebufferManagerBase::ReplaceVirtualXFB()
VirtualXFBListType::iterator it = m_virtualXFBList.begin(); {
VirtualXFBListType::iterator it = m_virtualXFBList.begin();
const s32 srcLower = it->xfbAddr;
const s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; const s32 srcLower = it->xfbAddr;
const s32 lineSize = 2 * it->xfbWidth; const s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
const s32 lineSize = 2 * it->xfbWidth;
++it;
++it;
for (; it != m_virtualXFBList.end(); ++it)
{ for (; it != m_virtualXFBList.end(); ++it)
s32 dstLower = it->xfbAddr; {
s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; s32 dstLower = it->xfbAddr;
s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
if (dstLower >= srcLower && dstUpper <= srcUpper)
{ if (dstLower >= srcLower && dstUpper <= srcUpper)
// Invalidate the data {
it->xfbAddr = 0; // Invalidate the data
it->xfbHeight = 0; it->xfbAddr = 0;
it->xfbWidth = 0; it->xfbHeight = 0;
} it->xfbWidth = 0;
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) }
{ else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
s32 upperOverlap = (srcUpper - dstLower) / lineSize; {
s32 lowerOverlap = (dstUpper - srcLower) / lineSize; s32 upperOverlap = (srcUpper - dstLower) / lineSize;
s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
if (upperOverlap > 0 && lowerOverlap < 0)
{ if (upperOverlap > 0 && lowerOverlap < 0)
it->xfbAddr += lineSize * upperOverlap; {
it->xfbHeight -= upperOverlap; it->xfbAddr += lineSize * upperOverlap;
} it->xfbHeight -= upperOverlap;
else if (lowerOverlap > 0) }
{ else if (lowerOverlap > 0)
it->xfbHeight -= lowerOverlap; {
} it->xfbHeight -= lowerOverlap;
} }
} }
} }
}

View File

@ -1,92 +1,92 @@
#ifndef _FRAMEBUFFERMANAGER_H #ifndef _FRAMEBUFFERMANAGER_H
#define _FRAMEBUFFERMANAGER_H #define _FRAMEBUFFERMANAGER_H
#include <list> #include <list>
#include "VideoCommon.h" #include "VideoCommon.h"
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
{ {
return !((aLower >= bUpper) || (bLower >= aUpper)); return !((aLower >= bUpper) || (bLower >= aUpper));
} }
struct XFBSourceBase struct XFBSourceBase
{ {
virtual ~XFBSourceBase() {} virtual ~XFBSourceBase() {}
// TODO: only DX9 uses the width/height params // TODO: only DX9 uses the width/height params
virtual void Draw(const MathUtil::Rectangle<float> &sourcerc, virtual void Draw(const MathUtil::Rectangle<float> &sourcerc,
const MathUtil::Rectangle<float> &drawrc, int width, int height) const = 0; const MathUtil::Rectangle<float> &drawrc, int width, int height) const = 0;
virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0; virtual void DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) = 0;
virtual void CopyEFB() = 0; virtual void CopyEFB() = 0;
u32 srcAddr; u32 srcAddr;
u32 srcWidth; u32 srcWidth;
u32 srcHeight; u32 srcHeight;
int texWidth; unsigned int texWidth;
int texHeight; unsigned int texHeight;
// TODO: only used by OGL // TODO: only used by OGL
TargetRectangle sourceRc; TargetRectangle sourceRc;
}; };
class FramebufferManagerBase class FramebufferManagerBase
{ {
public: public:
enum enum
{ {
// There may be multiple XFBs in GameCube RAM. This is the maximum number to // There may be multiple XFBs in GameCube RAM. This is the maximum number to
// virtualize. // virtualize.
MAX_VIRTUAL_XFB = 8 MAX_VIRTUAL_XFB = 8
}; };
FramebufferManagerBase(); FramebufferManagerBase();
virtual ~FramebufferManagerBase(); virtual ~FramebufferManagerBase();
static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); static void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
protected: protected:
struct VirtualXFB struct VirtualXFB
{ {
VirtualXFB() : xfbSource(NULL) {} VirtualXFB() : xfbSource(NULL) {}
// Address and size in GameCube RAM // Address and size in GameCube RAM
u32 xfbAddr; u32 xfbAddr;
u32 xfbWidth; u32 xfbWidth;
u32 xfbHeight; u32 xfbHeight;
XFBSourceBase *xfbSource; XFBSourceBase *xfbSource;
}; };
typedef std::list<VirtualXFB> VirtualXFBListType; typedef std::list<VirtualXFB> VirtualXFBListType;
private: private:
virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0; virtual XFBSourceBase* CreateXFBSource(unsigned int target_width, unsigned int target_height) = 0;
// TODO: figure out why OGL is different for this guy // TODO: figure out why OGL is different for this guy
virtual void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) = 0; virtual void GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) = 0;
static VirtualXFBListType::iterator FindVirtualXFB(u32 xfbAddr, u32 width, u32 height); static VirtualXFBListType::iterator FindVirtualXFB(u32 xfbAddr, u32 width, u32 height);
static void ReplaceVirtualXFB(); static void ReplaceVirtualXFB();
// TODO: merge these virtual funcs, they are nearly all the same // TODO: merge these virtual funcs, they are nearly all the same
virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) = 0; virtual void CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) = 0;
static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); static void CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
static const XFBSourceBase* const* GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); static const XFBSourceBase* const* GetVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
static XFBSourceBase *m_realXFBSource; // Only used in Real XFB mode static XFBSourceBase *m_realXFBSource; // Only used in Real XFB mode
static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode static VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB]; static const XFBSourceBase* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
}; };
extern FramebufferManagerBase *g_framebuffer_manager; extern FramebufferManagerBase *g_framebuffer_manager;
#endif #endif