Merge branch 'master' into zcomploc-support

Conflicts:
	Source/Core/VideoCommon/Src/PixelShaderGen.cpp
This commit is contained in:
Pierre Bourdon
2012-03-22 15:21:52 +01:00
854 changed files with 42647 additions and 21611 deletions

View File

@@ -45,7 +45,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -56,7 +55,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>

View File

@@ -6,33 +6,33 @@ set(SRCS Src/AudioCommon.cpp
set(LIBS "")
if(ALSA_FOUND)
set(SRCS ${SRCS} Src/AlsaSoundStream.cpp)
set(LIBS ${LIBS} ${ALSA_LIBRARIES})
endif(ALSA_FOUND)
if(AO_FOUND)
set(SRCS ${SRCS} Src/AOSoundStream.cpp)
set(LIBS ${LIBS} ${AO_LIBRARIES})
endif(AO_FOUND)
if(OPENAL_FOUND)
set(SRCS ${SRCS} Src/OpenALStream.cpp Src/aldlist.cpp)
set(LIBS ${LIBS} ${OPENAL_LIBRARY})
endif(OPENAL_FOUND)
if(PULSEAUDIO_FOUND)
set(SRCS ${SRCS} Src/PulseAudioStream.cpp)
set(LIBS ${LIBS} ${PULSEAUDIO_LIBRARIES})
endif(PULSEAUDIO_FOUND)
if(WIN32)
set(SRCS ${SRCS} Src/DSoundStream.cpp)
set(SRCS ${SRCS} Src/XAudio2Stream.cpp)
endif(WIN32)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SRCS ${SRCS} Src/CoreAudioSoundStream.cpp)
else()
if(ALSA_FOUND)
set(SRCS ${SRCS} Src/AlsaSoundStream.cpp)
set(LIBS ${LIBS} ${ALSA_LIBRARIES})
endif(ALSA_FOUND)
if(AO_FOUND)
set(SRCS ${SRCS} Src/AOSoundStream.cpp)
set(LIBS ${LIBS} ${AO_LIBRARIES})
endif(AO_FOUND)
if(OPENAL_FOUND)
set(SRCS ${SRCS} Src/OpenALStream.cpp Src/aldlist.cpp)
set(LIBS ${LIBS} openal)
endif(OPENAL_FOUND)
if(PULSEAUDIO_FOUND)
set(SRCS ${SRCS} Src/PulseAudioStream.cpp)
set(LIBS ${LIBS} ${PULSEAUDIO_LIBRARIES})
endif(PULSEAUDIO_FOUND)
if(WIN32)
set(SRCS ${SRCS} Src/DSoundStream.cpp)
set(SRCS ${SRCS} Src/XAudio2Stream.cpp)
endif(WIN32)
endif()
add_library(audiocommon STATIC ${SRCS})

View File

@@ -25,6 +25,8 @@
void AOSound::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - ao");
uint_32 numBytesToRender = 256;
ao_initialize();
default_driver = ao_default_driver_id();

View File

@@ -60,6 +60,7 @@ void AlsaSound::SoundLoop()
thread_data = 2;
return;
}
Common::SetCurrentThreadName("Audio thread - alsa");
while (!thread_data)
{
m_mixer->Mix(reinterpret_cast<short *>(mix_buffer), frames_to_deliver);

View File

@@ -18,6 +18,7 @@
#include "AudioCommon.h"
#include "CommonPaths.h"
#include "FileUtil.h"
#include "../../Core/Src/ConfigManager.h"
AudioCommonConfig ac_Config;
@@ -31,7 +32,6 @@ void AudioCommonConfig::Load()
file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true);
file.Get("Config", "EnableThrottle", &m_EnableThrottle, true);
file.Get("Config", "EnableJIT", &m_EnableJIT, true);
file.Get("Config", "DumpAudio", &m_DumpAudio, false);
#if defined __linux__ && HAVE_ALSA
@@ -54,7 +54,6 @@ void AudioCommonConfig::SaveSettings()
file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic);
file.Set("Config", "EnableThrottle", m_EnableThrottle);
file.Set("Config", "EnableJIT", m_EnableJIT);
file.Set("Config", "DumpAudio", m_DumpAudio);
file.Set("Config", "Backend", sBackend);
@@ -67,7 +66,7 @@ void AudioCommonConfig::SaveSettings()
// Update according to the values (stream/mixer)
void AudioCommonConfig::Update() {
if (soundStream) {
soundStream->GetMixer()->SetThrottle(m_EnableThrottle);
soundStream->GetMixer()->SetThrottle(SConfig::GetInstance().m_Framelimit == 2);
soundStream->GetMixer()->SetDTKMusic(m_EnableDTKMusic);
soundStream->SetVolume(m_Volume);
}

View File

@@ -34,7 +34,6 @@
struct AudioCommonConfig
{
bool m_EnableDTKMusic;
bool m_EnableThrottle;
bool m_EnableJIT;
bool m_DumpAudio;
int m_Volume;

View File

@@ -96,6 +96,8 @@ bool DSound::WriteDataToBuffer(DWORD dwOffset, // Our own write
// The audio thread.
void DSound::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - dsound");
currentPos = 0;
lastPos = 0;
dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
@@ -130,7 +132,7 @@ bool DSound::Start()
DWORD num1;
short* p1;
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, DSBLOCK_ENTIREBUFFER);
memset(p1, 0, num1);
dsBuffer->Unlock(p1, num1, 0, 0);
thread = std::thread(std::mem_fun(&DSound::SoundLoop), this);

View File

@@ -121,6 +121,8 @@ void OpenALStream::Clear(bool mute)
void OpenALStream::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - openal");
ALenum err;
u32 ulFrequency = m_mixer->GetSampleRate();

View File

@@ -58,6 +58,8 @@ void PulseAudio::Update()
// Called on audio thread.
void PulseAudio::SoundLoop()
{
Common::SetCurrentThreadName("Audio thread - pulse");
thread_running = PulseInit();
while (thread_running)

View File

@@ -27,6 +27,9 @@
#ifdef _WIN32
#include "../../../../Externals/OpenAL/include/al.h"
#include "../../../../Externals/OpenAL/include/alc.h"
#elif defined(__APPLE__)
#include <al.h>
#include <alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>

View File

@@ -45,7 +45,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -56,7 +55,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>

View File

@@ -189,7 +189,7 @@ unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize) {
#ifdef __GNUC__
(frameSize + 15) & -16;
#else
frameSize;
(frameSize + 3) & -4;
#endif
return alignedSize;
}
@@ -200,16 +200,15 @@ void XEmitter::ABI_AlignStack(unsigned int frameSize) {
// Linux requires the stack to be 16-byte aligned before calls that put SSE
// vectors on the stack, but since we do not keep track of which calls do that,
// it is effectively every call as well.
// Windows binaries compiled with MSVC do not have such a restriction, but I
// Windows binaries compiled with MSVC do not have such a restriction*, but I
// expect that GCC on Windows acts the same as GCC on Linux in this respect.
// It would be nice if someone could verify this.
#ifdef __GNUC__
// *However, the MSVC optimizing compiler assumes a 4-byte-aligned stack at times.
unsigned int fillSize =
ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4);
if (fillSize != 0) {
SUB(32, R(ESP), Imm8(fillSize));
}
#endif
}
void XEmitter::ABI_RestoreStack(unsigned int frameSize) {

View File

@@ -18,6 +18,7 @@
#include "Common.h"
#include "DebugInterface.h"
#include "BreakPoints.h"
#include "../../Core/Src/PowerPC/JitCommon/JitBase.h"
#include <sstream>
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
@@ -70,7 +71,11 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bps)
void BreakPoints::Add(const TBreakPoint& bp)
{
if (!IsAddressBreakPoint(bp.iAddress))
{
m_BreakPoints.push_back(bp);
if (jit)
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
}
}
void BreakPoints::Add(u32 em_address, bool temp)
@@ -83,21 +88,35 @@ void BreakPoints::Add(u32 em_address, bool temp)
pt.iAddress = em_address;
m_BreakPoints.push_back(pt);
if (jit)
jit->GetBlockCache()->InvalidateICache(em_address, 4);
}
}
void BreakPoints::Remove(u32 _iAddress)
void BreakPoints::Remove(u32 em_address)
{
for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
{
if (i->iAddress == _iAddress)
if (i->iAddress == em_address)
{
m_BreakPoints.erase(i);
if (jit)
jit->GetBlockCache()->InvalidateICache(em_address, 4);
return;
}
}
}
void BreakPoints::Clear()
{
for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
{
if (jit)
jit->GetBlockCache()->InvalidateICache(i->iAddress, 4);
m_BreakPoints.erase(i);
}
}
MemChecks::TMemChecksStr MemChecks::GetStrings() const
{

View File

@@ -78,7 +78,7 @@ public:
// Remove Breakpoint
void Remove(u32 _iAddress);
void Clear() { m_BreakPoints.clear(); };
void Clear();
void DeleteByAddress(u32 _Address);

View File

@@ -32,6 +32,10 @@
//#include <config/i386/cpuid.h>
#include <xmmintrin.h>
#if defined __FreeBSD__
#include <sys/types.h>
#include <machine/cpufunc.h>
#else
static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
@@ -39,41 +43,42 @@ static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
// Note: EBX is reserved on Mac OS X and in PIC on Linux, so it has to
// restored at the end of the asm block.
__asm__ (
"mov %%rbx,%%rdi;"
"cpuid;"
"movl %%ebx,%1;"
"mov %%rdi,%%rbx;"
: "=a" (*eax),
"=g" (*ebx),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "a" (*eax)
: "rdi", "rbx"
: "rbx"
);
#else
__asm__(
"movl %%ebx,%%edi;"
__asm__ (
"cpuid;"
"movl %%ebx,%1;"
"movl %%edi,%%ebx;"
"movl %%ebx,%1;"
: "=a" (*eax),
"=g" (*ebx),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "a" (*eax)
: "edi", "ebx"
: "ebx"
);
#endif
}
#endif /* defined __FreeBSD__ */
static void __cpuid(int info[4], int x)
{
#if defined __FreeBSD__
do_cpuid((unsigned int)x, (unsigned int*)info);
#else
unsigned int eax = x, ebx = 0, ecx = 0, edx = 0;
do_cpuid(&eax, &ebx, &ecx, &edx);
info[0] = eax;
info[1] = ebx;
info[2] = ecx;
info[3] = edx;
#endif
}
#endif

View File

@@ -154,7 +154,21 @@ public:
}
(*ptr) += stringLen;
}
void Do(std::wstring &x)
{
int stringLen = sizeof(wchar_t)*((int)x.length() + 1);
Do(stringLen);
switch (mode) {
case MODE_READ: x = (wchar_t*)*ptr; break;
case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break;
case MODE_MEASURE: break;
case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break;
}
(*ptr) += stringLen;
}
template<class T>
void DoArray(T *x, int count) {
DoVoid((void *)x, sizeof(T) * count);
@@ -170,6 +184,17 @@ public:
// TODO
PanicAlert("Do(linked list<>) does not yet work.");
}
void DoMarker(const char* prevName, u32 arbitraryNumber=0x42)
{
u32 cookie = arbitraryNumber;
Do(cookie);
if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber)
{
PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
mode = PointerWrap::MODE_MEASURE;
}
}
};

