Merge branch 'master' into real-wiimote-scanning
Conflicts: Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp
This commit is contained in:
@@ -191,7 +191,6 @@
|
||||
<ClCompile Include="Src\aldlist.cpp" />
|
||||
<ClCompile Include="Src\AOSoundStream.cpp" />
|
||||
<ClCompile Include="Src\AudioCommon.cpp" />
|
||||
<ClCompile Include="Src\AudioCommonConfig.cpp" />
|
||||
<ClCompile Include="Src\DPL2Decoder.cpp" />
|
||||
<ClCompile Include="Src\DSoundStream.cpp" />
|
||||
<ClCompile Include="Src\Mixer.cpp" />
|
||||
@@ -204,7 +203,6 @@
|
||||
<ClInclude Include="Src\aldlist.h" />
|
||||
<ClInclude Include="Src\AOSoundStream.h" />
|
||||
<ClInclude Include="Src\AudioCommon.h" />
|
||||
<ClInclude Include="Src\AudioCommonConfig.h" />
|
||||
<ClInclude Include="Src\DPL2Decoder.h" />
|
||||
<ClInclude Include="Src\DSoundStream.h" />
|
||||
<ClInclude Include="Src\Mixer.h" />
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Src\aldlist.cpp" />
|
||||
<ClCompile Include="Src\AudioCommon.cpp" />
|
||||
<ClCompile Include="Src\AudioCommonConfig.cpp" />
|
||||
<ClCompile Include="Src\Mixer.cpp" />
|
||||
<ClCompile Include="Src\WaveFile.cpp" />
|
||||
<ClCompile Include="Src\AOSoundStream.cpp">
|
||||
@@ -26,7 +25,6 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Src\aldlist.h" />
|
||||
<ClInclude Include="Src\AudioCommon.h" />
|
||||
<ClInclude Include="Src\AudioCommonConfig.h" />
|
||||
<ClInclude Include="Src\Mixer.h" />
|
||||
<ClInclude Include="Src\SoundStream.h" />
|
||||
<ClInclude Include="Src\WaveFile.h" />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
set(SRCS Src/AudioCommon.cpp
|
||||
Src/AudioCommonConfig.cpp
|
||||
Src/DPL2Decoder.cpp
|
||||
Src/Mixer.cpp
|
||||
Src/WaveFile.cpp
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
#include "OpenALStream.h"
|
||||
#include "PulseAudioStream.h"
|
||||
#include "../../Core/Src/Movie.h"
|
||||
#include "../../Core/Src/ConfigManager.h"
|
||||
|
||||
// This shouldn't be a global, at least not here.
|
||||
SoundStream *soundStream;
|
||||
|
||||
namespace AudioCommon
|
||||
{
|
||||
@@ -34,7 +38,7 @@ namespace AudioCommon
|
||||
{
|
||||
// TODO: possible memleak with mixer
|
||||
|
||||
std::string backend = ac_Config.sBackend;
|
||||
std::string backend = SConfig::GetInstance().sBackend;
|
||||
if (backend == BACKEND_OPENAL && OpenALStream::isValid())
|
||||
soundStream = new OpenALStream(mixer);
|
||||
else if (backend == BACKEND_NULLSOUND && NullSound::isValid())
|
||||
@@ -54,10 +58,10 @@ namespace AudioCommon
|
||||
|
||||
if (soundStream != NULL)
|
||||
{
|
||||
ac_Config.Update();
|
||||
UpdateSoundStream();
|
||||
if (soundStream->Start())
|
||||
{
|
||||
if (ac_Config.m_DumpAudio)
|
||||
if (SConfig::GetInstance().m_DumpAudio)
|
||||
{
|
||||
std::string audio_file_name = File::GetUserPath(D_DUMPAUDIO_IDX) + "audiodump.wav";
|
||||
File::CreateFullPath(audio_file_name);
|
||||
@@ -82,7 +86,7 @@ namespace AudioCommon
|
||||
if (soundStream)
|
||||
{
|
||||
soundStream->Stop();
|
||||
if (ac_Config.m_DumpAudio)
|
||||
if (SConfig::GetInstance().m_DumpAudio)
|
||||
soundStream->GetMixer()->StopLogAudio();
|
||||
//soundStream->StopLogAudio();
|
||||
delete soundStream;
|
||||
@@ -122,7 +126,7 @@ namespace AudioCommon
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return ac_Config.m_EnableJIT;
|
||||
return SConfig::GetInstance().m_EnableJIT;
|
||||
}
|
||||
|
||||
void PauseAndLock(bool doLock, bool unpauseOnUnlock)
|
||||
@@ -143,4 +147,12 @@ namespace AudioCommon
|
||||
}
|
||||
}
|
||||
}
|
||||
void UpdateSoundStream()
|
||||
{
|
||||
if (soundStream)
|
||||
{
|
||||
soundStream->GetMixer()->SetThrottle(SConfig::GetInstance().m_Framelimit == 2);
|
||||
soundStream->SetVolume(SConfig::GetInstance().m_Volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,12 @@
|
||||
#define _AUDIO_COMMON_H_
|
||||
|
||||
#include "Common.h"
|
||||
#include "AudioCommonConfig.h"
|
||||
#include "SoundStream.h"
|
||||
|
||||
|
||||
class CMixer;
|
||||
|
||||
extern SoundStream *soundStream;
|
||||
extern AudioCommonConfig ac_Config;
|
||||
|
||||
// UDSPControl
|
||||
union UDSPControl
|
||||
@@ -60,6 +58,7 @@ namespace AudioCommon
|
||||
std::vector<std::string> GetSoundBackends();
|
||||
bool UseJIT();
|
||||
void PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
|
||||
void UpdateSoundStream();
|
||||
}
|
||||
|
||||
#endif // _AUDIO_COMMON_H_
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
// 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/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include "AudioCommon.h"
|
||||
#include "CommonPaths.h"
|
||||
#include "FileUtil.h"
|
||||
#include "../../Core/Src/ConfigManager.h"
|
||||
|
||||
AudioCommonConfig ac_Config;
|
||||
|
||||
// This shouldn't be a global, at least not here.
|
||||
SoundStream *soundStream;
|
||||
|
||||
// Load from given file
|
||||
void AudioCommonConfig::Load()
|
||||
{
|
||||
IniFile file;
|
||||
file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
|
||||
|
||||
file.Get("Config", "EnableJIT", &m_EnableJIT, true);
|
||||
file.Get("Config", "DumpAudio", &m_DumpAudio, false);
|
||||
#if defined __linux__ && HAVE_ALSA
|
||||
file.Get("Config", "Backend", &sBackend, BACKEND_ALSA);
|
||||
#elif defined __APPLE__
|
||||
file.Get("Config", "Backend", &sBackend, BACKEND_COREAUDIO);
|
||||
#elif defined _WIN32
|
||||
file.Get("Config", "Backend", &sBackend, BACKEND_DIRECTSOUND);
|
||||
#else
|
||||
file.Get("Config", "Backend", &sBackend, BACKEND_NULLSOUND);
|
||||
#endif
|
||||
file.Get("Config", "Volume", &m_Volume, 100);
|
||||
}
|
||||
|
||||
// Set the values for the file
|
||||
void AudioCommonConfig::SaveSettings()
|
||||
{
|
||||
IniFile file;
|
||||
file.Load(File::GetUserPath(F_DSPCONFIG_IDX));
|
||||
|
||||
file.Set("Config", "EnableJIT", m_EnableJIT);
|
||||
file.Set("Config", "DumpAudio", m_DumpAudio);
|
||||
file.Set("Config", "Backend", sBackend);
|
||||
file.Set("Config", "Volume", m_Volume);
|
||||
|
||||
file.Save(File::GetUserPath(F_DSPCONFIG_IDX));
|
||||
}
|
||||
|
||||
// Update according to the values (stream/mixer)
|
||||
void AudioCommonConfig::Update() {
|
||||
if (soundStream) {
|
||||
soundStream->GetMixer()->SetThrottle(SConfig::GetInstance().m_Framelimit == 2);
|
||||
soundStream->SetVolume(m_Volume);
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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/
|
||||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#ifndef _AUDIO_COMMON_CONFIG_H_
|
||||
#define _AUDIO_COMMON_CONFIG_H_
|
||||
|
||||
#include <string>
|
||||
#include "IniFile.h"
|
||||
|
||||
// Backend Types
|
||||
#define BACKEND_NULLSOUND "No audio output"
|
||||
#define BACKEND_ALSA "ALSA"
|
||||
#define BACKEND_AOSOUND "AOSound"
|
||||
#define BACKEND_COREAUDIO "CoreAudio"
|
||||
#define BACKEND_DIRECTSOUND "DSound"
|
||||
#define BACKEND_OPENAL "OpenAL"
|
||||
#define BACKEND_PULSEAUDIO "Pulse"
|
||||
#define BACKEND_XAUDIO2 "XAudio2"
|
||||
|
||||
struct AudioCommonConfig
|
||||
{
|
||||
bool m_EnableJIT;
|
||||
bool m_DumpAudio;
|
||||
int m_Volume;
|
||||
std::string sBackend;
|
||||
|
||||
// Load from given file
|
||||
void Load();
|
||||
|
||||
// Self explanatory
|
||||
void SaveSettings();
|
||||
|
||||
// Update according to the values (stream/mixer)
|
||||
void Update();
|
||||
};
|
||||
|
||||
#endif //AUDIO_COMMON_CONFIG
|
||||
@@ -232,70 +232,70 @@ float passive_lock(float x)
|
||||
|
||||
void matrix_decode(const float *in, const int k, const int il,
|
||||
const int ir, bool decode_rear,
|
||||
const int dlbuflen,
|
||||
float l_fwr, float r_fwr,
|
||||
float lpr_fwr, float lmr_fwr,
|
||||
float *adapt_l_gain, float *adapt_r_gain,
|
||||
float *adapt_lpr_gain, float *adapt_lmr_gain,
|
||||
float *lf, float *rf, float *lr,
|
||||
float *rr, float *cf)
|
||||
const int _dlbuflen,
|
||||
float _l_fwr, float _r_fwr,
|
||||
float _lpr_fwr, float _lmr_fwr,
|
||||
float *_adapt_l_gain, float *_adapt_r_gain,
|
||||
float *_adapt_lpr_gain, float *_adapt_lmr_gain,
|
||||
float *_lf, float *_rf, float *_lr,
|
||||
float *_rr, float *_cf)
|
||||
{
|
||||
static const float M9_03DB = 0.3535533906f;
|
||||
static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
|
||||
static const float MATAGCDECAY = 1.0f; /* AGC baseline decay rate (1/samp.) */
|
||||
static const float MATCOMPGAIN = 0.37f; /* Cross talk compensation gain, 0.50 - 0.55 is full cancellation. */
|
||||
|
||||
const int kr = (k + olddelay) % dlbuflen;
|
||||
float l_gain = (l_fwr + r_fwr) / (1 + l_fwr + l_fwr);
|
||||
float r_gain = (l_fwr + r_fwr) / (1 + r_fwr + r_fwr);
|
||||
const int kr = (k + olddelay) % _dlbuflen;
|
||||
float l_gain = (_l_fwr + _r_fwr) / (1 + _l_fwr + _l_fwr);
|
||||
float r_gain = (_l_fwr + _r_fwr) / (1 + _r_fwr + _r_fwr);
|
||||
/* The 2nd axis has strong gain fluctuations, and therefore require
|
||||
limits. The factor corresponds to the 1 / amplification of (Lt
|
||||
- Rt) when (Lt, Rt) is strongly correlated. (e.g. during
|
||||
dialogues). It should be bigger than -12 dB to prevent
|
||||
distortion. */
|
||||
float lmr_lim_fwr = lmr_fwr > M9_03DB * lpr_fwr ? lmr_fwr : M9_03DB * lpr_fwr;
|
||||
float lpr_gain = (lpr_fwr + lmr_lim_fwr) / (1 + lpr_fwr + lpr_fwr);
|
||||
float lmr_gain = (lpr_fwr + lmr_lim_fwr) / (1 + lmr_lim_fwr + lmr_lim_fwr);
|
||||
float lmr_unlim_gain = (lpr_fwr + lmr_fwr) / (1 + lmr_fwr + lmr_fwr);
|
||||
float lmr_lim_fwr = _lmr_fwr > M9_03DB * _lpr_fwr ? _lmr_fwr : M9_03DB * _lpr_fwr;
|
||||
float lpr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + _lpr_fwr + _lpr_fwr);
|
||||
float lmr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + lmr_lim_fwr + lmr_lim_fwr);
|
||||
float lmr_unlim_gain = (_lpr_fwr + _lmr_fwr) / (1 + _lmr_fwr + _lmr_fwr);
|
||||
float lpr, lmr;
|
||||
float l_agc, r_agc, lpr_agc, lmr_agc;
|
||||
float f, d_gain, c_gain, c_agc_cfk;
|
||||
|
||||
/*** AXIS NO. 1: (Lt, Rt) -> (C, Ls, Rs) ***/
|
||||
/* AGC adaption */
|
||||
d_gain = (fabs(l_gain - *adapt_l_gain) + fabs(r_gain - *adapt_r_gain)) * 0.5f;
|
||||
d_gain = (fabs(l_gain - *_adapt_l_gain) + fabs(r_gain - *_adapt_r_gain)) * 0.5f;
|
||||
f = d_gain * (1.0f / MATAGCTRIG);
|
||||
f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
|
||||
*adapt_l_gain = (1 - f) * *adapt_l_gain + f * l_gain;
|
||||
*adapt_r_gain = (1 - f) * *adapt_r_gain + f * r_gain;
|
||||
*_adapt_l_gain = (1 - f) * *_adapt_l_gain + f * l_gain;
|
||||
*_adapt_r_gain = (1 - f) * *_adapt_r_gain + f * r_gain;
|
||||
/* Matrix */
|
||||
l_agc = in[il] * passive_lock(*adapt_l_gain);
|
||||
r_agc = in[ir] * passive_lock(*adapt_r_gain);
|
||||
cf[k] = (l_agc + r_agc) * (float)M_SQRT1_2;
|
||||
l_agc = in[il] * passive_lock(*_adapt_l_gain);
|
||||
r_agc = in[ir] * passive_lock(*_adapt_r_gain);
|
||||
_cf[k] = (l_agc + r_agc) * (float)M_SQRT1_2;
|
||||
if (decode_rear)
|
||||
{
|
||||
lr[kr] = rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2;
|
||||
_lr[kr] = _rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2;
|
||||
/* Stereo rear channel is steered with the same AGC steering as
|
||||
the decoding matrix. Note this requires a fast updating AGC
|
||||
at the order of 20 ms (which is the case here). */
|
||||
lr[kr] *= (l_fwr + l_fwr) / (1 + l_fwr + r_fwr);
|
||||
rr[kr] *= (r_fwr + r_fwr) / (1 + l_fwr + r_fwr);
|
||||
_lr[kr] *= (_l_fwr + _l_fwr) / (1 + _l_fwr + _r_fwr);
|
||||
_rr[kr] *= (_r_fwr + _r_fwr) / (1 + _l_fwr + _r_fwr);
|
||||
}
|
||||
|
||||
/*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/
|
||||
lpr = (in[il] + in[ir]) * (float)M_SQRT1_2;
|
||||
lmr = (in[il] - in[ir]) * (float)M_SQRT1_2;
|
||||
/* AGC adaption */
|
||||
d_gain = fabs(lmr_unlim_gain - *adapt_lmr_gain);
|
||||
d_gain = fabs(lmr_unlim_gain - *_adapt_lmr_gain);
|
||||
f = d_gain * (1.0f / MATAGCTRIG);
|
||||
f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
|
||||
*adapt_lpr_gain = (1 - f) * *adapt_lpr_gain + f * lpr_gain;
|
||||
*adapt_lmr_gain = (1 - f) * *adapt_lmr_gain + f * lmr_gain;
|
||||
*_adapt_lpr_gain = (1 - f) * *_adapt_lpr_gain + f * lpr_gain;
|
||||
*_adapt_lmr_gain = (1 - f) * *_adapt_lmr_gain + f * lmr_gain;
|
||||
/* Matrix */
|
||||
lpr_agc = lpr * passive_lock(*adapt_lpr_gain);
|
||||
lmr_agc = lmr * passive_lock(*adapt_lmr_gain);
|
||||
lf[k] = (lpr_agc + lmr_agc) * (float)M_SQRT1_2;
|
||||
rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2;
|
||||
lpr_agc = lpr * passive_lock(*_adapt_lpr_gain);
|
||||
lmr_agc = lmr * passive_lock(*_adapt_lmr_gain);
|
||||
_lf[k] = (lpr_agc + lmr_agc) * (float)M_SQRT1_2;
|
||||
_rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2;
|
||||
|
||||
/*** CENTER FRONT CANCELLATION ***/
|
||||
/* A heuristic approach exploits that Lt + Rt gain contains the
|
||||
@@ -303,16 +303,16 @@ void matrix_decode(const float *in, const int k, const int il,
|
||||
the front and rear "cones" to concentrate Lt + Rt to C and
|
||||
introduce Lt - Rt in L, R. */
|
||||
/* 0.67677 is the empirical lower bound for lpr_gain. */
|
||||
c_gain = 8 * (*adapt_lpr_gain - 0.67677f);
|
||||
c_gain = 8 * (*_adapt_lpr_gain - 0.67677f);
|
||||
c_gain = c_gain > 0 ? c_gain : 0;
|
||||
/* c_gain should not be too high, not even reaching full
|
||||
cancellation (~ 0.50 - 0.55 at current AGC implementation), or
|
||||
the center will sound too narrow. */
|
||||
c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
|
||||
c_agc_cfk = c_gain * cf[k];
|
||||
lf[k] -= c_agc_cfk;
|
||||
rf[k] -= c_agc_cfk;
|
||||
cf[k] += c_agc_cfk + c_agc_cfk;
|
||||
c_agc_cfk = c_gain * _cf[k];
|
||||
_lf[k] -= c_agc_cfk;
|
||||
_rf[k] -= c_agc_cfk;
|
||||
_cf[k] += c_agc_cfk + c_agc_cfk;
|
||||
}
|
||||
|
||||
void dpl2decode(float *samples, int numsamples, float *out)
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
|
||||
std::mutex& MixerCritical() { return m_csMixing; }
|
||||
|
||||
volatile float GetCurrentSpeed() const { return m_speed; }
|
||||
float GetCurrentSpeed() const { return m_speed; }
|
||||
void UpdateSpeed(volatile float val) { m_speed = val; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -316,7 +316,7 @@ void OpenALStream::SoundLoop()
|
||||
if (iBuffersFilled == numBuffers)
|
||||
{
|
||||
alSourcePlay(uiSource);
|
||||
ALenum err = alGetError();
|
||||
err = alGetError();
|
||||
if (err != 0)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Error occurred during playback: %08x", err);
|
||||
@@ -328,7 +328,7 @@ void OpenALStream::SoundLoop()
|
||||
{
|
||||
// Buffer underrun occurred, resume playback
|
||||
alSourcePlay(uiSource);
|
||||
ALenum err = alGetError();
|
||||
err = alGetError();
|
||||
if (err != 0)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Error occurred resuming playback: %08x", err);
|
||||
|
||||
@@ -146,7 +146,7 @@ ALDeviceList::~ALDeviceList()
|
||||
{
|
||||
for (u32 i = 0; i < vDeviceInfo.size(); i++) {
|
||||
if (vDeviceInfo[i].pvstrExtensions) {
|
||||
vDeviceInfo[i].pvstrExtensions->empty();
|
||||
vDeviceInfo[i].pvstrExtensions->clear();
|
||||
delete vDeviceInfo[i].pvstrExtensions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,11 +89,11 @@
|
||||
#define MAIL_LOGS_DIR LOGS_DIR DIR_SEP "Mail"
|
||||
#define SHADERS_DIR "Shaders"
|
||||
#define WII_SYSCONF_DIR "shared2" DIR_SEP "sys"
|
||||
#define THEMES_DIR "Themes"
|
||||
|
||||
// Filenames
|
||||
// Files in the directory returned by GetUserPath(D_CONFIG_IDX)
|
||||
#define DOLPHIN_CONFIG "Dolphin.ini"
|
||||
#define DSP_CONFIG "DSP.ini"
|
||||
#define DEBUGGER_CONFIG "Debugger.ini"
|
||||
#define LOGGER_CONFIG "Logger.ini"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "FileSearch.h"
|
||||
|
||||
@@ -72,36 +73,36 @@ void CFileSearch::FindFiles(const std::string& _searchString, const std::string&
|
||||
|
||||
|
||||
#else
|
||||
size_t dot_pos = _searchString.rfind(".");
|
||||
// TODO: super lame/broken
|
||||
|
||||
if (dot_pos == std::string::npos)
|
||||
return;
|
||||
auto end_match(_searchString);
|
||||
|
||||
// assuming we have a "*.blah"-like pattern
|
||||
if (!end_match.empty() && end_match[0] == '*')
|
||||
end_match.erase(0, 1);
|
||||
|
||||
// ugly
|
||||
if (end_match == ".*")
|
||||
end_match.clear();
|
||||
|
||||
std::string ext = _searchString.substr(dot_pos);
|
||||
DIR* dir = opendir(_strPath.c_str());
|
||||
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
dirent* dp;
|
||||
|
||||
while (true)
|
||||
while (auto const dp = readdir(dir))
|
||||
{
|
||||
dp = readdir(dir);
|
||||
std::string found(dp->d_name);
|
||||
|
||||
if (!dp)
|
||||
break;
|
||||
|
||||
std::string s(dp->d_name);
|
||||
|
||||
if ( (!ext.compare(".*") && s.compare(".") && s.compare("..")) ||
|
||||
((s.size() > ext.size()) && (!strcasecmp(s.substr(s.size() - ext.size()).c_str(), ext.c_str())) ))
|
||||
if ((found != ".") && (found != "..")
|
||||
&& (found.size() >= end_match.size())
|
||||
&& std::equal(end_match.rbegin(), end_match.rend(), found.rbegin()))
|
||||
{
|
||||
std::string full_name;
|
||||
if (_strPath.c_str()[_strPath.size()-1] == DIR_SEP_CHR)
|
||||
full_name = _strPath + s;
|
||||
full_name = _strPath + found;
|
||||
else
|
||||
full_name = _strPath + DIR_SEP + s;
|
||||
full_name = _strPath + DIR_SEP + found;
|
||||
|
||||
m_FileNames.push_back(full_name);
|
||||
}
|
||||
|
||||
@@ -512,12 +512,24 @@ bool DeleteDirRecursively(const std::string &directory)
|
||||
if (IsDirectory(newPath))
|
||||
{
|
||||
if (!DeleteDirRecursively(newPath))
|
||||
{
|
||||
#ifndef _WIN32
|
||||
closedir(dirp);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!File::Delete(newPath))
|
||||
{
|
||||
#ifndef _WIN32
|
||||
closedir(dirp);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -678,9 +690,9 @@ std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath)
|
||||
paths[D_DUMPDSP_IDX] = paths[D_USER_IDX] + DUMP_DSP_DIR DIR_SEP;
|
||||
paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP;
|
||||
paths[D_MAILLOGS_IDX] = paths[D_USER_IDX] + MAIL_LOGS_DIR DIR_SEP;
|
||||
paths[D_THEMES_IDX] = paths[D_USER_IDX] + THEMES_DIR DIR_SEP;
|
||||
paths[D_WIISYSCONF_IDX] = paths[D_WIIUSER_IDX] + WII_SYSCONF_DIR DIR_SEP;
|
||||
paths[F_DOLPHINCONFIG_IDX] = paths[D_CONFIG_IDX] + DOLPHIN_CONFIG;
|
||||
paths[F_DSPCONFIG_IDX] = paths[D_CONFIG_IDX] + DSP_CONFIG;
|
||||
paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
|
||||
paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG;
|
||||
paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG;
|
||||
|
||||
@@ -50,8 +50,8 @@ enum {
|
||||
D_LOGS_IDX,
|
||||
D_MAILLOGS_IDX,
|
||||
D_WIISYSCONF_IDX,
|
||||
D_THEMES_IDX,
|
||||
F_DOLPHINCONFIG_IDX,
|
||||
F_DSPCONFIG_IDX,
|
||||
F_DEBUGGERCONFIG_IDX,
|
||||
F_LOGGERCONFIG_IDX,
|
||||
F_MAINLOG_IDX,
|
||||
|
||||
@@ -43,7 +43,8 @@ void MemArena::GrabLowMemSpace(size_t size)
|
||||
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
fd = open(ram_temp_file, O_RDWR | O_CREAT, mode);
|
||||
unlink(ram_temp_file);
|
||||
ftruncate(fd, size);
|
||||
if (ftruncate(fd, size) < 0)
|
||||
ERROR_LOG(MEMMAP, "Failed to allocate low memory space");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -117,7 +117,8 @@ void* AllocateAlignedMemory(size_t size,size_t alignment)
|
||||
void* ptr = _aligned_malloc(size,alignment);
|
||||
#else
|
||||
void* ptr = NULL;
|
||||
posix_memalign(&ptr, alignment, size);
|
||||
if (posix_memalign(&ptr, alignment, size) != 0)
|
||||
ERROR_LOG(MEMMAP, "Failed to allocate aligned memory");
|
||||
;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -69,7 +69,8 @@ std::string StringFromFormat(const char* format, ...)
|
||||
delete[] buf;
|
||||
#else
|
||||
va_start(args, format);
|
||||
vasprintf(&buf, format, args);
|
||||
if (vasprintf(&buf, format, args) < 0)
|
||||
ERROR_LOG(COMMON, "Unable to allocate memory for string");
|
||||
va_end(args);
|
||||
|
||||
std::string temp = buf;
|
||||
|
||||
@@ -257,6 +257,19 @@ bool CBoot::BootUp()
|
||||
EmulatedBS2(_StartupPara.bWii);
|
||||
}
|
||||
|
||||
// Scan for common HLE functions
|
||||
if (_StartupPara.bSkipIdle && !_StartupPara.bEnableDebugging)
|
||||
{
|
||||
PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
|
||||
SignatureDB db;
|
||||
if (db.Load((File::GetSysDirectory() + TOTALDB).c_str()))
|
||||
{
|
||||
db.Apply(&g_symbolDB);
|
||||
HLE::PatchFunctions();
|
||||
db.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to load the symbol map if there is one, and then scan it for
|
||||
and eventually replace code */
|
||||
if (LoadMapFromFilename(_StartupPara.m_strFilename, gameID))
|
||||
|
||||
@@ -375,7 +375,7 @@ bool CBoot::EmulatedBS2_Wii()
|
||||
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
|
||||
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;
|
||||
|
||||
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffse: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
|
||||
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
|
||||
} while(PowerPC::ppcState.gpr[3] != 0x00);
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ namespace BootManager
|
||||
// Apply fire liberally
|
||||
struct ConfigCache
|
||||
{
|
||||
bool valid, bCPUThread, bSkipIdle, bEnableFPRF, bMMU, bMMUBAT,
|
||||
bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bDisableWiimoteSpeaker;
|
||||
int iTLBHack;
|
||||
bool valid, bCPUThread, bSkipIdle, bEnableFPRF, bMMU, bDCBZOFF,
|
||||
bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bHLE_BS2;
|
||||
int iTLBHack, iCPUCore;
|
||||
std::string strBackend;
|
||||
};
|
||||
static ConfigCache config_cache;
|
||||
@@ -89,30 +89,32 @@ bool BootCore(const std::string& _rFilename)
|
||||
config_cache.valid = true;
|
||||
config_cache.bCPUThread = StartUp.bCPUThread;
|
||||
config_cache.bSkipIdle = StartUp.bSkipIdle;
|
||||
config_cache.iCPUCore = StartUp.iCPUCore;
|
||||
config_cache.bEnableFPRF = StartUp.bEnableFPRF;
|
||||
config_cache.bMMU = StartUp.bMMU;
|
||||
config_cache.bMMUBAT = StartUp.bMMUBAT;
|
||||
config_cache.bDCBZOFF = StartUp.bDCBZOFF;
|
||||
config_cache.iTLBHack = StartUp.iTLBHack;
|
||||
config_cache.bVBeam = StartUp.bVBeam;
|
||||
config_cache.bFastDiscSpeed = StartUp.bFastDiscSpeed;
|
||||
config_cache.bMergeBlocks = StartUp.bMergeBlocks;
|
||||
config_cache.bDSPHLE = StartUp.bDSPHLE;
|
||||
config_cache.bDisableWiimoteSpeaker = StartUp.bDisableWiimoteSpeaker;
|
||||
config_cache.strBackend = StartUp.m_strVideoBackend;
|
||||
config_cache.bHLE_BS2 = StartUp.bHLE_BS2;
|
||||
|
||||
// General settings
|
||||
game_ini.Get("Core", "CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread);
|
||||
game_ini.Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
|
||||
game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF);
|
||||
game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU);
|
||||
game_ini.Get("Core", "BAT", &StartUp.bMMUBAT, StartUp.bMMUBAT);
|
||||
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
||||
game_ini.Get("Core", "DCBZ", &StartUp.bDCBZOFF, StartUp.bDCBZOFF);
|
||||
game_ini.Get("Core", "VBeam", &StartUp.bVBeam, StartUp.bVBeam);
|
||||
game_ini.Get("Core", "FastDiscSpeed", &StartUp.bFastDiscSpeed, StartUp.bFastDiscSpeed);
|
||||
game_ini.Get("Core", "BlockMerging", &StartUp.bMergeBlocks, StartUp.bMergeBlocks);
|
||||
game_ini.Get("Core", "DSPHLE", &StartUp.bDSPHLE, StartUp.bDSPHLE);
|
||||
game_ini.Get("Wii", "DisableWiimoteSpeaker",&StartUp.bDisableWiimoteSpeaker, StartUp.bDisableWiimoteSpeaker);
|
||||
game_ini.Get("Core", "GFXBackend", &StartUp.m_strVideoBackend, StartUp.m_strVideoBackend.c_str());
|
||||
game_ini.Get("Core", "CPUCore", &StartUp.iCPUCore, StartUp.iCPUCore);
|
||||
game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2);
|
||||
VideoBackend::ActivateBackend(StartUp.m_strVideoBackend);
|
||||
|
||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
||||
@@ -122,6 +124,7 @@ bool BootCore(const std::string& _rFilename)
|
||||
StartUp.bDSPHLE = Movie::IsDSPHLE();
|
||||
StartUp.bProgressive = Movie::IsProgressive();
|
||||
StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed();
|
||||
StartUp.iCPUCore = Movie::GetCPUMode();
|
||||
if (Movie::IsUsingMemcard() && Movie::IsStartingFromClearSave() && !StartUp.bWii)
|
||||
{
|
||||
if (File::Exists("Movie.raw"))
|
||||
@@ -159,17 +162,18 @@ void Stop()
|
||||
config_cache.valid = false;
|
||||
StartUp.bCPUThread = config_cache.bCPUThread;
|
||||
StartUp.bSkipIdle = config_cache.bSkipIdle;
|
||||
StartUp.iCPUCore = config_cache.iCPUCore;
|
||||
StartUp.bEnableFPRF = config_cache.bEnableFPRF;
|
||||
StartUp.bMMU = config_cache.bMMU;
|
||||
StartUp.bMMUBAT = config_cache.bMMUBAT;
|
||||
StartUp.bDCBZOFF = config_cache.bDCBZOFF;
|
||||
StartUp.iTLBHack = config_cache.iTLBHack;
|
||||
StartUp.bVBeam = config_cache.bVBeam;
|
||||
StartUp.bFastDiscSpeed = config_cache.bFastDiscSpeed;
|
||||
StartUp.bMergeBlocks = config_cache.bMergeBlocks;
|
||||
StartUp.bDSPHLE = config_cache.bDSPHLE;
|
||||
StartUp.bDisableWiimoteSpeaker = config_cache.bDisableWiimoteSpeaker;
|
||||
StartUp.m_strVideoBackend = config_cache.strBackend;
|
||||
VideoBackend::ActivateBackend(StartUp.m_strVideoBackend);
|
||||
StartUp.bHLE_BS2 = config_cache.bHLE_BS2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,6 @@ void SConfig::SaveSettings()
|
||||
ini.Set("Interface", "OnScreenDisplayMessages", m_LocalCoreStartupParameter.bOnScreenDisplayMessages);
|
||||
ini.Set("Interface", "HideCursor", m_LocalCoreStartupParameter.bHideCursor);
|
||||
ini.Set("Interface", "AutoHideCursor", m_LocalCoreStartupParameter.bAutoHideCursor);
|
||||
ini.Set("Interface", "Theme", m_LocalCoreStartupParameter.iTheme);
|
||||
ini.Set("Interface", "MainWindowPosX", (m_LocalCoreStartupParameter.iPosX == -32000) ? 0 : m_LocalCoreStartupParameter.iPosX); // TODO - HAX
|
||||
ini.Set("Interface", "MainWindowPosY", (m_LocalCoreStartupParameter.iPosY == -32000) ? 0 : m_LocalCoreStartupParameter.iPosY); // TODO - HAX
|
||||
ini.Set("Interface", "MainWindowWidth", m_LocalCoreStartupParameter.iWidth);
|
||||
@@ -175,6 +174,7 @@ void SConfig::SaveSettings()
|
||||
ini.Set("Interface", "ShowLogWindow", m_InterfaceLogWindow);
|
||||
ini.Set("Interface", "ShowLogConfigWindow", m_InterfaceLogConfigWindow);
|
||||
ini.Set("Interface", "ShowConsole", m_InterfaceConsole);
|
||||
ini.Set("Interface", "ThemeName", m_LocalCoreStartupParameter.theme_name);
|
||||
|
||||
// Hotkeys
|
||||
for (int i = 0; i < NUM_HOTKEYS; i++)
|
||||
@@ -256,6 +256,12 @@ void SConfig::SaveSettings()
|
||||
ini.Set("Movie", "PauseMovie", m_PauseMovie);
|
||||
ini.Set("Movie", "Author", m_strMovieAuthor);
|
||||
|
||||
// DSP
|
||||
ini.Set("DSP", "EnableJIT", m_EnableJIT);
|
||||
ini.Set("DSP", "DumpAudio", m_DumpAudio);
|
||||
ini.Set("DSP", "Backend", sBackend);
|
||||
ini.Set("DSP", "Volume", m_Volume);
|
||||
|
||||
ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
|
||||
m_SYSCONF->Save();
|
||||
}
|
||||
@@ -303,7 +309,6 @@ void SConfig::LoadSettings()
|
||||
ini.Get("Interface", "OnScreenDisplayMessages", &m_LocalCoreStartupParameter.bOnScreenDisplayMessages, true);
|
||||
ini.Get("Interface", "HideCursor", &m_LocalCoreStartupParameter.bHideCursor, false);
|
||||
ini.Get("Interface", "AutoHideCursor", &m_LocalCoreStartupParameter.bAutoHideCursor, false);
|
||||
ini.Get("Interface", "Theme", &m_LocalCoreStartupParameter.iTheme, 0);
|
||||
ini.Get("Interface", "MainWindowPosX", &m_LocalCoreStartupParameter.iPosX, 100);
|
||||
ini.Get("Interface", "MainWindowPosY", &m_LocalCoreStartupParameter.iPosY, 100);
|
||||
ini.Get("Interface", "MainWindowWidth", &m_LocalCoreStartupParameter.iWidth, 800);
|
||||
@@ -314,6 +319,7 @@ void SConfig::LoadSettings()
|
||||
ini.Get("Interface", "ShowLogWindow", &m_InterfaceLogWindow, false);
|
||||
ini.Get("Interface", "ShowLogConfigWindow", &m_InterfaceLogConfigWindow, false);
|
||||
ini.Get("Interface", "ShowConsole", &m_InterfaceConsole, false);
|
||||
ini.Get("Interface", "ThemeName", &m_LocalCoreStartupParameter.theme_name, "Boomy");
|
||||
|
||||
// Hotkeys
|
||||
for (int i = 0; i < NUM_HOTKEYS; i++)
|
||||
@@ -394,7 +400,7 @@ void SConfig::LoadSettings()
|
||||
ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0);
|
||||
ini.Get("Core", "VBeam", &m_LocalCoreStartupParameter.bVBeam, false);
|
||||
ini.Get("Core", "FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false);
|
||||
ini.Get("Core", "BAT", &m_LocalCoreStartupParameter.bMMUBAT, false);
|
||||
ini.Get("Core", "DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false);
|
||||
ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default
|
||||
ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default
|
||||
|
||||
@@ -404,6 +410,20 @@ void SConfig::LoadSettings()
|
||||
// Movie
|
||||
ini.Get("General", "PauseMovie", &m_PauseMovie, false);
|
||||
ini.Get("Movie", "Author", &m_strMovieAuthor, "");
|
||||
|
||||
// DSP
|
||||
ini.Get("DSP", "EnableJIT", &m_EnableJIT, true);
|
||||
ini.Get("DSP", "DumpAudio", &m_DumpAudio, false);
|
||||
#if defined __linux__ && HAVE_ALSA
|
||||
ini.Get("DSP", "Backend", &sBackend, BACKEND_ALSA);
|
||||
#elif defined __APPLE__
|
||||
ini.Get("DSP", "Backend", &sBackend, BACKEND_COREAUDIO);
|
||||
#elif defined _WIN32
|
||||
ini.Get("DSP", "Backend", &sBackend, BACKEND_DIRECTSOUND);
|
||||
#else
|
||||
ini.Get("DSP", "Backend", &sBackend, BACKEND_NULLSOUND);
|
||||
#endif
|
||||
ini.Get("DSP", "Volume", &m_Volume, 100);
|
||||
}
|
||||
|
||||
m_SYSCONF = new SysConf();
|
||||
|
||||
@@ -26,6 +26,16 @@
|
||||
#include "HW/SI_Device.h"
|
||||
#include "SysConf.h"
|
||||
|
||||
// DSP Backend Types
|
||||
#define BACKEND_NULLSOUND "No audio output"
|
||||
#define BACKEND_ALSA "ALSA"
|
||||
#define BACKEND_AOSOUND "AOSound"
|
||||
#define BACKEND_COREAUDIO "CoreAudio"
|
||||
#define BACKEND_DIRECTSOUND "DSound"
|
||||
#define BACKEND_OPENAL "OpenAL"
|
||||
#define BACKEND_PULSEAUDIO "Pulse"
|
||||
#define BACKEND_XAUDIO2 "XAudio2"
|
||||
|
||||
struct SConfig : NonCopyable
|
||||
{
|
||||
// Wii Devices
|
||||
@@ -83,6 +93,12 @@ struct SConfig : NonCopyable
|
||||
bool m_ShowLag;
|
||||
std::string m_strMovieAuthor;
|
||||
|
||||
// DSP settings
|
||||
bool m_EnableJIT;
|
||||
bool m_DumpAudio;
|
||||
int m_Volume;
|
||||
std::string sBackend;
|
||||
|
||||
SysConf* m_SYSCONF;
|
||||
|
||||
// save settings
|
||||
|
||||
@@ -310,9 +310,7 @@ void CpuThread()
|
||||
g_video_backend->Video_Prepare();
|
||||
}
|
||||
|
||||
Common::SetCurrentThreadAffinity(1); // Force to first core
|
||||
|
||||
#if defined(_WIN32) && defined(_M_X64)
|
||||
#if defined(_M_X64)
|
||||
EMM::InstallExceptionHandler(); // Let's run under memory watch
|
||||
#endif
|
||||
|
||||
@@ -343,8 +341,6 @@ void FifoPlayerThread()
|
||||
Common::SetCurrentThreadName("FIFO-GPU thread");
|
||||
}
|
||||
|
||||
Common::SetCurrentThreadAffinity(1); // Force to first core
|
||||
|
||||
g_bStarted = true;
|
||||
|
||||
// Enter CPU run loop. When we leave it - we are done.
|
||||
@@ -369,13 +365,6 @@ void EmuThread()
|
||||
|
||||
Common::SetCurrentThreadName("Emuthread - Starting");
|
||||
|
||||
{
|
||||
if (cpu_info.num_cores > 3) // Force to third, non-HT core
|
||||
Common::SetCurrentThreadAffinity(4);
|
||||
else // Force to second core
|
||||
Common::SetCurrentThreadAffinity(2);
|
||||
}
|
||||
|
||||
DisplayMessage(cpu_info.brand_string, 8000);
|
||||
DisplayMessage(cpu_info.Summarize(), 8000);
|
||||
DisplayMessage(_CoreParameter.m_strFilename, 3000);
|
||||
@@ -428,7 +417,7 @@ void EmuThread()
|
||||
CBoot::BootUp();
|
||||
|
||||
// Setup our core, but can't use dynarec if we are compare server
|
||||
if (Movie::GetCPUMode() && (!_CoreParameter.bRunCompareServer ||
|
||||
if (_CoreParameter.iCPUCore && (!_CoreParameter.bRunCompareServer ||
|
||||
_CoreParameter.bRunCompareClient))
|
||||
PowerPC::SetMode(PowerPC::MODE_JIT);
|
||||
else
|
||||
@@ -625,77 +614,7 @@ void VideoThrottle()
|
||||
u32 ElapseTime = (u32)Timer.GetTimeDifference();
|
||||
if ((ElapseTime >= 1000 && DrawnVideo > 0) || g_requestRefreshInfo)
|
||||
{
|
||||
g_requestRefreshInfo = false;
|
||||
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||
|
||||
if (ElapseTime == 0)
|
||||
ElapseTime = 1;
|
||||
|
||||
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
|
||||
u32 VPS = DrawnVideo * 1000 / ElapseTime;
|
||||
u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime);
|
||||
|
||||
// Settings are shown the same for both extended and summary info
|
||||
std::string SSettings = StringFromFormat("%s %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC");
|
||||
|
||||
// Use extended or summary information. The summary information does not print the ticks data,
|
||||
// that's more of a debugging interest, it can always be optional of course if someone is interested.
|
||||
//#define EXTENDED_INFO
|
||||
#ifdef EXTENDED_INFO
|
||||
u64 newTicks = CoreTiming::GetTicks();
|
||||
u64 newIdleTicks = CoreTiming::GetIdleTicks();
|
||||
|
||||
u64 diff = (newTicks - ticks) / 1000000;
|
||||
u64 idleDiff = (newIdleTicks - idleTicks) / 1000000;
|
||||
|
||||
ticks = newTicks;
|
||||
idleTicks = newIdleTicks;
|
||||
|
||||
float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100;
|
||||
|
||||
std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
|
||||
SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)",
|
||||
_CoreParameter.bSkipIdle ? "~" : "",
|
||||
(int)(diff),
|
||||
(int)(diff - idleDiff),
|
||||
(int)(idleDiff),
|
||||
SystemTimers::GetTicksPerSecond() / 1000000,
|
||||
_CoreParameter.bSkipIdle ? "~" : "",
|
||||
TicksPercentage);
|
||||
|
||||
#else // Summary information
|
||||
std::string SFPS;
|
||||
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
|
||||
|
||||
// This is our final "frame counter" string
|
||||
std::string SMessage = StringFromFormat("%s | %s",
|
||||
SSettings.c_str(), SFPS.c_str());
|
||||
std::string TMessage = StringFromFormat("%s | ", scm_rev_str) +
|
||||
SMessage;
|
||||
|
||||
// Show message
|
||||
g_video_backend->UpdateFPSDisplay(SMessage.c_str());
|
||||
|
||||
// Update the audio timestretcher with the current speed
|
||||
if (soundStream)
|
||||
{
|
||||
CMixer* pMixer = soundStream->GetMixer();
|
||||
pMixer->UpdateSpeed((float)Speed / 100);
|
||||
}
|
||||
|
||||
if (_CoreParameter.bRenderToMain &&
|
||||
SConfig::GetInstance().m_InterfaceStatusbar) {
|
||||
Host_UpdateStatusBar(SMessage.c_str());
|
||||
Host_UpdateTitle(scm_rev_str);
|
||||
} else
|
||||
Host_UpdateTitle(TMessage.c_str());
|
||||
|
||||
UpdateTitle();
|
||||
|
||||
// Reset counter
|
||||
Timer.Update();
|
||||
@@ -742,4 +661,79 @@ const char *Callback_ISOName()
|
||||
return "";
|
||||
}
|
||||
|
||||
void UpdateTitle()
|
||||
{
|
||||
u32 ElapseTime = (u32)Timer.GetTimeDifference();
|
||||
g_requestRefreshInfo = false;
|
||||
SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||
|
||||
if (ElapseTime == 0)
|
||||
ElapseTime = 1;
|
||||
|
||||
u32 FPS = Common::AtomicLoad(DrawnFrame) * 1000 / ElapseTime;
|
||||
u32 VPS = DrawnVideo * 1000 / ElapseTime;
|
||||
u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime);
|
||||
|
||||
// Settings are shown the same for both extended and summary info
|
||||
std::string SSettings = StringFromFormat("%s %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC");
|
||||
|
||||
// Use extended or summary information. The summary information does not print the ticks data,
|
||||
// that's more of a debugging interest, it can always be optional of course if someone is interested.
|
||||
//#define EXTENDED_INFO
|
||||
#ifdef EXTENDED_INFO
|
||||
u64 newTicks = CoreTiming::GetTicks();
|
||||
u64 newIdleTicks = CoreTiming::GetIdleTicks();
|
||||
|
||||
u64 diff = (newTicks - ticks) / 1000000;
|
||||
u64 idleDiff = (newIdleTicks - idleTicks) / 1000000;
|
||||
|
||||
ticks = newTicks;
|
||||
idleTicks = newIdleTicks;
|
||||
|
||||
float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100;
|
||||
|
||||
std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
|
||||
SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)",
|
||||
_CoreParameter.bSkipIdle ? "~" : "",
|
||||
(int)(diff),
|
||||
(int)(diff - idleDiff),
|
||||
(int)(idleDiff),
|
||||
SystemTimers::GetTicksPerSecond() / 1000000,
|
||||
_CoreParameter.bSkipIdle ? "~" : "",
|
||||
TicksPercentage);
|
||||
|
||||
#else // Summary information
|
||||
std::string SFPS;
|
||||
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
|
||||
|
||||
// This is our final "frame counter" string
|
||||
std::string SMessage = StringFromFormat("%s | %s",
|
||||
SSettings.c_str(), SFPS.c_str());
|
||||
std::string TMessage = StringFromFormat("%s | ", scm_rev_str) +
|
||||
SMessage;
|
||||
|
||||
// Show message
|
||||
g_video_backend->UpdateFPSDisplay(SMessage.c_str());
|
||||
|
||||
// Update the audio timestretcher with the current speed
|
||||
if (soundStream)
|
||||
{
|
||||
CMixer* pMixer = soundStream->GetMixer();
|
||||
pMixer->UpdateSpeed((float)Speed / 100);
|
||||
}
|
||||
|
||||
if (_CoreParameter.bRenderToMain &&
|
||||
SConfig::GetInstance().m_InterfaceStatusbar) {
|
||||
Host_UpdateStatusBar(SMessage.c_str());
|
||||
Host_UpdateTitle(scm_rev_str);
|
||||
} else
|
||||
Host_UpdateTitle(TMessage.c_str());
|
||||
}
|
||||
|
||||
} // Core
|
||||
|
||||
@@ -89,6 +89,8 @@ bool ShouldSkipFrame(int skipped);
|
||||
void VideoThrottle();
|
||||
void RequestRefreshInfo();
|
||||
|
||||
void UpdateTitle();
|
||||
|
||||
// waits until all systems are paused and fully idle, and acquires a lock on that state.
|
||||
// or, if doLock is false, releases a lock on that state and optionally unpauses.
|
||||
// calls must be balanced (once with doLock true, then once with doLock false) but may be recursive.
|
||||
|
||||
@@ -49,17 +49,16 @@ SCoreStartupParameter::SCoreStartupParameter()
|
||||
bMergeBlocks(false),
|
||||
bDPL2Decoder(false), iLatency(14),
|
||||
bRunCompareServer(false), bRunCompareClient(false),
|
||||
bMMU(false), bMMUBAT(false), iTLBHack(0), bVBeam(false),
|
||||
bMMU(false), bDCBZOFF(false), iTLBHack(0), bVBeam(false),
|
||||
bFastDiscSpeed(false),
|
||||
SelectedLanguage(0), bWii(false), bDisableWiimoteSpeaker(false),
|
||||
bConfirmStop(false), bHideCursor(false),
|
||||
SelectedLanguage(0), bWii(false),
|
||||
bConfirmStop(false), bHideCursor(false),
|
||||
bAutoHideCursor(false), bUsePanicHandlers(true), bOnScreenDisplayMessages(true),
|
||||
iRenderWindowXPos(-1), iRenderWindowYPos(-1),
|
||||
iRenderWindowWidth(640), iRenderWindowHeight(480),
|
||||
bRenderWindowAutoSize(false), bKeepWindowOnTop(false),
|
||||
bFullscreen(false), bRenderToMain(false),
|
||||
bProgressive(false), bDisableScreenSaver(false),
|
||||
iTheme(0),
|
||||
iPosX(100), iPosY(100), iWidth(800), iHeight(600)
|
||||
{
|
||||
LoadDefaults();
|
||||
@@ -76,7 +75,7 @@ void SCoreStartupParameter::LoadDefaults()
|
||||
bDSPThread = true;
|
||||
bEnableFPRF = false;
|
||||
bMMU = false;
|
||||
bMMUBAT = false;
|
||||
bDCBZOFF = false;
|
||||
iTLBHack = 0;
|
||||
bVBeam = false;
|
||||
bFastDiscSpeed = false;
|
||||
@@ -100,8 +99,6 @@ void SCoreStartupParameter::LoadDefaults()
|
||||
bJITPairedOff = false;
|
||||
bJITSystemRegistersOff = false;
|
||||
|
||||
bDisableWiimoteSpeaker = false;
|
||||
|
||||
m_strName = "NONE";
|
||||
m_strUniqueID = "00000000";
|
||||
}
|
||||
@@ -349,7 +346,11 @@ void SCoreStartupParameter::CheckMemcardPath(std::string& memcardPath, std::stri
|
||||
{
|
||||
// Use default memcard path if there is no user defined name
|
||||
std::string defaultFilename = isSlotA ? GC_MEMCARDA : GC_MEMCARDB;
|
||||
memcardPath = File::GetUserPath(D_GCUSER_IDX) + defaultFilename + ext;
|
||||
#ifdef _WIN32
|
||||
memcardPath = "." + File::GetUserPath(D_GCUSER_IDX).substr(File::GetExeDirectory().size()) + defaultFilename + ext;
|
||||
#else
|
||||
memcardPath = File::GetUserPath(D_GCUSER_IDX) + defaultFilename + ext;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -113,7 +113,7 @@ struct SCoreStartupParameter
|
||||
bool bRunCompareClient;
|
||||
|
||||
bool bMMU;
|
||||
bool bMMUBAT;
|
||||
bool bDCBZOFF;
|
||||
int iTLBHack;
|
||||
bool bVBeam;
|
||||
bool bFastDiscSpeed;
|
||||
@@ -121,10 +121,10 @@ struct SCoreStartupParameter
|
||||
int SelectedLanguage;
|
||||
|
||||
bool bWii;
|
||||
bool bDisableWiimoteSpeaker;
|
||||
|
||||
// Interface settings
|
||||
bool bConfirmStop, bHideCursor, bAutoHideCursor, bUsePanicHandlers, bOnScreenDisplayMessages;
|
||||
std::string theme_name;
|
||||
|
||||
// Hotkeys
|
||||
int iHotkey[NUM_HOTKEYS];
|
||||
@@ -138,7 +138,6 @@ struct SCoreStartupParameter
|
||||
bool bFullscreen, bRenderToMain;
|
||||
bool bProgressive, bDisableScreenSaver;
|
||||
|
||||
int iTheme;
|
||||
int iPosX, iPosY, iWidth, iHeight;
|
||||
|
||||
enum EBootBS2
|
||||
|
||||
@@ -165,10 +165,11 @@ u16 dsp_read_accelerator()
|
||||
// Somehow, YN1 and YN2 must be initialized with their "loop" values,
|
||||
// so yeah, it seems likely that we should raise an exception to let
|
||||
// the DSP program do that, at least if DSP_FORMAT == 0x0A.
|
||||
if ((Address & ~0x1f) == (EndAddress & ~0x1f))
|
||||
if (Address >= EndAddress)
|
||||
{
|
||||
// Set address back to start address.
|
||||
Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL];
|
||||
if ((Address & ~0x1f) == (EndAddress & ~0x1f))
|
||||
Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL];
|
||||
DSPCore_SetException(EXP_ACCOV);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
DSPEmulator *CreateDSPEmulator(bool HLE)
|
||||
{
|
||||
ac_Config.Load();
|
||||
|
||||
if (HLE)
|
||||
{
|
||||
return new DSPHLE();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "CoreTiming.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#include "HW/GPFifo.h"
|
||||
#include "HW/Memmap.h"
|
||||
@@ -28,7 +27,6 @@
|
||||
#include "PowerPC/PowerPC.h"
|
||||
|
||||
#include "BPMemory.h"
|
||||
#include "CommandProcessor.h"
|
||||
|
||||
FifoPlayer::~FifoPlayer()
|
||||
{
|
||||
@@ -96,40 +94,7 @@ bool FifoPlayer::Play()
|
||||
if (m_EarlyMemoryUpdates && m_CurrentFrame == m_FrameRangeStart)
|
||||
WriteAllMemoryUpdates();
|
||||
|
||||
// Stop Fifo processing until we've written the new frame
|
||||
WriteCP(CommandProcessor::CTRL_REGISTER, 0x10); // disable read & breakpoints, enable GP link
|
||||
|
||||
// Write frame data
|
||||
WriteFrame(m_File->GetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]);
|
||||
|
||||
// Enable frame processing and break when done
|
||||
u16 write_ptr_lo = ReadCP(CommandProcessor::FIFO_WRITE_POINTER_LO);
|
||||
u16 write_ptr_hi = ReadCP(CommandProcessor::FIFO_WRITE_POINTER_HI);
|
||||
WriteCP(CommandProcessor::FIFO_BP_LO, write_ptr_lo);
|
||||
WriteCP(CommandProcessor::FIFO_BP_HI, write_ptr_hi);
|
||||
WriteCP(CommandProcessor::CTRL_REGISTER, 0x13); // enable read, breakpoints & GP link
|
||||
|
||||
// If necessary, wait until GP has reached the breakpoint to prevent fifo overflows
|
||||
// TODO: Can this be done any better? Dual core mode is slower than single core mode even with these conditions..
|
||||
if (m_CurrentFrame < m_FrameRangeEnd)
|
||||
{
|
||||
// Check if FIFO would be overflown when writing the next frame
|
||||
u32 CPRWDistance = (ReadCP(CommandProcessor::FIFO_RW_DISTANCE_HI)<<16) | ReadCP(CommandProcessor::FIFO_RW_DISTANCE_LO);
|
||||
CPRWDistance += m_File->GetFrame(m_CurrentFrame+1).fifoDataSize + CommandProcessor::GATHER_PIPE_SIZE;
|
||||
u32 CPFifoBase = (ReadCP(CommandProcessor::FIFO_BASE_HI)<<16) | ReadCP(CommandProcessor::FIFO_BASE_LO);
|
||||
u32 CPFifoEnd = (ReadCP(CommandProcessor::FIFO_END_HI)<<16) | ReadCP(CommandProcessor::FIFO_END_LO);
|
||||
|
||||
bool bWait = (CPRWDistance > CPFifoEnd - CPFifoBase);
|
||||
while (bWait && (ReadCP(CommandProcessor::FIFO_READ_POINTER_LO) != write_ptr_lo ||
|
||||
ReadCP(CommandProcessor::FIFO_READ_POINTER_HI) != write_ptr_hi))
|
||||
{
|
||||
Common::YieldCPU();
|
||||
CoreTiming::Advance(); // Process scheduled events (esp. PixelEngine::SetFinish!)
|
||||
|
||||
if (PowerPC::GetState() == PowerPC::CPU_POWERDOWN)
|
||||
break;
|
||||
}
|
||||
}
|
||||
WriteFrame(m_File->GetFrame(m_CurrentFrame), m_FrameInfo[m_CurrentFrame]);
|
||||
|
||||
++m_CurrentFrame;
|
||||
}
|
||||
@@ -422,11 +387,6 @@ void FifoPlayer::LoadMemory()
|
||||
FlushWGP();
|
||||
}
|
||||
|
||||
u16 FifoPlayer::ReadCP(u32 address)
|
||||
{
|
||||
return Memory::Read_U16(0xCC000000 | address);
|
||||
}
|
||||
|
||||
void FifoPlayer::WriteCP(u32 address, u16 value)
|
||||
{
|
||||
Memory::Write_U16(value, 0xCC000000 | address);
|
||||
|
||||
@@ -87,7 +87,6 @@ private:
|
||||
|
||||
void LoadMemory();
|
||||
|
||||
u16 ReadCP(u32 address);
|
||||
void WriteCP(u32 address, u16 value);
|
||||
void WritePI(u32 address, u32 value);
|
||||
|
||||
|
||||
@@ -171,9 +171,9 @@ bool InstallCodeHandler()
|
||||
Memory::Write_U8(1, 0x80001807);
|
||||
|
||||
// Invalidate the icache
|
||||
for (unsigned int i = 0; i < data.length(); i += 32)
|
||||
for (unsigned int j = 0; j < data.length(); j += 32)
|
||||
{
|
||||
PowerPC::ppcState.iCache.Invalidate(0x80001800 + i);
|
||||
PowerPC::ppcState.iCache.Invalidate(0x80001800 + j);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <map>
|
||||
#include "Common.h"
|
||||
|
||||
#include "HLE.h"
|
||||
@@ -27,6 +26,9 @@
|
||||
|
||||
#include "HLE_OS.h"
|
||||
#include "HLE_Misc.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_es.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "Core.h"
|
||||
|
||||
namespace HLE
|
||||
{
|
||||
@@ -45,55 +47,72 @@ struct SPatch
|
||||
{
|
||||
char m_szPatchName[128];
|
||||
TPatchFunction PatchFunction;
|
||||
int type;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static const SPatch OSPatches[] =
|
||||
{
|
||||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
|
||||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// speedup
|
||||
//{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse },
|
||||
//{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState },
|
||||
//{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ "memcpy", HLE_Misc::gc_memcpy, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
|
||||
//{ "memcmp", HLE_Misc::gc_memcmp, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
|
||||
//{ "memset", HLE_Misc::gc_memset, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
|
||||
//{ "memmove", HLE_Misc::gc_memmove, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
|
||||
|
||||
//{ "__div2i", HLE_Misc::div2i, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower?
|
||||
//{ "__div2u", HLE_Misc::div2u, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower?
|
||||
|
||||
//{ "DCFlushRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ "DCInvalidateRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ "DCZeroRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// debug out is very nice ;)
|
||||
{ "OSReport", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "OSPanic", HLE_OS::HLE_OSPanic },
|
||||
{ "vprintf", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "printf", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "puts", HLE_OS::HLE_GeneralDebugPrint }, // gcc-optimized printf?
|
||||
{ "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint }, // used for early init things (normally)
|
||||
{ "___blank", HLE_OS::HLE_GeneralDebugPrint },
|
||||
{ "__write_console", HLE_OS::HLE_write_console }, // used by sysmenu (+more?)
|
||||
{ "OSReport", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "OSPanic", HLE_OS::HLE_OSPanic, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "vprintf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "printf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "puts", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // gcc-optimized printf?
|
||||
{ "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used for early init things (normally)
|
||||
{ "___blank", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
{ "__write_console", HLE_OS::HLE_write_console, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used by sysmenu (+more?)
|
||||
|
||||
// wii only
|
||||
//{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction },
|
||||
//{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// Super Monkey Ball - no longer needed.
|
||||
//{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine },
|
||||
//{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize },
|
||||
//{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength },
|
||||
//{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize },
|
||||
{ "PanicAlert", HLE_Misc::HLEPanicAlert },
|
||||
//{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal },
|
||||
//{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal },
|
||||
//{ ".atan2", HLE_Misc::SMB_atan2},
|
||||
//{ ".sqrt_fz", HLE_Misc::FZ_sqrt},
|
||||
//{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
{ "PanicAlert", HLE_Misc::HLEPanicAlert, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
//{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".atan2", HLE_Misc::SMB_atan2HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".sqrt_fz", HLE_Misc::FZ_sqrtHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// F-zero still isn't working correctly, but these aren't really helping.
|
||||
|
||||
//{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal },
|
||||
//{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal },
|
||||
//{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
//{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
//{ ".kill_infinites", HLE_Misc::FZero_kill_infinites },
|
||||
//{ ".kill_infinites", HLE_Misc::FZero_kill_infinites, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
// special
|
||||
// { "GXPeekZ", HLE_Misc::GXPeekZ},
|
||||
// { "GXPeekARGB", HLE_Misc::GXPeekARGB},
|
||||
// { "GXPeekZ", HLE_Misc::GXPeekZHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
// { "GXPeekARGB", HLE_Misc::GXPeekARGBHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// Name doesn't matter, installed in CBoot::BootUp()
|
||||
{ "HBReload", HLE_Misc::HBReload },
|
||||
{ "HBReload", HLE_Misc::HBReload, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
// ES_LAUNCH
|
||||
{ "__OSBootDol", HLE_Misc::OSBootDol, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
{ "OSGetResetCode", HLE_Misc::OSGetResetCode, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
};
|
||||
|
||||
static const SPatch OSBreakPoints[] =
|
||||
@@ -101,17 +120,13 @@ static const SPatch OSBreakPoints[] =
|
||||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
|
||||
};
|
||||
|
||||
|
||||
static std::map<u32, u32> orig_instruction;
|
||||
|
||||
void Patch(u32 address, const char *hle_func_name)
|
||||
void Patch(u32 addr, const char *hle_func_name)
|
||||
{
|
||||
for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++)
|
||||
{
|
||||
if (!strcmp(OSPatches[i].m_szPatchName, hle_func_name))
|
||||
{
|
||||
u32 HLEPatchValue = (1 & 0x3f) << 26;
|
||||
Memory::Write_U32(HLEPatchValue | i, address);
|
||||
orig_instruction[addr] = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -125,23 +140,24 @@ void PatchFunctions()
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
|
||||
if (symbol > 0)
|
||||
{
|
||||
u32 HLEPatchValue = (1 & 0x3f) << 26;
|
||||
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
|
||||
{
|
||||
orig_instruction[addr] = Memory::ReadUnchecked_U32(addr);
|
||||
Memory::Write_U32(HLEPatchValue | i, addr);
|
||||
orig_instruction[addr] = i;
|
||||
}
|
||||
INFO_LOG(OSHLE, "Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++)
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
|
||||
if (symbol > 0)
|
||||
for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++)
|
||||
{
|
||||
PowerPC::breakpoints.Add(symbol->address, false);
|
||||
INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
|
||||
if (symbol > 0)
|
||||
{
|
||||
PowerPC::breakpoints.Add(symbol->address, false);
|
||||
INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,10 +179,46 @@ void Execute(u32 _CurrentPC, u32 _Instruction)
|
||||
// _dbg_assert_msg_(HLE,NPC == LR, "Broken HLE function (doesn't set NPC)", OSPatches[pos].m_szPatchName);
|
||||
}
|
||||
|
||||
u32 GetOrigInstruction(u32 addr)
|
||||
u32 GetFunctionIndex(u32 addr)
|
||||
{
|
||||
std::map<u32, u32>::const_iterator iter = orig_instruction.find(addr);
|
||||
return (iter != orig_instruction.end()) ? iter->second : 0;
|
||||
}
|
||||
|
||||
int GetFunctionTypeByIndex(u32 index)
|
||||
{
|
||||
return OSPatches[index].type;
|
||||
}
|
||||
|
||||
int GetFunctionFlagsByIndex(u32 index)
|
||||
{
|
||||
return OSPatches[index].flags;
|
||||
}
|
||||
|
||||
bool IsEnabled(int flags)
|
||||
{
|
||||
if (flags == HLE::HLE_TYPE_MEMORY && Core::g_CoreStartupParameter.bMMU)
|
||||
return false;
|
||||
|
||||
if (flags == HLE::HLE_TYPE_DEBUG && !Core::g_CoreStartupParameter.bEnableDebugging && PowerPC::GetMode() != MODE_INTERPRETER)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 UnPatch(std::string patchName)
|
||||
{
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(patchName.c_str());
|
||||
if (symbol > 0)
|
||||
{
|
||||
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
|
||||
{
|
||||
orig_instruction[addr] = 0;
|
||||
PowerPC::ppcState.iCache.Invalidate(addr);
|
||||
}
|
||||
return symbol->address;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end of namespace HLE
|
||||
|
||||
@@ -18,15 +18,40 @@
|
||||
#ifndef _HLE_H
|
||||
#define _HLE_H
|
||||
|
||||
#include <map>
|
||||
#include "Common.h"
|
||||
|
||||
namespace HLE
|
||||
{
|
||||
enum
|
||||
{
|
||||
HLE_HOOK_START = 0, // Hook the beginning of the function and execute the function afterwards
|
||||
HLE_HOOK_END = 1, // Hook the end of the function, executing the function first before the hook
|
||||
HLE_HOOK_REPLACE = 2, // Replace the function with the HLE version
|
||||
HLE_HOOK_NONE = 3, // Do not hook the function
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HLE_TYPE_GENERIC = 0, // Miscellaneous function
|
||||
HLE_TYPE_MEMORY = 1, // Memory operation
|
||||
HLE_TYPE_FP = 2, // Floating Point operation
|
||||
HLE_TYPE_DEBUG = 3, // Debug output function
|
||||
};
|
||||
|
||||
void PatchFunctions();
|
||||
|
||||
void Patch(u32 pc, const char *func_name);
|
||||
u32 UnPatch(std::string patchName);
|
||||
void Execute(u32 _CurrentPC, u32 _Instruction);
|
||||
|
||||
u32 GetOrigInstruction(u32 em_address);
|
||||
u32 GetFunctionIndex(u32 em_address);
|
||||
int GetFunctionTypeByIndex(u32 index);
|
||||
int GetFunctionFlagsByIndex(u32 index);
|
||||
|
||||
bool IsEnabled(int flags);
|
||||
|
||||
static std::map<u32, u32> orig_instruction;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,10 +22,25 @@
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../Host.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_DI.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "VolumeCreator.h"
|
||||
#include "Filesystem.h"
|
||||
#include "../Boot/Boot_DOL.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
|
||||
#include "HLE.h"
|
||||
#include "PowerPC/PPCAnalyst.h"
|
||||
#include "PowerPC/SignatureDB.h"
|
||||
#include "PowerPC/PPCSymbolDB.h"
|
||||
#include "CommonPaths.h"
|
||||
|
||||
namespace HLE_Misc
|
||||
{
|
||||
|
||||
std::string args;
|
||||
u32 argsPtr;
|
||||
u32 bootType;
|
||||
|
||||
// Helper to quickly read the floating point value at a memory location.
|
||||
inline float F(u32 addr)
|
||||
{
|
||||
@@ -282,4 +297,253 @@ void HBReload()
|
||||
Host_Message(WM_USER_STOP);
|
||||
}
|
||||
|
||||
void ExecuteDOL(u8* dolFile, u32 fileSize)
|
||||
{
|
||||
// Clear memory before loading the dol
|
||||
for (u32 i = 0x80004000; i < Memory::Read_U32(0x00000034); i += 4)
|
||||
{
|
||||
// TODO: Should not write over the "save region"
|
||||
Memory::Write_U32(0x00000000, i);
|
||||
}
|
||||
CDolLoader dolLoader(dolFile, fileSize);
|
||||
dolLoader.Load();
|
||||
|
||||
// Scan for common HLE functions
|
||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
g_symbolDB.Clear();
|
||||
PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
|
||||
SignatureDB db;
|
||||
if (db.Load((File::GetSysDirectory() + TOTALDB).c_str()))
|
||||
{
|
||||
db.Apply(&g_symbolDB);
|
||||
HLE::PatchFunctions();
|
||||
db.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
PowerPC::ppcState.iCache.Reset();
|
||||
|
||||
CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
|
||||
size_t size = s_Usb->m_WiiMotes.size();
|
||||
bool* wiiMoteConnected = new bool[size];
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
|
||||
|
||||
WII_IPC_HLE_Interface::Reset(true);
|
||||
WII_IPC_HLE_Interface::Init();
|
||||
s_Usb = GetUsbPointer();
|
||||
for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++)
|
||||
{
|
||||
if (wiiMoteConnected[i])
|
||||
{
|
||||
s_Usb->m_WiiMotes[i].Activate(false);
|
||||
s_Usb->m_WiiMotes[i].Activate(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_Usb->m_WiiMotes[i].Activate(false);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] wiiMoteConnected;
|
||||
|
||||
if (argsPtr)
|
||||
{
|
||||
u32 args_base = Memory::Read_U32(0x800000f4);
|
||||
u32 ptr_to_num_args = 0xc;
|
||||
u32 num_args = 1;
|
||||
u32 hi_ptr = args_base + ptr_to_num_args + 4;
|
||||
u32 new_args_ptr = args_base + ptr_to_num_args + 8;
|
||||
|
||||
Memory::Write_U32(ptr_to_num_args, args_base + 8);
|
||||
Memory::Write_U32(num_args, args_base + ptr_to_num_args);
|
||||
Memory::Write_U32(0x14, hi_ptr);
|
||||
|
||||
for (unsigned int i = 0; i < args.length(); i++)
|
||||
Memory::WriteUnchecked_U8(args[i], new_args_ptr+i);
|
||||
}
|
||||
|
||||
NPC = dolLoader.GetEntryPoint() | 0x80000000;
|
||||
}
|
||||
|
||||
void LoadDOLFromDisc(std::string dol)
|
||||
{
|
||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str());
|
||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
||||
|
||||
if (dol.length() > 1 && dol.compare(0, 1, "/") == 0)
|
||||
dol = dol.substr(1);
|
||||
|
||||
u32 fileSize = (u32) pFileSystem->GetFileSize(dol.c_str());
|
||||
u8* dolFile = new u8[fileSize];
|
||||
if (fileSize > 0)
|
||||
{
|
||||
pFileSystem->ReadFile(dol.c_str(), dolFile, fileSize);
|
||||
ExecuteDOL(dolFile, fileSize);
|
||||
}
|
||||
delete[] dolFile;
|
||||
}
|
||||
|
||||
void LoadBootDOLFromDisc()
|
||||
{
|
||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str());
|
||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
||||
u32 fileSize = pFileSystem->GetBootDOLSize();
|
||||
u8* dolFile = new u8[fileSize];
|
||||
if (fileSize > 0)
|
||||
{
|
||||
pFileSystem->GetBootDOL(dolFile, fileSize);
|
||||
ExecuteDOL(dolFile, fileSize);
|
||||
}
|
||||
delete[] dolFile;
|
||||
}
|
||||
|
||||
u32 GetDolFileSize(std::string dol)
|
||||
{
|
||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str());
|
||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
||||
|
||||
std::string dolFile;
|
||||
|
||||
if (dol.length() > 1 && dol.compare(0, 1, "/") == 0)
|
||||
dolFile = dol.substr(1);
|
||||
else
|
||||
dolFile = dol;
|
||||
|
||||
return (u32)pFileSystem->GetFileSize(dolFile.c_str());
|
||||
}
|
||||
|
||||
void gc_memmove()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memmove((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memcpy()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memcpy((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memset()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 ch = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memset((u8*)(Memory::base + dest), ch, count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memcmp()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
GPR(3) = memcmp((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void div2i()
|
||||
{
|
||||
s64 num = (s64)(GPR(3)) << 32 | GPR(4);
|
||||
s64 den = (s64)(GPR(5)) << 32 | GPR(6);
|
||||
s64 quo = num / den;
|
||||
GPR(3) = quo >> 32;
|
||||
GPR(4) = quo & 0xffffffff;
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void div2u()
|
||||
{
|
||||
u64 num = (u64)(GPR(3)) << 32 | GPR(4);
|
||||
u64 den = (u64)(GPR(5)) << 32 | GPR(6);
|
||||
u64 quo = num / den;
|
||||
GPR(3) = quo >> 32;
|
||||
GPR(4) = quo & 0xffffffff;
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void OSGetResetCode()
|
||||
{
|
||||
u32 resetCode = Memory::Read_U32(0xCC003024);
|
||||
|
||||
if ((resetCode & 0x1fffffff) != 0)
|
||||
{
|
||||
GPR(3) = resetCode | 0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPR(3) = 0;
|
||||
}
|
||||
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
u16 GetIOSVersion()
|
||||
{
|
||||
return Memory::Read_U16(0x00003140);
|
||||
}
|
||||
|
||||
void OSBootDol()
|
||||
{
|
||||
if (GetIOSVersion() >= 30)
|
||||
{
|
||||
bootType = GPR(4);
|
||||
|
||||
if ((GPR(4) >> 28) == 0x8)
|
||||
{
|
||||
u32 resetCode = GPR(30);
|
||||
|
||||
// Reset game
|
||||
Memory::Write_U32(resetCode, 0xCC003024);
|
||||
LoadBootDOLFromDisc();
|
||||
return;
|
||||
}
|
||||
else if ((GPR(4) >> 28) == 0xA)
|
||||
{
|
||||
// Boot from disc partition
|
||||
PanicAlert("Boot Partition: %08x", GPR(26));
|
||||
}
|
||||
else if ((GPR(4) >> 28) == 0xC)
|
||||
{
|
||||
std::string dol;
|
||||
|
||||
// Boot DOL from disc
|
||||
u32 ptr = GPR(28);
|
||||
Memory::GetString(dol, ptr);
|
||||
|
||||
if (GetDolFileSize(dol) == 0)
|
||||
{
|
||||
ptr = GPR(30);
|
||||
Memory::GetString(dol, ptr);
|
||||
if (GetDolFileSize(dol) == 0)
|
||||
{
|
||||
// Cannot locate the dol file, exit.
|
||||
HLE::UnPatch("__OSBootDol");
|
||||
NPC = PC;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
argsPtr = Memory::Read_U32(GPR(5));
|
||||
Memory::GetString(args, argsPtr);
|
||||
LoadDOLFromDisc(dol);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("Unknown boot type: %08x", GPR(4));
|
||||
}
|
||||
}
|
||||
HLE::UnPatch("__OSBootDol");
|
||||
NPC = PC;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,15 @@ namespace HLE_Misc
|
||||
void FZ_sqrt_internal();
|
||||
void FZ_rsqrt_internal();
|
||||
void HBReload();
|
||||
void OSBootDol();
|
||||
void OSGetResetCode();
|
||||
void memcpy();
|
||||
void memset();
|
||||
void memmove();
|
||||
void memcmp();
|
||||
void div2i();
|
||||
void div2u();
|
||||
void ExecuteDOL(u8* dolFile, u32 fileSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,10 +37,6 @@ namespace
|
||||
|
||||
void CCPU::Init(int cpu_core)
|
||||
{
|
||||
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
|
||||
{
|
||||
cpu_core = Movie::GetCPUMode();
|
||||
}
|
||||
PowerPC::Init(cpu_core);
|
||||
m_SyncEvent = 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "DSPHLE.h"
|
||||
#include "UCodes/UCodes.h"
|
||||
#include "../AudioInterface.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
DSPHLE::DSPHLE() {
|
||||
m_InitMixer = false;
|
||||
|
||||
@@ -203,10 +203,12 @@ u16 AcceleratorGetSample()
|
||||
//
|
||||
// On real hardware, this would raise an interrupt that is handled by the
|
||||
// UCode. We simulate what this interrupt does here.
|
||||
if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F))
|
||||
if (*acc_cur_addr >= acc_end_addr)
|
||||
{
|
||||
// If we are really at the end, loop back to loop_addr.
|
||||
*acc_cur_addr = acc_loop_addr;
|
||||
// If we are really at the end (and we don't simply have cur_addr >
|
||||
// end_addr all the time), loop back to loop_addr.
|
||||
if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F))
|
||||
*acc_cur_addr = acc_loop_addr;
|
||||
|
||||
if (acc_pb->audio_addr.looping)
|
||||
{
|
||||
|
||||
@@ -104,26 +104,6 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle)
|
||||
{
|
||||
Common::SetCurrentThreadName("DSP thread");
|
||||
|
||||
{
|
||||
if (cpu_info.num_cores > 3)
|
||||
{
|
||||
// HACK (delroth): there is no way to know where hyperthreads are in
|
||||
// the current Dolphin version.
|
||||
bool windows = false;
|
||||
#ifdef _WIN32
|
||||
windows = true;
|
||||
#endif
|
||||
|
||||
u8 core_id;
|
||||
if (windows && cpu_info.num_cores > 4) // Probably HT
|
||||
core_id = 5; // 3rd non HT core
|
||||
else
|
||||
core_id = 3; // 3rd core
|
||||
|
||||
Common::SetCurrentThreadAffinity(1 << (core_id - 1));
|
||||
}
|
||||
}
|
||||
|
||||
while (dsp_lle->m_bIsRunning)
|
||||
{
|
||||
int cycles = (int)dsp_lle->m_cycle_count;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "EXI.h"
|
||||
#include "Sram.h"
|
||||
#include "../Movie.h"
|
||||
SRAM g_SRAM;
|
||||
|
||||
namespace ExpansionInterface
|
||||
@@ -44,7 +45,12 @@ void Init()
|
||||
for (u32 i = 0; i < NUM_CHANNELS; i++)
|
||||
g_Channels[i] = new CEXIChannel(i);
|
||||
|
||||
g_Channels[0]->AddDevice(SConfig::GetInstance().m_EXIDevice[0], 0); // SlotA
|
||||
if (Movie::IsPlayingInput() && Movie::IsUsingMemcard() && Movie::IsConfigSaved())
|
||||
g_Channels[0]->AddDevice(EXIDEVICE_MEMORYCARD, 0); // SlotA
|
||||
else if(Movie::IsPlayingInput() && !Movie::IsUsingMemcard() && Movie::IsConfigSaved())
|
||||
g_Channels[0]->AddDevice(EXIDEVICE_NONE, 0); // SlotA
|
||||
else
|
||||
g_Channels[0]->AddDevice(SConfig::GetInstance().m_EXIDevice[0], 0); // SlotA
|
||||
g_Channels[0]->AddDevice(EXIDEVICE_MASKROM, 1);
|
||||
g_Channels[0]->AddDevice(SConfig::GetInstance().m_EXIDevice[2], 2); // Serial Port 1
|
||||
g_Channels[1]->AddDevice(SConfig::GetInstance().m_EXIDevice[1], 0); // SlotB
|
||||
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
|
||||
virtual void TransferByte(u8 &_uByte);
|
||||
bool IsWriteCommand() const { return !!(m_uAddress & (1 << 31)); }
|
||||
const u32 CommandRegion() const { return (m_uAddress & ~(1 << 31)) >> 8; }
|
||||
u32 CommandRegion() const { return (m_uAddress & ~(1 << 31)) >> 8; }
|
||||
|
||||
void LoadFileToIPL(std::string filename, u32 offset);
|
||||
};
|
||||
|
||||
@@ -416,10 +416,7 @@ bool AreMemoryBreakpointsActivated()
|
||||
u32 Read_Instruction(const u32 em_address)
|
||||
{
|
||||
UGeckoInstruction inst = ReadUnchecked_U32(em_address);
|
||||
if (inst.OPCD == 1)
|
||||
return HLE::GetOrigInstruction(em_address);
|
||||
else
|
||||
return inst.hex;
|
||||
return inst.hex;
|
||||
}
|
||||
|
||||
u32 Read_Opcode_JIT_Uncached(const u32 _Address)
|
||||
|
||||
@@ -956,7 +956,7 @@ u32 TranslateAddress(const u32 _Address, const XCheckTLBFlag _Flag)
|
||||
// Check MSR[DR] bit before translating data addresses
|
||||
//if (((_Flag == FLAG_READ) || (_Flag == FLAG_WRITE)) && !(MSR & (1 << (31 - 27)))) return _Address;
|
||||
|
||||
u32 tlb_addr = Core::g_CoreStartupParameter.bMMUBAT?TranslateBlockAddress(_Address, _Flag):0;
|
||||
u32 tlb_addr = TranslateBlockAddress(_Address, _Flag);
|
||||
if (tlb_addr == 0)
|
||||
{
|
||||
tlb_addr = TranslatePageAddress(_Address, _Flag);
|
||||
|
||||
@@ -96,8 +96,7 @@ void Init()
|
||||
m_FlipperRev = 0x246500B1; // revision C
|
||||
m_Unknown = 0;
|
||||
|
||||
// Bleh, why?
|
||||
//m_ResetCode |= 0x80000000;
|
||||
m_ResetCode = 0x80000000; // Cold reset
|
||||
m_InterruptCause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI;
|
||||
|
||||
toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", &ToggleResetButtonCallback);
|
||||
@@ -199,6 +198,7 @@ void Write32(const u32 _uValue, const u32 _iAddress)
|
||||
|
||||
case PI_RESET_CODE:
|
||||
DEBUG_LOG(PROCESSORINTERFACE, "Write %08x to PI_RESET_CODE", _uValue);
|
||||
m_ResetCode = _uValue;
|
||||
break;
|
||||
|
||||
case PI_FLIPPER_UNK:
|
||||
|
||||
@@ -251,12 +251,11 @@ void Init()
|
||||
// Now the 1500 is a pure assumption
|
||||
// We need to figure out the real frequency though
|
||||
|
||||
// FIXME: does Wiimote Speaker support really require a different interval? (issue 4608)
|
||||
const int interval = SConfig::GetInstance().m_LocalCoreStartupParameter.
|
||||
bDisableWiimoteSpeaker ? 15000 : 4000;
|
||||
// FYI, WII_IPC_HLE_Interface::Update is also called in WII_IPCInterface::Write32
|
||||
const int freq = 1500;
|
||||
const int fields = SConfig::GetInstance().m_LocalCoreStartupParameter.
|
||||
bVBeam ? 2 : 1;
|
||||
IPC_HLE_PERIOD = GetTicksPerSecond() / (interval * fields);
|
||||
IPC_HLE_PERIOD = GetTicksPerSecond() / (freq * fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -144,8 +144,8 @@ void Preset(bool _bNTSC)
|
||||
m_HorizontalStepping.FbSteps = 40;
|
||||
m_HorizontalStepping.FieldSteps = 40;
|
||||
|
||||
m_HBeamPos = 1;
|
||||
m_VBeamPos = 1;
|
||||
m_HBeamPos = -1; // NTSC-U N64 VC games check for a non-zero HBeamPos
|
||||
m_VBeamPos = 0; // RG4JC0 checks for a zero VBeamPos
|
||||
|
||||
// 54MHz, capable of progressive scan
|
||||
m_Clock = Core::g_CoreStartupParameter.bProgressive;
|
||||
|
||||
@@ -221,6 +221,7 @@ void Write32(const u32 _Value, const u32 _Address)
|
||||
break;
|
||||
}
|
||||
|
||||
WII_IPC_HLE_Interface::Update();
|
||||
UpdateInterrupts();
|
||||
}
|
||||
|
||||
|
||||
@@ -97,8 +97,9 @@ void Turntable::GetState(u8* const data, const bool focus)
|
||||
|
||||
// crossfade slider
|
||||
{
|
||||
u8 cfs = 0;
|
||||
m_crossfade->GetState(&cfs, 8, 7);
|
||||
s8 cfs = 0;
|
||||
m_crossfade->GetState(&cfs, focus ? 7 : 0);
|
||||
cfs += 8;
|
||||
|
||||
ttdata->slider = cfs;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Attachment/Classic.h"
|
||||
#include "Attachment/Nunchuk.h"
|
||||
#include "Attachment/Guitar.h"
|
||||
@@ -39,6 +41,13 @@ inline double round(double x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); }
|
||||
|
||||
#include "../../Movie.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// :)
|
||||
auto const TAU = 6.28318530717958647692;
|
||||
auto const PI = TAU / 2.0;
|
||||
}
|
||||
|
||||
namespace WiimoteEmu
|
||||
{
|
||||
|
||||
@@ -89,23 +98,32 @@ const ReportFeatures reporting_mode_features[] =
|
||||
{ 0, 0, 0, 0, 23 },
|
||||
};
|
||||
|
||||
void EmulateShake( AccelData* const accel
|
||||
void EmulateShake(AccelData* const accel
|
||||
, ControllerEmu::Buttons* const buttons_group
|
||||
, u8* const shake_step )
|
||||
{
|
||||
static const double shake_data[] = { -2.5f, -5.0f, -2.5f, 0.0f, 2.5f, 5.0f, 2.5f, 0.0f };
|
||||
// frame count of one up/down shake
|
||||
// < 9 no shake detection in "Wario Land: Shake It"
|
||||
auto const shake_step_max = 15;
|
||||
|
||||
// peak G-force
|
||||
auto const shake_intensity = 3.f;
|
||||
|
||||
// shake is a bitfield of X,Y,Z shake button states
|
||||
static const unsigned int btns[] = { 0x01, 0x02, 0x04 };
|
||||
unsigned int shake = 0;
|
||||
|
||||
buttons_group->GetState( &shake, btns );
|
||||
for ( unsigned int i=0; i<3; ++i )
|
||||
|
||||
for (int i = 0; i != 3; ++i)
|
||||
{
|
||||
if (shake & (1 << i))
|
||||
{
|
||||
(&(accel->x))[i] = shake_data[shake_step[i]++];
|
||||
shake_step[i] %= sizeof(shake_data)/sizeof(double);
|
||||
(&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * shake_intensity;
|
||||
shake_step[i] = (shake_step[i] + 1) % shake_step_max;
|
||||
}
|
||||
else
|
||||
shake_step[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void EmulateTilt(AccelData* const accel
|
||||
@@ -113,7 +131,8 @@ void EmulateTilt(AccelData* const accel
|
||||
, const bool focus, const bool sideways, const bool upright)
|
||||
{
|
||||
float roll, pitch;
|
||||
tilt_group->GetState( &roll, &pitch, 0, focus ? (PI / 2) : 0 ); // 90 degrees
|
||||
// 180 degrees
|
||||
tilt_group->GetState(&roll, &pitch, 0, focus ? PI : 0);
|
||||
|
||||
unsigned int ud = 0, lr = 0, fb = 0;
|
||||
|
||||
@@ -256,6 +275,9 @@ Wiimote::Wiimote( const unsigned int index )
|
||||
for (unsigned int i=0; i < sizeof(named_buttons)/sizeof(*named_buttons); ++i)
|
||||
m_buttons->controls.push_back(new ControlGroup::Input( named_buttons[i]));
|
||||
|
||||
// udp
|
||||
groups.push_back(m_udp = new UDPWrapper(m_index, _trans("UDP Wiimote")));
|
||||
|
||||
// ir
|
||||
groups.push_back(m_ir = new Cursor(_trans("IR")));
|
||||
|
||||
@@ -265,9 +287,6 @@ Wiimote::Wiimote( const unsigned int index )
|
||||
// tilt
|
||||
groups.push_back(m_tilt = new Tilt(_trans("Tilt")));
|
||||
|
||||
// udp
|
||||
groups.push_back(m_udp = new UDPWrapper(m_index, _trans("UDP Wiimote")));
|
||||
|
||||
// shake
|
||||
groups.push_back(m_shake = new Buttons(_trans("Shake")));
|
||||
m_shake->controls.push_back(new ControlGroup::Input("X"));
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
// Registry sizes
|
||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||
#define WIIMOTE_EEPROM_FREE_SIZE 0x1700
|
||||
|
||||
@@ -201,7 +201,7 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes(size_t max_wiimotes)
|
||||
unsigned int k = 0;
|
||||
auto const wm = new Wiimote;
|
||||
wm->dev_handle = dev;
|
||||
memcpy(wm->devicepath, detail_data->DevicePath, 197);
|
||||
wm->devicepath = detail_data->DevicePath;
|
||||
|
||||
wiimotes.push_back(wm);
|
||||
}
|
||||
@@ -223,7 +223,7 @@ bool WiimoteScanner::IsReady() const
|
||||
// Connect to a wiimote with a known device path.
|
||||
bool Wiimote::Connect()
|
||||
{
|
||||
dev_handle = CreateFile(devicepath,
|
||||
dev_handle = CreateFile(devicepath.c_str(),
|
||||
(GENERIC_READ | GENERIC_WRITE),
|
||||
(FILE_SHARE_READ | FILE_SHARE_WRITE),
|
||||
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
|
||||
@@ -160,13 +160,6 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const
|
||||
rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||
}
|
||||
|
||||
if (rpt.first[0] == (WM_SET_REPORT | WM_BT_OUTPUT) &&
|
||||
rpt.first[1] == 0x18 && rpt.second == 23)
|
||||
{
|
||||
m_audio_reports.Push(rpt);
|
||||
return;
|
||||
}
|
||||
|
||||
m_write_reports.Push(rpt);
|
||||
}
|
||||
|
||||
@@ -192,24 +185,26 @@ bool Wiimote::Read()
|
||||
|
||||
bool Wiimote::Write()
|
||||
{
|
||||
Report rpt;
|
||||
bool audio_written = false;
|
||||
|
||||
if (m_audio_reports.Pop(rpt))
|
||||
if (!m_write_reports.Empty())
|
||||
{
|
||||
IOWrite(rpt.first, rpt.second);
|
||||
delete[] rpt.first;
|
||||
audio_written = true;
|
||||
Report const& rpt = m_write_reports.Front();
|
||||
|
||||
bool const is_speaker_data = rpt.first[1] == WM_WRITE_SPEAKER_DATA;
|
||||
|
||||
if (!is_speaker_data || last_audio_report.GetTimeDifference() > 5)
|
||||
{
|
||||
IOWrite(rpt.first, rpt.second);
|
||||
|
||||
if (is_speaker_data)
|
||||
last_audio_report.Update();
|
||||
|
||||
delete[] rpt.first;
|
||||
m_write_reports.Pop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_write_reports.Pop(rpt))
|
||||
{
|
||||
IOWrite(rpt.first, rpt.second);
|
||||
delete[] rpt.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
return audio_written;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the next report that should be sent
|
||||
@@ -384,25 +379,9 @@ void Wiimote::ThreadFunc()
|
||||
while (Write()) {}
|
||||
Common::SleepCurrentThread(1);
|
||||
#else
|
||||
// TODO: this is all a mess
|
||||
while (m_run_thread && IsConnected())
|
||||
{
|
||||
bool const did_write = Write();
|
||||
|
||||
if (did_write)
|
||||
break;
|
||||
else
|
||||
if (!Read())
|
||||
break;
|
||||
|
||||
// TODO: what is this doing?
|
||||
//if (m_audio_reports.Size() && did_write)
|
||||
// Read();
|
||||
|
||||
// TODO: make work well
|
||||
//Common::SleepCurrentThread(m_audio_reports.Size() ? 5 : 2);
|
||||
Common::SleepCurrentThread(2);
|
||||
}
|
||||
bool const did_something = Write() || Read();
|
||||
if (!did_something)
|
||||
Common::SleepCurrentThread(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ChunkFile.h"
|
||||
#include "Thread.h"
|
||||
#include "FifoQueue.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include "../Wiimote.h"
|
||||
#include "../WiimoteEmu/WiimoteEmu.h"
|
||||
@@ -88,7 +89,7 @@ public:
|
||||
int int_sock; // Interrupt socket
|
||||
|
||||
#elif defined(_WIN32)
|
||||
char devicepath[255]; // Unique wiimote reference
|
||||
std::string devicepath; // Unique wiimote reference
|
||||
//ULONGLONG btaddr; // Bluetooth address
|
||||
HANDLE dev_handle; // HID handle
|
||||
OVERLAPPED hid_overlap; // Overlap handle
|
||||
@@ -113,7 +114,8 @@ private:
|
||||
|
||||
Common::FifoQueue<Report> m_read_reports;
|
||||
Common::FifoQueue<Report> m_write_reports;
|
||||
Common::FifoQueue<Report> m_audio_reports;
|
||||
|
||||
Common::Timer last_audio_report;
|
||||
};
|
||||
|
||||
class WiimoteScanner
|
||||
|
||||
@@ -58,6 +58,8 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC
|
||||
#include "../HW/WII_IPC.h"
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../HW/SystemTimers.h"
|
||||
#include "CoreTiming.h"
|
||||
|
||||
|
||||
namespace WII_IPC_HLE_Interface
|
||||
@@ -80,8 +82,17 @@ typedef std::deque<u32> ipc_msg_queue;
|
||||
static ipc_msg_queue request_queue; // ppc -> arm
|
||||
static ipc_msg_queue reply_queue; // arm -> ppc
|
||||
|
||||
static int enque_reply;
|
||||
|
||||
void EnqueReplyCallback(u64 userdata, int)
|
||||
{
|
||||
reply_queue.push_back(userdata);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
enque_reply = CoreTiming::RegisterEvent("IPCReply", EnqueReplyCallback);
|
||||
|
||||
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
|
||||
CWII_IPC_HLE_Device_es::m_ContentFile = "";
|
||||
u32 i;
|
||||
@@ -382,7 +393,7 @@ void ExecuteCommand(u32 _Address)
|
||||
}
|
||||
else
|
||||
{
|
||||
IWII_IPC_HLE_Device* pDevice = CreateFileIO(DeviceID, DeviceName);
|
||||
pDevice = CreateFileIO(DeviceID, DeviceName);
|
||||
CmdSuccess = pDevice->Open(_Address, Mode);
|
||||
|
||||
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
|
||||
@@ -394,6 +405,7 @@ void ExecuteCommand(u32 _Address)
|
||||
else
|
||||
{
|
||||
delete pDevice;
|
||||
pDevice = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +436,10 @@ void ExecuteCommand(u32 _Address)
|
||||
|
||||
// Don't delete hardware
|
||||
if (!pDevice->IsHardware())
|
||||
{
|
||||
delete pDevice;
|
||||
pDevice = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -504,7 +519,8 @@ void ExecuteCommand(u32 _Address)
|
||||
if (CmdSuccess)
|
||||
{
|
||||
// Generate a reply to the IPC command
|
||||
EnqReply(_Address);
|
||||
int const reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
||||
EnqReply(_Address, reply_delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -526,9 +542,9 @@ void EnqRequest(u32 _Address)
|
||||
}
|
||||
|
||||
// Called when IOS module has some reply
|
||||
void EnqReply(u32 _Address)
|
||||
void EnqReply(u32 _Address, int cycles_in_future)
|
||||
{
|
||||
reply_queue.push_back(_Address);
|
||||
CoreTiming::ScheduleEvent(cycles_in_future, enque_reply, _Address);
|
||||
}
|
||||
|
||||
// This is called every IPC_HLE_PERIOD from SystemTimers.cpp
|
||||
|
||||
@@ -62,7 +62,7 @@ void UpdateDevices();
|
||||
void ExecuteCommand(u32 _Address);
|
||||
|
||||
void EnqRequest(u32 _Address);
|
||||
void EnqReply(u32 _Address);
|
||||
void EnqReply(u32 _Address, int cycles_in_future = 0);
|
||||
|
||||
enum ECommandType
|
||||
{
|
||||
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
virtual bool IOCtlV (u32) { UNIMPLEMENTED_CMD(IOCtlV) }
|
||||
#undef UNIMPLEMENTED_CMD
|
||||
|
||||
virtual int GetCmdDelay(u32) { return 0; }
|
||||
|
||||
virtual u32 Update() { return 0; }
|
||||
|
||||
virtual bool IsHardware() { return m_Hardware; }
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "VolumeCreator.h"
|
||||
#include "Filesystem.h"
|
||||
#include "LogManager.h"
|
||||
#include "../HW/SystemTimers.h"
|
||||
|
||||
#include "../../DiscIO/Src/FileMonitor.h"
|
||||
|
||||
@@ -460,3 +461,9 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||
// i dunno but prolly 1 is okay all the time :)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CWII_IPC_HLE_Device_di::GetCmdDelay(u32)
|
||||
{
|
||||
// Less than ~1/150th of a second hangs Oregon Trail at "loading wheel".
|
||||
return SystemTimers::GetTicksPerSecond() / 100;
|
||||
}
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
|
||||
bool IOCtl(u32 _CommandAddress);
|
||||
bool IOCtlV(u32 _CommandAddress);
|
||||
|
||||
int GetCmdDelay(u32);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -780,7 +780,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
// someone with an affected game should test
|
||||
IOSv = TitleID & 0xffff;
|
||||
}
|
||||
if (!bSuccess)
|
||||
if (!bSuccess && IOSv >= 30 && IOSv != 0xffff)
|
||||
{
|
||||
PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload ios or a title that is not available in your nand dump\n"
|
||||
"TitleID %016llx.\n Dolphin will likely hang now", TitleID);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "FileUtil.h"
|
||||
#include "NandPaths.h"
|
||||
#include "ChunkFile.h"
|
||||
#include "../HW/SystemTimers.h"
|
||||
|
||||
#include "../VolumeHandler.h"
|
||||
|
||||
@@ -499,6 +500,13 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
||||
return FS_RESULT_FATAL;
|
||||
}
|
||||
|
||||
int CWII_IPC_HLE_Device_fs::GetCmdDelay(u32)
|
||||
{
|
||||
// ~1/1000th of a second is too short and causes hangs in Wii Party
|
||||
// Play it safe at 1/500th
|
||||
return SystemTimers::GetTicksPerSecond() / 500;
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_fs::DoState(PointerWrap& p)
|
||||
{
|
||||
DoStateShared(p);
|
||||
|
||||
@@ -55,6 +55,8 @@ public:
|
||||
|
||||
virtual bool IOCtl(u32 _CommandAddress);
|
||||
virtual bool IOCtlV(u32 _CommandAddress);
|
||||
|
||||
virtual int GetCmdDelay(u32);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -336,23 +336,23 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8
|
||||
pWiiMote->ExecuteL2capCmd(_pData, _Size);
|
||||
}
|
||||
|
||||
// Here we send ACL packets to CPU. They will consist of header + data.
|
||||
// The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041.
|
||||
// ---------------------------------------------------
|
||||
// AyuanX: Basically, our WII_IPC_HLE is efficient enough to send the packet immediately
|
||||
// rather than enqueue it to some other memory
|
||||
// But...the only exception comes from the Wiimote_Plugin
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::IncDataPacket(u16 _ConnectionHandle)
|
||||
{
|
||||
m_PacketCount[_ConnectionHandle & 0xff]++;
|
||||
|
||||
// I don't think this makes sense or should be necessary
|
||||
// m_PacketCount refers to "completed" packets and is not related to some buffer size, yes?
|
||||
#if 0
|
||||
if (m_PacketCount[_ConnectionHandle & 0xff] > (unsigned int)m_acl_pkts_num)
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL buffer overflow");
|
||||
m_PacketCount[_ConnectionHandle & 0xff] = m_acl_pkts_num;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Here we send ACL packets to CPU. They will consist of header + data.
|
||||
// The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041.
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size)
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", _ConnectionHandle);
|
||||
@@ -374,8 +374,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, "
|
||||
"queueing(%d)...", m_acl_pool.GetWritePos());
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint not currently valid, queueing...");
|
||||
m_acl_pool.Store(_pData, _Size, _ConnectionHandle);
|
||||
}
|
||||
}
|
||||
@@ -486,18 +485,8 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
|
||||
}
|
||||
}
|
||||
|
||||
// The Real Wiimote sends report every ~6.66ms (150 Hz).
|
||||
// However, we don't actually reach here at dependable intervals, so we
|
||||
// instead just timeslice in such a way that makes the stack think we have
|
||||
// perfect "radio quality" (WPADGetRadioSensitivity) and yet still have some
|
||||
// idle time.
|
||||
// Somehow, Dolphin's Wiimote Speaker support requires using an update interval
|
||||
// of 5ms (200 Hz) for its output to work. This increased frequency tends to
|
||||
// fill the ACL queue (even) quicker than it can be processed by Dolphin,
|
||||
// especially during simultaneous requests involving many (emulated) Wiimotes...
|
||||
// Thus, we only use that interval when the option is enabled. See issue 4608.
|
||||
const u64 interval = SystemTimers::GetTicksPerSecond() / (SConfig::GetInstance().
|
||||
m_LocalCoreStartupParameter.bDisableWiimoteSpeaker ? 150 : 200);
|
||||
// The Real Wiimote sends report every ~5ms (200 Hz).
|
||||
const u64 interval = SystemTimers::GetTicksPerSecond() / 200;
|
||||
const u64 each_wiimote_interval = interval / m_WiiMotes.size();
|
||||
const u64 now = CoreTiming::GetTicks();
|
||||
|
||||
@@ -518,25 +507,47 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
|
||||
return packet_transferred;
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::Store(const u8* data, const u16 size, const u16 conn_handle)
|
||||
{
|
||||
if (m_queue.size() >= 100)
|
||||
{
|
||||
// Many simultaneous exchanges of ACL packets tend to cause the queue to fill up.
|
||||
ERROR_LOG(WII_IPC_WIIMOTE, "ACL queue size reached 100 - current packet will be dropped!");
|
||||
return;
|
||||
}
|
||||
|
||||
_dbg_assert_msg_(WII_IPC_WIIMOTE,
|
||||
size < m_acl_pkt_size, "acl packet too large for pool");
|
||||
|
||||
m_queue.push_back(Packet());
|
||||
auto& packet = m_queue.back();
|
||||
|
||||
std::copy(data, data + size, packet.data);
|
||||
packet.size = size;
|
||||
packet.conn_handle = conn_handle;
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305::ACLPool::WriteToEndpoint(CtrlBuffer& endpoint)
|
||||
{
|
||||
const u8 *data = m_pool + m_acl_pkt_size * m_read_ptr;
|
||||
const u16 size = m_info[m_read_ptr].size;
|
||||
const u16 conn_handle = m_info[m_read_ptr].conn_handle;
|
||||
auto& packet = m_queue.front();
|
||||
|
||||
const u8* const data = packet.data;
|
||||
const u16 size = packet.size;
|
||||
const u16 conn_handle = packet.conn_handle;
|
||||
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from "
|
||||
"queue(%d) to %08x", GetReadPos(), endpoint.m_address);
|
||||
"queue to %08x", endpoint.m_address);
|
||||
|
||||
hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_buffer);
|
||||
pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
||||
pHeader->length = size;
|
||||
|
||||
// Write the packet to the buffer
|
||||
memcpy((u8*)pHeader + sizeof(hci_acldata_hdr_t), data, pHeader->length);
|
||||
std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t));
|
||||
|
||||
endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size);
|
||||
|
||||
m_read_ptr = (m_read_ptr + 1) % m_acl_pkts_num;
|
||||
m_queue.pop_front();
|
||||
|
||||
WII_IPC_HLE_Interface::EnqReply(endpoint.m_address);
|
||||
endpoint.Invalidate();
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hci.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
#include "hci.h"
|
||||
#include "WII_IPC_HLE.h"
|
||||
#include "WII_IPC_HLE_Device.h"
|
||||
#include "WII_IPC_HLE_WiiMote.h"
|
||||
@@ -168,70 +170,33 @@ private:
|
||||
|
||||
class ACLPool
|
||||
{
|
||||
u8 m_pool[m_acl_pkt_size * m_acl_pkts_num];
|
||||
int m_read_ptr;
|
||||
int m_write_ptr;
|
||||
|
||||
struct
|
||||
struct Packet
|
||||
{
|
||||
u8 data[m_acl_pkt_size];
|
||||
u16 size;
|
||||
u16 conn_handle;
|
||||
} m_info[m_acl_pkts_num];
|
||||
};
|
||||
|
||||
std::deque<Packet> m_queue;
|
||||
|
||||
public:
|
||||
ACLPool()
|
||||
: m_read_ptr(0)
|
||||
, m_write_ptr(0)
|
||||
: m_queue()
|
||||
{}
|
||||
|
||||
void Store(const u8* data, const u16 size, const u16 conn_handle)
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_WIIMOTE,
|
||||
size < m_acl_pkt_size, "acl packet too large for pool");
|
||||
|
||||
const int next_write_ptr = (m_write_ptr + 1) % m_acl_pkts_num;
|
||||
if (next_write_ptr == m_read_ptr)
|
||||
{
|
||||
// Many simultaneous exchanges of ACL packets tend to cause the
|
||||
// 10-packet limit to be exceeded. Typically, this occurs when
|
||||
// many emulated Wiimotes are requesting connections at once.
|
||||
// See issue 4608 for more info.
|
||||
ERROR_LOG(WII_IPC_WIIMOTE, "ACL queue is full - current packet will be "
|
||||
"dropped! (m_write_ptr(%d) was about to overlap m_read_ptr(%d))",
|
||||
m_write_ptr, m_read_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(m_pool + m_acl_pkt_size * m_write_ptr, data, size);
|
||||
m_info[m_write_ptr].size = size;
|
||||
m_info[m_write_ptr].conn_handle = conn_handle;
|
||||
m_write_ptr = next_write_ptr;
|
||||
}
|
||||
void Store(const u8* data, const u16 size, const u16 conn_handle);
|
||||
|
||||
void WriteToEndpoint(CtrlBuffer& endpoint);
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_write_ptr == m_read_ptr;
|
||||
}
|
||||
|
||||
int GetWritePos() const
|
||||
{
|
||||
return m_write_ptr;
|
||||
}
|
||||
|
||||
int GetReadPos() const
|
||||
{
|
||||
return m_read_ptr;
|
||||
return m_queue.empty();
|
||||
}
|
||||
|
||||
// For SaveStates
|
||||
void DoState(PointerWrap &p)
|
||||
{
|
||||
p.Do(m_write_ptr);
|
||||
p.Do(m_read_ptr);
|
||||
p.DoArray((u8 *)m_pool, sizeof(m_pool));
|
||||
p.DoArray((u8 *)m_info, sizeof(m_info));
|
||||
p.Do(m_queue);
|
||||
}
|
||||
} m_acl_pool;
|
||||
|
||||
|
||||
@@ -736,16 +736,6 @@ bool PlayInput(const char *filename)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Load savestate (and skip to frame data)
|
||||
if(tmpHeader.bFromSaveState)
|
||||
{
|
||||
const std::string stateFilename = std::string(filename) + ".sav";
|
||||
if(File::Exists(stateFilename))
|
||||
Core::SetStateFileName(stateFilename);
|
||||
g_bRecordingFromSaveState = true;
|
||||
Movie::LoadInput(filename);
|
||||
}
|
||||
|
||||
ReadHeader();
|
||||
g_totalFrames = tmpHeader.frameCount;
|
||||
g_totalLagCount = tmpHeader.lagCount;
|
||||
@@ -762,6 +752,16 @@ bool PlayInput(const char *filename)
|
||||
g_currentByte = 0;
|
||||
g_recordfd.Close();
|
||||
|
||||
// Load savestate (and skip to frame data)
|
||||
if(tmpHeader.bFromSaveState)
|
||||
{
|
||||
const std::string stateFilename = std::string(filename) + ".sav";
|
||||
if(File::Exists(stateFilename))
|
||||
Core::SetStateFileName(stateFilename);
|
||||
g_bRecordingFromSaveState = true;
|
||||
Movie::LoadInput(filename);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
@@ -786,7 +786,13 @@ void DoState(PointerWrap &p)
|
||||
|
||||
void LoadInput(const char *filename)
|
||||
{
|
||||
File::IOFile t_record(filename, "r+b");
|
||||
File::IOFile t_record;
|
||||
if (!t_record.Open(filename, "r+b"))
|
||||
{
|
||||
PanicAlertT("Failed to read %s", filename);
|
||||
EndPlayInput(false);
|
||||
return;
|
||||
}
|
||||
|
||||
t_record.ReadArray(&tmpHeader, 1);
|
||||
|
||||
@@ -849,7 +855,7 @@ void LoadInput(const char *filename)
|
||||
{
|
||||
// this is a "you did something wrong" alert for the user's benefit.
|
||||
// we'll try to say what's going on in excruciating detail, otherwise the user might not believe us.
|
||||
if(Core::g_CoreStartupParameter.bWii)
|
||||
if(IsUsingWiimote(0))
|
||||
{
|
||||
// TODO: more detail
|
||||
PanicAlertT("Warning: You loaded a save whose movie mismatches on byte %d (0x%X). You should load another save before continuing, or load this state with read-only mode off. Otherwise you'll probably get a desync.", i+256, i+256);
|
||||
@@ -925,18 +931,6 @@ void PlayController(SPADStatus *PadStatus, int controllerID)
|
||||
if (!IsPlayingInput() || !IsUsingPad(controllerID) || tmpInput == NULL)
|
||||
return;
|
||||
|
||||
if (g_currentFrame == 1)
|
||||
{
|
||||
if (tmpHeader.bMemcard)
|
||||
{
|
||||
ExpansionInterface::ChangeDevice(0, EXIDEVICE_MEMORYCARD, 0);
|
||||
}
|
||||
else if (!tmpHeader.bMemcard)
|
||||
{
|
||||
ExpansionInterface::ChangeDevice(0, EXIDEVICE_NONE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_currentByte + 8 > g_totalBytes)
|
||||
{
|
||||
PanicAlertT("Premature movie end in PlayController. %u + 8 > %u", (u32)g_currentByte, (u32)g_totalBytes);
|
||||
@@ -1194,9 +1188,13 @@ void GetSettings()
|
||||
g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA);
|
||||
bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::hex << SCM_REV_STR;
|
||||
ss >> revision;
|
||||
int temp;
|
||||
|
||||
for(int i = 0; i < 4; ++i )
|
||||
{
|
||||
sscanf(SCM_REV_STR + 2 * i, "%2x", &temp );
|
||||
revision[i] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMD5()
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "PowerPCDisasm.h"
|
||||
#include "../../IPC_HLE/WII_IPC_HLE.h"
|
||||
#include "Atomic.h"
|
||||
#include "HLE/HLE.h"
|
||||
|
||||
|
||||
namespace {
|
||||
@@ -79,57 +80,63 @@ int startTrace = 0;
|
||||
|
||||
void Trace( UGeckoInstruction &instCode )
|
||||
{
|
||||
char regs[500]="";
|
||||
char reg[25]="";
|
||||
std::string regs = "";
|
||||
for (int i=0; i<32; i++) {
|
||||
sprintf(regs, "%sr%02d: %08x ", regs, i, PowerPC::ppcState.gpr[i]);
|
||||
sprintf(reg, "r%02d: %08x ", i, PowerPC::ppcState.gpr[i]);
|
||||
regs.append(reg);
|
||||
}
|
||||
|
||||
char fregs[500]="";
|
||||
char freg[25]="";
|
||||
std::string fregs = "";
|
||||
for (int i=0; i<32; i++) {
|
||||
sprintf(fregs, "%sf%02d: %08llx %08llx ", fregs, i,
|
||||
PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
|
||||
sprintf(freg, "f%02d: %08llx %08llx ", i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
|
||||
fregs.append(freg);
|
||||
}
|
||||
|
||||
char ppcInst[256];
|
||||
DisassembleGekko(instCode.hex, PC, ppcInst, 256);
|
||||
|
||||
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, instCode.hex, ppcInst);
|
||||
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str(), instCode.hex, ppcInst);
|
||||
}
|
||||
|
||||
int Interpreter::SingleStepInner(void)
|
||||
{
|
||||
static UGeckoInstruction instCode;
|
||||
|
||||
NPC = PC + sizeof(UGeckoInstruction);
|
||||
instCode.hex = Memory::Read_Opcode(PC);
|
||||
|
||||
// Uncomment to trace the interpreter
|
||||
//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
|
||||
// startTrace = 1;
|
||||
//else
|
||||
// startTrace = 0;
|
||||
|
||||
if (startTrace)
|
||||
u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches
|
||||
if (function != 0)
|
||||
{
|
||||
Trace(instCode);
|
||||
}
|
||||
|
||||
if (instCode.hex != 0)
|
||||
{
|
||||
UReg_MSR& msr = (UReg_MSR&)MSR;
|
||||
if (msr.FP) //If FPU is enabled, just execute
|
||||
int type = HLE::GetFunctionTypeByIndex(function);
|
||||
if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
|
||||
{
|
||||
m_opTable[instCode.OPCD](instCode);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
int flags = HLE::GetFunctionFlagsByIndex(function);
|
||||
if (HLE::IsEnabled(flags))
|
||||
{
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
HLEFunction(function);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
NPC = PC + sizeof(UGeckoInstruction);
|
||||
instCode.hex = Memory::Read_Opcode(PC);
|
||||
|
||||
// Uncomment to trace the interpreter
|
||||
//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
|
||||
// startTrace = 1;
|
||||
//else
|
||||
// startTrace = 0;
|
||||
|
||||
if (startTrace)
|
||||
{
|
||||
// check if we have to generate a FPU unavailable exception
|
||||
if (!PPCTables::UsesFPU(instCode))
|
||||
Trace(instCode);
|
||||
}
|
||||
|
||||
if (instCode.hex != 0)
|
||||
{
|
||||
UReg_MSR& msr = (UReg_MSR&)MSR;
|
||||
if (msr.FP) //If FPU is enabled, just execute
|
||||
{
|
||||
m_opTable[instCode.OPCD](instCode);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
@@ -140,17 +147,30 @@ int Interpreter::SingleStepInner(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE);
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
// check if we have to generate a FPU unavailable exception
|
||||
if (!PPCTables::UsesFPU(instCode))
|
||||
{
|
||||
m_opTable[instCode.OPCD](instCode);
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||
{
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE);
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Memory exception on instruction fetch
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
else
|
||||
{
|
||||
// Memory exception on instruction fetch
|
||||
PowerPC::CheckExceptions();
|
||||
m_EndBlock = true;
|
||||
}
|
||||
}
|
||||
last_pc = PC;
|
||||
PC = NPC;
|
||||
|
||||
@@ -407,7 +407,7 @@ void Interpreter::dcbtst(UGeckoInstruction _inst)
|
||||
void Interpreter::dcbz(UGeckoInstruction _inst)
|
||||
{
|
||||
// HACK but works... we think
|
||||
if (HID2.WPE || !HID0.DCFA)
|
||||
if (!Core::g_CoreStartupParameter.bDCBZOFF)
|
||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
||||
if (!jit)
|
||||
PowerPC::CheckExceptions();
|
||||
|
||||
@@ -252,8 +252,6 @@ void Jit64::HLEFunction(UGeckoInstruction _inst)
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
||||
MOV(32, R(EAX), M(&NPC));
|
||||
WriteExitDestInEAX();
|
||||
}
|
||||
|
||||
void Jit64::DoNothing(UGeckoInstruction _inst)
|
||||
@@ -566,6 +564,27 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
ABI_CallFunction(thunks.ProtectFunction((void *)&GPFifo::CheckGatherPipe, 0));
|
||||
}
|
||||
|
||||
u32 function = HLE::GetFunctionIndex(ops[i].address);
|
||||
if (function != 0)
|
||||
{
|
||||
int type = HLE::GetFunctionTypeByIndex(function);
|
||||
if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
|
||||
{
|
||||
int flags = HLE::GetFunctionFlagsByIndex(function);
|
||||
if (HLE::IsEnabled(flags))
|
||||
{
|
||||
HLEFunction(function);
|
||||
if (type == HLE::HLE_HOOK_REPLACE)
|
||||
{
|
||||
MOV(32, R(EAX), M(&NPC));
|
||||
js.downcountAmount += js.st.numCycles;
|
||||
WriteExitDestInEAX();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ops[i].skip)
|
||||
{
|
||||
if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
||||
@@ -668,6 +687,20 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
break;
|
||||
}
|
||||
|
||||
u32 function = HLE::GetFunctionIndex(js.blockStart);
|
||||
if (function != 0)
|
||||
{
|
||||
int type = HLE::GetFunctionTypeByIndex(function);
|
||||
if (type == HLE::HLE_HOOK_END)
|
||||
{
|
||||
int flags = HLE::GetFunctionFlagsByIndex(function);
|
||||
if (HLE::IsEnabled(flags))
|
||||
{
|
||||
HLEFunction(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (memory_exception)
|
||||
{
|
||||
// Address of instruction could not be translated
|
||||
|
||||
@@ -139,14 +139,13 @@ void Jit64::lXXx(UGeckoInstruction inst)
|
||||
MOV(32, gpr.R(d), R(EAX));
|
||||
gpr.UnlockAll();
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
// if it's still 0, we can wait until the next event
|
||||
TEST(32, R(EAX), R(EAX));
|
||||
FixupBranch noIdle = J_CC(CC_NZ);
|
||||
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
ABI_CallFunctionC((void *)&PowerPC::OnIdle, PowerPC::ppcState.gpr[a] + (s32)(s16)inst.SIMM_16);
|
||||
|
||||
// ! we must continue executing of the loop after exception handling, maybe there is still 0 in r0
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace JitILProfiler
|
||||
static u64 beginTime;
|
||||
static Block& Add(u64 codeHash)
|
||||
{
|
||||
const u32 _blockIndex = blocks.size();
|
||||
const u32 _blockIndex = (u32)blocks.size();
|
||||
blocks.push_back(Block());
|
||||
Block& block = blocks.back();
|
||||
block.index = _blockIndex;
|
||||
@@ -649,6 +649,27 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
js.next_compilerPC = ops[i + 1].address;
|
||||
}
|
||||
|
||||
u32 function = HLE::GetFunctionIndex(ops[i].address);
|
||||
if (function != 0)
|
||||
{
|
||||
int type = HLE::GetFunctionTypeByIndex(function);
|
||||
if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
|
||||
{
|
||||
int flags = HLE::GetFunctionFlagsByIndex(function);
|
||||
if (HLE::IsEnabled(flags))
|
||||
{
|
||||
HLEFunction(function);
|
||||
if (type == HLE::HLE_HOOK_REPLACE)
|
||||
{
|
||||
MOV(32, R(EAX), M(&NPC));
|
||||
jit->js.downcountAmount += jit->js.st.numCycles;
|
||||
WriteExitDestInOpArg(R(EAX));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ops[i].skip)
|
||||
{
|
||||
if (js.memcheck && (opinfo->flags & FL_USE_FPU))
|
||||
@@ -665,7 +686,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
{
|
||||
ibuild.EmitBreakPointCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
|
||||
JitILTables::CompileInstruction(ops[i]);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
@@ -681,6 +702,20 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
}
|
||||
}
|
||||
|
||||
u32 function = HLE::GetFunctionIndex(jit->js.blockStart);
|
||||
if (function != 0)
|
||||
{
|
||||
int type = HLE::GetFunctionTypeByIndex(function);
|
||||
if (type == HLE::HLE_HOOK_END)
|
||||
{
|
||||
int flags = HLE::GetFunctionFlagsByIndex(function);
|
||||
if (HLE::IsEnabled(flags))
|
||||
{
|
||||
HLEFunction(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (memory_exception)
|
||||
{
|
||||
ibuild.EmitISIException(ibuild.EmitIntConst(em_address));
|
||||
|
||||
@@ -71,7 +71,7 @@ void JitILAsmRoutineManager::Generate()
|
||||
#endif
|
||||
// INT3();
|
||||
|
||||
const u8 *outerLoop = GetCodePtr();
|
||||
const u8 *outer_loop = GetCodePtr();
|
||||
ABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
|
||||
FixupBranch skipToRealDispatch = J(); //skip the sync and compare first time
|
||||
|
||||
@@ -220,7 +220,7 @@ void JitILAsmRoutineManager::Generate()
|
||||
MOV(32, M(&PC), R(EAX));
|
||||
|
||||
TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||
J_CC(CC_Z, outerLoop, true);
|
||||
J_CC(CC_Z, outer_loop, true);
|
||||
//Landing pad for drec space
|
||||
ABI_PopAllCalleeSavedRegsAndAdjustStack();
|
||||
RET();
|
||||
|
||||
@@ -90,6 +90,13 @@ const u8 *TrampolineCache::GetReadTrampoline(const InstructionInfo &info)
|
||||
case 4:
|
||||
CALL(thunks.ProtectFunction((void *)&Memory::Read_U32, 1));
|
||||
break;
|
||||
case 2:
|
||||
CALL(thunks.ProtectFunction((void *)&Memory::Read_U16, 1));
|
||||
SHL(32, R(EAX), Imm8(16));
|
||||
break;
|
||||
case 1:
|
||||
CALL(thunks.ProtectFunction((void *)&Memory::Read_U8, 1));
|
||||
break;
|
||||
}
|
||||
ABI_PopAllCallerSavedRegsAndAdjustStack();
|
||||
if (dataReg != EAX) {
|
||||
@@ -176,10 +183,6 @@ const u8 *JitBase::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *c
|
||||
codePtr, emAddress);
|
||||
}*/
|
||||
|
||||
if (info.operandSize != 4) {
|
||||
BackPatchError(StringFromFormat("BackPatch - no support for operand size %i", info.operandSize), codePtr, emAddress);
|
||||
}
|
||||
|
||||
if (info.otherReg != RBX)
|
||||
PanicAlert("BackPatch : Base reg not RBX."
|
||||
"\n\nAttempted to access %08x.", emAddress);
|
||||
@@ -188,7 +191,6 @@ const u8 *JitBase::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *c
|
||||
PanicAlert("BackPatch : Currently only supporting reads."
|
||||
"\n\nAttempted to write to %08x.", emAddress);
|
||||
|
||||
// In the first iteration, we assume that all accesses are 32-bit. We also only deal with reads.
|
||||
if (accessType == 0)
|
||||
{
|
||||
XEmitter emitter(codePtr);
|
||||
|
||||
@@ -135,7 +135,11 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||
// is full and when saving and loading states.
|
||||
void JitBlockCache::Clear()
|
||||
{
|
||||
Core::DisplayMessage("Clearing code cache.", 3000);
|
||||
if (IsFull())
|
||||
Core::DisplayMessage("Clearing block cache.", 3000);
|
||||
else
|
||||
Core::DisplayMessage("Clearing code cache.", 3000);
|
||||
|
||||
for (int i = 0; i < num_blocks; i++)
|
||||
{
|
||||
DestroyBlock(i, false);
|
||||
|
||||
@@ -96,7 +96,11 @@ void EmuCodeBlock::UnsafeLoadToEAX(const Gen::OpArg & opAddress, int accessSize,
|
||||
MOVZX(32, accessSize, EAX, MDisp(EAX, (u32)Memory::base + offset));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Add a 2 bytes NOP to have some space for the backpatching
|
||||
if (accessSize == 8)
|
||||
NOP(2);
|
||||
|
||||
if (accessSize == 32)
|
||||
{
|
||||
BSWAP(32, EAX);
|
||||
@@ -118,14 +122,13 @@ void EmuCodeBlock::UnsafeLoadToEAX(const Gen::OpArg & opAddress, int accessSize,
|
||||
|
||||
void EmuCodeBlock::SafeLoadToEAX(const Gen::OpArg & opAddress, int accessSize, s32 offset, bool signExtend)
|
||||
{
|
||||
#if defined(_WIN32) && defined(_M_X64)
|
||||
#if defined(_M_X64)
|
||||
#ifdef ENABLE_MEM_CHECK
|
||||
if (accessSize == 32 && !Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
if (!Core::g_CoreStartupParameter.bMMU && !Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
#else
|
||||
if (accessSize == 32 && !Core::g_CoreStartupParameter.bMMU)
|
||||
if (!Core::g_CoreStartupParameter.bMMU)
|
||||
#endif
|
||||
{
|
||||
// BackPatch only supports 32-bits accesses
|
||||
UnsafeLoadToEAX(opAddress, accessSize, offset, signExtend);
|
||||
}
|
||||
else
|
||||
@@ -269,23 +272,18 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
|
||||
|
||||
void EmuCodeBlock::SafeWriteFloatToReg(X64Reg xmm_value, X64Reg reg_addr)
|
||||
{
|
||||
u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS;
|
||||
|
||||
if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack)
|
||||
{
|
||||
mem_mask |= Memory::ADDR_MASK_MEM1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MEM_CHECK
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
mem_mask |= Memory::EXRAM_MASK;
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(32, R(reg_addr), Imm32(mem_mask));
|
||||
if (false && cpu_info.bSSSE3) {
|
||||
// This path should be faster but for some reason it causes errors so I've disabled it.
|
||||
u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS;
|
||||
|
||||
if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack)
|
||||
mem_mask |= Memory::ADDR_MASK_MEM1;
|
||||
|
||||
#ifdef ENABLE_MEM_CHECK
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
mem_mask |= Memory::EXRAM_MASK;
|
||||
#endif
|
||||
TEST(32, R(reg_addr), Imm32(mem_mask));
|
||||
FixupBranch argh = J_CC(CC_Z);
|
||||
MOVSS(M(&float_buffer), xmm_value);
|
||||
MOV(32, R(EAX), M(&float_buffer));
|
||||
|
||||
@@ -70,8 +70,8 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
||||
|
||||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 10;
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 11;
|
||||
|
||||
struct StateHeader
|
||||
{
|
||||
|
||||
@@ -222,7 +222,7 @@ bool CompressFileToBlob(const char* infile, const char* outfile, u32 sub_type,
|
||||
// u64 size = header.block_size;
|
||||
std::fill(in_buf, in_buf + header.block_size, 0);
|
||||
if (scrubbing)
|
||||
DiscScrubber::GetNextBlock(inf.GetHandle(), in_buf);
|
||||
DiscScrubber::GetNextBlock(inf, in_buf);
|
||||
else
|
||||
inf.ReadBytes(in_buf, header.block_size);
|
||||
z_stream z;
|
||||
|
||||
@@ -127,7 +127,7 @@ bool SetupScrub(const char* filename, int block_size)
|
||||
return success;
|
||||
}
|
||||
|
||||
void GetNextBlock(FILE* in, u8* buffer)
|
||||
void GetNextBlock(File::IOFile& in, u8* buffer)
|
||||
{
|
||||
u64 CurrentOffset = m_BlockCount * m_BlockSize;
|
||||
u64 i = CurrentOffset / CLUSTER_SIZE;
|
||||
@@ -136,12 +136,12 @@ void GetNextBlock(FILE* in, u8* buffer)
|
||||
{
|
||||
DEBUG_LOG(DISCIO, "Freeing 0x%016llx", CurrentOffset);
|
||||
std::fill(buffer, buffer + m_BlockSize, 0xFF);
|
||||
fseeko(in, m_BlockSize, SEEK_CUR);
|
||||
in.Seek(m_BlockSize, SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(DISCIO, "Used 0x%016llx", CurrentOffset);
|
||||
fread(buffer, m_BlockSize, 1, in);
|
||||
in.ReadBytes(buffer, m_BlockSize);
|
||||
}
|
||||
|
||||
m_BlockCount++;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace DiscScrubber
|
||||
{
|
||||
|
||||
bool SetupScrub(const char* filename, int block_size);
|
||||
void GetNextBlock(FILE* in, u8* buffer);
|
||||
void GetNextBlock(File::IOFile& in, u8* buffer);
|
||||
void Cleanup();
|
||||
|
||||
} // namespace DiscScrubber
|
||||
|
||||
@@ -153,7 +153,7 @@ bool CFileSystemGCWii::ExportApploader(const char* _rExportFolder) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const
|
||||
u32 CFileSystemGCWii::GetBootDOLSize() const
|
||||
{
|
||||
u32 DolOffset = Read32(0x420) << m_OffsetShift;
|
||||
u32 DolSize = 0, offset = 0, size = 0;
|
||||
@@ -175,6 +175,19 @@ bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const
|
||||
if (offset + size > DolSize)
|
||||
DolSize = offset + size;
|
||||
}
|
||||
return DolSize;
|
||||
}
|
||||
|
||||
bool CFileSystemGCWii::GetBootDOL(u8* &buffer, u32 DolSize) const
|
||||
{
|
||||
u32 DolOffset = Read32(0x420) << m_OffsetShift;
|
||||
return m_rVolume->Read(DolOffset, DolSize, buffer);
|
||||
}
|
||||
|
||||
bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const
|
||||
{
|
||||
u32 DolOffset = Read32(0x420) << m_OffsetShift;
|
||||
u32 DolSize = GetBootDOLSize();
|
||||
|
||||
std::vector<u8> buffer(DolSize);
|
||||
if (m_rVolume->Read(DolOffset, DolSize, &buffer[0]))
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
virtual bool ExportFile(const char* _rFullPath, const char* _rExportFilename);
|
||||
virtual bool ExportApploader(const char* _rExportFolder) const;
|
||||
virtual bool ExportDOL(const char* _rExportFolder) const;
|
||||
virtual bool GetBootDOL(u8* &buffer, u32 DolSize) const;
|
||||
virtual u32 GetBootDOLSize() const;
|
||||
|
||||
private:
|
||||
bool m_Initialized;
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
virtual bool ExportApploader(const char* _rExportFolder) const = 0;
|
||||
virtual bool ExportDOL(const char* _rExportFolder) const = 0;
|
||||
virtual const char* GetFileName(u64 _Address) = 0;
|
||||
virtual bool GetBootDOL(u8* &buffer, u32 DolSize) const = 0;
|
||||
virtual u32 GetBootDOLSize() const = 0;
|
||||
|
||||
virtual const IVolume *GetVolume() const { return m_rVolume; }
|
||||
protected:
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
virtual std::string GetApploaderDate() const = 0;
|
||||
virtual bool SupportsIntegrityCheck() const { return false; }
|
||||
virtual bool CheckIntegrity() const { return false; }
|
||||
virtual bool IsDiscTwo() const { return false; }
|
||||
|
||||
enum ECountry
|
||||
{
|
||||
|
||||
@@ -137,4 +137,11 @@ u64 CVolumeGC::GetSize() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CVolumeGC::IsDiscTwo() const
|
||||
{
|
||||
bool discTwo;
|
||||
Read(6,1, (u8*) &discTwo);
|
||||
return discTwo;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
std::string GetApploaderDate() const;
|
||||
ECountry GetCountry() const;
|
||||
u64 GetSize() const;
|
||||
bool IsDiscTwo() const;
|
||||
|
||||
private:
|
||||
IBlobReader* m_pReader;
|
||||
|
||||
@@ -129,10 +129,10 @@ bool CVolumeWAD::GetWName(std::vector<std::wstring>& _rwNames) const
|
||||
_rwNames.push_back(L"");
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < 42; ++i)
|
||||
for (int j = 0; j < 42; ++j)
|
||||
{
|
||||
u16 t = Common::swap16(temp[i]);
|
||||
if (t == 0 && i > 0)
|
||||
u16 t = Common::swap16(temp[j]);
|
||||
if (t == 0 && j > 0)
|
||||
{
|
||||
if (out_temp.at(out_temp.size()-1) != ' ')
|
||||
out_temp.push_back(' ');
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win32\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
@@ -151,6 +152,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
@@ -167,6 +169,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win32\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
@@ -181,6 +184,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win32\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
@@ -197,6 +201,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
@@ -213,6 +218,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
xcopy "$(SolutionDir)..\Externals\Cg64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
#include <string> // System
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <wx/spinbutt.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "CommonPaths.h"
|
||||
#include "FileSearch.h"
|
||||
|
||||
#include "Core.h" // Core
|
||||
#include "HW/EXI.h"
|
||||
@@ -40,6 +42,14 @@
|
||||
#include "Main.h"
|
||||
#include "VideoBackendBase.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <tr1/functional>
|
||||
using std::tr1::function;
|
||||
#else
|
||||
#include <functional>
|
||||
using std::function;
|
||||
#endif
|
||||
|
||||
#define TEXT_BOX(page, text) new wxStaticText(page, wxID_ANY, text, wxDefaultPosition, wxDefaultSize)
|
||||
|
||||
extern CFrame* main_frame;
|
||||
@@ -126,7 +136,6 @@ EVT_SLIDER(ID_VOLUME, CConfigMain::AudioSettingsChanged)
|
||||
EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::DisplaySettingsChanged)
|
||||
EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::DisplaySettingsChanged)
|
||||
EVT_CHECKBOX(ID_INTERFACE_ONSCREENDISPLAYMESSAGES, CConfigMain::DisplaySettingsChanged)
|
||||
EVT_CHOICE(ID_INTERFACE_THEME, CConfigMain::DisplaySettingsChanged)
|
||||
EVT_CHOICE(ID_INTERFACE_LANG, CConfigMain::DisplaySettingsChanged)
|
||||
EVT_BUTTON(ID_HOTKEY_CONFIG, CConfigMain::DisplaySettingsChanged)
|
||||
|
||||
@@ -253,14 +262,6 @@ void CConfigMain::InitializeGUILists()
|
||||
arrayStringFor_DSPEngine.Add(_("DSP LLE recompiler"));
|
||||
arrayStringFor_DSPEngine.Add(_("DSP LLE interpreter (slow)"));
|
||||
|
||||
|
||||
// Display page
|
||||
// Themes
|
||||
arrayStringFor_Themes.Add(wxT("Boomy"));
|
||||
arrayStringFor_Themes.Add(wxT("Vista"));
|
||||
arrayStringFor_Themes.Add(wxT("X-Plastik"));
|
||||
arrayStringFor_Themes.Add(wxT("KDE"));
|
||||
|
||||
// Gamecube page
|
||||
// GC Language arrayStrings
|
||||
arrayStringFor_GCSystemLang.Add(_("English"));
|
||||
@@ -320,9 +321,6 @@ void CConfigMain::InitializeGUIValues()
|
||||
{
|
||||
const SCoreStartupParameter& startup_params = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||
|
||||
// Load DSP Settings.
|
||||
ac_Config.Load();
|
||||
|
||||
// General - Basic
|
||||
CPUThread->SetValue(startup_params.bCPUThread);
|
||||
SkipIdle->SetValue(startup_params.bSkipIdle);
|
||||
@@ -339,7 +337,6 @@ void CConfigMain::InitializeGUIValues()
|
||||
ConfirmStop->SetValue(startup_params.bConfirmStop);
|
||||
UsePanicHandlers->SetValue(startup_params.bUsePanicHandlers);
|
||||
OnScreenDisplayMessages->SetValue(startup_params.bOnScreenDisplayMessages);
|
||||
Theme->SetSelection(startup_params.iTheme);
|
||||
// need redesign
|
||||
for (unsigned int i = 0; i < sizeof(langIds) / sizeof(wxLanguage); i++)
|
||||
{
|
||||
@@ -354,17 +351,17 @@ void CConfigMain::InitializeGUIValues()
|
||||
if (startup_params.bDSPHLE)
|
||||
DSPEngine->SetSelection(0);
|
||||
else
|
||||
DSPEngine->SetSelection(ac_Config.m_EnableJIT ? 1 : 2);
|
||||
DSPEngine->SetSelection(SConfig::GetInstance().m_EnableJIT ? 1 : 2);
|
||||
|
||||
// Audio
|
||||
VolumeSlider->Enable(SupportsVolumeChanges(ac_Config.sBackend));
|
||||
VolumeSlider->SetValue(ac_Config.m_Volume);
|
||||
VolumeText->SetLabel(wxString::Format(wxT("%d %%"), ac_Config.m_Volume));
|
||||
VolumeSlider->Enable(SupportsVolumeChanges(SConfig::GetInstance().sBackend));
|
||||
VolumeSlider->SetValue(SConfig::GetInstance().m_Volume);
|
||||
VolumeText->SetLabel(wxString::Format(wxT("%d %%"), SConfig::GetInstance().m_Volume));
|
||||
DSPThread->SetValue(startup_params.bDSPThread);
|
||||
DumpAudio->SetValue(ac_Config.m_DumpAudio ? true : false);
|
||||
DPL2Decoder->Enable(std::string(ac_Config.sBackend) == BACKEND_OPENAL);
|
||||
DumpAudio->SetValue(SConfig::GetInstance().m_DumpAudio ? true : false);
|
||||
DPL2Decoder->Enable(std::string(SConfig::GetInstance().sBackend) == BACKEND_OPENAL);
|
||||
DPL2Decoder->SetValue(startup_params.bDPL2Decoder);
|
||||
Latency->Enable(std::string(ac_Config.sBackend) == BACKEND_OPENAL);
|
||||
Latency->Enable(std::string(SConfig::GetInstance().sBackend) == BACKEND_OPENAL);
|
||||
Latency->SetValue(startup_params.iLatency);
|
||||
// add backends to the list
|
||||
AddAudioBackends();
|
||||
@@ -497,12 +494,9 @@ void CConfigMain::InitializeGUITooltips()
|
||||
|
||||
// Display - Interface
|
||||
ConfirmStop->SetToolTip(_("Show a confirmation box before stopping a game."));
|
||||
UsePanicHandlers->SetToolTip(_("Show a message box when a potentially serious error has occured.\nDisabling this may avoid annoying and non-fatal messages, but it may also mean that Dolphin suddenly crashes without any explanation at all."));
|
||||
UsePanicHandlers->SetToolTip(_("Show a message box when a potentially serious error has occurred.\nDisabling this may avoid annoying and non-fatal messages, but it may also mean that Dolphin suddenly crashes without any explanation at all."));
|
||||
OnScreenDisplayMessages->SetToolTip(_("Show messages on the emulation screen area.\nThese messages include memory card writes, video backend and CPU information, and JIT cache clearing."));
|
||||
|
||||
// Display - Themes: Copyright notice
|
||||
Theme->SetToolTip(_("Boomy: Milosz Wlazlo [[email protected]]\nVista: VistaIcons.com\nX-Plastik: black_rider [ForumW.org]\nKDE: KDE-Look.org"));
|
||||
|
||||
InterfaceLang->SetToolTip(_("Change the language of the user interface.\nRequires restart."));
|
||||
|
||||
// Audio tooltips
|
||||
@@ -584,9 +578,6 @@ void CConfigMain::CreateGUIControls()
|
||||
// Hotkey configuration
|
||||
HotkeyConfig = new wxButton(DisplayPage, ID_HOTKEY_CONFIG, _("Hotkeys"),
|
||||
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator);
|
||||
// Themes
|
||||
Theme = new wxChoice(DisplayPage, ID_INTERFACE_THEME, wxDefaultPosition,
|
||||
wxDefaultSize, arrayStringFor_Themes, 0, wxDefaultValidator);
|
||||
// Interface settings
|
||||
ConfirmStop = new wxCheckBox(DisplayPage, ID_INTERFACE_CONFIRMSTOP, _("Confirm on Stop"),
|
||||
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
@@ -600,10 +591,42 @@ void CConfigMain::CreateGUIControls()
|
||||
sInterface->Add(InterfaceLang, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sInterface->AddStretchSpacer();
|
||||
sInterface->Add(HotkeyConfig, 0, wxALIGN_RIGHT | wxALL, 5);
|
||||
wxBoxSizer* scInterface = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// theme selection
|
||||
auto const theme_selection = new wxChoice(DisplayPage, wxID_ANY);
|
||||
|
||||
CFileSearch::XStringVector theme_dirs;
|
||||
theme_dirs.push_back(File::GetUserPath(D_THEMES_IDX));
|
||||
#if !defined(_WIN32)
|
||||
theme_dirs.push_back(SHARED_USER_DIR THEMES_DIR);
|
||||
#endif
|
||||
|
||||
CFileSearch cfs(CFileSearch::XStringVector(1, "*"), theme_dirs);
|
||||
auto const& sv = cfs.GetFileNames();
|
||||
std::for_each(sv.begin(), sv.end(), [theme_selection](const std::string& filename)
|
||||
{
|
||||
std::string name, ext;
|
||||
SplitPath(filename, NULL, &name, &ext);
|
||||
|
||||
name += ext;
|
||||
if (-1 == theme_selection->FindString(name))
|
||||
theme_selection->Append(name);
|
||||
});
|
||||
|
||||
theme_selection->SetStringSelection(SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name);
|
||||
|
||||
// std::function = avoid error on msvc
|
||||
theme_selection->Bind(wxEVT_COMMAND_CHOICE_SELECTED, function<void(wxEvent&)>([theme_selection](wxEvent&)
|
||||
{
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name = theme_selection->GetStringSelection();
|
||||
main_frame->InitBitmaps();
|
||||
}));
|
||||
|
||||
auto const scInterface = new wxBoxSizer(wxHORIZONTAL);
|
||||
scInterface->Add(TEXT_BOX(DisplayPage, _("Theme:")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
scInterface->Add(Theme, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
scInterface->Add(theme_selection, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
scInterface->AddStretchSpacer();
|
||||
|
||||
sbInterface = new wxStaticBoxSizer(wxVERTICAL, DisplayPage, _("Interface Settings"));
|
||||
sbInterface->Add(ConfirmStop, 0, wxALL, 5);
|
||||
sbInterface->Add(UsePanicHandlers, 0, wxALL, 5);
|
||||
@@ -838,9 +861,6 @@ void CConfigMain::OnOk(wxCommandEvent& WXUNUSED (event))
|
||||
|
||||
// Save the config. Dolphin crashes to often to save the settings on closing only
|
||||
SConfig::GetInstance().SaveSettings();
|
||||
|
||||
// Save Audio settings
|
||||
ac_Config.SaveSettings();
|
||||
}
|
||||
|
||||
// Core settings
|
||||
@@ -860,7 +880,7 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
||||
break;
|
||||
case ID_FRAMELIMIT:
|
||||
SConfig::GetInstance().m_Framelimit = Framelimit->GetSelection();
|
||||
ac_Config.Update();
|
||||
AudioCommon::UpdateSoundStream();
|
||||
break;
|
||||
case ID_FRAMELIMIT_USEFPSFORLIMITING:
|
||||
SConfig::GetInstance().b_UseFPS = UseFPSForLimiting->IsChecked();
|
||||
@@ -895,10 +915,6 @@ void CConfigMain::DisplaySettingsChanged(wxCommandEvent& event)
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bOnScreenDisplayMessages = OnScreenDisplayMessages->IsChecked();
|
||||
SetEnableAlert(OnScreenDisplayMessages->IsChecked());
|
||||
break;
|
||||
case ID_INTERFACE_THEME:
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.iTheme = Theme->GetSelection();
|
||||
main_frame->InitBitmaps();
|
||||
break;
|
||||
case ID_INTERFACE_LANG:
|
||||
if (SConfig::GetInstance().m_InterfaceLanguage != langIds[InterfaceLang->GetSelection()])
|
||||
SuccessAlertT("You must restart Dolphin in order for the change to take effect.");
|
||||
@@ -922,13 +938,13 @@ void CConfigMain::AudioSettingsChanged(wxCommandEvent& event)
|
||||
case ID_DSPENGINE:
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE = DSPEngine->GetSelection() == 0;
|
||||
if (!DSPEngine->GetSelection() == 0)
|
||||
ac_Config.m_EnableJIT = DSPEngine->GetSelection() == 1;
|
||||
ac_Config.Update();
|
||||
SConfig::GetInstance().m_EnableJIT = DSPEngine->GetSelection() == 1;
|
||||
AudioCommon::UpdateSoundStream();
|
||||
break;
|
||||
|
||||
case ID_VOLUME:
|
||||
ac_Config.m_Volume = VolumeSlider->GetValue();
|
||||
ac_Config.Update();
|
||||
SConfig::GetInstance().m_Volume = VolumeSlider->GetValue();
|
||||
AudioCommon::UpdateSoundStream();
|
||||
VolumeText->SetLabel(wxString::Format(wxT("%d %%"), VolumeSlider->GetValue()));
|
||||
break;
|
||||
|
||||
@@ -944,8 +960,8 @@ void CConfigMain::AudioSettingsChanged(wxCommandEvent& event)
|
||||
VolumeSlider->Enable(SupportsVolumeChanges(std::string(BackendSelection->GetStringSelection().mb_str())));
|
||||
Latency->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL);
|
||||
DPL2Decoder->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL);
|
||||
ac_Config.sBackend = BackendSelection->GetStringSelection().mb_str();
|
||||
ac_Config.Update();
|
||||
SConfig::GetInstance().sBackend = BackendSelection->GetStringSelection().mb_str();
|
||||
AudioCommon::UpdateSoundStream();
|
||||
break;
|
||||
|
||||
case ID_LATENCY:
|
||||
@@ -953,7 +969,7 @@ void CConfigMain::AudioSettingsChanged(wxCommandEvent& event)
|
||||
break;
|
||||
|
||||
default:
|
||||
ac_Config.m_DumpAudio = DumpAudio->GetValue();
|
||||
SConfig::GetInstance().m_DumpAudio = DumpAudio->GetValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -967,7 +983,7 @@ void CConfigMain::AddAudioBackends()
|
||||
{
|
||||
BackendSelection->Append(wxString::FromAscii((*iter).c_str()));
|
||||
int num = BackendSelection->\
|
||||
FindString(wxString::FromAscii(ac_Config.sBackend.c_str()));
|
||||
FindString(wxString::FromAscii(SConfig::GetInstance().sBackend.c_str()));
|
||||
BackendSelection->SetSelection(num);
|
||||
}
|
||||
}
|
||||
@@ -1048,6 +1064,13 @@ void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA)
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (!strncmp(File::GetExeDirectory().c_str(), filename.c_str(), File::GetExeDirectory().size()))
|
||||
{
|
||||
filename.erase(0, File::GetExeDirectory().size() +1);
|
||||
filename = "./" + filename;
|
||||
}
|
||||
#endif
|
||||
|
||||
// also check that the path isn't used for the other memcard...
|
||||
if (filename.compare(isSlotA ? SConfig::GetInstance().m_strMemoryCardB
|
||||
|
||||
@@ -87,7 +87,6 @@ private:
|
||||
ID_INTERFACE_CONFIRMSTOP,
|
||||
ID_INTERFACE_USEPANICHANDLERS,
|
||||
ID_INTERFACE_ONSCREENDISPLAYMESSAGES,
|
||||
ID_INTERFACE_THEME,
|
||||
ID_INTERFACE_LANG,
|
||||
ID_HOTKEY_CONFIG,
|
||||
|
||||
@@ -165,7 +164,6 @@ private:
|
||||
wxCheckBox* ConfirmStop;
|
||||
wxCheckBox* UsePanicHandlers;
|
||||
wxCheckBox* OnScreenDisplayMessages;
|
||||
wxChoice* Theme;
|
||||
wxChoice* InterfaceLang;
|
||||
wxButton* HotkeyConfig;
|
||||
|
||||
@@ -227,7 +225,6 @@ private:
|
||||
wxArrayString arrayStringFor_CPUEngine;
|
||||
wxArrayString arrayStringFor_DSPEngine;
|
||||
wxArrayString arrayStringFor_FullscreenResolution;
|
||||
wxArrayString arrayStringFor_Themes;
|
||||
wxArrayString arrayStringFor_InterfaceLang;
|
||||
wxArrayString arrayStringFor_GCSystemLang;
|
||||
wxArrayString arrayStringFor_WiiSensBarPos;
|
||||
|
||||
@@ -52,10 +52,7 @@
|
||||
|
||||
extern "C" // Bitmaps
|
||||
{
|
||||
#include "../../resources/toolbar_play.c"
|
||||
#include "../../resources/toolbar_pause.c"
|
||||
#include "../../resources/toolbar_add_memorycheck.c"
|
||||
#include "../../resources/toolbar_debugger_delete.c"
|
||||
#include "../../resources/toolbar_add_breakpoint.c"
|
||||
}
|
||||
|
||||
@@ -563,23 +560,21 @@ bool CCodeWindow::JITBlockLinking()
|
||||
void CCodeWindow::InitBitmaps()
|
||||
{
|
||||
// load original size 48x48
|
||||
m_Bitmaps[Toolbar_DebugGo] = wxGetBitmapFromMemory(toolbar_play_png);
|
||||
m_Bitmaps[Toolbar_Step] = wxGetBitmapFromMemory(toolbar_add_breakpoint_png);
|
||||
m_Bitmaps[Toolbar_StepOver] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
|
||||
m_Bitmaps[Toolbar_Skip] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
|
||||
m_Bitmaps[Toolbar_GotoPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
|
||||
m_Bitmaps[Toolbar_SetPC] = wxGetBitmapFromMemory(toolbar_add_memcheck_png);
|
||||
m_Bitmaps[Toolbar_DebugPause] = wxGetBitmapFromMemory(toolbar_pause_png);
|
||||
|
||||
// scale to 24x24 for toolbar
|
||||
for (size_t n = Toolbar_DebugGo; n < ToolbarDebugBitmapMax; n++)
|
||||
for (size_t n = 0; n < ToolbarDebugBitmapMax; n++)
|
||||
m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(24, 24));
|
||||
}
|
||||
|
||||
void CCodeWindow::PopulateToolbar(wxAuiToolBar* toolBar)
|
||||
{
|
||||
int w = m_Bitmaps[Toolbar_DebugGo].GetWidth(),
|
||||
h = m_Bitmaps[Toolbar_DebugGo].GetHeight();
|
||||
int w = m_Bitmaps[0].GetWidth(),
|
||||
h = m_Bitmaps[0].GetHeight();
|
||||
|
||||
toolBar->SetToolBitmapSize(wxSize(w, h));
|
||||
toolBar->AddTool(IDM_STEP, _("Step"), m_Bitmaps[Toolbar_Step]);
|
||||
|
||||
@@ -54,15 +54,6 @@
|
||||
|
||||
#include "ConfigManager.h"
|
||||
|
||||
extern "C" // Bitmaps
|
||||
{
|
||||
#include "../../resources/toolbar_play.c"
|
||||
#include "../../resources/toolbar_pause.c"
|
||||
#include "../../resources/toolbar_add_memorycheck.c"
|
||||
#include "../../resources/toolbar_debugger_delete.c"
|
||||
#include "../../resources/toolbar_add_breakpoint.c"
|
||||
}
|
||||
|
||||
// Save and load settings
|
||||
// -----------------------------
|
||||
void CCodeWindow::Load()
|
||||
|
||||
@@ -483,8 +483,7 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event)
|
||||
SearchResult result;
|
||||
result.frame_idx = frame_idx;
|
||||
|
||||
int obj_idx = m_objectsList->GetSelection();
|
||||
result.obj_idx = obj_idx;
|
||||
result.obj_idx = m_objectsList->GetSelection();
|
||||
result.cmd_idx = 0;
|
||||
for (unsigned int cmd_idx = 1; cmd_idx < m_objectCmdOffsets.size(); ++cmd_idx)
|
||||
{
|
||||
@@ -642,8 +641,8 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
||||
{
|
||||
m_objectCmdOffsets.push_back(objectdata - objectdata_start);
|
||||
int new_offset = objectdata - &fifo_frame.fifoData[frame.objectStarts[0]];
|
||||
int cmd = *objectdata++;
|
||||
switch (cmd)
|
||||
int command = *objectdata++;
|
||||
switch (command)
|
||||
{
|
||||
case GX_NOP:
|
||||
newLabel = _("NOP");
|
||||
@@ -691,9 +690,9 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
||||
case GX_LOAD_INDX_C:
|
||||
case GX_LOAD_INDX_D:
|
||||
objectdata += 4;
|
||||
newLabel = wxString::Format(wxT("LOAD INDX %s"), (cmd == GX_LOAD_INDX_A) ? _("A") :
|
||||
(cmd == GX_LOAD_INDX_B) ? _("B") :
|
||||
(cmd == GX_LOAD_INDX_C) ? _("C") : _("D"));
|
||||
newLabel = wxString::Format(wxT("LOAD INDX %s"), (command == GX_LOAD_INDX_A) ? _("A") :
|
||||
(command == GX_LOAD_INDX_B) ? _("B") :
|
||||
(command == GX_LOAD_INDX_C) ? _("C") : _("D"));
|
||||
break;
|
||||
|
||||
case GX_CMD_CALL_DL:
|
||||
|
||||
@@ -52,22 +52,6 @@
|
||||
|
||||
extern "C" {
|
||||
#include "../resources/Dolphin.c" // Dolphin icon
|
||||
#include "../resources/toolbar_browse.c"
|
||||
#include "../resources/toolbar_file_open.c"
|
||||
#include "../resources/toolbar_fullscreen.c"
|
||||
#include "../resources/toolbar_help.c"
|
||||
#include "../resources/toolbar_pause.c"
|
||||
#include "../resources/toolbar_play.c"
|
||||
#include "../resources/toolbar_plugin_dsp.c"
|
||||
#include "../resources/toolbar_plugin_gfx.c"
|
||||
#include "../resources/toolbar_plugin_options.c"
|
||||
#include "../resources/toolbar_plugin_pad.c"
|
||||
#include "../resources/toolbar_refresh.c"
|
||||
#include "../resources/toolbar_stop.c"
|
||||
#include "../resources/Boomy.h" // Theme packages
|
||||
#include "../resources/Vista.h"
|
||||
#include "../resources/X-Plastik.h"
|
||||
#include "../resources/KDE.h"
|
||||
};
|
||||
|
||||
|
||||
@@ -329,7 +313,7 @@ CFrame::CFrame(wxFrame* parent,
|
||||
ConsoleListener *Console = LogManager::GetInstance()->GetConsoleListener();
|
||||
if (SConfig::GetInstance().m_InterfaceConsole) Console->Open();
|
||||
|
||||
// Start debugging mazimized
|
||||
// Start debugging maximized
|
||||
if (UseDebugger) this->Maximize(true);
|
||||
// Debugger class
|
||||
if (UseDebugger)
|
||||
@@ -756,78 +740,107 @@ bool IsHotkey(wxKeyEvent &event, int Id)
|
||||
|
||||
int GetCmdForHotkey(unsigned int key)
|
||||
{
|
||||
if (key == HK_OPEN)
|
||||
switch (key)
|
||||
{
|
||||
case HK_OPEN:
|
||||
return wxID_OPEN;
|
||||
if (key == HK_CHANGE_DISC)
|
||||
|
||||
case HK_CHANGE_DISC:
|
||||
return IDM_CHANGEDISC;
|
||||
if (key == HK_REFRESH_LIST)
|
||||
|
||||
case HK_REFRESH_LIST:
|
||||
return wxID_REFRESH;
|
||||
|
||||
if (key == HK_PLAY_PAUSE)
|
||||
case HK_PLAY_PAUSE:
|
||||
return IDM_PLAY;
|
||||
if (key == HK_STOP)
|
||||
|
||||
case HK_STOP:
|
||||
return IDM_STOP;
|
||||
if (key == HK_RESET)
|
||||
|
||||
case HK_RESET:
|
||||
return IDM_RESET;
|
||||
if (key == HK_FRAME_ADVANCE)
|
||||
|
||||
case HK_FRAME_ADVANCE:
|
||||
return IDM_FRAMESTEP;
|
||||
|
||||
if (key == HK_START_RECORDING)
|
||||
case HK_START_RECORDING:
|
||||
return IDM_RECORD;
|
||||
if (key == HK_PLAY_RECORDING)
|
||||
|
||||
case HK_PLAY_RECORDING:
|
||||
return IDM_PLAYRECORD;
|
||||
if (key == HK_EXPORT_RECORDING)
|
||||
|
||||
case HK_EXPORT_RECORDING:
|
||||
return IDM_RECORDEXPORT;
|
||||
if (key == HK_READ_ONLY_MODE)
|
||||
|
||||
case HK_READ_ONLY_MODE:
|
||||
return IDM_RECORDREADONLY;
|
||||
|
||||
if (key == HK_FULLSCREEN)
|
||||
case HK_FULLSCREEN:
|
||||
return IDM_TOGGLE_FULLSCREEN;
|
||||
if (key == HK_SCREENSHOT)
|
||||
|
||||
case HK_SCREENSHOT:
|
||||
return IDM_SCREENSHOT;
|
||||
|
||||
if (key == HK_WIIMOTE1_CONNECT)
|
||||
case HK_WIIMOTE1_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE1;
|
||||
if (key == HK_WIIMOTE2_CONNECT)
|
||||
|
||||
case HK_WIIMOTE2_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE2;
|
||||
if (key == HK_WIIMOTE3_CONNECT)
|
||||
|
||||
case HK_WIIMOTE3_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE3;
|
||||
if (key == HK_WIIMOTE4_CONNECT)
|
||||
|
||||
case HK_WIIMOTE4_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE4;
|
||||
|
||||
if (key == HK_LOAD_STATE_SLOT_1)
|
||||
case HK_LOAD_STATE_SLOT_1:
|
||||
return IDM_LOADSLOT1;
|
||||
if (key == HK_LOAD_STATE_SLOT_2)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_2:
|
||||
return IDM_LOADSLOT2;
|
||||
if (key == HK_LOAD_STATE_SLOT_3)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_3:
|
||||
return IDM_LOADSLOT3;
|
||||
if (key == HK_LOAD_STATE_SLOT_4)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_4:
|
||||
return IDM_LOADSLOT4;
|
||||
if (key == HK_LOAD_STATE_SLOT_5)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_5:
|
||||
return IDM_LOADSLOT5;
|
||||
if (key == HK_LOAD_STATE_SLOT_6)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_6:
|
||||
return IDM_LOADSLOT6;
|
||||
if (key == HK_LOAD_STATE_SLOT_7)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_7:
|
||||
return IDM_LOADSLOT7;
|
||||
if (key == HK_LOAD_STATE_SLOT_8)
|
||||
|
||||
case HK_LOAD_STATE_SLOT_8:
|
||||
return IDM_LOADSLOT8;
|
||||
|
||||
if (key == HK_SAVE_STATE_SLOT_1)
|
||||
case HK_SAVE_STATE_SLOT_1:
|
||||
return IDM_SAVESLOT1;
|
||||
if (key == HK_SAVE_STATE_SLOT_2)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_2:
|
||||
return IDM_SAVESLOT2;
|
||||
if (key == HK_SAVE_STATE_SLOT_3)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_3:
|
||||
return IDM_SAVESLOT3;
|
||||
if (key == HK_SAVE_STATE_SLOT_4)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_4:
|
||||
return IDM_SAVESLOT4;
|
||||
if (key == HK_SAVE_STATE_SLOT_5)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_5:
|
||||
return IDM_SAVESLOT5;
|
||||
if (key == HK_SAVE_STATE_SLOT_6)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_6:
|
||||
return IDM_SAVESLOT6;
|
||||
if (key == HK_SAVE_STATE_SLOT_7)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_7:
|
||||
return IDM_SAVESLOT7;
|
||||
if (key == HK_SAVE_STATE_SLOT_8)
|
||||
|
||||
case HK_SAVE_STATE_SLOT_8:
|
||||
return IDM_SAVESLOT8;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -210,15 +210,6 @@ private:
|
||||
EToolbar_Max
|
||||
};
|
||||
|
||||
enum EBitmapsThemes
|
||||
{
|
||||
BOOMY,
|
||||
VISTA,
|
||||
XPLASTIK,
|
||||
KDE,
|
||||
THEMES_MAX
|
||||
};
|
||||
|
||||
wxBitmap m_Bitmaps[EToolbar_Max];
|
||||
wxBitmap m_BitmapsMenu[EToolbar_Max];
|
||||
|
||||
|
||||
@@ -78,23 +78,6 @@ Core::GetWindowHandle().
|
||||
// Resources
|
||||
extern "C" {
|
||||
#include "../resources/Dolphin.c" // Dolphin icon
|
||||
#include "../resources/toolbar_browse.c"
|
||||
#include "../resources/toolbar_file_open.c"
|
||||
#include "../resources/toolbar_fullscreen.c"
|
||||
#include "../resources/toolbar_help.c"
|
||||
#include "../resources/toolbar_pause.c"
|
||||
#include "../resources/toolbar_play.c"
|
||||
#include "../resources/toolbar_plugin_dsp.c"
|
||||
#include "../resources/toolbar_plugin_gfx.c"
|
||||
#include "../resources/toolbar_plugin_options.c"
|
||||
#include "../resources/toolbar_plugin_pad.c"
|
||||
#include "../resources/toolbar_plugin_wiimote.c"
|
||||
#include "../resources/toolbar_refresh.c"
|
||||
#include "../resources/toolbar_stop.c"
|
||||
#include "../resources/Boomy.h" // Theme packages
|
||||
#include "../resources/Vista.h"
|
||||
#include "../resources/X-Plastik.h"
|
||||
#include "../resources/KDE.h"
|
||||
};
|
||||
|
||||
bool confirmStop = false;
|
||||
@@ -441,7 +424,7 @@ void CFrame::PopulateToolbar(wxAuiToolBar* ToolBar)
|
||||
ToolBar->AddTool(IDM_PLAY, _("Play"), m_Bitmaps[Toolbar_Play], _("Play"));
|
||||
ToolBar->AddTool(IDM_STOP, _("Stop"), m_Bitmaps[Toolbar_Stop], _("Stop"));
|
||||
ToolBar->AddTool(IDM_TOGGLE_FULLSCREEN, _("FullScr"), m_Bitmaps[Toolbar_FullScreen], _("Toggle Fullscreen"));
|
||||
ToolBar->AddTool(IDM_SCREENSHOT, _("ScrShot"), m_Bitmaps[Toolbar_FullScreen], _("Take Screenshot"));
|
||||
ToolBar->AddTool(IDM_SCREENSHOT, _("ScrShot"), m_Bitmaps[Toolbar_Screenshot], _("Take Screenshot"));
|
||||
ToolBar->AddSeparator();
|
||||
ToolBar->AddTool(wxID_PREFERENCES, _("Config"), m_Bitmaps[Toolbar_ConfigMain], _("Configure..."));
|
||||
ToolBar->AddTool(IDM_CONFIG_GFX_BACKEND, _("Graphics"), m_Bitmaps[Toolbar_ConfigGFX], _("Graphics settings"));
|
||||
@@ -512,102 +495,33 @@ void CFrame::RecreateToolbar()
|
||||
|
||||
void CFrame::InitBitmaps()
|
||||
{
|
||||
// Get selected theme
|
||||
int Theme = SConfig::GetInstance().m_LocalCoreStartupParameter.iTheme;
|
||||
std::string theme(SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name + "/");
|
||||
std::string dir(File::GetUserPath(D_THEMES_IDX) + theme);
|
||||
|
||||
// Save memory by only having one set of bitmaps loaded at any time. I mean, they are still
|
||||
// in the exe, which is in memory, but at least we wont make another copy of all of them.
|
||||
switch (Theme)
|
||||
{
|
||||
case BOOMY:
|
||||
{
|
||||
// These are stored as 48x48
|
||||
m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(toolbar_file_open_png);
|
||||
m_Bitmaps[Toolbar_Refresh] = wxGetBitmapFromMemory(toolbar_refresh_png);
|
||||
m_Bitmaps[Toolbar_Browse] = wxGetBitmapFromMemory(toolbar_browse_png);
|
||||
m_Bitmaps[Toolbar_Play] = wxGetBitmapFromMemory(toolbar_play_png);
|
||||
m_Bitmaps[Toolbar_Stop] = wxGetBitmapFromMemory(toolbar_stop_png);
|
||||
m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(toolbar_pause_png);
|
||||
m_Bitmaps[Toolbar_ConfigMain] = wxGetBitmapFromMemory(toolbar_plugin_options_png);
|
||||
m_Bitmaps[Toolbar_ConfigGFX] = wxGetBitmapFromMemory(toolbar_plugin_gfx_png);
|
||||
m_Bitmaps[Toolbar_ConfigDSP] = wxGetBitmapFromMemory(toolbar_plugin_dsp_png);
|
||||
m_Bitmaps[Toolbar_ConfigPAD] = wxGetBitmapFromMemory(toolbar_plugin_pad_png);
|
||||
m_Bitmaps[Toolbar_Wiimote] = wxGetBitmapFromMemory(toolbar_plugin_wiimote_png);
|
||||
m_Bitmaps[Toolbar_Screenshot] = wxGetBitmapFromMemory(toolbar_fullscreen_png);
|
||||
m_Bitmaps[Toolbar_FullScreen] = wxGetBitmapFromMemory(toolbar_fullscreen_png);
|
||||
m_Bitmaps[Toolbar_Help] = wxGetBitmapFromMemory(toolbar_help_png);
|
||||
#if !defined(_WIN32)
|
||||
// If theme does not exist in user's dir load from shared directory
|
||||
if (!File::Exists(dir))
|
||||
dir = SHARED_USER_DIR THEMES_DIR "/" + theme;
|
||||
#endif
|
||||
|
||||
// Scale the 48x48 bitmaps to 24x24
|
||||
for (size_t n = Toolbar_FileOpen; n < EToolbar_Max; n++)
|
||||
{
|
||||
m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(24, 24));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VISTA:
|
||||
{
|
||||
// These are stored as 24x24 and need no scaling
|
||||
m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(Toolbar_Open1_png);
|
||||
m_Bitmaps[Toolbar_Refresh] = wxGetBitmapFromMemory(Toolbar_Refresh1_png);
|
||||
m_Bitmaps[Toolbar_Browse] = wxGetBitmapFromMemory(Toolbar_Browse1_png);
|
||||
m_Bitmaps[Toolbar_Play] = wxGetBitmapFromMemory(Toolbar_Play1_png);
|
||||
m_Bitmaps[Toolbar_Stop] = wxGetBitmapFromMemory(Toolbar_Stop1_png);
|
||||
m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(Toolbar_Pause1_png);
|
||||
m_Bitmaps[Toolbar_ConfigMain] = wxGetBitmapFromMemory(Toolbar_Options1_png);
|
||||
m_Bitmaps[Toolbar_ConfigGFX] = wxGetBitmapFromMemory(Toolbar_Gfx1_png);
|
||||
m_Bitmaps[Toolbar_ConfigDSP] = wxGetBitmapFromMemory(Toolbar_DSP1_png);
|
||||
m_Bitmaps[Toolbar_ConfigPAD] = wxGetBitmapFromMemory(Toolbar_Pad1_png);
|
||||
m_Bitmaps[Toolbar_Wiimote] = wxGetBitmapFromMemory(Toolbar_Wiimote1_png);
|
||||
m_Bitmaps[Toolbar_Screenshot] = wxGetBitmapFromMemory(Toolbar_Fullscreen1_png);
|
||||
m_Bitmaps[Toolbar_FullScreen] = wxGetBitmapFromMemory(Toolbar_Fullscreen1_png);
|
||||
m_Bitmaps[Toolbar_Help] = wxGetBitmapFromMemory(Toolbar_Help1_png);
|
||||
}
|
||||
break;
|
||||
|
||||
case XPLASTIK:
|
||||
{
|
||||
m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(Toolbar_Open2_png);
|
||||
m_Bitmaps[Toolbar_Refresh] = wxGetBitmapFromMemory(Toolbar_Refresh2_png);
|
||||
m_Bitmaps[Toolbar_Browse] = wxGetBitmapFromMemory(Toolbar_Browse2_png);
|
||||
m_Bitmaps[Toolbar_Play] = wxGetBitmapFromMemory(Toolbar_Play2_png);
|
||||
m_Bitmaps[Toolbar_Stop] = wxGetBitmapFromMemory(Toolbar_Stop2_png);
|
||||
m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(Toolbar_Pause2_png);
|
||||
m_Bitmaps[Toolbar_ConfigMain] = wxGetBitmapFromMemory(Toolbar_Options2_png);
|
||||
m_Bitmaps[Toolbar_ConfigGFX] = wxGetBitmapFromMemory(Toolbar_Gfx2_png);
|
||||
m_Bitmaps[Toolbar_ConfigDSP] = wxGetBitmapFromMemory(Toolbar_DSP2_png);
|
||||
m_Bitmaps[Toolbar_ConfigPAD] = wxGetBitmapFromMemory(Toolbar_Pad2_png);
|
||||
m_Bitmaps[Toolbar_Wiimote] = wxGetBitmapFromMemory(Toolbar_Wiimote2_png);
|
||||
m_Bitmaps[Toolbar_Screenshot] = wxGetBitmapFromMemory(Toolbar_Fullscreen2_png);
|
||||
m_Bitmaps[Toolbar_FullScreen] = wxGetBitmapFromMemory(Toolbar_Fullscreen2_png);
|
||||
m_Bitmaps[Toolbar_Help] = wxGetBitmapFromMemory(Toolbar_Help2_png);
|
||||
}
|
||||
break;
|
||||
|
||||
case KDE:
|
||||
{
|
||||
m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(Toolbar_Open3_png);
|
||||
m_Bitmaps[Toolbar_Refresh] = wxGetBitmapFromMemory(Toolbar_Refresh3_png);
|
||||
m_Bitmaps[Toolbar_Browse] = wxGetBitmapFromMemory(Toolbar_Browse3_png);
|
||||
m_Bitmaps[Toolbar_Play] = wxGetBitmapFromMemory(Toolbar_Play3_png);
|
||||
m_Bitmaps[Toolbar_Stop] = wxGetBitmapFromMemory(Toolbar_Stop3_png);
|
||||
m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(Toolbar_Pause3_png);
|
||||
m_Bitmaps[Toolbar_ConfigMain] = wxGetBitmapFromMemory(Toolbar_Options3_png);
|
||||
m_Bitmaps[Toolbar_ConfigGFX] = wxGetBitmapFromMemory(Toolbar_Gfx3_png);
|
||||
m_Bitmaps[Toolbar_ConfigDSP] = wxGetBitmapFromMemory(Toolbar_DSP3_png);
|
||||
m_Bitmaps[Toolbar_ConfigPAD] = wxGetBitmapFromMemory(Toolbar_Pad3_png);
|
||||
m_Bitmaps[Toolbar_Wiimote] = wxGetBitmapFromMemory(Toolbar_Wiimote3_png);
|
||||
m_Bitmaps[Toolbar_Screenshot] = wxGetBitmapFromMemory(Toolbar_Fullscreen3_png);
|
||||
m_Bitmaps[Toolbar_FullScreen] = wxGetBitmapFromMemory(Toolbar_Fullscreen3_png);
|
||||
m_Bitmaps[Toolbar_Help] = wxGetBitmapFromMemory(Toolbar_Help3_png);
|
||||
}
|
||||
break;
|
||||
|
||||
default: PanicAlertT("Theme selection went wrong");
|
||||
}
|
||||
m_Bitmaps[Toolbar_FileOpen].LoadFile(dir + "open.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Refresh].LoadFile(dir + "refresh.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Browse].LoadFile(dir + "browse.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Play].LoadFile(dir + "play.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Stop].LoadFile(dir + "stop.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Pause].LoadFile(dir + "pause.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_ConfigMain].LoadFile(dir + "config.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_ConfigGFX].LoadFile(dir + "graphics.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_ConfigDSP].LoadFile(dir + "dsp.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_ConfigPAD].LoadFile(dir + "gcpad.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Wiimote].LoadFile(dir + "wiimote.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Screenshot].LoadFile(dir + "screenshot.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_FullScreen].LoadFile(dir + "fullscreen.png", wxBITMAP_TYPE_PNG);
|
||||
m_Bitmaps[Toolbar_Help].LoadFile(dir + "help.png", wxBITMAP_TYPE_PNG);
|
||||
|
||||
// Update in case the bitmap has been updated
|
||||
if (m_ToolBar != NULL) RecreateToolbar();
|
||||
if (m_ToolBar != NULL)
|
||||
RecreateToolbar();
|
||||
}
|
||||
|
||||
// Menu items
|
||||
@@ -1037,6 +951,7 @@ void CFrame::DoPause()
|
||||
Core::SetState(Core::CORE_PAUSE);
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
|
||||
m_RenderParent->SetCursor(wxNullCursor);
|
||||
Core::UpdateTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1214,6 +1129,8 @@ void CFrame::OnConfigPAD(wxCommandEvent& WXUNUSED (event))
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
Window win = X11Utils::XWindowFromHandle(GetHandle());
|
||||
Pad::Initialize((void *)win);
|
||||
#elif defined(__APPLE__)
|
||||
Pad::Initialize((void *)this);
|
||||
#else
|
||||
Pad::Initialize(GetHandle());
|
||||
#endif
|
||||
@@ -1238,6 +1155,8 @@ void CFrame::OnConfigWiimote(wxCommandEvent& WXUNUSED (event))
|
||||
#if defined(HAVE_X11) && HAVE_X11
|
||||
Window win = X11Utils::XWindowFromHandle(GetHandle());
|
||||
Wiimote::Initialize((void *)win);
|
||||
#elif defined(__APPLE__)
|
||||
Wiimote::Initialize((void *)this);
|
||||
#else
|
||||
Wiimote::Initialize(GetHandle());
|
||||
#endif
|
||||
@@ -1647,6 +1566,8 @@ void CFrame::UpdateGUI()
|
||||
if (m_ToolBar)
|
||||
m_ToolBar->EnableTool(IDM_PLAY, true);
|
||||
GetMenuBar()->FindItem(IDM_PLAY)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_RECORD)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_PLAYRECORD)->Enable(true);
|
||||
}
|
||||
// Prepare to load last selected file, enable play button
|
||||
else if (!SConfig::GetInstance().m_LastFilename.empty()
|
||||
@@ -1655,6 +1576,8 @@ void CFrame::UpdateGUI()
|
||||
if (m_ToolBar)
|
||||
m_ToolBar->EnableTool(IDM_PLAY, true);
|
||||
GetMenuBar()->FindItem(IDM_PLAY)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_RECORD)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_PLAYRECORD)->Enable(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1662,6 +1585,8 @@ void CFrame::UpdateGUI()
|
||||
if (m_ToolBar)
|
||||
m_ToolBar->EnableTool(IDM_PLAY, false);
|
||||
GetMenuBar()->FindItem(IDM_PLAY)->Enable(false);
|
||||
GetMenuBar()->FindItem(IDM_RECORD)->Enable(false);
|
||||
GetMenuBar()->FindItem(IDM_PLAYRECORD)->Enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1677,6 +1602,8 @@ void CFrame::UpdateGUI()
|
||||
if (m_ToolBar)
|
||||
m_ToolBar->EnableTool(IDM_PLAY, true);
|
||||
GetMenuBar()->FindItem(IDM_PLAY)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_RECORD)->Enable(true);
|
||||
GetMenuBar()->FindItem(IDM_PLAYRECORD)->Enable(true);
|
||||
}
|
||||
}
|
||||
else if (Initialized)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "VideoConfig.h"
|
||||
#include "Host.h"
|
||||
#include "RenderBase.h"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#include "VertexShaderManager.h"
|
||||
#include "../GLInterface.h"
|
||||
@@ -90,13 +91,6 @@ bool cInterfaceAGL::Create(void *&window_handle)
|
||||
}
|
||||
|
||||
bool cInterfaceAGL::MakeCurrent()
|
||||
{
|
||||
[GLWin.cocoaCtx makeCurrentContext];
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update window width, size and etc. Called from Render.cpp
|
||||
void cInterfaceAGL::Update()
|
||||
{
|
||||
int width, height;
|
||||
|
||||
@@ -110,6 +104,7 @@ void cInterfaceAGL::Update()
|
||||
[GLWin.cocoaCtx makeCurrentContext];
|
||||
s_backbuffer_width = width;
|
||||
s_backbuffer_height = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Close backend
|
||||
|
||||
@@ -26,6 +26,12 @@ void cInterfaceEGL::UpdateFPSDisplay(const char *text)
|
||||
{
|
||||
XStoreName(GLWin.dpy, GLWin.win, text);
|
||||
}
|
||||
|
||||
void cInterfaceEGL::SwapInterval(int Interval)
|
||||
{
|
||||
eglSwapInterval(GLWin.egl_dpy, Interval);
|
||||
}
|
||||
|
||||
void cInterfaceEGL::Swap()
|
||||
{
|
||||
eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf);
|
||||
@@ -42,38 +48,30 @@ bool cInterfaceEGL::Create(void *&window_handle)
|
||||
s_backbuffer_width = _twidth;
|
||||
s_backbuffer_height = _theight;
|
||||
|
||||
const char *s;
|
||||
EGLint egl_major, egl_minor;
|
||||
EGLint egl_major, egl_minor;
|
||||
|
||||
GLWin.dpy = XOpenDisplay(NULL);
|
||||
GLWin.dpy = XOpenDisplay(NULL);
|
||||
|
||||
if (!GLWin.dpy) {
|
||||
printf("Error: couldn't open display\n");
|
||||
return false;
|
||||
}
|
||||
if (!GLWin.dpy) {
|
||||
ERROR_LOG(VIDEO, "Error: couldn't open display\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
GLWin.egl_dpy = eglGetDisplay(GLWin.dpy);
|
||||
if (!GLWin.egl_dpy) {
|
||||
printf("Error: eglGetDisplay() failed\n");
|
||||
return false;
|
||||
}
|
||||
GLWin.egl_dpy = eglGetDisplay(GLWin.dpy);
|
||||
if (!GLWin.egl_dpy) {
|
||||
ERROR_LOG(VIDEO, "Error: eglGetDisplay() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglInitialize(GLWin.egl_dpy, &egl_major, &egl_minor)) {
|
||||
printf("Error: eglInitialize() failed\n");
|
||||
return false;
|
||||
}
|
||||
if (!eglInitialize(GLWin.egl_dpy, &egl_major, &egl_minor)) {
|
||||
ERROR_LOG(VIDEO, "Error: eglInitialize() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
s = eglQueryString(GLWin.egl_dpy, EGL_VERSION);
|
||||
printf("EGL_VERSION = %s\n", s);
|
||||
|
||||
s = eglQueryString(GLWin.egl_dpy, EGL_VENDOR);
|
||||
printf("EGL_VENDOR = %s\n", s);
|
||||
|
||||
s = eglQueryString(GLWin.egl_dpy, EGL_EXTENSIONS);
|
||||
printf("EGL_EXTENSIONS = %s\n", s);
|
||||
|
||||
s = eglQueryString(GLWin.egl_dpy, EGL_CLIENT_APIS);
|
||||
printf("EGL_CLIENT_APIS = %s\n", s);
|
||||
INFO_LOG(VIDEO, "EGL_VERSION = %s\n", eglQueryString(GLWin.egl_dpy, EGL_VERSION));
|
||||
INFO_LOG(VIDEO, "EGL_VENDOR = %s\n", eglQueryString(GLWin.egl_dpy, EGL_VENDOR));
|
||||
INFO_LOG(VIDEO, "EGL_EXTENSIONS = %s\n", eglQueryString(GLWin.egl_dpy, EGL_EXTENSIONS));
|
||||
INFO_LOG(VIDEO, "EGL_CLIENT_APIS = %s\n", eglQueryString(GLWin.egl_dpy, EGL_CLIENT_APIS));
|
||||
|
||||
// attributes for a visual in RGBA format with at least
|
||||
// 8 bits per color and a 24 bit depth buffer
|
||||
@@ -102,29 +100,29 @@ bool cInterfaceEGL::Create(void *&window_handle)
|
||||
if (GLWin.parent == 0)
|
||||
GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen);
|
||||
|
||||
XVisualInfo visTemplate;
|
||||
int num_visuals;
|
||||
EGLConfig config;
|
||||
EGLint num_configs;
|
||||
EGLint vid;
|
||||
XVisualInfo visTemplate;
|
||||
int num_visuals;
|
||||
EGLConfig config;
|
||||
EGLint num_configs;
|
||||
EGLint vid;
|
||||
|
||||
if (!eglChooseConfig( GLWin.egl_dpy, attribs, &config, 1, &num_configs)) {
|
||||
printf("Error: couldn't get an EGL visual config\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!eglChooseConfig( GLWin.egl_dpy, attribs, &config, 1, &num_configs)) {
|
||||
ERROR_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
|
||||
printf("Error: eglGetConfigAttrib() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
|
||||
ERROR_LOG(VIDEO, "Error: eglGetConfigAttrib() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The X window visual must match the EGL config */
|
||||
visTemplate.visualid = vid;
|
||||
GLWin.vi = XGetVisualInfo(GLWin.dpy, VisualIDMask, &visTemplate, &num_visuals);
|
||||
if (!GLWin.vi) {
|
||||
printf("Error: couldn't get X visual\n");
|
||||
exit(1);
|
||||
}
|
||||
/* The X window visual must match the EGL config */
|
||||
visTemplate.visualid = vid;
|
||||
GLWin.vi = XGetVisualInfo(GLWin.dpy, VisualIDMask, &visTemplate, &num_visuals);
|
||||
if (!GLWin.vi) {
|
||||
ERROR_LOG(VIDEO, "Error: couldn't get X visual\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
GLWin.x = _tx;
|
||||
GLWin.y = _ty;
|
||||
@@ -138,33 +136,26 @@ bool cInterfaceEGL::Create(void *&window_handle)
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
#endif
|
||||
GLWin.egl_ctx = eglCreateContext(GLWin.egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
|
||||
if (!GLWin.egl_ctx) {
|
||||
printf("Error: eglCreateContext failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!GLWin.egl_ctx) {
|
||||
ERROR_LOG(VIDEO, "Error: eglCreateContext failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, GLWin.win, NULL);
|
||||
if (!GLWin.egl_surf) {
|
||||
printf("Error: eglCreateWindowSurface failed\n");
|
||||
exit(1);
|
||||
}
|
||||
GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, GLWin.win, NULL);
|
||||
if (!GLWin.egl_surf) {
|
||||
ERROR_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx)) {
|
||||
|
||||
printf("Error: eglMakeCurrent() failed\n");
|
||||
return false;
|
||||
}
|
||||
if (!eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx)) {
|
||||
ERROR_LOG(VIDEO, "Error: eglMakeCurrent() failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
|
||||
printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
|
||||
printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
|
||||
printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
|
||||
/* Set initial projection/viewing transformation.
|
||||
* We can't be sure we'll get a ConfigureNotify event when the window
|
||||
* first appears.
|
||||
*/
|
||||
glViewport(0, 0, (GLint) _twidth, (GLint) _theight);
|
||||
INFO_LOG(VIDEO, "GL_VENDOR: %s\n", glGetString(GL_VENDOR));
|
||||
INFO_LOG(VIDEO, "GL_RENDERER: %s\n", glGetString(GL_RENDERER));
|
||||
INFO_LOG(VIDEO, "GL_VERSION: %s\n", glGetString(GL_VERSION));
|
||||
INFO_LOG(VIDEO, "GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
|
||||
window_handle = (void *)GLWin.win;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
cX11Window XWindow;
|
||||
public:
|
||||
friend class cX11Window;
|
||||
void SwapInterval(int Interval);
|
||||
void Swap();
|
||||
void UpdateFPSDisplay(const char *Text);
|
||||
bool Create(void *&window_handle);
|
||||
|
||||
@@ -27,6 +27,15 @@ void cInterfaceGLX::UpdateFPSDisplay(const char *text)
|
||||
{
|
||||
XStoreName(GLWin.dpy, GLWin.win, text);
|
||||
}
|
||||
|
||||
void cInterfaceGLX::SwapInterval(int Interval)
|
||||
{
|
||||
if (glXSwapIntervalSGI)
|
||||
glXSwapIntervalSGI(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
}
|
||||
|
||||
void cInterfaceGLX::Swap()
|
||||
{
|
||||
glXSwapBuffers(GLWin.dpy, GLWin.win);
|
||||
|
||||
@@ -31,6 +31,7 @@ private:
|
||||
cX11Window XWindow;
|
||||
public:
|
||||
friend class cX11Window;
|
||||
void SwapInterval(int Interval);
|
||||
void Swap();
|
||||
void UpdateFPSDisplay(const char *Text);
|
||||
bool Create(void *&window_handle);
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
virtual bool MakeCurrent() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void SwapInterval(int Interval) { }
|
||||
virtual u32 GetBackBufferWidth() { return s_backbuffer_width; }
|
||||
virtual u32 GetBackBufferHeight() { return s_backbuffer_height; }
|
||||
virtual void SetBackBufferDimensions(u32 W, u32 H) {s_backbuffer_width = W; s_backbuffer_height = H; }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user