View File

@@ -89,6 +89,8 @@ private:
// Since it is always around on windows
#define HAVE_WX 1
#define HAVE_PORTAUDIO 1
// Debug definitions
#if defined(_DEBUG)
#include <crtdbg.h>
@@ -137,14 +139,18 @@ private:
// wxWidgets does not have a true dummy macro for this.
#define _trans(a) a
#if defined __APPLE__ && defined __i386__
#define _M_SSE 0x300
#elif defined __APPLE__ && defined __x86_64__
#define _M_SSE 0x301
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
#define _M_SSE 0x301
#elif _MSC_VER >= 1500 // Visual Studio 2008
#define _M_SSE 0x402
#if defined __GNUC__
# if defined __SSE4_2__
# define _M_SSE 0x402
# elif defined __SSE4_1__
# define _M_SSE 0x401
# elif defined __SSSE3__
# define _M_SSE 0x301
# elif defined __SSE3__
# define _M_SSE 0x300
# endif
#elif (_MSC_VER >= 1500) || __INTEL_COMPILER // Visual Studio 2008
# define _M_SSE 0x402
#endif
// Host communication.

View File

@@ -27,6 +27,13 @@
template <bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true> {};
#define b2(x) ( (x) | ( (x) >> 1) )
#define b4(x) ( b2(x) | ( b2(x) >> 2) )
#define b8(x) ( b4(x) | ( b4(x) >> 4) )
#define b16(x) ( b8(x) | ( b8(x) >> 8) )
#define b32(x) (b16(x) | (b16(x) >>16) )
#define ROUND_UP_POW2(x) (b32(x - 1) + 1)
#if defined __GNUC__ && !defined __SSSE3__
#include <emmintrin.h>
static __inline __m128i __attribute__((__always_inline__))
@@ -45,6 +52,8 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
#include <errno.h>
#ifdef __linux__
#include <byteswap.h>
#elif defined __FreeBSD__
#include <sys/endian.h>
#endif
// go to debugger mode
@@ -137,6 +146,10 @@ inline __attribute__((always_inline)) u32 swap32(u32 _data)
{return __builtin_bswap32(_data);}
inline __attribute__((always_inline)) u64 swap64(u64 _data)
{return __builtin_bswap64(_data);}
#elif __FreeBSD__
inline u16 swap16(u16 _data) {return bswap16(_data);}
inline u32 swap32(u32 _data) {return bswap32(_data);}
inline u64 swap64(u64 _data) {return bswap64(_data);}
#else
// Slow generic implementation.
inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);}

View File

@@ -126,6 +126,8 @@
#define WII_USA_SETTING "setting-usa.txt"
#define WII_JAP_SETTING "setting-jpn.txt"
#define GECKO_CODE_HANDLER "codehandler.bin"
// Subdirs in Sys
#define GC_SYS_DIR "GC"
#define WII_SYS_DIR "Wii"

View File

@@ -167,7 +167,7 @@ u64 GetMurmurHash3(const u8 *src, int len, u32 samples)
const u8 * data = (const u8*)src;
const int nblocks = len / 16;
u32 Step = (len / 8);
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
@@ -245,7 +245,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples)
u32 Step = (len / 8);
const u64 *data = (const u64 *)src;
const u64 *end = data + Step;
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
while(data < end)
@@ -275,7 +275,7 @@ u64 GetHashHiresTexture(const u8 *src, int len, u32 samples)
u32 Step = (len / 8);
const u64 *data = (const u64 *)src;
const u64 *end = data + Step;
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
while(data < end)
@@ -318,7 +318,7 @@ u64 GetCRC32(const u8 *src, int len, u32 samples)
u32 Step = (len/4);
const u32 *data = (const u32 *)src;
const u32 *end = data + Step;
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
while(data < end)
@@ -390,7 +390,7 @@ u64 GetMurmurHash3(const u8* src, int len, u32 samples)
u32 out[2];
const int nblocks = len / 8;
u32 Step = (len / 4);
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
@@ -464,7 +464,7 @@ u64 GetHashHiresTexture(const u8 *src, int len, u32 samples)
u32 Step = (len / 8);
const u64 *data = (const u64 *)src;
const u64 *end = data + Step;
if(samples == 0) samples = Step;
if(samples == 0) samples = max(Step, 1u);
Step = Step / samples;
if(Step < 1) Step = 1;
while(data < end)

View File

@@ -459,7 +459,11 @@ bool IniFile::Save(const char* filename)
return false;
}
for (std::vector<Section>::const_iterator iter = sections.begin(); iter != sections.end(); ++iter)
// Currently testing if dolphin community can handle the requirements of C++11 compilation
// If you get a compiler error on this line, your compiler is probably old.
// Update to g++ 4.4 or a recent version of clang (XCode 4.2 on OS X).
// If you don't want to update, complain in a google code issue, the dolphin forums or #dolphin-emu.
for (auto iter = sections.begin(); iter != sections.end(); ++iter)
{
const Section& section = *iter;

View File

@@ -21,12 +21,10 @@
#include "Common.h"
#include <fstream>
// Update this to the current SVN revision every time you change shader generation code.
// We don't automatically get this from SVN_REV because that would mean regenerating the
// shader cache for every revision, graphics-related or not, which is simply annoying.
// Increment this every time you change shader generation code.
enum
{
LINEAR_DISKCACHE_VER = 6964
LINEAR_DISKCACHE_VER = 6972
};
// On disk format:
@@ -73,36 +71,58 @@ public:
// close any currently opened file
Close();
m_num_entries = 0;
// try opening for reading/writing
m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary | ios_base::app);
m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary);
m_file.seekg(0, std::ios::end);
std::fstream::pos_type end_pos = m_file.tellg();
m_file.seekg(0, std::ios::beg);
std::fstream::pos_type start_pos = m_file.tellg();
std::streamoff file_size = end_pos - start_pos;
if (m_file.is_open() && ValidateHeader())
{
// good header, read some key/value pairs
u32 num_entries = 0;
K key;
V *value = NULL;
u32 value_size;
u32 entry_number;
std::fstream::pos_type last_pos = m_file.tellg();
while (Read(&value_size))
{
std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size;
if (next_extent > file_size)
break;
delete[] value;
value = new V[value_size];
// read key/value and pass to reader
if (Read(&key) && Read(value, value_size))
if (Read(&key) &&
Read(value, value_size) &&
Read(&entry_number) &&
entry_number == m_num_entries+1)
{
reader.Read(key, value, value_size);
}
else
{
break;
}
++num_entries;
m_num_entries++;
last_pos = m_file.tellg();
}
m_file.seekp(last_pos);
m_file.clear();
delete[] value;
return num_entries;
return m_num_entries;
}
// failed to open file for reading or bad header
@@ -129,10 +149,12 @@ public:
// Appends a key-value pair to the store.
void Append(const K &key, const V *value, u32 value_size)
{
// TODO: Should do a check that we don't already have "key"?
// TODO: Should do a check that we don't already have "key"? (I think each caller does that already.)
Write(&value_size);
Write(&key);
Write(value, value_size);
m_num_entries++;
Write(&m_num_entries);
}
private:
@@ -176,6 +198,7 @@ private:
} m_header;
std::fstream m_file;
u32 m_num_entries;
};
#endif // _LINEAR_DISKCACHE

View File

@@ -85,12 +85,17 @@ LogManager::LogManager()
m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX).c_str());
m_consoleLog = new ConsoleListener();
m_debuggerLog = new DebuggerLogListener();
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
{
m_Log[i]->SetEnable(true);
m_Log[i]->AddListener(m_fileLog);
m_Log[i]->AddListener(m_consoleLog);
#ifdef _MSC_VER
if (IsDebuggerPresent())
m_Log[i]->AddListener(m_debuggerLog);
#endif
}
}
@@ -100,6 +105,7 @@ LogManager::~LogManager()
{
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog);
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog);
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_debuggerLog);
}
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
@@ -187,3 +193,10 @@ void FileLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
std::lock_guard<std::mutex> lk(m_log_lock);
m_logfile << msg << std::flush;
}
void DebuggerLogListener::Log(LogTypes::LOG_LEVELS, const char *msg)
{
#if _MSC_VER
::OutputDebugStringA(msg);
#endif
}

View File

@@ -58,6 +58,12 @@ private:
bool m_enable;
};
class DebuggerLogListener : public LogListener
{
public:
void Log(LogTypes::LOG_LEVELS, const char *msg);
};
class LogContainer
{
public:
@@ -97,6 +103,7 @@ private:
LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS];
FileLogListener *m_fileLog;
ConsoleListener *m_consoleLog;
DebuggerLogListener *m_debuggerLog;
static LogManager *m_logManager; // Singleton. Ugh.
LogManager();
@@ -153,6 +160,11 @@ public:
return m_consoleLog;
}
DebuggerLogListener *GetDebuggerListener() const
{
return m_debuggerLog;
}
static LogManager* GetInstance()
{
return m_logManager;

View File

@@ -27,28 +27,65 @@
#include <stdio.h>
#endif
#if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT)
#include <unistd.h>
#define PAGE_MASK (getpagesize() - 1)
#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
#endif
// This is purposely not a full wrapper for virtualalloc/mmap, but it
// provides exactly the primitive operations that Dolphin needs.
void* AllocateExecutableMemory(size_t size, bool low)
{
#ifdef _WIN32
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#if defined(_WIN32)
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
static char *map_hint = 0;
#if defined(__x86_64__) && !defined(MAP_32BIT)
// This OS has no flag to enforce allocation below the 4 GB boundary,
// but if we hint that we want a low address it is very likely we will
// get one.
// An older version of this code used MAP_FIXED, but that has the side
// effect of discarding already mapped pages that happen to be in the
// requested virtual memory range (such as the emulated RAM, sometimes).
if (low && (!map_hint))
map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
#endif
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE
#if defined __linux__ && defined __x86_64__
#if defined(__x86_64__) && defined(MAP_32BIT)
| (low ? MAP_32BIT : 0)
#endif
, -1, 0);
#endif
#endif /* defined(_WIN32) */
// printf("Mapped executable memory at %p (size %ld)\n", ptr,
// (unsigned long)size);
#if defined(__FreeBSD__)
if (ptr == MAP_FAILED)
{
ptr = NULL;
#else
if (ptr == NULL)
{
#endif
PanicAlert("Failed to allocate executable memory");
#ifdef _M_X64
}
#if !defined(_WIN32) && defined(__x86_64__) && !defined(MAP_32BIT)
else
{
if (low)
{
map_hint += size;
map_hint = (char*)round_page(map_hint); /* round up to the next page */
// printf("Next map will (hopefully) be at %p\n", map_hint);
}
}
#endif
#if defined(_M_X64)
if ((u64)ptr >= 0x80000000 && low == true)
PanicAlert("Executable memory ended up above 2GB!");
#endif

View File

@@ -86,7 +86,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
va_list args;
va_start(args, format);
CharArrayFromFormatV(buffer, 2047, str_translator(format).c_str(), args);
CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args);
va_end(args);
ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);

View File

@@ -7,7 +7,9 @@
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
// GCC 4.4 provides <thread>
#ifndef _GLIBCXX_USE_SCHED_YIELD
#define _GLIBCXX_USE_SCHED_YIELD
#endif
#include <thread>
#else

View File

@@ -125,15 +125,26 @@ std::string StripQuotes(const std::string& s)
bool TryParse(const std::string &str, u32 *const output)
{
char *endptr = NULL;
u32 value = strtoul(str.c_str(), &endptr, 0);
// Reset errno to a value other than ERANGE
errno = 0;
unsigned long value = strtoul(str.c_str(), &endptr, 0);
if (!endptr || *endptr)
return false;
if (value == ULONG_MAX && errno == ERANGE)
if (errno == ERANGE)
return false;
*output = value;
if (ULONG_MAX > UINT_MAX) {
// Note: The typecasts avoid GCC warnings when long is 32 bits wide.
if (value >= static_cast<unsigned long>(0x100000000ull)
&& value <= static_cast<unsigned long>(0xFFFFFFFF00000000ull))
return false;
}
*output = static_cast<u32>(value);
return true;
}

View File

@@ -387,7 +387,7 @@ bool SysConf::SaveToFile(const char *filename)
}
else if (i->type == Type_SmallArray)
{
const u8 len = i->dataLength;
const u8 len = (u8)(i->dataLength);
f.WriteArray(&len, 1);
}

View File

@@ -66,10 +66,9 @@ struct SSysConfEntry
}
bool SetArrayData(u8* buffer, u16 bufferSize)
{
if (buffer && bufferSize <= dataLength)
if (buffer)
{
memcpy(data, buffer, bufferSize);
memcpy(data, buffer, min<u16>(bufferSize, dataLength));
return true;
}
return false;

View File

@@ -72,6 +72,13 @@ public:
is_set = false;
}
void Reset()
{
std::unique_lock<std::mutex> lk(m_mutex);
// no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration
is_set = false;
}
private:
class IsSet
{

View File

@@ -30,7 +30,12 @@ const char *scm_rev_str = "Dolphin "
#if !SCM_IS_MASTER
"[" SCM_BRANCH_STR "] "
#endif
#ifdef __INTEL_COMPILER
BUILD_TYPE_STR SCM_DESC_STR "-ICC";
#else
BUILD_TYPE_STR SCM_DESC_STR;
#endif
#ifdef _M_X64
#define NP_ARCH "x64"

View File

@@ -119,6 +119,7 @@ public:
virtual void Video_GatherPipeBursted() = 0;
virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
virtual bool Video_IsHiWatermarkActive() = 0;
virtual void Video_AbortFrame() = 0;
virtual readFn16 Video_CPRead16() = 0;
@@ -140,6 +141,7 @@ class VideoBackendHardware : public VideoBackend
{
void DoState(PointerWrap &p);
void RunLoop(bool enable);
bool Initialize(void *&) { InitializeShared(); return true; }
void EmuStateChange(EMUSTATE_CHANGE);
@@ -158,6 +160,7 @@ class VideoBackendHardware : public VideoBackend
void Video_GatherPipeBursted();
bool Video_IsPossibleWaitingSetDrawDone();
bool Video_IsHiWatermarkActive();
void Video_AbortFrame();
readFn16 Video_CPRead16();
@@ -165,6 +168,9 @@ class VideoBackendHardware : public VideoBackend
readFn16 Video_PERead16();
writeFn16 Video_PEWrite16();
writeFn32 Video_PEWrite32();
protected:
void InitializeShared();
};
#endif

View File

@@ -834,6 +834,102 @@ void XEmitter::SHL(int bits, OpArg dest, OpArg shift) {WriteShift(bits, dest, sh
void XEmitter::SHR(int bits, OpArg dest, OpArg shift) {WriteShift(bits, dest, shift, 5);}
void XEmitter::SAR(int bits, OpArg dest, OpArg shift) {WriteShift(bits, dest, shift, 7);}
// index can be either imm8 or register, don't use memory destination because it's slow
void XEmitter::WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext)
{
if (dest.IsImm())
{
_assert_msg_(DYNA_REC, 0, "WriteBitTest - can't test imms");
}
if ((index.IsImm() && index.GetImmBits() != 8))
{
_assert_msg_(DYNA_REC, 0, "WriteBitTest - illegal argument");
}
if (bits == 16) Write8(0x66);
if (index.IsImm())
{
dest.WriteRex(this, bits, bits);
Write8(0x0F); Write8(0xBA);
dest.WriteRest(this, 1, (X64Reg)ext);
Write8((u8)index.offset);
}
else
{
X64Reg operand = index.GetSimpleReg();
dest.WriteRex(this, bits, bits, operand);
Write8(0x0F); Write8(0x83 + 8*ext);
dest.WriteRest(this, 1, operand);
}
}
void XEmitter::BT(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 4);}
void XEmitter::BTS(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 5);}
void XEmitter::BTR(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 6);}
void XEmitter::BTC(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 7);}
//shift can be either imm8 or cl
void XEmitter::SHRD(int bits, OpArg dest, OpArg src, OpArg shift)
{
bool writeImm = false;
if (dest.IsImm())
{
_assert_msg_(DYNA_REC, 0, "SHRD - can't use imms as destination");
}
if (!src.IsSimpleReg())
{
_assert_msg_(DYNA_REC, 0, "SHRD - must use simple register as source");
}
if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8))
{
_assert_msg_(DYNA_REC, 0, "SHRD - illegal shift");
}
if (bits == 16) Write8(0x66);
X64Reg operand = src.GetSimpleReg();
dest.WriteRex(this, bits, bits, operand);
if (shift.GetImmBits() == 8)
{
Write8(0x0F); Write8(0xAC);
dest.WriteRest(this, 1, operand);
Write8((u8)shift.offset);
}
else
{
Write8(0x0F); Write8(0xAD);
dest.WriteRest(this, 0, operand);
}
}
void XEmitter::SHLD(int bits, OpArg dest, OpArg src, OpArg shift)
{
bool writeImm = false;
if (dest.IsImm())
{
_assert_msg_(DYNA_REC, 0, "SHLD - can't use imms as destination");
}
if (!src.IsSimpleReg())
{
_assert_msg_(DYNA_REC, 0, "SHLD - must use simple register as source");
}
if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8))
{
_assert_msg_(DYNA_REC, 0, "SHLD - illegal shift");
}
if (bits == 16) Write8(0x66);
X64Reg operand = src.GetSimpleReg();
dest.WriteRex(this, bits, bits, operand);
if (shift.GetImmBits() == 8)
{
Write8(0x0F); Write8(0xA4);
dest.WriteRest(this, 1, operand);
Write8((u8)shift.offset);
}
else
{
Write8(0x0F); Write8(0xA5);
dest.WriteRest(this, 0, operand);
}
}
void OpArg::WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg _operandReg, int bits)
{
if (bits == 16)

View File

@@ -249,6 +249,7 @@ private:
void WriteMulDivType(int bits, OpArg src, int ext);
void WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2);
void WriteShift(int bits, OpArg dest, OpArg &shift, int ext);
void WriteBitTest(int bits, OpArg &dest, OpArg &index, int ext);
void WriteMXCSR(OpArg arg, int ext);
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
@@ -374,6 +375,16 @@ public:
void SHR(int bits, OpArg dest, OpArg shift);
void SAR(int bits, OpArg dest, OpArg shift);
// Bit Test
void BT(int bits, OpArg dest, OpArg index);
void BTS(int bits, OpArg dest, OpArg index);
void BTR(int bits, OpArg dest, OpArg index);
void BTC(int bits, OpArg dest, OpArg index);
// Double-Precision Shift
void SHRD(int bits, OpArg dest, OpArg src, OpArg shift);
void SHLD(int bits, OpArg dest, OpArg src, OpArg shift);
// Extend EAX into EDX in various ways
void CWD(int bits = 16);
inline void CDQ() {CWD(32);}

View File

@@ -101,6 +101,7 @@ set(SRCS Src/ActionReplay.cpp
Src/HW/EXI_DeviceIPL.cpp
Src/HW/EXI_DeviceMemoryCard.cpp
Src/HW/EXI_DeviceMic.cpp
Src/HW/GCMemcard.cpp
Src/HW/GCPad.cpp
Src/HW/GCPadEmu.cpp
Src/HW/GPFifo.cpp

View File

@@ -45,7 +45,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -56,7 +55,6 @@
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -117,7 +115,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -129,7 +127,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -141,7 +139,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -155,7 +153,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -169,7 +167,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -183,7 +181,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
<ClCompile>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -289,6 +287,7 @@
<ClCompile Include="Src\HW\EXI_DeviceIPL.cpp" />
<ClCompile Include="Src\HW\EXI_DeviceMemoryCard.cpp" />
<ClCompile Include="Src\HW\EXI_DeviceMic.cpp" />
<ClCompile Include="Src\HW\GCMemcard.cpp" />
<ClCompile Include="Src\HW\GCPad.cpp" />
<ClCompile Include="Src\HW\GCPadEmu.cpp" />
<ClCompile Include="Src\HW\GPFifo.cpp" />
@@ -485,6 +484,7 @@
<ClInclude Include="Src\HW\EXI_DeviceIPL.h" />
<ClInclude Include="Src\HW\EXI_DeviceMemoryCard.h" />
<ClInclude Include="Src\HW\EXI_DeviceMic.h" />
<ClInclude Include="Src\HW\GCMemcard.h" />
<ClInclude Include="Src\HW\GCPad.h" />
<ClInclude Include="Src\HW\GCPadEmu.h" />
<ClInclude Include="Src\HW\GPFifo.h" />

View File

@@ -553,6 +553,9 @@
<Filter>FifoPlayer</Filter>
</ClCompile>
<ClCompile Include="Src\Movie.cpp" />
<ClCompile Include="Src\HW\GCMemcard.cpp">
<Filter>HW %28Flipper/Hollywood%29\GCMemcard</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\ConfigManager.h" />
@@ -1027,6 +1030,9 @@
<Filter>FifoPlayer</Filter>
</ClInclude>
<ClInclude Include="Src\Movie.h" />
<ClInclude Include="Src\HW\GCMemcard.h">
<Filter>HW %28Flipper/Hollywood%29\GCMemcard</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
@@ -1165,5 +1171,8 @@
<Filter Include="FifoPlayer">
<UniqueIdentifier>{ca7d56f7-4e84-4d15-9aea-7ae6fa7d6586}</UniqueIdentifier>
</Filter>
<Filter Include="HW %28Flipper/Hollywood%29\GCMemcard">
<UniqueIdentifier>{3e9e6e83-c1bf-45f9-aeff-231f98f60d29}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@@ -97,6 +97,7 @@ files = [
'Src/HW/EXI_DeviceIPL.cpp',
'Src/HW/EXI_DeviceMemoryCard.cpp',
'Src/HW/EXI_DeviceMic.cpp',
'Src/HW/GCMemcard.cpp',
'Src/HW/GCPad.cpp',
'Src/HW/GCPadEmu.cpp',
'Src/HW/GPFifo.cpp',

View File

@@ -195,10 +195,13 @@ bool CBoot::BootUp()
NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
// HLE jump to loader (homebrew)
HLE::Patch(0x80001800, "HBReload");
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
Memory::WriteBigEData(stubstr, 0x80001804, 8);
// HLE jump to loader (homebrew). Disabled when Gecko is active as it interferes with the code handler
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
{
HLE::Patch(0x80001800, "HBReload");
const u8 stubstr[] = { 'S', 'T', 'U', 'B', 'H', 'A', 'X', 'X' };
Memory::WriteBigEData(stubstr, 0x80001804, 8);
}
g_symbolDB.Clear();
VideoInterface::Preset(_StartupPara.bNTSC);

View File

@@ -66,7 +66,7 @@ bool CBoot::EmulatedBS2_GC()
DVDInterface::DVDRead(0x00000000, 0x80000000, 0x20); // write disc info
Memory::Write_U32(0x0D15EA5E, 0x80000020); // booted from bootrom. 0xE5207C22 = booted from jtag
Memory::Write_U32(0x01800000, 0x80000028); // Physical Memory Size (24MB on retail)
Memory::Write_U32(Memory::REALRAM_SIZE, 0x80000028); // Physical Memory Size (24MB on retail)
// TODO determine why some games fail when using a retail id. (Seem to take different EXI paths, see ikaruga for example)
Memory::Write_U32(0x10000006, 0x8000002C); // Console type - DevKit (retail ID == 0x00000003) see yagcd 4.2.1.1.2
@@ -172,7 +172,6 @@ bool CBoot::EmulatedBS2_GC()
return true;
}
bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
{
INFO_LOG(BOOT, "Setup Wii Memory...");
@@ -238,14 +237,14 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
DVDInterface::DVDRead(0x00000000, 0x00000000, 0x20); // Game Code
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
Memory::Write_U32(0x00000001, 0x00000024); // Unknown
Memory::Write_U32(0x01800000, 0x00000028); // MEM1 size 24MB
Memory::Write_U32(Memory::REALRAM_SIZE, 0x00000028); // MEM1 size 24MB
Memory::Write_U32(0x00000023, 0x0000002c); // Production Board Model
Memory::Write_U32(0x00000000, 0x00000030); // Init
Memory::Write_U32(0x817FEC60, 0x00000034); // Init
// 38, 3C should get start, size of FST through apploader
Memory::Write_U32(0x38a00040, 0x00000060); // Exception init
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(0x01800000, 0x000000f0); // "Simulated memory size" (debug mode?)
Memory::Write_U32(Memory::REALRAM_SIZE, 0x000000f0); // "Simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed

View File

@@ -223,7 +223,6 @@ void SConfig::SaveSettings()
ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage);
ini.Set("Core", "MemcardA", m_strMemoryCardA);
ini.Set("Core", "MemcardB", m_strMemoryCardB);
ini.Set("Core", "ReloadMemcardOnState", b_reloadMCOnState);
ini.Set("Core", "SlotA", m_EXIDevice[0]);
ini.Set("Core", "SlotB", m_EXIDevice[1]);
ini.Set("Core", "SerialPort1", m_EXIDevice[2]);
@@ -354,8 +353,7 @@ void SConfig::LoadSettings()
ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0);
ini.Get("Core", "MemcardA", &m_strMemoryCardA);
ini.Get("Core", "MemcardB", &m_strMemoryCardB);
ini.Get("Core", "ReloadMemcardOnState", &b_reloadMCOnState, true);
ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD_A);
ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD);
ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_NONE);
ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_NONE);
ini.Get("Core", "BBA_MAC", &m_bba_mac);
@@ -366,7 +364,7 @@ void SConfig::LoadSettings()
for (int i = 0; i < 4; ++i)
{
sprintf(sidevicenum, "SIDevice%i", i);
ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i], i==0 ? SI_GC_CONTROLLER:SI_NONE);
ini.Get("Core", sidevicenum, (u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE);
}
ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false);

View File

@@ -47,12 +47,8 @@ struct SConfig : NonCopyable
std::string m_strMemoryCardA;
std::string m_strMemoryCardB;
// eject and reload the memory card on state
// in ZTP and other games if the save file has been deleted from the memory card
//this is necessary to save after loading a savestate
bool b_reloadMCOnState;
TEXIDevices m_EXIDevice[3];
TSIDevices m_SIDevice[4];
SIDevices m_SIDevice[4];
std::string m_bba_mac;
// interface language

View File

@@ -101,6 +101,7 @@ std::string g_stateFileName;
std::thread g_EmuThread;
static std::thread g_cpu_thread;
static bool g_requestRefreshInfo;
SCoreStartupParameter g_CoreStartupParameter;
@@ -261,7 +262,7 @@ void Stop() // - Hammertime!
SConfig::GetInstance().m_SYSCONF->Reload();
INFO_LOG(CONSOLE, "Stop [Main Thread]\t\t---- Shutdown complete ----");
Movie::g_InputCounter = 0;
Movie::g_currentInputCount = 0;
g_bStopping = false;
}
@@ -345,6 +346,8 @@ void EmuThread()
DisplayMessage(cpu_info.Summarize(), 8000);
DisplayMessage(_CoreParameter.m_strFilename, 3000);
Movie::Init();
HW::Init();
if (!g_video_backend->Initialize(g_pWindowHandle))
@@ -537,15 +540,20 @@ void SaveScreenShot()
SetState(CORE_RUN);
}
void RequestRefreshInfo()
{
g_requestRefreshInfo = true;
}
// Apply Frame Limit and Display FPS info
// This should only be called from VI
void VideoThrottle()
{
u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 1) ?
SConfig::GetInstance().m_Framelimit * 5 : VideoInterface::TargetRefreshRate;
u32 TargetVPS = (SConfig::GetInstance().m_Framelimit > 2) ?
(SConfig::GetInstance().m_Framelimit - 1) * 5 : VideoInterface::TargetRefreshRate;
// Disable the frame-limiter when the throttle (Tab) key is held down
if (SConfig::GetInstance().m_Framelimit && !Host_GetKeyState('\t'))
// Disable the frame-limiter when the throttle (Tab) key is held down. Audio throttle: m_Framelimit = 2
if (SConfig::GetInstance().m_Framelimit && SConfig::GetInstance().m_Framelimit != 2 && !Host_GetKeyState('\t'))
{
u32 frametime = ((SConfig::GetInstance().b_UseFPS)? Common::AtomicLoad(DrawnFrame) : DrawnVideo) * 1000 / TargetVPS;
@@ -561,8 +569,9 @@ void VideoThrottle()
// Update info per second
u32 ElapseTime = (u32)Timer.GetTimeDifference();
if ((ElapseTime >= 1000 && DrawnVideo > 0) || Movie::g_bFrameStep)
if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo)
{
g_requestRefreshInfo = false;
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
@@ -599,8 +608,10 @@ void VideoThrottle()
#else // Summary information
std::string SFPS;
if (Movie::IsPlayingInput() || Movie::IsRecordingInput())
SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - SPEED: %u%%", Movie::g_frameCounter, Movie::g_InputCounter, FPS, VPS, Speed);
if (Movie::IsPlayingInput())
SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed);
else if (Movie::IsRecordingInput())
SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed);
else
SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
#endif

View File

@@ -85,6 +85,7 @@ void StopTrace();
bool ShouldSkipFrame(int skipped);
void VideoThrottle();
void RequestRefreshInfo();
#ifdef RERECORDING

View File

@@ -133,6 +133,7 @@ void Init()
void Shutdown()
{
MoveEvents();
ClearPendingEvents();
UnregisterAllEvents();
@@ -163,6 +164,7 @@ void DoState(PointerWrap &p)
p.Do(fakeDecStartTicks);
p.Do(fakeTBStartValue);
p.Do(fakeTBStartTicks);
p.DoMarker("CoreTimingData");
// OK, here we're gonna need to specialize depending on the mode.
// Should do something generic to serialize linked lists.
switch (p.GetMode()) {
@@ -209,6 +211,7 @@ void DoState(PointerWrap &p)
break;
}
}
p.DoMarker("CoreTimingEvents");
}
u64 GetTicks()

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -19,7 +19,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
====================================================================*/

View File

@@ -85,14 +85,14 @@ void LoadBPReg(const BPCmd &bp, BPMemory &bpMem)
void GetTlutLoadData(u32 &tlutAddr, u32 &memAddr, u32 &tlutXferCount, BPMemory &bpMem)
{
tlutAddr = (bpMem.tlutXferDest & 0x3FF) << 9;
tlutXferCount = (bpMem.tlutXferDest & 0x1FFC00) >> 5;
tlutAddr = (bpMem.tmem_config.tlut_dest & 0x3FF) << 9;
tlutXferCount = (bpMem.tmem_config.tlut_dest & 0x1FFC00) >> 5;
// TODO - figure out a cleaner way.
if (Core::g_CoreStartupParameter.bWii)
memAddr = bpmem.tlutXferSrc << 5;
memAddr = bpmem.tmem_config.tlut_src << 5;
else
memAddr = (bpmem.tlutXferSrc & 0xFFFFF) << 5;
memAddr = (bpmem.tmem_config.tlut_src & 0xFFFFF) << 5;
}
void LoadCPReg(u32 subCmd, u32 value, CPMemory &cpMem)
@@ -232,4 +232,4 @@ void CalculateVertexElementSizes(int sizes[], int vatIndex, const CPMemory &cpMe
}
}
}
}

View File

@@ -51,4 +51,4 @@ namespace FifoAnalyzer
void CalculateVertexElementSizes(int sizes[], int vatIndex, const CPMemory &cpMem);
}
#endif
#endif

View File

@@ -282,4 +282,4 @@ void FifoDataFile::ReadMemoryUpdates(u64 fileOffset, u32 numUpdates, std::vector
file.Seek(srcUpdate.dataOffset, SEEK_SET);
file.ReadBytes(dstUpdate.data, srcUpdate.dataSize);
}
}
}

View File

@@ -109,4 +109,4 @@ private:
std::vector<FifoFrameInfo> m_Frames;
};
#endif
#endif

View File

@@ -82,4 +82,4 @@ struct FileMemoryUpdate
}
#endif
#endif

View File

@@ -343,4 +343,4 @@ void FifoPlaybackAnalyzer::StoreWrittenRegion(u32 address, u32 size)
m_WrittenMemory.push_back(range);
}
}
}

View File

@@ -61,4 +61,4 @@ private:
FifoAnalyzer::CPMemory m_CpMem;
};
#endif
#endif

View File

@@ -118,4 +118,4 @@ private:
std::vector<AnalyzedFrameInfo> m_FrameInfo;
};
#endif
#endif

View File

@@ -302,4 +302,4 @@ void FifoRecordAnalyzer::WriteTexMapMemory(int texMap, u32 &writtenTexMaps)
}
FifoRecorder::GetInstance().WriteMemory(imageBase, textureSize, MemoryUpdate::TEXTURE_MAP);
}
}

View File

@@ -53,4 +53,4 @@ private:
FifoAnalyzer::CPMemory m_CpMem;
};
#endif
#endif

View File

@@ -77,4 +77,4 @@ private:
FifoRecordAnalyzer m_RecordAnalyzer;
};
#endif
#endif

View File

@@ -1,3 +1,17 @@
// Copyright (C) 2003 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/
#include "GeckoCode.h"
#include "Thread.h"
@@ -5,6 +19,8 @@
#include "ConfigManager.h"
#include "vector"
#include "PowerPC/PowerPC.h"
#include "CommonPaths.h"
namespace Gecko
{
@@ -40,6 +56,9 @@ static struct
// codes execute when counter is 0
static int code_execution_counter = 0;
// Track whether the code handler has been installed
static bool code_handler_installed = false;
// the currently active codes
std::vector<GeckoCode> active_codes;
@@ -93,6 +112,70 @@ void SetActiveCodes(const std::vector<GeckoCode>& gcodes)
}
inserted_asm_codes.clear();
code_handler_installed = false;
}
bool InstallCodeHandler()
{
u32 codelist_location = 0x800028B8; // Debugger on location (0x800022A8 = Debugger off, using codehandleronly.bin)
std::string data;
std::string _rCodeHandlerFilename = File::GetSysDirectory() + GECKO_CODE_HANDLER;
if (!File::ReadFileToString(false, _rCodeHandlerFilename.c_str(), data))
return false;
// Install code handler
Memory::WriteBigEData((const u8*)data.data(), 0x80001800, data.length());
// Turn off Pause on start
Memory::Write_U32(0, 0x80002774);
// Write the Game ID into the location expected by WiiRD
Memory::WriteBigEData(Memory::GetPointer(0x80000000), 0x80001800, 6);
// Create GCT in memory
Memory::Write_U32(0x00d0c0de, codelist_location);
Memory::Write_U32(0x00d0c0de, codelist_location + 4);
std::lock_guard<std::mutex> lk(active_codes_lock);
int i = 0;
std::vector<GeckoCode>::iterator
gcodes_iter = active_codes.begin(),
gcodes_end = active_codes.end();
for (; gcodes_iter!=gcodes_end; ++gcodes_iter)
{
if (gcodes_iter->enabled)
{
current_code = codes_start = &*gcodes_iter->codes.begin();
codes_end = &*gcodes_iter->codes.end();
for (; current_code < codes_end; ++current_code)
{
const GeckoCode::Code& code = *current_code;
// Make sure we have enough memory to hold the code list
if ((codelist_location + 24 + i) < 0x80003000)
{
Memory::Write_U32(code.address, codelist_location + 8 + i);
Memory::Write_U32(code.data, codelist_location + 12 + i);
i += 8;
}
}
}
}
Memory::Write_U32(0xff000000, codelist_location + 8 + i);
Memory::Write_U32(0x00000000, codelist_location + 12 + i);
// Turn on codes
Memory::Write_U8(1, 0x80001807);
// Invalidate the icache
for (int i = 0; i < data.length(); i += 32)
{
PowerPC::ppcState.iCache.Invalidate(0x80001800 + i);
}
return true;
}
bool RunGeckoCode(GeckoCode& gecko_code)
@@ -137,7 +220,7 @@ bool RunGeckoCode(GeckoCode& gecko_code)
gecko_code.enabled = false;
PanicAlertT("GeckoCode failed to run (CT%i CST%i) (%s)"
"\n(either a bad code or the code type is not yet supported.)"
"\n(either a bad code or the code type is not yet supported. Try using the native code handler by placing the codehandler.bin file into the Sys directory and restarting Dolphin.)"
, code.type, code.subtype, gecko_code.name.c_str());
return false;
}
@@ -168,6 +251,44 @@ bool RunActiveCodes()
return true;
}
void RunCodeHandler()
{
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
{
u8 *gameId = Memory::GetPointer(0x80000000);
u8 *wiirdId = Memory::GetPointer(0x80001800);
if (!code_handler_installed || memcmp(gameId, wiirdId, 6))
code_handler_installed = InstallCodeHandler();
if (code_handler_installed)
{
if (PC == LR)
{
u32 oldLR = LR;
PowerPC::CoreMode oldMode = PowerPC::GetMode();
PC = 0x800018A8;
LR = 0;
// Execute the code handler in interpreter mode to track when it exits
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
while (PC != 0)
PowerPC::SingleStep();
PowerPC::SetMode(oldMode);
PC = LR = oldLR;
}
}
else
{
// Use the emulated code handler
Gecko::RunActiveCodes();
}
}
}
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes() {
return inserted_asm_codes;
}

View File

@@ -1,3 +1,16 @@
// Copyright (C) 2003 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/
#ifndef __GECKOCODE_h__
#define __GECKOCODE_h__
@@ -67,6 +80,7 @@ namespace Gecko
void SetActiveCodes(const std::vector<GeckoCode>& gcodes);
bool RunActiveCodes();
void RunCodeHandler();
const std::map<u32, std::vector<u32> >& GetInsertedAsmCodes();
} // namespace Gecko

View File

@@ -1,3 +1,16 @@
// Copyright (C) 2003 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/
#include "GeckoCodeConfig.h"

View File

@@ -1,3 +1,16 @@
// Copyright (C) 2003 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/
#ifndef __GECKOCODECONFIG_h__
#define __GECKOCODECONFIG_h__

View File

@@ -69,9 +69,10 @@ void GetStringVA(std::string& _rOutBuffer, u32 strReg)
char ArgumentBuffer[256];
u32 ParameterCounter = 4;
u32 FloatingParameterCounter = 1;
char* pString = (char*)Memory::GetPointer(GPR(strReg));
if (!pString) {
//PanicAlert("Invalid GetStringVA call");
char *pString = (char*)Memory::GetPointer(GPR(strReg));
if (!pString)
{
ERROR_LOG(OSREPORT, "r%i invalid", strReg);
return;
}

View File

@@ -153,6 +153,12 @@ void Init()
m_Volume.hex = 0;
m_SampleCounter = 0;
m_InterruptTiming = 0;
g_LastCPUTime = 0;
g_CPUCyclesPerSample = 0xFFFFFFFFFFFULL;
g_AISSampleRate = 48000;
g_AIDSampleRate = 32000;
}
void Shutdown()

View File

@@ -115,6 +115,7 @@ void CCPU::EnableStepping(const bool _bStepping)
if (_bStepping)
{
PowerPC::Pause();
m_StepEvent.Reset();
g_video_backend->EmuStateChange(EMUSTATE_CHANGE_PAUSE);
DSP::GetDSPEmulator()->DSP_ClearAudioBuffer(true);
}

View File

@@ -131,7 +131,51 @@ void DSPHLE::SwapUCode(u32 _crc)
void DSPHLE::DoState(PointerWrap &p)
{
p.Do(m_InitMixer);
GetUCode()->DoState(p);
p.Do(m_DSPControl);
p.Do(m_dspState);
int ucode_crc = IUCode::GetCRC(m_pUCode);
int ucode_crc_beforeLoad = ucode_crc;
int lastucode_crc = IUCode::GetCRC(m_lastUCode);
int lastucode_crc_beforeLoad = lastucode_crc;
p.Do(ucode_crc);
p.Do(lastucode_crc);
// if a different type of ucode was being used when the savestate was created,
// we have to reconstruct the old type of ucode so that we have a valid thing to call DoState on.
IUCode* ucode = (ucode_crc == ucode_crc_beforeLoad) ? m_pUCode : UCodeFactory( ucode_crc, this, m_bWii);
IUCode* lastucode = (lastucode_crc != lastucode_crc_beforeLoad) ? m_lastUCode : UCodeFactory(lastucode_crc, this, m_bWii);
if (ucode)
ucode->DoState(p);
if (lastucode)
lastucode->DoState(p);
// if a different type of ucode was being used when the savestate was created,
// discard it if we're not loading, otherwise discard the old one and keep the new one.
if (ucode != m_pUCode)
{
if (p.GetMode() != PointerWrap::MODE_READ)
delete ucode;
else
{
delete m_pUCode;
m_pUCode = ucode;
}
}
if (lastucode != m_lastUCode)
{
if (p.GetMode() != PointerWrap::MODE_READ)
delete lastucode;
else
{
delete m_lastUCode;
m_lastUCode = lastucode;
}
}
m_MailHandler.DoState(p);
}
// Mailbox fuctions

View File

@@ -28,9 +28,8 @@
#include "UCode_AX_Voice.h"
CUCode_AX::CUCode_AX(DSPHLE *dsp_hle, u32 l_CRC)
: IUCode(dsp_hle)
: IUCode(dsp_hle, l_CRC)
, m_addressPBs(0xFFFFFFFF)
, _CRC(l_CRC)
{
// we got loaded
m_rMailHandler.PushMail(DSP_INIT);
@@ -175,7 +174,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize)
ProcessUpdates(PB);
if (_CRC != 0x3389a79e)
if (m_CRC != 0x3389a79e)
VoiceHacks(PB);
MixAddVoice(PB, templbuffer, temprbuffer, _iSize);
@@ -463,11 +462,8 @@ void CUCode_AX::DoState(PointerWrap &p)
{
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(_CRC);
p.Do(numPBaddr);
p.Do(m_addressPBs);
p.Do(PBaddr);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@@ -41,7 +41,6 @@ public:
u8 numPBaddr;
u32 PBaddr[8]; //2 needed for MP2
u32 m_addressPBs;
u32 _CRC;
private:
enum

View File

@@ -28,9 +28,8 @@
CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
: IUCode(dsp_hle)
: IUCode(dsp_hle, l_CRC)
, m_addressPBs(0xFFFFFFFF)
, _CRC(l_CRC)
{
// we got loaded
m_rMailHandler.PushMail(DSP_INIT);
@@ -38,7 +37,7 @@ CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC)
templbuffer = new int[1024 * 1024];
temprbuffer = new int[1024 * 1024];
wiisportsHack = _CRC == 0xfa450138;
wiisportsHack = m_CRC == 0xfa450138;
}
CUCode_AXWii::~CUCode_AXWii()
@@ -260,10 +259,7 @@ void CUCode_AXWii::DoState(PointerWrap &p)
{
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(_CRC);
p.Do(m_addressPBs);
p.Do(wiisportsHack);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@@ -21,8 +21,8 @@
#include "../../DSP.h"
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
DEBUG_LOG(DSPHLE, "CUCode_CARD - initialized");
m_rMailHandler.PushMail(DSP_INIT);

View File

@@ -23,7 +23,7 @@
class CUCode_CARD : public IUCode
{
public:
CUCode_CARD(DSPHLE *dsp_hle);
CUCode_CARD(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_CARD();
void HandleMail(u32 _uMail);

View File

@@ -20,8 +20,8 @@
#include "../../DSP.h"
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
m_rMailHandler.PushMail(DSP_INIT);
}

View File

@@ -21,7 +21,7 @@
struct CUCode_GBA : public IUCode
{
CUCode_GBA(DSPHLE *dsp_hle);
CUCode_GBA(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_GBA();
void HandleMail(u32 _uMail);

View File

@@ -18,8 +18,8 @@
#include "UCodes.h"
#include "UCode_InitAudioSystem.h"
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
{
DEBUG_LOG(DSPHLE, "CUCode_InitAudioSystem - initialized");
}

View File

@@ -23,7 +23,7 @@
class CUCode_InitAudioSystem : public IUCode
{
public:
CUCode_InitAudioSystem(DSPHLE *dsp_hle);
CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc);
virtual ~CUCode_InitAudioSystem();
void HandleMail(u32 _uMail);

View File

@@ -20,8 +20,8 @@
#include "Hash.h"
#include "../../Memmap.h"
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle)
: IUCode(dsp_hle)
CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle, u32 crc)
: IUCode(dsp_hle, crc)
, m_CurrentUCode()
, m_BootTask_numSteps(0)
, m_NextParameter(0)
@@ -117,4 +117,10 @@ void CUCode_Rom::BootUCode()
m_DSPHLE->SetUCode(ector_crc);
}
void CUCode_Rom::DoState(PointerWrap &p)
{
p.Do(m_CurrentUCode);
p.Do(m_BootTask_numSteps);
p.Do(m_NextParameter);
}

View File

@@ -23,12 +23,14 @@
class CUCode_Rom : public IUCode
{
public:
CUCode_Rom(DSPHLE *dsp_hle);
CUCode_Rom(DSPHLE *dsp_hle, u32 _crc);
virtual ~CUCode_Rom();
void HandleMail(u32 _uMail);
void Update(int cycles);
void DoState(PointerWrap &p);
private:
struct SUCode
{

View File

@@ -31,8 +31,7 @@
CUCode_Zelda::CUCode_Zelda(DSPHLE *dsp_hle, u32 _CRC)
:
IUCode(dsp_hle),
m_CRC(_CRC),
IUCode(dsp_hle, _CRC),
m_bSyncInProgress(false),
m_MaxVoice(0),
@@ -572,8 +571,6 @@ void CUCode_Zelda::DoState(PointerWrap &p)
// It's bad if we try to save during Mix()
std::lock_guard<std::mutex> lk(m_csMix);
p.Do(m_CRC);
p.Do(m_AFCCoefTable);
p.Do(m_MiscTable);
@@ -616,6 +613,4 @@ void CUCode_Zelda::DoState(PointerWrap &p)
p.Do(m_PBAddress2);
p.Do(m_UploadSetupInProgress);
m_rMailHandler.DoState(p);
}

View File

@@ -212,8 +212,6 @@ private:
}
}
u32 m_CRC;
// These are the only dynamically allocated things allowed in the ucode.
s32* m_VoiceBuffer;
s16* m_ResampleBuffer;

View File

@@ -426,18 +426,15 @@ void CUCode_Zelda::RenderVoice_Raw(ZeldaVoicePB &PB, s16 *_Buffer, int _Size)
PB.Unk36[0] = (u16)(ACC0 >> 16);
// This subtract does really not make much sense at all.
ACC0 -= AX0 << 16;
if ((s64)ACC0 < 0)
{
// There's something wrong with this looping code.
ERROR_LOG(DSPHLE, "Raw loop: ReadAudio size = %04x 34:%04x %08x", PB.Unk36[0], PB.raw[0x34 ^ 1], (int)ACC0);
// ERROR_LOG(DSPHLE, "Raw loop: ReadAudio size = %04x 34:%04x %08x", PB.Unk36[0], PB.raw[0x34 ^ 1], (int)ACC0);
Decoder21_ReadAudio(PB, PB.Unk36[0], _Buffer);
ACC0 = _Size << 16;
ACC0 -= PB.Unk36[0] << 16;
ACC0 = -(s64)ACC0;
_Buffer += PB.Unk36[0];
PB.raw[0x34 ^ 1] = 0;

View File

@@ -32,19 +32,19 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii)
{
case UCODE_ROM:
INFO_LOG(DSPHLE, "Switching to ROM ucode");
return new CUCode_Rom(dsp_hle);
return new CUCode_Rom(dsp_hle, _CRC);
case UCODE_INIT_AUDIO_SYSTEM:
INFO_LOG(DSPHLE, "Switching to INIT ucode");
return new CUCode_InitAudioSystem(dsp_hle);
return new CUCode_InitAudioSystem(dsp_hle, _CRC);
case 0x65d6cc6f: // CARD
INFO_LOG(DSPHLE, "Switching to CARD ucode");
return new CUCode_CARD(dsp_hle);
return new CUCode_CARD(dsp_hle, _CRC);
case 0xdd7e72d5:
INFO_LOG(DSPHLE, "Switching to GBA ucode");
return new CUCode_GBA(dsp_hle);
return new CUCode_GBA(dsp_hle, _CRC);
case 0x3ad3b7ac: // Naruto3, Paper Mario - The Thousand Year Door
case 0x3daf59b9: // Alien Hominid
@@ -103,6 +103,9 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii)
PanicAlert("DSPHLE: Unknown ucode (CRC = %08x) - forcing AX.\n\nTry LLE emulator if this is homebrew.", _CRC);
return new CUCode_AX(dsp_hle, _CRC);
}
case UCODE_NULL:
break;
}
return NULL;

View File

@@ -25,8 +25,9 @@
#include "../DSPHLE.h"
#include "../../Memmap.h"
#define UCODE_ROM 0x0000000
#define UCODE_INIT_AUDIO_SYSTEM 0x0000001
#define UCODE_ROM 0x00000000
#define UCODE_INIT_AUDIO_SYSTEM 0x00000001
#define UCODE_NULL 0xFFFFFFFF
class CMailHandler;
@@ -73,10 +74,11 @@ inline void* HLEMemory_Get_Pointer(u32 _uAddress)
class IUCode
{
public:
IUCode(DSPHLE *dsphle)
IUCode(DSPHLE *dsphle, u32 _crc)
: m_rMailHandler(dsphle->AccessMailHandler())
, m_UploadSetupInProgress(false)
, m_DSPHLE(dsphle)
, m_CRC(_crc)
, m_NextUCode()
, m_NextUCode_steps(0)
, m_NeedsResumeMail(false)
@@ -93,6 +95,8 @@ public:
virtual void DoState(PointerWrap &p) {}
static u32 GetCRC(IUCode* pUCode) { return pUCode ? pUCode->m_CRC : UCODE_NULL; }
protected:
void PrepareBootUCode(u32 mail);
@@ -121,6 +125,10 @@ protected:
// Need a pointer back to DSPHLE to switch ucodes.
DSPHLE *m_DSPHLE;
// used for reconstruction when loading saves,
// and for variations within certain ucodes.
u32 m_CRC;
private:
struct SUCode
{

View File

@@ -49,6 +49,9 @@ DSPLLE::DSPLLE() {
m_cycle_count = 0;
}
Common::Event dspEvent;
Common::Event ppcEvent;
void DSPLLE::DoState(PointerWrap &p)
{
p.Do(g_dsp.r);
@@ -96,7 +99,10 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle)
Common::AtomicStore(dsp_lle->m_cycle_count, 0);
}
else
Common::YieldCPU();
{
ppcEvent.Set();
dspEvent.Wait();
}
}
}
@@ -138,6 +144,8 @@ void DSPLLE::DSP_StopSoundStream()
m_bIsRunning = false;
if (m_bDSPThread)
{
ppcEvent.Set();
dspEvent.Set();
m_hDSPThread.join();
}
}
@@ -274,9 +282,10 @@ void DSPLLE::DSP_Update(int cycles)
else
{
// Wait for dsp thread to complete its cycle. Note: this logic should be thought through.
while (m_cycle_count != 0)
;
ppcEvent.Wait();
Common::AtomicStore(m_cycle_count, dsp_cycles);
dspEvent.Set();
}
}

View File

@@ -522,7 +522,7 @@ void GenerateDIInterrupt(DI_InterruptType _DVDInterrupt)
void ExecuteCommand(UDICR& _DICR)
{
// _dbg_assert_(DVDINTERFACE, _DICR.RW == 0); // only DVD to Memory
int GCAM = ((SConfig::GetInstance().m_SIDevice[0] == SI_AM_BASEBOARD)
int GCAM = ((SConfig::GetInstance().m_SIDevice[0] == SIDEVICE_AM_BASEBOARD)
&& (SConfig::GetInstance().m_EXIDevice[2] == EXIDEVICE_AM_BASEBOARD))
? 1 : 0;

View File

@@ -64,29 +64,31 @@ void Shutdown()
void DoState(PointerWrap &p)
{
// TODO: Complete DoState for each IEXIDevice
g_Channels[0]->GetDevice(1)->DoState(p);
g_Channels[0]->GetDevice(2)->DoState(p);
g_Channels[0]->GetDevice(4)->DoState(p);
g_Channels[1]->GetDevice(1)->DoState(p);
g_Channels[2]->GetDevice(1)->DoState(p);
for (int c = 0; c < NUM_CHANNELS; ++c)
g_Channels[c]->DoState(p);
}
void OnAfterLoad()
{
for (int c = 0; c < NUM_CHANNELS; ++c)
g_Channels[c]->OnAfterLoad();
}
void ChangeDeviceCallback(u64 userdata, int cyclesLate)
{
u8 channel = (u8)(userdata >> 32);
u8 device = (u8)(userdata >> 16);
u8 slot = (u8)userdata;
u8 type = (u8)(userdata >> 16);
u8 num = (u8)userdata;
g_Channels[channel]->AddDevice((TEXIDevices)device, slot);
g_Channels[channel]->AddDevice((TEXIDevices)type, num);
}
void ChangeDevice(u8 channel, TEXIDevices device, u8 slot)
void ChangeDevice(const u8 channel, const TEXIDevices device_type, const u8 device_num)
{
// Called from GUI, so we need to make it thread safe.
// Let the hardware see no device for .5b cycles
CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | ((u64)EXIDEVICE_NONE << 16) | slot);
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | ((u64)device << 16) | slot);
CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | ((u64)EXIDEVICE_NONE << 16) | device_num);
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDevice, ((u64)channel << 32) | ((u64)device_type << 16) | device_num);
}
// Unused (?!)

View File

@@ -28,12 +28,13 @@ namespace ExpansionInterface
void Init();
void Shutdown();
void DoState(PointerWrap &p);
void OnAfterLoad();
void Update();
void UpdateInterrupts();
void ChangeDeviceCallback(u64 userdata, int cyclesLate);
void ChangeDevice(u8 channel, TEXIDevices device, u8 slot);
void ChangeDevice(const u8 channel, const TEXIDevices device_type, const u8 device_num);
void Read32(u32& _uReturnValue, const u32 _iAddress);
void Write32(const u32 _iValue, const u32 _iAddress);

View File

@@ -18,6 +18,8 @@
#include "EXI_Channel.h"
#include "EXI_Device.h"
#include "EXI.h"
#include "../ConfigManager.h"
#include "../Movie.h"
#define EXI_READ 0
#define EXI_WRITE 1
@@ -42,7 +44,7 @@ CEXIChannel::CEXIChannel(u32 ChannelId) :
m_Status.CHIP_SELECT = 1;
for (int i = 0; i < NUM_DEVICES; i++)
m_pDevices[i] = EXIDevice_Create(EXIDEVICE_NONE);
m_pDevices[i] = EXIDevice_Create(EXIDEVICE_NONE, m_ChannelId);
}
CEXIChannel::~CEXIChannel()
@@ -59,26 +61,35 @@ void CEXIChannel::RemoveDevices()
}
}
void CEXIChannel::AddDevice(const TEXIDevices _device, const unsigned int _iSlot)
void CEXIChannel::AddDevice(const TEXIDevices device_type, const int device_num)
{
_dbg_assert_(EXPANSIONINTERFACE, _iSlot < NUM_DEVICES);
IEXIDevice* pNewDevice = EXIDevice_Create(device_type, m_ChannelId);
AddDevice(pNewDevice, device_num);
}
void CEXIChannel::AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged)
{
_dbg_assert_(EXPANSIONINTERFACE, device_num < NUM_DEVICES);
// delete the old device
if (m_pDevices[_iSlot] != NULL)
if (m_pDevices[device_num] != NULL)
{
delete m_pDevices[_iSlot];
m_pDevices[_iSlot] = NULL;
delete m_pDevices[device_num];
m_pDevices[device_num] = NULL;
}
// create the new one
m_pDevices[_iSlot] = EXIDevice_Create(_device);
// replace it with the new one
m_pDevices[device_num] = pDevice;
// This means "device presence changed", software has to check
// m_Status.EXT to see if it is now present or not
if (m_ChannelId != 2)
if(notifyPresenceChanged)
{
m_Status.EXTINT = 1;
UpdateInterrupts();
// This means "device presence changed", software has to check
// m_Status.EXT to see if it is now present or not
if (m_ChannelId != 2)
{
m_Status.EXTINT = 1;
UpdateInterrupts();
}
}
}
@@ -107,9 +118,9 @@ bool CEXIChannel::IsCausingInterrupt()
}
}
IEXIDevice* CEXIChannel::GetDevice(u8 _CHIP_SELECT)
IEXIDevice* CEXIChannel::GetDevice(const u8 chip_select)
{
switch(_CHIP_SELECT)
switch (chip_select)
{
case 1: return m_pDevices[0];
case 2: return m_pDevices[1];
@@ -264,3 +275,43 @@ void CEXIChannel::Write32(const u32 _iValue, const u32 _iRegister)
break;
}
}
void CEXIChannel::DoState(PointerWrap &p)
{
p.Do(m_Status);
p.Do(m_DMAMemoryAddress);
p.Do(m_DMALength);
p.Do(m_Control);
p.Do(m_ImmData);
for (int d = 0; d < NUM_DEVICES; ++d)
{
IEXIDevice* pDevice = m_pDevices[d];
TEXIDevices type = pDevice->m_deviceType;
p.Do(type);
IEXIDevice* pSaveDevice = (type == pDevice->m_deviceType) ? pDevice : EXIDevice_Create(type, m_ChannelId);
pSaveDevice->DoState(p);
if(pSaveDevice != pDevice)
{
// if we had to create a temporary device, discard it if we're not loading.
// also, if no movie is active, we'll assume the user wants to keep their current devices
// instead of the ones they had when the savestate was created,
// unless the device is NONE (since ChangeDevice sets that temporarily).
if(p.GetMode() != PointerWrap::MODE_READ)
{
delete pSaveDevice;
}
else
{
AddDevice(pSaveDevice, d, false);
}
}
}
}
void CEXIChannel::OnAfterLoad()
{
for (int d = 0; d < NUM_DEVICES; ++d)
m_pDevices[d]->OnAfterLoad();
}

View File

@@ -112,12 +112,13 @@ private:
public:
// get device
IEXIDevice* GetDevice(u8 _CHIP_SELECT);
IEXIDevice* GetDevice(const u8 _CHIP_SELECT);
CEXIChannel(u32 ChannelId);
~CEXIChannel();
void AddDevice(const TEXIDevices _device, const unsigned int _iSlot);
void AddDevice(const TEXIDevices device_type, const int device_num);
void AddDevice(IEXIDevice* pDevice, const int device_num, bool notifyPresenceChanged=true);
// Remove all devices
void RemoveDevices();
@@ -128,6 +129,8 @@ public:
void Update();
bool IsCausingInterrupt();
void UpdateInterrupts();
void DoState(PointerWrap &p);
void OnAfterLoad();
// This should only be used to transition interrupts from SP1 to Channel 2
void SetEXIINT(bool exiint) { m_Status.EXIINT = !!exiint; }

Some files were not shown because too many files have changed in this diff Show More