mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-21 09:49:01 +00:00
Merge branch 'master' into GLSL-master
Conflicts: CMakeLists.txt Source/Core/DolphinWX/Dolphin.vcxproj Source/Core/DolphinWX/Src/GLInterface/WX.cpp Source/Core/DolphinWX/Src/GLInterface/WX.h Source/Core/VideoCommon/Src/TextureCacheBase.cpp Source/Core/VideoCommon/Src/TextureCacheBase.h Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp Source/Plugins/Plugin_VideoDX11/Src/TextureCache.h Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp Source/Plugins/Plugin_VideoDX9/Src/TextureCache.h Source/Plugins/Plugin_VideoOGL/Src/Render.cpp Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp Source/Plugins/Plugin_VideoOGL/Src/TextureCache.h Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp damn mipmap_fixes ...
This commit is contained in:
commit
a629dea4dc
184 changed files with 7637 additions and 6605 deletions
|
@ -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);
|
||||
|
|
|
@ -205,14 +205,7 @@ void CPUInfo::Detect()
|
|||
// Turn the cpu info into a string we can show
|
||||
std::string CPUInfo::Summarize()
|
||||
{
|
||||
std::string sum;
|
||||
if (num_cores == 1)
|
||||
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
|
||||
else
|
||||
{
|
||||
sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);
|
||||
if (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count);
|
||||
}
|
||||
std::string sum(cpu_string);
|
||||
if (bSSE) sum += ", SSE";
|
||||
if (bSSE2) sum += ", SSE2";
|
||||
if (bSSE3) sum += ", SSE3";
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
|
@ -196,8 +197,9 @@ bool CreateFullPath(const std::string &fullPath)
|
|||
// we're done, yay!
|
||||
if (position == fullPath.npos)
|
||||
return true;
|
||||
|
||||
std::string subPath = fullPath.substr(0, position);
|
||||
|
||||
// Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
|
||||
std::string const subPath(fullPath.substr(0, position + 1));
|
||||
if (!File::IsDirectory(subPath))
|
||||
File::CreateDir(subPath);
|
||||
|
||||
|
@ -773,6 +775,24 @@ IOFile::~IOFile()
|
|||
Close();
|
||||
}
|
||||
|
||||
IOFile::IOFile(IOFile&& other)
|
||||
: m_file(NULL), m_good(true)
|
||||
{
|
||||
Swap(other);
|
||||
}
|
||||
|
||||
IOFile& IOFile::operator=(IOFile other)
|
||||
{
|
||||
Swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void IOFile::Swap(IOFile& other)
|
||||
{
|
||||
std::swap(m_file, other.m_file);
|
||||
std::swap(m_good, other.m_good);
|
||||
}
|
||||
|
||||
bool IOFile::Open(const std::string& filename, const char openmode[])
|
||||
{
|
||||
Close();
|
||||
|
|
|
@ -150,7 +150,7 @@ bool ReadFileToString(bool text_file, const char *filename, std::string &str);
|
|||
// simple wrapper for cstdlib file functions to
|
||||
// hopefully will make error checking easier
|
||||
// and make forgetting an fclose() harder
|
||||
class IOFile : NonCopyable
|
||||
class IOFile
|
||||
{
|
||||
public:
|
||||
IOFile();
|
||||
|
@ -158,6 +158,11 @@ public:
|
|||
IOFile(const std::string& filename, const char openmode[]);
|
||||
|
||||
~IOFile();
|
||||
|
||||
IOFile(IOFile&& other);
|
||||
IOFile& operator=(IOFile other);
|
||||
|
||||
void Swap(IOFile& other);
|
||||
|
||||
bool Open(const std::string& filename, const char openmode[]);
|
||||
bool Close();
|
||||
|
@ -212,6 +217,7 @@ public:
|
|||
void Clear() { m_good = true; std::clearerr(m_file); }
|
||||
|
||||
private:
|
||||
IOFile(const IOFile&) /*= delete*/;
|
||||
IOFile& operator=(const IOFile&) /*= delete*/;
|
||||
|
||||
std::FILE* m_file;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace BootManager
|
|||
struct ConfigCache
|
||||
{
|
||||
bool valid, bCPUThread, bSkipIdle, bEnableFPRF, bMMU, bDCBZOFF,
|
||||
bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bDisableWiimoteSpeaker, bHLE_BS2;
|
||||
bVBeam, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bHLE_BS2;
|
||||
int iTLBHack, iCPUCore;
|
||||
std::string strBackend;
|
||||
};
|
||||
|
@ -98,7 +98,6 @@ bool BootCore(const std::string& _rFilename)
|
|||
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;
|
||||
|
||||
|
@ -113,7 +112,6 @@ bool BootCore(const std::string& _rFilename)
|
|||
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);
|
||||
|
@ -173,7 +171,6 @@ void Stop()
|
|||
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;
|
||||
|
|
|
@ -51,8 +51,8 @@ SCoreStartupParameter::SCoreStartupParameter()
|
|||
bRunCompareServer(false), bRunCompareClient(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),
|
||||
|
@ -99,8 +99,6 @@ void SCoreStartupParameter::LoadDefaults()
|
|||
bJITPairedOff = false;
|
||||
bJITSystemRegistersOff = false;
|
||||
|
||||
bDisableWiimoteSpeaker = false;
|
||||
|
||||
m_strName = "NONE";
|
||||
m_strUniqueID = "00000000";
|
||||
}
|
||||
|
|
|
@ -121,7 +121,6 @@ struct SCoreStartupParameter
|
|||
int SelectedLanguage;
|
||||
|
||||
bool bWii;
|
||||
bool bDisableWiimoteSpeaker;
|
||||
|
||||
// Interface settings
|
||||
bool bConfirmStop, bHideCursor, bAutoHideCursor, bUsePanicHandlers, bOnScreenDisplayMessages;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -98,8 +98,8 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
|
|||
client_running = false;
|
||||
clientThread.join();
|
||||
|
||||
recv_fifo = std::queue<u8>();
|
||||
send_fifo = std::queue<u8>();
|
||||
recv_fifo = std::deque<u8>();
|
||||
send_fifo = std::deque<u8>();
|
||||
}
|
||||
clientThread = std::thread(std::mem_fun(&GeckoSockServer::ClientThread), this);
|
||||
client_count++;
|
||||
|
@ -120,28 +120,39 @@ void GeckoSockServer::ClientThread()
|
|||
|
||||
while (client_running)
|
||||
{
|
||||
u8 data;
|
||||
std::size_t got = 0;
|
||||
bool did_nothing = true;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(transfer_lock);
|
||||
|
||||
if (client.Receive((char*)&data, sizeof(data), got)
|
||||
== sf::Socket::Disconnected)
|
||||
// what's an ideal buffer size?
|
||||
char data[128];
|
||||
std::size_t got = 0;
|
||||
|
||||
if (client.Receive(&data[0], ARRAYSIZE(data), got) == sf::Socket::Disconnected)
|
||||
client_running = false;
|
||||
if (got)
|
||||
recv_fifo.push(data);
|
||||
|
||||
if (send_fifo.size())
|
||||
|
||||
if (got != 0)
|
||||
{
|
||||
if (client.Send((char*)&send_fifo.front(), sizeof(u8))
|
||||
== sf::Socket::Disconnected)
|
||||
did_nothing = false;
|
||||
|
||||
recv_fifo.insert(recv_fifo.end(), &data[0], &data[got]);
|
||||
}
|
||||
|
||||
if (!send_fifo.empty())
|
||||
{
|
||||
did_nothing = false;
|
||||
|
||||
std::vector<char> packet(send_fifo.begin(), send_fifo.end());
|
||||
send_fifo.clear();
|
||||
|
||||
if (client.Send(&packet[0], packet.size()) == sf::Socket::Disconnected)
|
||||
client_running = false;
|
||||
send_fifo.pop();
|
||||
}
|
||||
} // unlock transfer
|
||||
|
||||
SLEEP(1);
|
||||
if (did_nothing)
|
||||
Common::YieldCPU();
|
||||
}
|
||||
|
||||
client.Close();
|
||||
|
@ -180,7 +191,7 @@ void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
|
|||
if (!recv_fifo.empty())
|
||||
{
|
||||
_uData = 0x08000000 | (recv_fifo.front() << 16);
|
||||
recv_fifo.pop();
|
||||
recv_fifo.pop_front();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -190,7 +201,7 @@ void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
|
|||
case CMD_SEND:
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(transfer_lock);
|
||||
send_fifo.push(_uData >> 20);
|
||||
send_fifo.push_back(_uData >> 20);
|
||||
_uData = 0x04000000;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "SFML/Network.hpp"
|
||||
#include "Thread.h"
|
||||
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
|
||||
class GeckoSockServer
|
||||
|
@ -36,8 +38,8 @@ public:
|
|||
std::thread clientThread;
|
||||
std::mutex transfer_lock;
|
||||
|
||||
std::queue<u8> send_fifo;
|
||||
std::queue<u8> recv_fifo;
|
||||
std::deque<u8> send_fifo;
|
||||
std::deque<u8> recv_fifo;
|
||||
|
||||
private:
|
||||
static int client_count;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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 = 0;
|
||||
m_VBeamPos = 0;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,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
|
||||
{
|
||||
|
||||
|
|
|
@ -30,13 +30,6 @@
|
|||
#include <vector>
|
||||
#include <queue>
|
||||
|
||||
namespace
|
||||
{
|
||||
// :)
|
||||
auto const TAU = 6.28318530717958647692;
|
||||
auto const PI = TAU / 2.0;
|
||||
}
|
||||
|
||||
// Registry sizes
|
||||
#define WIIMOTE_EEPROM_SIZE (16*1024)
|
||||
#define WIIMOTE_EEPROM_FREE_SIZE 0x1700
|
||||
|
|
|
@ -184,7 +184,7 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes)
|
|||
bool found = false;
|
||||
for(int i = 0; i < MAX_WIIMOTES; i++)
|
||||
{
|
||||
if(wm[i] && strcmp(wm[i]->devicepath, detail_data->DevicePath) == 0)
|
||||
if(wm[i] && (wm[i]->devicepath == detail_data->DevicePath))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
|
@ -210,7 +210,7 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes)
|
|||
for (; k < MAX_WIIMOTES && !(WIIMOTE_SRC_REAL & g_wiimote_sources[k] && !wm[k]); ++k);
|
||||
wm[k] = new Wiimote(k);
|
||||
wm[k]->dev_handle = dev;
|
||||
memcpy(wm[k]->devicepath, detail_data->DevicePath, 197);
|
||||
wm[k]->devicepath = detail_data->DevicePath;
|
||||
|
||||
if (!wm[k]->Connect())
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ bool Wiimote::Connect()
|
|||
|
||||
if (!dev_handle)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -181,23 +181,23 @@ bool Wiimote::Read()
|
|||
bool Wiimote::Write()
|
||||
{
|
||||
Report rpt;
|
||||
bool audio_written = false;
|
||||
|
||||
if (m_audio_reports.Pop(rpt))
|
||||
if (last_audio_report.GetTimeDifference() > 5 && m_audio_reports.Pop(rpt))
|
||||
{
|
||||
IOWrite(rpt.first, rpt.second);
|
||||
last_audio_report.Update();
|
||||
|
||||
delete[] rpt.first;
|
||||
audio_written = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_write_reports.Pop(rpt))
|
||||
else 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
|
||||
|
@ -319,14 +319,9 @@ void Wiimote::ThreadFunc()
|
|||
while (Write()) {}
|
||||
Common::SleepCurrentThread(1);
|
||||
#else
|
||||
bool read = false;
|
||||
while (Write() || (read = true, IsOpen() && Read()))
|
||||
{
|
||||
if (m_audio_reports.Size() && !read)
|
||||
Read();
|
||||
Common::SleepCurrentThread(m_audio_reports.Size() ? 5 : 2);
|
||||
read = false;
|
||||
}
|
||||
bool const did_something = Write() || Read();
|
||||
if (!did_something)
|
||||
Common::SleepCurrentThread(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "ChunkFile.h"
|
||||
#include "Thread.h"
|
||||
#include "FifoQueue.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include "../Wiimote.h"
|
||||
#include "../WiimoteEmu/WiimoteEmu.h"
|
||||
|
@ -77,7 +78,7 @@ public:
|
|||
void Close();
|
||||
|
||||
#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
|
||||
|
@ -103,6 +104,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;
|
||||
};
|
||||
|
||||
extern std::mutex g_refresh_lock;
|
||||
|
|
|
@ -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,19 @@ 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;
|
||||
|
||||
static u64 last_reply_time;
|
||||
|
||||
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;
|
||||
|
@ -152,6 +165,7 @@ void Reset(bool _bHard)
|
|||
}
|
||||
request_queue.clear();
|
||||
reply_queue.clear();
|
||||
last_reply_time = 0;
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
@ -235,6 +249,7 @@ void DoState(PointerWrap &p)
|
|||
{
|
||||
p.Do(request_queue);
|
||||
p.Do(reply_queue);
|
||||
p.Do(last_reply_time);
|
||||
|
||||
TDeviceMap::const_iterator itr;
|
||||
|
||||
|
@ -338,7 +353,7 @@ void ExecuteCommand(u32 _Address)
|
|||
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
|
||||
|
||||
|
||||
WARN_LOG(WII_IPC_HLE, "Tried to open %s as %d", DeviceName.c_str(), DeviceID);
|
||||
WARN_LOG(WII_IPC_HLE, "Trying to open %s as %d", DeviceName.c_str(), DeviceID);
|
||||
if (DeviceID >= 0)
|
||||
{
|
||||
if (DeviceName.find("/dev/es") == 0)
|
||||
|
@ -382,7 +397,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 +409,7 @@ void ExecuteCommand(u32 _Address)
|
|||
else
|
||||
{
|
||||
delete pDevice;
|
||||
pDevice = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -424,7 +440,10 @@ void ExecuteCommand(u32 _Address)
|
|||
|
||||
// Don't delete hardware
|
||||
if (!pDevice->IsHardware())
|
||||
{
|
||||
delete pDevice;
|
||||
pDevice = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -503,8 +522,19 @@ void ExecuteCommand(u32 _Address)
|
|||
|
||||
if (CmdSuccess)
|
||||
{
|
||||
// Ensure replies happen in order, fairly ugly
|
||||
// Without this, tons of games fail now that DI commads have different reply delays
|
||||
int reply_delay = pDevice ? pDevice->GetCmdDelay(_Address) : 0;
|
||||
|
||||
const s64 ticks_til_last_reply = last_reply_time - CoreTiming::GetTicks();
|
||||
|
||||
if (ticks_til_last_reply > 0)
|
||||
reply_delay = ticks_til_last_reply;
|
||||
|
||||
last_reply_time = CoreTiming::GetTicks() + reply_delay;
|
||||
|
||||
// Generate a reply to the IPC command
|
||||
EnqReply(_Address);
|
||||
EnqReply(_Address, reply_delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -526,9 +556,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,45 @@ 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 _CommandAddress)
|
||||
{
|
||||
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
u32 Command = Memory::Read_U32(BufferIn) >> 24;
|
||||
|
||||
// Hacks below
|
||||
|
||||
switch (Command)
|
||||
{
|
||||
case DVDLowRead:
|
||||
case DVDLowUnencryptedRead:
|
||||
{
|
||||
u32 const Size = Memory::Read_U32(BufferIn + 0x04);
|
||||
// Delay depends on size of read, that makes sense, right?
|
||||
// More than ~1150K "bytes / sec" hangs NSMBWii on boot.
|
||||
// Less than ~800K "bytes / sec" hangs DKCR randomly (ok, probably not true)
|
||||
return SystemTimers::GetTicksPerSecond() / 975000 * Size;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVDLowClearCoverInterrupt:
|
||||
// Less than ~1/155th of a second hangs Oregon Trail at "loading wheel".
|
||||
// More than ~1/140th of a second hangs Resident Evil Archives: Resident Evil Zero.
|
||||
return SystemTimers::GetTicksPerSecond() / 146;
|
||||
break;
|
||||
|
||||
// case DVDLowAudioBufferConfig:
|
||||
// case DVDLowInquiry:
|
||||
// case DVDLowReadDiskID:
|
||||
// case DVDLowWaitForCoverClose:
|
||||
// case DVDLowGetCoverReg:
|
||||
// case DVDLowGetCoverStatus:
|
||||
// case DVDLowReset:
|
||||
// case DVDLowClosePartition:
|
||||
default:
|
||||
// ranom numbers here!
|
||||
// More than ~1/2000th of a second hangs DKCR with DSP HLE, maybe.
|
||||
return SystemTimers::GetTicksPerSecond() / 15000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ public:
|
|||
|
||||
bool IOCtl(u32 _CommandAddress);
|
||||
bool IOCtlV(u32 _CommandAddress);
|
||||
|
||||
int GetCmdDelay(u32);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -28,17 +28,16 @@
|
|||
|
||||
static Common::replace_v replacements;
|
||||
|
||||
// This is used by several of the FileIO and /dev/fs functions
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
||||
// This is used by several of the FileIO and /dev/fs functions
|
||||
std::string HLE_IPC_BuildFilename(std::string path_wii, int _size)
|
||||
{
|
||||
std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
|
||||
std::string path_wii(_pFilename);
|
||||
|
||||
if ((path_wii.length() > 0) && (path_wii[1] == '0'))
|
||||
path_full += std::string("/title"); // this looks and feel like a hack...
|
||||
|
||||
// Replaces chars that FAT32 can't support with strings defined in /sys/replace
|
||||
for (Common::replace_v::const_iterator i = replacements.begin(); i != replacements.end(); ++i)
|
||||
for (auto i = replacements.begin(); i != replacements.end(); ++i)
|
||||
{
|
||||
for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j)
|
||||
path_wii.replace(j, 1, i->second);
|
||||
|
@ -82,9 +81,8 @@ void HLE_IPC_CreateVirtualFATFilesystem()
|
|||
}
|
||||
}
|
||||
|
||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
|
||||
, m_pFileHandle(NULL)
|
||||
, m_Mode(0)
|
||||
, m_SeekPos(0)
|
||||
{
|
||||
|
@ -108,12 +106,9 @@ bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
|
|||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||
{
|
||||
{
|
||||
m_Mode = _Mode;
|
||||
u32 ReturnValue = 0;
|
||||
|
||||
// close the file handle if we get a reopen
|
||||
//m_pFileHandle.Close();
|
||||
|
||||
static const char* const Modes[] =
|
||||
{
|
||||
|
@ -122,20 +117,19 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
"Write only",
|
||||
"Read and Write"
|
||||
};
|
||||
|
||||
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
|
||||
|
||||
m_filepath = HLE_IPC_BuildFilename(m_Name, 64);
|
||||
|
||||
// The file must exist before we can open it
|
||||
// It should be created by ISFS_CreateFile, not here
|
||||
if (File::Exists(m_Filename))
|
||||
if (File::Exists(m_filepath))
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
|
||||
ReturnValue = m_DeviceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], m_Filename.c_str());
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], m_filepath.c_str());
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
|
@ -145,55 +139,43 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
{
|
||||
const char* open_mode = "";
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case ISFS_OPEN_READ:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "rb");
|
||||
open_mode = "rb";
|
||||
break;
|
||||
}
|
||||
|
||||
case ISFS_OPEN_WRITE:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
}
|
||||
case ISFS_OPEN_RW:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
open_mode = "r+b";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_pFileHandle.IsOpen();
|
||||
|
||||
return File::IOFile(m_filepath, open_mode);
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_FileIO::CloseFile()
|
||||
{
|
||||
m_pFileHandle.Close();
|
||||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
{
|
||||
u32 ReturnValue = FS_RESULT_FATAL;
|
||||
const u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
ReturnValue = FS_RESULT_FATAL;
|
||||
|
||||
const u64 fileSize = m_pFileHandle.GetSize();
|
||||
const u64 fileSize = file.GetSize();
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||
switch (Mode){
|
||||
switch (Mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (SeekPosition <= fileSize)
|
||||
|
@ -230,7 +212,6 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
|||
break;
|
||||
}
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -248,18 +229,18 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to read 0x%x bytes to 0x%08x on write-only file %s", Size, Address, m_Name.c_str());
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle.GetHandle());
|
||||
if (ReturnValue != Size && ferror(m_pFileHandle.GetHandle()))
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle());
|
||||
if (ReturnValue != Size && ferror(file.GetHandle()))
|
||||
{
|
||||
ReturnValue = FS_EACCESS;
|
||||
}
|
||||
|
@ -269,7 +250,6 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
}
|
||||
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -288,23 +268,22 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to write 0x%x bytes from 0x%08x to read-only file %s", Size, Address, m_Name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
if (m_pFileHandle.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
if (file.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
{
|
||||
ReturnValue = Size;
|
||||
m_SeekPos += Size;
|
||||
}
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -329,9 +308,9 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
u32 m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||
u32 m_FileLength = (u32)file.GetSize();
|
||||
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||
|
@ -339,7 +318,6 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
|
||||
Memory::Write_U32(m_FileLength, BufferOut);
|
||||
Memory::Write_U32(m_SeekPos, BufferOut+4);
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -365,30 +343,8 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
|||
{
|
||||
DoStateShared(p);
|
||||
|
||||
bool have_file_handle = (m_pFileHandle != 0);
|
||||
s32 seek = (have_file_handle) ? (s32)m_pFileHandle.Tell() : 0;
|
||||
|
||||
p.Do(have_file_handle);
|
||||
p.Do(m_Mode);
|
||||
p.Do(seek);
|
||||
p.Do(m_SeekPos);
|
||||
p.Do(m_Filename);
|
||||
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
{
|
||||
int mode = m_Mode;
|
||||
bool active = m_Active;
|
||||
if (have_file_handle)
|
||||
{
|
||||
Open(0, m_Mode);
|
||||
_dbg_assert_msg_(WII_IPC_HLE, m_pFileHandle, "bad filehandle");
|
||||
}
|
||||
else
|
||||
Close(0, true);
|
||||
m_Mode = mode;
|
||||
m_Active = active;
|
||||
}
|
||||
|
||||
if (have_file_handle)
|
||||
m_pFileHandle.Seek(seek, SEEK_SET);
|
||||
|
||||
m_filepath = HLE_IPC_BuildFilename(m_Name, 64);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "WII_IPC_HLE_Device.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
|
||||
std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size);
|
||||
void HLE_IPC_CreateVirtualFATFilesystem();
|
||||
|
||||
class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
|
||||
|
@ -39,8 +39,7 @@ public:
|
|||
bool IOCtl(u32 _CommandAddress);
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
bool OpenFile();
|
||||
void CloseFile();
|
||||
File::IOFile OpenFile();
|
||||
|
||||
private:
|
||||
enum
|
||||
|
@ -76,12 +75,10 @@ private:
|
|||
ISFS_IOCTL_SHUTDOWN
|
||||
};
|
||||
|
||||
File::IOFile m_pFileHandle;
|
||||
u32 m_Mode;
|
||||
|
||||
u32 m_SeekPos;
|
||||
|
||||
std::string m_Filename;
|
||||
|
||||
std::string m_filepath;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "FileUtil.h"
|
||||
#include "NandPaths.h"
|
||||
#include "ChunkFile.h"
|
||||
#include "../HW/SystemTimers.h"
|
||||
|
||||
#include "../VolumeHandler.h"
|
||||
|
||||
|
@ -427,7 +428,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
File::CreateFullPath(FilenameRename);
|
||||
|
||||
// if there is already a file, delete it
|
||||
if (File::Exists(FilenameRename))
|
||||
if (File::Exists(Filename) && File::Exists(FilenameRename))
|
||||
{
|
||||
File::Delete(FilenameRename);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 = 13;
|
||||
|
||||
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
|
||||
|
|
|
@ -215,7 +215,7 @@ bool CNANDContentLoader::Initialize(const std::string& _rName)
|
|||
{
|
||||
std::string TMDFileName(m_Path);
|
||||
|
||||
if (File::IsDirectory(TMDFileName))
|
||||
if ('/' == *TMDFileName.rbegin())
|
||||
TMDFileName += "title.tmd";
|
||||
else
|
||||
m_Path = TMDFileName.substr(0, TMDFileName.find("title.tmd"));
|
||||
|
|
|
@ -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>
|
||||
|
@ -150,6 +151,7 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
|||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
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>
|
||||
|
@ -166,6 +168,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>
|
||||
|
@ -180,6 +183,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>
|
||||
|
@ -195,6 +199,11 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
|||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
xcopy "$(SolutionDir)..\Externals\Cg64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
>>>>>>> master
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
|
@ -210,6 +219,11 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
|
|||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)..\Data" "$(TargetDir)" /e /s /y /d
|
||||
echo Copying External .dlls
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
xcopy "$(SolutionDir)..\Externals\Cg64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
xcopy "$(SolutionDir)..\Externals\OpenAL\Win64\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
>>>>>>> master
|
||||
xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /s /y /q /d
|
||||
</Command>
|
||||
<Message>Copying Data\* to $(TargetDir)</Message>
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -625,7 +624,9 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
|||
int stream_size = Common::swap16(objectdata);
|
||||
objectdata += 2;
|
||||
wxString newLabel = wxString::Format(wxT("%08X: %02X %04X "), obj_offset, cmd, stream_size);
|
||||
if ((objectdata_end - objectdata) % stream_size) newLabel += _("NOTE: Stream size doesn't match actual data length\n");
|
||||
if (stream_size && ((objectdata_end - objectdata) % stream_size))
|
||||
newLabel += _("NOTE: Stream size doesn't match actual data length\n");
|
||||
|
||||
while (objectdata < objectdata_end)
|
||||
{
|
||||
newLabel += wxString::Format(wxT("%02X"), *objectdata++);
|
||||
|
@ -642,8 +643,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 +692,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:
|
||||
|
|
|
@ -1566,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()
|
||||
|
@ -1574,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
|
||||
{
|
||||
|
@ -1581,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1596,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)
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -27,6 +27,13 @@
|
|||
static HDC hDC = NULL; // Private GDI Device Context
|
||||
static HGLRC hRC = NULL; // Permanent Rendering Context
|
||||
|
||||
void cInterfaceWGL::SwapInterval(int Interval)
|
||||
{
|
||||
if (WGLEW_EXT_swap_control)
|
||||
wglSwapIntervalEXT(Interval);
|
||||
else
|
||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||
}
|
||||
void cInterfaceWGL::Swap()
|
||||
{
|
||||
SwapBuffers(hDC);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
class cInterfaceWGL : public cInterfaceBase
|
||||
{
|
||||
public:
|
||||
void SwapInterval(int Interval);
|
||||
void Swap();
|
||||
void UpdateFPSDisplay(const char *Text);
|
||||
bool Create(void *&window_handle);
|
||||
|
|
|
@ -57,6 +57,8 @@ size_t CGameListCtrl::m_numberItem = 0;
|
|||
std::string CGameListCtrl::m_currentFilename;
|
||||
bool sorted = false;
|
||||
|
||||
extern CFrame* main_frame;
|
||||
|
||||
static int CompareGameListItems(const GameListItem* iso1, const GameListItem* iso2,
|
||||
long sortData = CGameListCtrl::COLUMN_TITLE)
|
||||
{
|
||||
|
@ -94,6 +96,13 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is
|
|||
switch(sortData)
|
||||
{
|
||||
case CGameListCtrl::COLUMN_TITLE:
|
||||
if (!strcasecmp(iso1->GetName(indexOne).c_str(),iso2->GetName(indexOther).c_str()))
|
||||
{
|
||||
if (iso1->IsDiscTwo())
|
||||
return 1 * t;
|
||||
else if (iso2->IsDiscTwo())
|
||||
return -1 * t;
|
||||
}
|
||||
return strcasecmp(iso1->GetName(indexOne).c_str(),
|
||||
iso2->GetName(indexOther).c_str()) * t;
|
||||
case CGameListCtrl::COLUMN_NOTES:
|
||||
|
@ -366,7 +375,8 @@ void CGameListCtrl::Update()
|
|||
SetItemFont(index, *wxITALIC_FONT);
|
||||
SetColumnWidth(0, wxLIST_AUTOSIZE);
|
||||
}
|
||||
|
||||
if (GetSelectedISO() == NULL)
|
||||
main_frame->UpdateGUI();
|
||||
Show();
|
||||
|
||||
AutomaticColumnWidth();
|
||||
|
@ -968,7 +978,7 @@ const GameListItem * CGameListCtrl::GetSelectedISO()
|
|||
{
|
||||
long item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
|
||||
if (item == wxNOT_FOUND)
|
||||
return new GameListItem(""); // TODO: wtf is this
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
// Here is a little workaround for multiselections:
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "ChunkFile.h"
|
||||
#include "../resources/no_banner.cpp"
|
||||
|
||||
#define CACHE_REVISION 0x10E
|
||||
#define CACHE_REVISION 0x10F
|
||||
|
||||
#define DVD_BANNER_WIDTH 96
|
||||
#define DVD_BANNER_HEIGHT 32
|
||||
|
@ -91,6 +91,7 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||
|
||||
m_UniqueID = pVolume->GetUniqueID();
|
||||
m_BlobCompressed = DiscIO::IsCompressedBlob(_rFileName.c_str());
|
||||
m_IsDiscTwo = pVolume->IsDiscTwo();
|
||||
|
||||
// check if we can get some infos from the banner file too
|
||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
||||
|
@ -235,6 +236,7 @@ void GameListItem::DoState(PointerWrap &p)
|
|||
p.Do(m_BlobCompressed);
|
||||
p.Do(m_pImage);
|
||||
p.Do(m_Platform);
|
||||
p.Do(m_IsDiscTwo);
|
||||
}
|
||||
|
||||
std::string GameListItem::CreateCacheFilename()
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
bool IsCompressed() const {return m_BlobCompressed;}
|
||||
u64 GetFileSize() const {return m_FileSize;}
|
||||
u64 GetVolumeSize() const {return m_VolumeSize;}
|
||||
bool IsDiscTwo() const {return m_IsDiscTwo;}
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
const wxImage& GetImage() const {return m_Image;}
|
||||
#endif
|
||||
|
@ -87,6 +88,7 @@ private:
|
|||
bool m_BlobCompressed;
|
||||
std::vector<u8> m_pImage;
|
||||
u32 m_ImageSize;
|
||||
bool m_IsDiscTwo;
|
||||
|
||||
bool LoadFromCache();
|
||||
void SaveToCache();
|
||||
|
|
|
@ -328,8 +328,6 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
|||
|
||||
// Wii Console
|
||||
EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||
DisableWiimoteSpeaker = new wxCheckBox(m_GameConfig, ID_DISABLEWIIMOTESPEAKER, _("Alternate Wiimote Timing"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||
DisableWiimoteSpeaker->SetToolTip(_("Mutes the Wiimote speaker. Fixes random disconnections on real wiimotes. No effect on emulated wiimotes."));
|
||||
|
||||
// Video
|
||||
UseBBox = new wxCheckBox(m_GameConfig, ID_USE_BBOX, _("Enable Bounding Box Calculation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER);
|
||||
|
@ -377,10 +375,8 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
|||
{
|
||||
sbWiiOverrides->ShowItems(false);
|
||||
EnableWideScreen->Hide();
|
||||
DisableWiimoteSpeaker->Hide();
|
||||
}
|
||||
sbWiiOverrides->Add(EnableWideScreen, 0, wxLEFT, 5);
|
||||
sbWiiOverrides->Add(DisableWiimoteSpeaker, 0, wxLEFT, 5);
|
||||
|
||||
wxStaticBoxSizer * const sbVideoOverrides =
|
||||
new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Video"));
|
||||
|
@ -966,11 +962,6 @@ void CISOProperties::LoadGameConfig()
|
|||
else
|
||||
EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED);
|
||||
|
||||
if (GameIni.Get("Wii", "DisableWiimoteSpeaker", &bTemp))
|
||||
DisableWiimoteSpeaker->Set3StateValue((wxCheckBoxState)bTemp);
|
||||
else
|
||||
DisableWiimoteSpeaker->Set3StateValue(wxCHK_UNDETERMINED);
|
||||
|
||||
if (GameIni.Get("Video", "UseBBox", &bTemp))
|
||||
UseBBox->Set3StateValue((wxCheckBoxState)bTemp);
|
||||
else
|
||||
|
@ -999,7 +990,6 @@ void CISOProperties::LoadGameConfig()
|
|||
if (!sTemp.empty())
|
||||
{
|
||||
EmuIssues->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
|
||||
bRefreshList = true;
|
||||
}
|
||||
EmuIssues->Enable(EmuState->GetSelection() != 0);
|
||||
|
||||
|
@ -1060,11 +1050,6 @@ bool CISOProperties::SaveGameConfig()
|
|||
else
|
||||
GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue());
|
||||
|
||||
if (DisableWiimoteSpeaker->Get3StateValue() == wxCHK_UNDETERMINED)
|
||||
GameIni.DeleteKey("Wii", "DisableWiimoteSpeaker");
|
||||
else
|
||||
GameIni.Set("Wii", "DisableWiimoteSpeaker", DisableWiimoteSpeaker->Get3StateValue());
|
||||
|
||||
if (UseBBox->Get3StateValue() == wxCHK_UNDETERMINED)
|
||||
GameIni.DeleteKey("Video", "UseBBox");
|
||||
else
|
||||
|
@ -1085,6 +1070,11 @@ bool CISOProperties::SaveGameConfig()
|
|||
GameIni.Set("Video", "PH_ZFar", PHack_Data.PHZFar);
|
||||
|
||||
GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection());
|
||||
|
||||
std::string sTemp;
|
||||
GameIni.Get("EmuState","EmulationIssues", &sTemp);
|
||||
if (EmuIssues->GetValue() != sTemp)
|
||||
bRefreshList = true;
|
||||
GameIni.Set("EmuState", "EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent));
|
||||
|
||||
PatchList_Save();
|
||||
|
|
|
@ -72,7 +72,7 @@ private:
|
|||
wxCheckBox *CPUThread, *SkipIdle, *MMU, *DCBZOFF, *TLBHack;
|
||||
wxCheckBox *VBeam, *FastDiscSpeed, *BlockMerging, *DSPHLE;
|
||||
// Wii
|
||||
wxCheckBox *EnableWideScreen, *DisableWiimoteSpeaker;
|
||||
wxCheckBox *EnableWideScreen;
|
||||
// Video
|
||||
wxCheckBox *UseZTPSpeedupHack, *PHackEnable, *UseBBox;
|
||||
wxButton *PHSettings;
|
||||
|
@ -139,7 +139,6 @@ private:
|
|||
ID_PHSETTINGS,
|
||||
ID_ENABLEPROGRESSIVESCAN,
|
||||
ID_ENABLEWIDESCREEN,
|
||||
ID_DISABLEWIIMOTESPEAKER,
|
||||
ID_EDITCONFIG,
|
||||
ID_EMUSTATE,
|
||||
ID_EMU_ISSUES,
|
||||
|
|
|
@ -519,7 +519,7 @@ wxStaticBoxSizer* ControlDialog::CreateControlChooser(GamepadPage* const parent)
|
|||
button_sizer->Add(add_button, 1, 0, 5);
|
||||
}
|
||||
|
||||
range_slider = new wxSlider(this, -1, SLIDER_TICK_COUNT, 0, SLIDER_TICK_COUNT * 5, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/);
|
||||
range_slider = new wxSlider(this, -1, SLIDER_TICK_COUNT, -SLIDER_TICK_COUNT * 5, SLIDER_TICK_COUNT * 5, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/);
|
||||
|
||||
range_slider->SetValue((int)(control_reference->range * SLIDER_TICK_COUNT));
|
||||
|
||||
|
|
|
@ -1099,8 +1099,8 @@ wxBitmap TASInputDlg::CreateStickBitmap(int x, int y)
|
|||
y = y/2;
|
||||
|
||||
wxMemoryDC memDC;
|
||||
wxBitmap bitmap(127, 127);
|
||||
memDC.SelectObject(bitmap);
|
||||
wxBitmap stick_bitmap(127, 127);
|
||||
memDC.SelectObject(stick_bitmap);
|
||||
memDC.SetBackground(*wxLIGHT_GREY_BRUSH);
|
||||
memDC.Clear();
|
||||
memDC.SetBrush(*wxWHITE_BRUSH);
|
||||
|
@ -1116,5 +1116,5 @@ wxBitmap TASInputDlg::CreateStickBitmap(int x, int y)
|
|||
memDC.SetBrush(*wxBLUE_BRUSH);
|
||||
memDC.DrawCircle(x,y,5);
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
return bitmap;
|
||||
return stick_bitmap;
|
||||
}
|
||||
|
|
|
@ -124,12 +124,12 @@ void EWMH_Fullscreen(Display *dpy, int action)
|
|||
#if defined(HAVE_WX) && HAVE_WX
|
||||
Window XWindowFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XID(GTK_WIDGET(Handle)->window);
|
||||
return GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
|
||||
Display *XDisplayFromHandle(void *Handle)
|
||||
{
|
||||
return GDK_WINDOW_XDISPLAY(GTK_WIDGET(Handle)->window);
|
||||
return GDK_WINDOW_XDISPLAY(gtk_widget_get_window(GTK_WIDGET(Handle)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,279 +1,28 @@
|
|||
static const unsigned char no_banner_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0xed, 0xc0, 0x7d, 0x54, 0x00, 0x00, 0x00,
|
||||
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
|
||||
0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x0a, 0x4f, 0x69, 0x43,
|
||||
0x43, 0x50, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20,
|
||||
0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00,
|
||||
0x00, 0x78, 0xda, 0x9d, 0x53, 0x67, 0x54, 0x53, 0xe9, 0x16, 0x3d, 0xf7,
|
||||
0xde, 0xf4, 0x42, 0x4b, 0x88, 0x80, 0x94, 0x4b, 0x6f, 0x52, 0x15, 0x08,
|
||||
0x20, 0x52, 0x42, 0x8b, 0x80, 0x14, 0x91, 0x26, 0x2a, 0x21, 0x09, 0x10,
|
||||
0x4a, 0x88, 0x21, 0xa1, 0xd9, 0x15, 0x51, 0xc1, 0x11, 0x45, 0x45, 0x04,
|
||||
0x1b, 0xc8, 0xa0, 0x88, 0x03, 0x8e, 0x8e, 0x80, 0x8c, 0x15, 0x51, 0x2c,
|
||||
0x0c, 0x8a, 0x0a, 0xd8, 0x07, 0xe4, 0x21, 0xa2, 0x8e, 0x83, 0xa3, 0x88,
|
||||
0x8a, 0xca, 0xfb, 0xe1, 0x7b, 0xa3, 0x6b, 0xd6, 0xbc, 0xf7, 0xe6, 0xcd,
|
||||
0xfe, 0xb5, 0xd7, 0x3e, 0xe7, 0xac, 0xf3, 0x9d, 0xb3, 0xcf, 0x07, 0xc0,
|
||||
0x08, 0x0c, 0x96, 0x48, 0x33, 0x51, 0x35, 0x80, 0x0c, 0xa9, 0x42, 0x1e,
|
||||
0x11, 0xe0, 0x83, 0xc7, 0xc4, 0xc6, 0xe1, 0xe4, 0x2e, 0x40, 0x81, 0x0a,
|
||||
0x24, 0x70, 0x00, 0x10, 0x08, 0xb3, 0x64, 0x21, 0x73, 0xfd, 0x23, 0x01,
|
||||
0x00, 0xf8, 0x7e, 0x3c, 0x3c, 0x2b, 0x22, 0xc0, 0x07, 0xbe, 0x00, 0x01,
|
||||
0x78, 0xd3, 0x0b, 0x08, 0x00, 0xc0, 0x4d, 0x9b, 0xc0, 0x30, 0x1c, 0x87,
|
||||
0xff, 0x0f, 0xea, 0x42, 0x99, 0x5c, 0x01, 0x80, 0x84, 0x01, 0xc0, 0x74,
|
||||
0x91, 0x38, 0x4b, 0x08, 0x80, 0x14, 0x00, 0x40, 0x7a, 0x8e, 0x42, 0xa6,
|
||||
0x00, 0x40, 0x46, 0x01, 0x80, 0x9d, 0x98, 0x26, 0x53, 0x00, 0xa0, 0x04,
|
||||
0x00, 0x60, 0xcb, 0x63, 0x62, 0xe3, 0x00, 0x50, 0x2d, 0x00, 0x60, 0x27,
|
||||
0x7f, 0xe6, 0xd3, 0x00, 0x80, 0x9d, 0xf8, 0x99, 0x7b, 0x01, 0x00, 0x5b,
|
||||
0x94, 0x21, 0x15, 0x01, 0xa0, 0x91, 0x00, 0x20, 0x13, 0x65, 0x88, 0x44,
|
||||
0x00, 0x68, 0x3b, 0x00, 0xac, 0xcf, 0x56, 0x8a, 0x45, 0x00, 0x58, 0x30,
|
||||
0x00, 0x14, 0x66, 0x4b, 0xc4, 0x39, 0x00, 0xd8, 0x2d, 0x00, 0x30, 0x49,
|
||||
0x57, 0x66, 0x48, 0x00, 0xb0, 0xb7, 0x00, 0xc0, 0xce, 0x10, 0x0b, 0xb2,
|
||||
0x00, 0x08, 0x0c, 0x00, 0x30, 0x51, 0x88, 0x85, 0x29, 0x00, 0x04, 0x7b,
|
||||
0x00, 0x60, 0xc8, 0x23, 0x23, 0x78, 0x00, 0x84, 0x99, 0x00, 0x14, 0x46,
|
||||
0xf2, 0x57, 0x3c, 0xf1, 0x2b, 0xae, 0x10, 0xe7, 0x2a, 0x00, 0x00, 0x78,
|
||||
0x99, 0xb2, 0x3c, 0xb9, 0x24, 0x39, 0x45, 0x81, 0x5b, 0x08, 0x2d, 0x71,
|
||||
0x07, 0x57, 0x57, 0x2e, 0x1e, 0x28, 0xce, 0x49, 0x17, 0x2b, 0x14, 0x36,
|
||||
0x61, 0x02, 0x61, 0x9a, 0x40, 0x2e, 0xc2, 0x79, 0x99, 0x19, 0x32, 0x81,
|
||||
0x34, 0x0f, 0xe0, 0xf3, 0xcc, 0x00, 0x00, 0xa0, 0x91, 0x15, 0x11, 0xe0,
|
||||
0x83, 0xf3, 0xfd, 0x78, 0xce, 0x0e, 0xae, 0xce, 0xce, 0x36, 0x8e, 0xb6,
|
||||
0x0e, 0x5f, 0x2d, 0xea, 0xbf, 0x06, 0xff, 0x22, 0x62, 0x62, 0xe3, 0xfe,
|
||||
0xe5, 0xcf, 0xab, 0x70, 0x40, 0x00, 0x00, 0xe1, 0x74, 0x7e, 0xd1, 0xfe,
|
||||
0x2c, 0x2f, 0xb3, 0x1a, 0x80, 0x3b, 0x06, 0x80, 0x6d, 0xfe, 0xa2, 0x25,
|
||||
0xee, 0x04, 0x68, 0x5e, 0x0b, 0xa0, 0x75, 0xf7, 0x8b, 0x66, 0xb2, 0x0f,
|
||||
0x40, 0xb5, 0x00, 0xa0, 0xe9, 0xda, 0x57, 0xf3, 0x70, 0xf8, 0x7e, 0x3c,
|
||||
0x3c, 0x45, 0xa1, 0x90, 0xb9, 0xd9, 0xd9, 0xe5, 0xe4, 0xe4, 0xd8, 0x4a,
|
||||
0xc4, 0x42, 0x5b, 0x61, 0xca, 0x57, 0x7d, 0xfe, 0x67, 0xc2, 0x5f, 0xc0,
|
||||
0x57, 0xfd, 0x6c, 0xf9, 0x7e, 0x3c, 0xfc, 0xf7, 0xf5, 0xe0, 0xbe, 0xe2,
|
||||
0x24, 0x81, 0x32, 0x5d, 0x81, 0x47, 0x04, 0xf8, 0xe0, 0xc2, 0xcc, 0xf4,
|
||||
0x4c, 0xa5, 0x1c, 0xcf, 0x92, 0x09, 0x84, 0x62, 0xdc, 0xe6, 0x8f, 0x47,
|
||||
0xfc, 0xb7, 0x0b, 0xff, 0xfc, 0x1d, 0xd3, 0x22, 0xc4, 0x49, 0x62, 0xb9,
|
||||
0x58, 0x2a, 0x14, 0xe3, 0x51, 0x12, 0x71, 0x8e, 0x44, 0x9a, 0x8c, 0xf3,
|
||||
0x32, 0xa5, 0x22, 0x89, 0x42, 0x92, 0x29, 0xc5, 0x25, 0xd2, 0xff, 0x64,
|
||||
0xe2, 0xdf, 0x2c, 0xfb, 0x03, 0x3e, 0xdf, 0x35, 0x00, 0xb0, 0x6a, 0x3e,
|
||||
0x01, 0x7b, 0x91, 0x2d, 0xa8, 0x5d, 0x63, 0x03, 0xf6, 0x4b, 0x27, 0x10,
|
||||
0x58, 0x74, 0xc0, 0xe2, 0xf7, 0x00, 0x00, 0xf2, 0xbb, 0x6f, 0xc1, 0xd4,
|
||||
0x28, 0x08, 0x03, 0x80, 0x68, 0x83, 0xe1, 0xcf, 0x77, 0xff, 0xef, 0x3f,
|
||||
0xfd, 0x47, 0xa0, 0x25, 0x00, 0x80, 0x66, 0x49, 0x92, 0x71, 0x00, 0x00,
|
||||
0x5e, 0x44, 0x24, 0x2e, 0x54, 0xca, 0xb3, 0x3f, 0xc7, 0x08, 0x00, 0x00,
|
||||
0x44, 0xa0, 0x81, 0x2a, 0xb0, 0x41, 0x1b, 0xf4, 0xc1, 0x18, 0x2c, 0xc0,
|
||||
0x06, 0x1c, 0xc1, 0x05, 0xdc, 0xc1, 0x0b, 0xfc, 0x60, 0x36, 0x84, 0x42,
|
||||
0x24, 0xc4, 0xc2, 0x42, 0x10, 0x42, 0x0a, 0x64, 0x80, 0x1c, 0x72, 0x60,
|
||||
0x29, 0xac, 0x82, 0x42, 0x28, 0x86, 0xcd, 0xb0, 0x1d, 0x2a, 0x60, 0x2f,
|
||||
0xd4, 0x40, 0x1d, 0x34, 0xc0, 0x51, 0x68, 0x86, 0x93, 0x70, 0x0e, 0x2e,
|
||||
0xc2, 0x55, 0xb8, 0x0e, 0x3d, 0x70, 0x0f, 0xfa, 0x61, 0x08, 0x9e, 0xc1,
|
||||
0x28, 0xbc, 0x81, 0x09, 0x04, 0x41, 0xc8, 0x08, 0x13, 0x61, 0x21, 0xda,
|
||||
0x88, 0x01, 0x62, 0x8a, 0x58, 0x23, 0x8e, 0x08, 0x17, 0x99, 0x85, 0xf8,
|
||||
0x21, 0xc1, 0x48, 0x04, 0x12, 0x8b, 0x24, 0x20, 0xc9, 0x88, 0x14, 0x51,
|
||||
0x22, 0x4b, 0x91, 0x35, 0x48, 0x31, 0x52, 0x8a, 0x54, 0x20, 0x55, 0x48,
|
||||
0x1d, 0xf2, 0x3d, 0x72, 0x02, 0x39, 0x87, 0x5c, 0x46, 0xba, 0x91, 0x3b,
|
||||
0xc8, 0x00, 0x32, 0x82, 0xfc, 0x86, 0xbc, 0x47, 0x31, 0x94, 0x81, 0xb2,
|
||||
0x51, 0x3d, 0xd4, 0x0c, 0xb5, 0x43, 0xb9, 0xa8, 0x37, 0x1a, 0x84, 0x46,
|
||||
0xa2, 0x0b, 0xd0, 0x64, 0x74, 0x31, 0x9a, 0x8f, 0x16, 0xa0, 0x9b, 0xd0,
|
||||
0x72, 0xb4, 0x1a, 0x3d, 0x8c, 0x36, 0xa1, 0xe7, 0xd0, 0xab, 0x68, 0x0f,
|
||||
0xda, 0x8f, 0x3e, 0x43, 0xc7, 0x30, 0xc0, 0xe8, 0x18, 0x07, 0x33, 0xc4,
|
||||
0x6c, 0x30, 0x2e, 0xc6, 0xc3, 0x42, 0xb1, 0x38, 0x2c, 0x09, 0x93, 0x63,
|
||||
0xcb, 0xb1, 0x22, 0xac, 0x0c, 0xab, 0xc6, 0x1a, 0xb0, 0x56, 0xac, 0x03,
|
||||
0xbb, 0x89, 0xf5, 0x63, 0xcf, 0xb1, 0x77, 0x04, 0x12, 0x81, 0x45, 0xc0,
|
||||
0x09, 0x36, 0x04, 0x77, 0x42, 0x20, 0x61, 0x1e, 0x41, 0x48, 0x58, 0x4c,
|
||||
0x58, 0x4e, 0xd8, 0x48, 0xa8, 0x20, 0x1c, 0x24, 0x34, 0x11, 0xda, 0x09,
|
||||
0x37, 0x09, 0x03, 0x84, 0x51, 0xc2, 0x27, 0x22, 0x93, 0xa8, 0x4b, 0xb4,
|
||||
0x26, 0xba, 0x11, 0xf9, 0xc4, 0x18, 0x62, 0x32, 0x31, 0x87, 0x58, 0x48,
|
||||
0x2c, 0x23, 0xd6, 0x12, 0x8f, 0x13, 0x2f, 0x10, 0x7b, 0x88, 0x43, 0xc4,
|
||||
0x37, 0x24, 0x12, 0x89, 0x43, 0x32, 0x27, 0xb9, 0x90, 0x02, 0x49, 0xb1,
|
||||
0xa4, 0x54, 0xd2, 0x12, 0xd2, 0x46, 0xd2, 0x6e, 0x52, 0x23, 0xe9, 0x2c,
|
||||
0xa9, 0x9b, 0x34, 0x48, 0x1a, 0x23, 0x93, 0xc9, 0xda, 0x64, 0x6b, 0xb2,
|
||||
0x07, 0x39, 0x94, 0x2c, 0x20, 0x2b, 0xc8, 0x85, 0xe4, 0x9d, 0xe4, 0xc3,
|
||||
0xe4, 0x33, 0xe4, 0x1b, 0xe4, 0x21, 0xf2, 0x5b, 0x0a, 0x9d, 0x62, 0x40,
|
||||
0x71, 0xa4, 0xf8, 0x53, 0xe2, 0x28, 0x52, 0xca, 0x6a, 0x4a, 0x19, 0xe5,
|
||||
0x10, 0xe5, 0x34, 0xe5, 0x06, 0x65, 0x98, 0x32, 0x41, 0x55, 0xa3, 0x9a,
|
||||
0x52, 0xdd, 0xa8, 0xa1, 0x54, 0x11, 0x35, 0x8f, 0x5a, 0x42, 0xad, 0xa1,
|
||||
0xb6, 0x52, 0xaf, 0x51, 0x87, 0xa8, 0x13, 0x34, 0x75, 0x9a, 0x39, 0xcd,
|
||||
0x83, 0x16, 0x49, 0x4b, 0xa5, 0xad, 0xa2, 0x95, 0xd3, 0x1a, 0x68, 0x17,
|
||||
0x68, 0xf7, 0x69, 0xaf, 0xe8, 0x74, 0xba, 0x11, 0xdd, 0x95, 0x1e, 0x4e,
|
||||
0x97, 0xd0, 0x57, 0xd2, 0xcb, 0xe9, 0x47, 0xe8, 0x97, 0xe8, 0x03, 0xf4,
|
||||
0x77, 0x0c, 0x0d, 0x86, 0x15, 0x83, 0xc7, 0x88, 0x67, 0x28, 0x19, 0x9b,
|
||||
0x18, 0x07, 0x18, 0x67, 0x19, 0x77, 0x18, 0xaf, 0x98, 0x4c, 0xa6, 0x19,
|
||||
0xd3, 0x8b, 0x19, 0xc7, 0x54, 0x30, 0x37, 0x31, 0xeb, 0x98, 0xe7, 0x99,
|
||||
0x0f, 0x99, 0x6f, 0x55, 0x58, 0x2a, 0xb6, 0x2a, 0x7c, 0x15, 0x91, 0xca,
|
||||
0x0a, 0x95, 0x4a, 0x95, 0x26, 0x95, 0x1b, 0x2a, 0x2f, 0x54, 0xa9, 0xaa,
|
||||
0xa6, 0xaa, 0xde, 0xaa, 0x0b, 0x55, 0xf3, 0x55, 0xcb, 0x54, 0x8f, 0xa9,
|
||||
0x5e, 0x53, 0x7d, 0xae, 0x46, 0x55, 0x33, 0x53, 0xe3, 0xa9, 0x09, 0xd4,
|
||||
0x96, 0xab, 0x55, 0xaa, 0x9d, 0x50, 0xeb, 0x53, 0x1b, 0x53, 0x67, 0xa9,
|
||||
0x3b, 0xa8, 0x87, 0xaa, 0x67, 0xa8, 0x6f, 0x54, 0x3f, 0xa4, 0x7e, 0x59,
|
||||
0xfd, 0x89, 0x06, 0x59, 0xc3, 0x4c, 0xc3, 0x4f, 0x43, 0xa4, 0x51, 0xa0,
|
||||
0xb1, 0x5f, 0xe3, 0xbc, 0xc6, 0x20, 0x0b, 0x63, 0x19, 0xb3, 0x78, 0x2c,
|
||||
0x21, 0x6b, 0x0d, 0xab, 0x86, 0x75, 0x81, 0x35, 0xc4, 0x26, 0xb1, 0xcd,
|
||||
0xd9, 0x7c, 0x76, 0x2a, 0xbb, 0x98, 0xfd, 0x1d, 0xbb, 0x8b, 0x3d, 0xaa,
|
||||
0xa9, 0xa1, 0x39, 0x43, 0x33, 0x4a, 0x33, 0x57, 0xb3, 0x52, 0xf3, 0x94,
|
||||
0x66, 0x3f, 0x07, 0xe3, 0x98, 0x71, 0xf8, 0x9c, 0x74, 0x4e, 0x09, 0xe7,
|
||||
0x28, 0xa7, 0x97, 0xf3, 0x7e, 0x8a, 0xde, 0x14, 0xef, 0x29, 0xe2, 0x29,
|
||||
0x1b, 0xa6, 0x34, 0x4c, 0xb9, 0x31, 0x65, 0x5c, 0x6b, 0xaa, 0x96, 0x97,
|
||||
0x96, 0x58, 0xab, 0x48, 0xab, 0x51, 0xab, 0x47, 0xeb, 0xbd, 0x36, 0xae,
|
||||
0xed, 0xa7, 0x9d, 0xa6, 0xbd, 0x45, 0xbb, 0x59, 0xfb, 0x81, 0x0e, 0x41,
|
||||
0xc7, 0x4a, 0x27, 0x5c, 0x27, 0x47, 0x67, 0x8f, 0xce, 0x05, 0x9d, 0xe7,
|
||||
0x53, 0xd9, 0x53, 0xdd, 0xa7, 0x0a, 0xa7, 0x16, 0x4d, 0x3d, 0x3a, 0xf5,
|
||||
0xae, 0x2e, 0xaa, 0x6b, 0xa5, 0x1b, 0xa1, 0xbb, 0x44, 0x77, 0xbf, 0x6e,
|
||||
0xa7, 0xee, 0x98, 0x9e, 0xbe, 0x5e, 0x80, 0x9e, 0x4c, 0x6f, 0xa7, 0xde,
|
||||
0x79, 0xbd, 0xe7, 0xfa, 0x1c, 0x7d, 0x2f, 0xfd, 0x54, 0xfd, 0x6d, 0xfa,
|
||||
0xa7, 0xf5, 0x47, 0x0c, 0x58, 0x06, 0xb3, 0x0c, 0x24, 0x06, 0xdb, 0x0c,
|
||||
0xce, 0x18, 0x3c, 0xc5, 0x35, 0x71, 0x6f, 0x3c, 0x1d, 0x2f, 0xc7, 0xdb,
|
||||
0xf1, 0x51, 0x43, 0x5d, 0xc3, 0x40, 0x43, 0xa5, 0x61, 0x95, 0x61, 0x97,
|
||||
0xe1, 0x84, 0x91, 0xb9, 0xd1, 0x3c, 0xa3, 0xd5, 0x46, 0x8d, 0x46, 0x0f,
|
||||
0x8c, 0x69, 0xc6, 0x5c, 0xe3, 0x24, 0xe3, 0x6d, 0xc6, 0x6d, 0xc6, 0xa3,
|
||||
0x26, 0x06, 0x26, 0x21, 0x26, 0x4b, 0x4d, 0xea, 0x4d, 0xee, 0x9a, 0x52,
|
||||
0x4d, 0xb9, 0xa6, 0x29, 0xa6, 0x3b, 0x4c, 0x3b, 0x4c, 0xc7, 0xcd, 0xcc,
|
||||
0xcd, 0xa2, 0xcd, 0xd6, 0x99, 0x35, 0x9b, 0x3d, 0x31, 0xd7, 0x32, 0xe7,
|
||||
0x9b, 0xe7, 0x9b, 0xd7, 0x9b, 0xdf, 0xb7, 0x60, 0x5a, 0x78, 0x5a, 0x2c,
|
||||
0xb6, 0xa8, 0xb6, 0xb8, 0x65, 0x49, 0xb2, 0xe4, 0x5a, 0xa6, 0x59, 0xee,
|
||||
0xb6, 0xbc, 0x6e, 0x85, 0x5a, 0x39, 0x59, 0xa5, 0x58, 0x55, 0x5a, 0x5d,
|
||||
0xb3, 0x46, 0xad, 0x9d, 0xad, 0x25, 0xd6, 0xbb, 0xad, 0xbb, 0xa7, 0x11,
|
||||
0xa7, 0xb9, 0x4e, 0x93, 0x4e, 0xab, 0x9e, 0xd6, 0x67, 0xc3, 0xb0, 0xf1,
|
||||
0xb6, 0xc9, 0xb6, 0xa9, 0xb7, 0x19, 0xb0, 0xe5, 0xd8, 0x06, 0xdb, 0xae,
|
||||
0xb6, 0x6d, 0xb6, 0x7d, 0x61, 0x67, 0x62, 0x17, 0x67, 0xb7, 0xc5, 0xae,
|
||||
0xc3, 0xee, 0x93, 0xbd, 0x93, 0x7d, 0xba, 0x7d, 0x8d, 0xfd, 0x3d, 0x07,
|
||||
0x0d, 0x87, 0xd9, 0x0e, 0xab, 0x1d, 0x5a, 0x1d, 0x7e, 0x73, 0xb4, 0x72,
|
||||
0x14, 0x3a, 0x56, 0x3a, 0xde, 0x9a, 0xce, 0x9c, 0xee, 0x3f, 0x7d, 0xc5,
|
||||
0xf4, 0x96, 0xe9, 0x2f, 0x67, 0x58, 0xcf, 0x10, 0xcf, 0xd8, 0x33, 0xe3,
|
||||
0xb6, 0x13, 0xcb, 0x29, 0xc4, 0x69, 0x9d, 0x53, 0x9b, 0xd3, 0x47, 0x67,
|
||||
0x17, 0x67, 0xb9, 0x73, 0x83, 0xf3, 0x88, 0x8b, 0x89, 0x4b, 0x82, 0xcb,
|
||||
0x2e, 0x97, 0x3e, 0x2e, 0x9b, 0x1b, 0xc6, 0xdd, 0xc8, 0xbd, 0xe4, 0x4a,
|
||||
0x74, 0xf5, 0x71, 0x5d, 0xe1, 0x7a, 0xd2, 0xf5, 0x9d, 0x9b, 0xb3, 0x9b,
|
||||
0xc2, 0xed, 0xa8, 0xdb, 0xaf, 0xee, 0x36, 0xee, 0x69, 0xee, 0x87, 0xdc,
|
||||
0x9f, 0xcc, 0x34, 0x9f, 0x29, 0x9e, 0x59, 0x33, 0x73, 0xd0, 0xc3, 0xc8,
|
||||
0x43, 0xe0, 0x51, 0xe5, 0xd1, 0x3f, 0x0b, 0x9f, 0x95, 0x30, 0x6b, 0xdf,
|
||||
0xac, 0x7e, 0x4f, 0x43, 0x4f, 0x81, 0x67, 0xb5, 0xe7, 0x23, 0x2f, 0x63,
|
||||
0x2f, 0x91, 0x57, 0xad, 0xd7, 0xb0, 0xb7, 0xa5, 0x77, 0xaa, 0xf7, 0x61,
|
||||
0xef, 0x17, 0x3e, 0xf6, 0x3e, 0x72, 0x9f, 0xe3, 0x3e, 0xe3, 0x3c, 0x37,
|
||||
0xde, 0x32, 0xde, 0x59, 0x5f, 0xcc, 0x37, 0xc0, 0xb7, 0xc8, 0xb7, 0xcb,
|
||||
0x4f, 0xc3, 0x6f, 0x9e, 0x5f, 0x85, 0xdf, 0x43, 0x7f, 0x23, 0xff, 0x64,
|
||||
0xff, 0x7a, 0xff, 0xd1, 0x00, 0xa7, 0x80, 0x25, 0x01, 0x67, 0x03, 0x89,
|
||||
0x81, 0x41, 0x81, 0x5b, 0x02, 0xfb, 0xf8, 0x7a, 0x7c, 0x21, 0xbf, 0x8e,
|
||||
0x3f, 0x3a, 0xdb, 0x65, 0xf6, 0xb2, 0xd9, 0xed, 0x41, 0x8c, 0xa0, 0xb9,
|
||||
0x41, 0x15, 0x41, 0x8f, 0x82, 0xad, 0x82, 0xe5, 0xc1, 0xad, 0x21, 0x68,
|
||||
0xc8, 0xec, 0x90, 0xad, 0x21, 0xf7, 0xe7, 0x98, 0xce, 0x91, 0xce, 0x69,
|
||||
0x0e, 0x85, 0x50, 0x7e, 0xe8, 0xd6, 0xd0, 0x07, 0x61, 0xe6, 0x61, 0x8b,
|
||||
0xc3, 0x7e, 0x0c, 0x27, 0x85, 0x87, 0x85, 0x57, 0x86, 0x3f, 0x8e, 0x70,
|
||||
0x88, 0x58, 0x1a, 0xd1, 0x31, 0x97, 0x35, 0x77, 0xd1, 0xdc, 0x43, 0x73,
|
||||
0xdf, 0x44, 0xfa, 0x44, 0x96, 0x44, 0xde, 0x9b, 0x67, 0x31, 0x4f, 0x39,
|
||||
0xaf, 0x2d, 0x4a, 0x35, 0x2a, 0x3e, 0xaa, 0x2e, 0x6a, 0x3c, 0xda, 0x37,
|
||||
0xba, 0x34, 0xba, 0x3f, 0xc6, 0x2e, 0x66, 0x59, 0xcc, 0xd5, 0x58, 0x9d,
|
||||
0x58, 0x49, 0x6c, 0x4b, 0x1c, 0x39, 0x2e, 0x2a, 0xae, 0x36, 0x6e, 0x6c,
|
||||
0xbe, 0xdf, 0xfc, 0xed, 0xf3, 0x87, 0xe2, 0x9d, 0xe2, 0x0b, 0xe3, 0x7b,
|
||||
0x17, 0x98, 0x2f, 0xc8, 0x5d, 0x70, 0x79, 0xa1, 0xce, 0xc2, 0xf4, 0x85,
|
||||
0xa7, 0x16, 0xa9, 0x2e, 0x12, 0x2c, 0x3a, 0x96, 0x40, 0x4c, 0x88, 0x4e,
|
||||
0x38, 0x94, 0xf0, 0x41, 0x10, 0x2a, 0xa8, 0x16, 0x8c, 0x25, 0xf2, 0x13,
|
||||
0x77, 0x25, 0x8e, 0x0a, 0x79, 0xc2, 0x1d, 0xc2, 0x67, 0x22, 0x2f, 0xd1,
|
||||
0x36, 0xd1, 0x88, 0xd8, 0x43, 0x5c, 0x2a, 0x1e, 0x4e, 0xf2, 0x48, 0x2a,
|
||||
0x4d, 0x7a, 0x92, 0xec, 0x91, 0xbc, 0x35, 0x79, 0x24, 0xc5, 0x33, 0xa5,
|
||||
0x2c, 0xe5, 0xb9, 0x84, 0x27, 0xa9, 0x90, 0xbc, 0x4c, 0x0d, 0x4c, 0xdd,
|
||||
0x9b, 0x3a, 0x9e, 0x16, 0x9a, 0x76, 0x20, 0x6d, 0x32, 0x3d, 0x3a, 0xbd,
|
||||
0x31, 0x83, 0x92, 0x91, 0x90, 0x71, 0x42, 0xaa, 0x21, 0x4d, 0x93, 0xb6,
|
||||
0x67, 0xea, 0x67, 0xe6, 0x66, 0x76, 0xcb, 0xac, 0x65, 0x85, 0xb2, 0xfe,
|
||||
0xc5, 0x6e, 0x8b, 0xb7, 0x2f, 0x1e, 0x95, 0x07, 0xc9, 0x6b, 0xb3, 0x90,
|
||||
0xac, 0x05, 0x59, 0x2d, 0x0a, 0xb6, 0x42, 0xa6, 0xe8, 0x54, 0x5a, 0x28,
|
||||
0xd7, 0x2a, 0x07, 0xb2, 0x67, 0x65, 0x57, 0x66, 0xbf, 0xcd, 0x89, 0xca,
|
||||
0x39, 0x96, 0xab, 0x9e, 0x2b, 0xcd, 0xed, 0xcc, 0xb3, 0xca, 0xdb, 0x90,
|
||||
0x37, 0x9c, 0xef, 0x9f, 0xff, 0xed, 0x12, 0xc2, 0x12, 0xe1, 0x92, 0xb6,
|
||||
0xa5, 0x86, 0x4b, 0x57, 0x2d, 0x1d, 0x58, 0xe6, 0xbd, 0xac, 0x6a, 0x39,
|
||||
0xb2, 0x3c, 0x71, 0x79, 0xdb, 0x0a, 0xe3, 0x15, 0x05, 0x2b, 0x86, 0x56,
|
||||
0x06, 0xac, 0x3c, 0xb8, 0x8a, 0xb6, 0x2a, 0x6d, 0xd5, 0x4f, 0xab, 0xed,
|
||||
0x57, 0x97, 0xae, 0x7e, 0xbd, 0x26, 0x7a, 0x4d, 0x6b, 0x81, 0x5e, 0xc1,
|
||||
0xca, 0x82, 0xc1, 0xb5, 0x01, 0x6b, 0xeb, 0x0b, 0x55, 0x0a, 0xe5, 0x85,
|
||||
0x7d, 0xeb, 0xdc, 0xd7, 0xed, 0x5d, 0x4f, 0x58, 0x2f, 0x59, 0xdf, 0xb5,
|
||||
0x61, 0xfa, 0x86, 0x9d, 0x1b, 0x3e, 0x15, 0x89, 0x8a, 0xae, 0x14, 0xdb,
|
||||
0x17, 0x97, 0x15, 0x7f, 0xd8, 0x28, 0xdc, 0x78, 0xe5, 0x1b, 0x87, 0x6f,
|
||||
0xca, 0xbf, 0x99, 0xdc, 0x94, 0xb4, 0xa9, 0xab, 0xc4, 0xb9, 0x64, 0xcf,
|
||||
0x66, 0xd2, 0x66, 0xe9, 0xe6, 0xde, 0x2d, 0x9e, 0x5b, 0x0e, 0x96, 0xaa,
|
||||
0x97, 0xe6, 0x97, 0x0e, 0x6e, 0x0d, 0xd9, 0xda, 0xb4, 0x0d, 0xdf, 0x56,
|
||||
0xb4, 0xed, 0xf5, 0xf6, 0x45, 0xdb, 0x2f, 0x97, 0xcd, 0x28, 0xdb, 0xbb,
|
||||
0x83, 0xb6, 0x43, 0xb9, 0xa3, 0xbf, 0x3c, 0xb8, 0xbc, 0x65, 0xa7, 0xc9,
|
||||
0xce, 0xcd, 0x3b, 0x3f, 0x54, 0xa4, 0x54, 0xf4, 0x54, 0xfa, 0x54, 0x36,
|
||||
0xee, 0xd2, 0xdd, 0xb5, 0x61, 0xd7, 0xf8, 0x6e, 0xd1, 0xee, 0x1b, 0x7b,
|
||||
0xbc, 0xf6, 0x34, 0xec, 0xd5, 0xdb, 0x5b, 0xbc, 0xf7, 0xfd, 0x3e, 0xc9,
|
||||
0xbe, 0xdb, 0x55, 0x01, 0x55, 0x4d, 0xd5, 0x66, 0xd5, 0x65, 0xfb, 0x49,
|
||||
0xfb, 0xb3, 0xf7, 0x3f, 0xae, 0x89, 0xaa, 0xe9, 0xf8, 0x96, 0xfb, 0x6d,
|
||||
0x5d, 0xad, 0x4e, 0x6d, 0x71, 0xed, 0xc7, 0x03, 0xd2, 0x03, 0xfd, 0x07,
|
||||
0x23, 0x0e, 0xb6, 0xd7, 0xb9, 0xd4, 0xd5, 0x1d, 0xd2, 0x3d, 0x54, 0x52,
|
||||
0x8f, 0xd6, 0x2b, 0xeb, 0x47, 0x0e, 0xc7, 0x1f, 0xbe, 0xfe, 0x9d, 0xef,
|
||||
0x77, 0x2d, 0x0d, 0x36, 0x0d, 0x55, 0x8d, 0x9c, 0xc6, 0xe2, 0x23, 0x70,
|
||||
0x44, 0x79, 0xe4, 0xe9, 0xf7, 0x09, 0xdf, 0xf7, 0x1e, 0x0d, 0x3a, 0xda,
|
||||
0x76, 0x8c, 0x7b, 0xac, 0xe1, 0x07, 0xd3, 0x1f, 0x76, 0x1d, 0x67, 0x1d,
|
||||
0x2f, 0x6a, 0x42, 0x9a, 0xf2, 0x9a, 0x46, 0x9b, 0x53, 0x9a, 0xfb, 0x5b,
|
||||
0x62, 0x5b, 0xba, 0x4f, 0xcc, 0x3e, 0xd1, 0xd6, 0xea, 0xde, 0x7a, 0xfc,
|
||||
0x47, 0xdb, 0x1f, 0x0f, 0x9c, 0x34, 0x3c, 0x59, 0x79, 0x4a, 0xf3, 0x54,
|
||||
0xc9, 0x69, 0xda, 0xe9, 0x82, 0xd3, 0x93, 0x67, 0xf2, 0xcf, 0x8c, 0x9d,
|
||||
0x95, 0x9d, 0x7d, 0x7e, 0x2e, 0xf9, 0xdc, 0x60, 0xdb, 0xa2, 0xb6, 0x7b,
|
||||
0xe7, 0x63, 0xce, 0xdf, 0x6a, 0x0f, 0x6f, 0xef, 0xba, 0x10, 0x74, 0xe1,
|
||||
0xd2, 0x45, 0xff, 0x8b, 0xe7, 0x3b, 0xbc, 0x3b, 0xce, 0x5c, 0xf2, 0xb8,
|
||||
0x74, 0xf2, 0xb2, 0xdb, 0xe5, 0x13, 0x57, 0xb8, 0x57, 0x9a, 0xaf, 0x3a,
|
||||
0x5f, 0x6d, 0xea, 0x74, 0xea, 0x3c, 0xfe, 0x93, 0xd3, 0x4f, 0xc7, 0xbb,
|
||||
0x9c, 0xbb, 0x9a, 0xae, 0xb9, 0x5c, 0x6b, 0xb9, 0xee, 0x7a, 0xbd, 0xb5,
|
||||
0x7b, 0x66, 0xf7, 0xe9, 0x1b, 0x9e, 0x37, 0xce, 0xdd, 0xf4, 0xbd, 0x79,
|
||||
0xf1, 0x16, 0xff, 0xd6, 0xd5, 0x9e, 0x39, 0x3d, 0xdd, 0xbd, 0xf3, 0x7a,
|
||||
0x6f, 0xf7, 0xc5, 0xf7, 0xf5, 0xdf, 0x16, 0xdd, 0x7e, 0x72, 0x27, 0xfd,
|
||||
0xce, 0xcb, 0xbb, 0xd9, 0x77, 0x27, 0xee, 0xad, 0xbc, 0x4f, 0xbc, 0x5f,
|
||||
0xf4, 0x40, 0xed, 0x41, 0xd9, 0x43, 0xdd, 0x87, 0xd5, 0x3f, 0x5b, 0xfe,
|
||||
0xdc, 0xd8, 0xef, 0xdc, 0x7f, 0x6a, 0xc0, 0x77, 0xa0, 0xf3, 0xd1, 0xdc,
|
||||
0x47, 0xf7, 0x06, 0x85, 0x83, 0xcf, 0xfe, 0x91, 0xf5, 0x8f, 0x0f, 0x43,
|
||||
0x05, 0x8f, 0x99, 0x8f, 0xcb, 0x86, 0x0d, 0x86, 0xeb, 0x9e, 0x38, 0x3e,
|
||||
0x39, 0x39, 0xe2, 0x3f, 0x72, 0xfd, 0xe9, 0xfc, 0xa7, 0x43, 0xcf, 0x64,
|
||||
0xcf, 0x26, 0x9e, 0x17, 0xfe, 0xa2, 0xfe, 0xcb, 0xae, 0x17, 0x16, 0x2f,
|
||||
0x7e, 0xf8, 0xd5, 0xeb, 0xd7, 0xce, 0xd1, 0x98, 0xd1, 0xa1, 0x97, 0xf2,
|
||||
0x97, 0x93, 0xbf, 0x6d, 0x7c, 0xa5, 0xfd, 0xea, 0xc0, 0xeb, 0x19, 0xaf,
|
||||
0xdb, 0xc6, 0xc2, 0xc6, 0x1e, 0xbe, 0xc9, 0x78, 0x33, 0x31, 0x5e, 0xf4,
|
||||
0x56, 0xfb, 0xed, 0xc1, 0x77, 0xdc, 0x77, 0x1d, 0xef, 0xa3, 0xdf, 0x0f,
|
||||
0x4f, 0xe4, 0x7c, 0x20, 0x7f, 0x28, 0xff, 0x68, 0xf9, 0xb1, 0xf5, 0x53,
|
||||
0xd0, 0xa7, 0xfb, 0x93, 0x19, 0x93, 0x93, 0xff, 0x04, 0x03, 0x98, 0xf3,
|
||||
0xfc, 0x63, 0x33, 0x2d, 0xdb, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52,
|
||||
0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9,
|
||||
0xff, 0x00, 0x00, 0x80, 0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea,
|
||||
0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5,
|
||||
0x46, 0x00, 0x00, 0x02, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec,
|
||||
0x98, 0x4d, 0x4e, 0x02, 0x41, 0x10, 0x85, 0x3f, 0x8d, 0xdb, 0xb9, 0x80,
|
||||
0x73, 0x01, 0x70, 0x2f, 0xee, 0x41, 0xf7, 0x72, 0x00, 0x0d, 0x7b, 0xc2,
|
||||
0xde, 0xc4, 0xb5, 0x09, 0x7b, 0xc2, 0xde, 0xe0, 0x01, 0xd0, 0xbd, 0x5c,
|
||||
0x00, 0x2e, 0xc0, 0x05, 0xe4, 0x00, 0xce, 0x01, 0x74, 0x53, 0x9d, 0x54,
|
||||
0xda, 0xea, 0x99, 0x46, 0x51, 0x8c, 0xd6, 0x4b, 0x3a, 0x0c, 0xdd, 0x3d,
|
||||
0x5d, 0x5d, 0xf5, 0xea, 0x2f, 0x73, 0x00, 0xbc, 0xe1, 0xd8, 0x1b, 0x0e,
|
||||
0xdd, 0x04, 0x4e, 0x80, 0x13, 0xe0, 0x70, 0x02, 0x9c, 0x00, 0x87, 0x13,
|
||||
0xe0, 0x04, 0x38, 0x9c, 0x00, 0x27, 0xc0, 0xe1, 0x04, 0x38, 0x01, 0x0e,
|
||||
0x27, 0xe0, 0xdf, 0xe0, 0xc8, 0x9a, 0x6c, 0x01, 0x13, 0xa0, 0x34, 0xd6,
|
||||
0x66, 0xc0, 0x58, 0x9e, 0xfb, 0xc0, 0x0d, 0x50, 0x18, 0xfb, 0x5e, 0x80,
|
||||
0x11, 0xb0, 0xce, 0xb8, 0x44, 0x07, 0xb8, 0x4f, 0xac, 0x55, 0x22, 0x73,
|
||||
0x9a, 0x71, 0xce, 0x50, 0x86, 0x96, 0x9d, 0xba, 0x63, 0x25, 0x7a, 0xcc,
|
||||
0xe5, 0xff, 0x0d, 0x70, 0xdd, 0xa0, 0x47, 0x21, 0x76, 0xe9, 0x18, 0xfb,
|
||||
0x96, 0xc0, 0x4a, 0xe4, 0x93, 0x38, 0x67, 0x0c, 0x2c, 0xa2, 0xf9, 0x03,
|
||||
0xa2, 0xaf, 0xa1, 0x05, 0xf0, 0x9c, 0x30, 0x6a, 0xc0, 0x54, 0x84, 0xdd,
|
||||
0x37, 0x18, 0xa4, 0x02, 0xce, 0xe5, 0xf7, 0xb3, 0x04, 0x04, 0xdc, 0x2a,
|
||||
0x63, 0x59, 0xb8, 0x13, 0x63, 0x07, 0x2c, 0x80, 0x87, 0x8c, 0x73, 0x07,
|
||||
0xc0, 0x69, 0x8d, 0xe1, 0xb4, 0x1e, 0x29, 0xe3, 0xe7, 0x10, 0x10, 0x70,
|
||||
0x21, 0x64, 0x24, 0x53, 0x50, 0x5b, 0x8c, 0xbf, 0x06, 0x4e, 0xa2, 0x31,
|
||||
0x92, 0x3d, 0xa7, 0x32, 0x42, 0x44, 0x9c, 0x18, 0x23, 0x78, 0x4c, 0x7b,
|
||||
0x8b, 0x70, 0x5c, 0xd6, 0xc8, 0x3c, 0xce, 0x34, 0xfe, 0x42, 0x39, 0x52,
|
||||
0xdd, 0x1d, 0x67, 0x86, 0x2e, 0xa3, 0x06, 0x3d, 0x82, 0xf1, 0xcf, 0x8c,
|
||||
0x7d, 0x83, 0xc8, 0x41, 0x53, 0xf2, 0xca, 0x9c, 0x14, 0x04, 0xf0, 0x9a,
|
||||
0xf0, 0x84, 0x9c, 0xb9, 0xd4, 0xfb, 0x4d, 0x68, 0x1b, 0x1e, 0x5b, 0x36,
|
||||
0xc8, 0xd1, 0xc6, 0xaf, 0x12, 0x69, 0xb3, 0xfa, 0xc2, 0x9c, 0xa5, 0xc7,
|
||||
0xc4, 0x98, 0x7b, 0x52, 0xcf, 0x97, 0x8a, 0x54, 0xad, 0x9b, 0x75, 0xde,
|
||||
0xd1, 0x6f, 0x2a, 0x48, 0x45, 0x4d, 0x88, 0x57, 0x89, 0x9c, 0xdf, 0x8f,
|
||||
0xde, 0x6f, 0xfd, 0xc0, 0x3d, 0xad, 0x3b, 0xae, 0x22, 0xa7, 0x29, 0x33,
|
||||
0xf5, 0xf8, 0x55, 0x04, 0xac, 0x55, 0x81, 0x47, 0xa5, 0x88, 0x21, 0xd0,
|
||||
0x8d, 0x6a, 0x40, 0x5f, 0xe5, 0xdb, 0xb1, 0x2a, 0xf6, 0x2d, 0x29, 0xa8,
|
||||
0xdf, 0x89, 0x41, 0xa2, 0xc8, 0x5e, 0xca, 0xf3, 0x3c, 0x8a, 0x08, 0x80,
|
||||
0x2b, 0xa0, 0x27, 0x7b, 0xa6, 0xbb, 0x20, 0x20, 0x30, 0xd9, 0xab, 0x49,
|
||||
0x27, 0xdb, 0xa6, 0xa2, 0xc2, 0x08, 0x5d, 0xcb, 0xa3, 0xfb, 0x92, 0x7a,
|
||||
0x72, 0x8a, 0xf3, 0x2e, 0x51, 0xc9, 0x1d, 0xbb, 0x86, 0x27, 0x6b, 0x8f,
|
||||
0xdf, 0x48, 0x3d, 0x8b, 0x1d, 0xa9, 0x97, 0xdb, 0x86, 0xe6, 0x60, 0x2e,
|
||||
0x6c, 0xb6, 0x6a, 0xc2, 0x7e, 0x9e, 0xd9, 0x86, 0x6a, 0x25, 0x86, 0x09,
|
||||
0xc5, 0xa7, 0x7b, 0x36, 0x7e, 0x88, 0xb4, 0xbb, 0x44, 0xbb, 0xba, 0x8c,
|
||||
0xd2, 0x50, 0x2e, 0x3e, 0xb4, 0xa1, 0xa5, 0x18, 0x76, 0x63, 0x28, 0x17,
|
||||
0xaf, 0x15, 0x62, 0x10, 0xab, 0x65, 0xdd, 0x6c, 0x61, 0x9c, 0x52, 0x85,
|
||||
0xaf, 0x85, 0x47, 0x09, 0x71, 0xbd, 0x6f, 0x6d, 0xf4, 0xd4, 0xf1, 0x1d,
|
||||
0x5f, 0xc4, 0xf3, 0x56, 0x86, 0x47, 0x76, 0xd4, 0x5a, 0x29, 0x5d, 0xd6,
|
||||
0x63, 0xd4, 0x22, 0x06, 0xc2, 0xf5, 0x5a, 0xc7, 0x88, 0x52, 0xb6, 0x94,
|
||||
0xb7, 0xac, 0x23, 0xc0, 0xe1, 0x9f, 0x22, 0x9c, 0x00, 0x87, 0x13, 0xe0,
|
||||
0x04, 0x38, 0x9c, 0x00, 0x27, 0xc0, 0xe1, 0x04, 0x38, 0x01, 0x0e, 0x27,
|
||||
0xe0, 0x4f, 0xe3, 0x7d, 0x00, 0x51, 0xbe, 0x83, 0xcd, 0x57, 0x34, 0x65,
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60,
|
||||
0x82,
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
|
||||
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x04, 0x03,
|
||||
0x00, 0x00, 0x00, 0x1f, 0xee, 0x60, 0x67, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48,
|
||||
0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a,
|
||||
0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdd, 0x02,
|
||||
0x09, 0x16, 0x39, 0x17, 0xf0, 0x40, 0x6e, 0x04, 0x00, 0x00, 0x00, 0x15, 0x50,
|
||||
0x4c, 0x54, 0x45, 0x66, 0x66, 0x66, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6d,
|
||||
0x6d, 0x6d, 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x80, 0x80, 0x80, 0xd1, 0x7d,
|
||||
0x40, 0x35, 0x00, 0x00, 0x00, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x8d,
|
||||
0xd4, 0x31, 0x0e, 0xc3, 0x20, 0x10, 0x44, 0xd1, 0x51, 0x64, 0xfa, 0x1c, 0x25,
|
||||
0x47, 0x48, 0x45, 0xed, 0xca, 0x07, 0xb0, 0x80, 0xfb, 0x1f, 0x21, 0x05, 0x60,
|
||||
0xd6, 0x30, 0xe3, 0xac, 0xbb, 0x95, 0xf8, 0x7a, 0xb2, 0x01, 0xa3, 0x98, 0x27,
|
||||
0x01, 0x00, 0x10, 0xfa, 0x9c, 0xeb, 0xbc, 0xd9, 0x35, 0xb0, 0x43, 0xf9, 0xd6,
|
||||
0x15, 0x47, 0x1b, 0xf7, 0x3a, 0x46, 0x1d, 0xdc, 0x09, 0x06, 0x4c, 0xc1, 0x9d,
|
||||
0x60, 0xc0, 0x1c, 0x58, 0x82, 0x02, 0x73, 0x60, 0x09, 0x0a, 0x2c, 0xc1, 0x20,
|
||||
0x38, 0xb0, 0x04, 0x83, 0xe0, 0xc0, 0x1a, 0x74, 0x42, 0x00, 0x6b, 0xd0, 0x89,
|
||||
0x0f, 0x07, 0x48, 0xd0, 0x08, 0x01, 0x90, 0xa0, 0x13, 0x1c, 0x60, 0x41, 0x7a,
|
||||
0x02, 0x58, 0x60, 0x88, 0xe8, 0x0b, 0xd2, 0x03, 0x40, 0x83, 0x8b, 0x88, 0xde,
|
||||
0xe0, 0xac, 0xeb, 0x5f, 0xc5, 0x1b, 0xb4, 0x4d, 0xbe, 0xee, 0xc5, 0xbf, 0x20,
|
||||
0xf7, 0x77, 0x08, 0xce, 0x60, 0xbf, 0xbe, 0xd2, 0xe1, 0x0a, 0xf2, 0xd8, 0x87,
|
||||
0xe0, 0x0a, 0x76, 0xb3, 0xd3, 0x87, 0x23, 0xc8, 0xf6, 0x2c, 0x05, 0x47, 0xd0,
|
||||
0x80, 0xb7, 0x20, 0x20, 0x80, 0x2d, 0x09, 0x02, 0x02, 0x88, 0xf3, 0x3f, 0x4a,
|
||||
0x05, 0xe3, 0xa2, 0x09, 0x02, 0x0a, 0x28, 0x82, 0x80, 0x02, 0x14, 0x01, 0x09,
|
||||
0x08, 0x02, 0x12, 0x10, 0x04, 0x34, 0xc0, 0x89, 0x1f, 0xe2, 0x9a, 0xca, 0x1c,
|
||||
0x5f, 0x12, 0x62, 0x57, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||
0x42, 0x60, 0x82
|
||||
};
|
||||
|
|
|
@ -121,7 +121,9 @@ Joystick::Axis::Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction d
|
|||
// Need to parse the element a bit first
|
||||
std::string description("unk");
|
||||
|
||||
switch (IOHIDElementGetUsage(m_element)) {
|
||||
int const usage = IOHIDElementGetUsage(m_element);
|
||||
switch (usage)
|
||||
{
|
||||
case kHIDUsage_GD_X:
|
||||
description = "X";
|
||||
break;
|
||||
|
@ -146,6 +148,13 @@ Joystick::Axis::Axis(IOHIDElementRef element, IOHIDDeviceRef device, direction d
|
|||
case kHIDUsage_Csmr_ACPan:
|
||||
description = "Pan";
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << usage;
|
||||
description = s.str();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_name = std::string("Axis ") + description;
|
||||
|
|
|
@ -458,6 +458,7 @@ void BPWritten(const BPCmd& bp)
|
|||
|
||||
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
|
||||
g_renderer->SetColorMask(); // alpha writing needs to be disabled if the new pixel format doesn't have an alpha channel
|
||||
g_renderer->SetBlendMode(true);
|
||||
OnPixelFormatChange();
|
||||
if(bp.changes & 3)
|
||||
SetBlendMode(); // dual source could be activated by changing to PIXELFMT_RGBA6_Z24
|
||||
|
@ -523,9 +524,8 @@ void BPWritten(const BPCmd& bp)
|
|||
|
||||
for (u32 i = 0; i < tmem_cfg.preload_tile_info.count; ++i)
|
||||
{
|
||||
// FIXME: Duplicate conditions.
|
||||
if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE ||
|
||||
tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE)
|
||||
tmem_addr_odd + TMEM_LINE_SIZE > TMEM_SIZE)
|
||||
break;
|
||||
|
||||
memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE);
|
||||
|
|
|
@ -84,35 +84,34 @@ TextureCache::~TextureCache()
|
|||
|
||||
void TextureCache::OnConfigChanged(VideoConfig& config)
|
||||
{
|
||||
if (!g_texture_cache)
|
||||
goto skip_checks;
|
||||
|
||||
// TODO: Invalidating texcache is really stupid in some of these cases
|
||||
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
|
||||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
|
||||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
|
||||
config.bHiresTextures != backup_config.s_hires_textures)
|
||||
if (g_texture_cache)
|
||||
{
|
||||
g_texture_cache->Invalidate();
|
||||
// TODO: Invalidating texcache is really stupid in some of these cases
|
||||
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
|
||||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
|
||||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
|
||||
config.bHiresTextures != backup_config.s_hires_textures)
|
||||
{
|
||||
g_texture_cache->Invalidate();
|
||||
|
||||
if(g_ActiveConfig.bHiresTextures)
|
||||
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
if(g_ActiveConfig.bHiresTextures)
|
||||
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
|
||||
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
|
||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
|
||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||
}
|
||||
|
||||
// TODO: Probably shouldn't clear all render targets here, just mark them dirty or something.
|
||||
if (config.bEFBCopyCacheEnable != backup_config.s_copy_cache_enable || // TODO: not sure if this is needed?
|
||||
config.bCopyEFBToTexture != backup_config.s_copy_efb_to_texture ||
|
||||
config.bCopyEFBScaled != backup_config.s_copy_efb_scaled ||
|
||||
config.bEFBCopyEnable != backup_config.s_copy_efb ||
|
||||
config.iEFBScale != backup_config.s_efb_scale)
|
||||
{
|
||||
g_texture_cache->ClearRenderTargets();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Probably shouldn't clear all render targets here, just mark them dirty or something.
|
||||
if (config.bEFBCopyCacheEnable != backup_config.s_copy_cache_enable || // TODO: not sure if this is needed?
|
||||
config.bCopyEFBToTexture != backup_config.s_copy_efb_to_texture ||
|
||||
config.bCopyEFBScaled != backup_config.s_copy_efb_scaled ||
|
||||
config.bEFBCopyEnable != backup_config.s_copy_efb ||
|
||||
config.iEFBScale != backup_config.s_efb_scale)
|
||||
{
|
||||
g_texture_cache->ClearRenderTargets();
|
||||
}
|
||||
|
||||
skip_checks:
|
||||
|
||||
backup_config.s_colorsamples = config.iSafeTextureCache_ColorSamples;
|
||||
backup_config.s_copy_efb_to_texture = config.bCopyEFBToTexture;
|
||||
backup_config.s_copy_efb_scaled = config.bCopyEFBScaled;
|
||||
|
@ -218,6 +217,9 @@ void TextureCache::ClearRenderTargets()
|
|||
|
||||
bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels)
|
||||
{
|
||||
if (levels == 1)
|
||||
return false;
|
||||
|
||||
// Just checking if the necessary files exist, if they can't be loaded or have incorrect dimensions LODs will be black
|
||||
char texBasePathTemp[MAX_PATH];
|
||||
char texPathTemp[MAX_PATH];
|
||||
|
@ -298,14 +300,30 @@ void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level)
|
|||
entry->Save(szTemp, level);
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
||||
u32 address, unsigned int width, unsigned int height, int texformat,
|
||||
unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel, bool from_tmem)
|
||||
static u32 CalculateLevelSize(u32 level_0_size, u32 level)
|
||||
{
|
||||
return (level_0_size + ((1 << level) - 1)) >> level;
|
||||
}
|
||||
|
||||
// Used by TextureCache::Load
|
||||
static TextureCache::TCacheEntryBase* ReturnEntry(unsigned int stage, TextureCache::TCacheEntryBase* entry)
|
||||
{
|
||||
entry->frameCount = frameCount;
|
||||
entry->Bind(stage);
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE, true);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
|
||||
u32 const address, unsigned int width, unsigned int height, int const texformat,
|
||||
unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int const maxlevel, bool const from_tmem)
|
||||
{
|
||||
if (0 == address)
|
||||
return NULL;
|
||||
|
||||
// TexelSizeInNibbles(format)*width*height/16;
|
||||
// TexelSizeInNibbles(format) * width * height / 16;
|
||||
const unsigned int bsw = TexDecoder_GetBlockWidthInTexels(texformat) - 1;
|
||||
const unsigned int bsh = TexDecoder_GetBlockHeightInTexels(texformat) - 1;
|
||||
|
||||
|
@ -314,11 +332,9 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
const unsigned int nativeW = width;
|
||||
const unsigned int nativeH = height;
|
||||
|
||||
bool using_custom_texture = false;
|
||||
bool using_custom_lods = false;
|
||||
|
||||
u32 texID = address;
|
||||
u64 tex_hash = TEXHASH_INVALID; // Hash assigned to texcache entry (also used to generate filenames used for texture dumping and custom texture lookup)
|
||||
// Hash assigned to texcache entry (also used to generate filenames used for texture dumping and custom texture lookup)
|
||||
u64 tex_hash = TEXHASH_INVALID;
|
||||
u64 tlut_hash = TEXHASH_INVALID;
|
||||
|
||||
u32 full_format = texformat;
|
||||
|
@ -329,9 +345,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
full_format = texformat | (tlutfmt << 16);
|
||||
|
||||
const u32 texture_size = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, texformat);
|
||||
u8* src_data;
|
||||
if (from_tmem) src_data = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE];
|
||||
else src_data = Memory::GetPointer(address);
|
||||
|
||||
const u8* src_data;
|
||||
if (from_tmem)
|
||||
src_data = &texMem[bpmem.tex[stage / 4].texImage1[stage % 4].tmem_even * TMEM_LINE_SIZE];
|
||||
else
|
||||
src_data = Memory::GetPointer(address);
|
||||
|
||||
// TODO: This doesn't hash GB tiles for preloaded RGBA8 textures (instead, it's hashing more data from the low tmem bank than it should)
|
||||
tex_hash = GetHash64(src_data, texture_size, g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
|
@ -366,15 +385,17 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
{
|
||||
entry->type = TCET_EC_VRAM;
|
||||
|
||||
// TODO: Print a warning if the format changes! In this case, we could reinterpret the internal texture object data to the new pixel format (similiar to what is already being done in Renderer::ReinterpretPixelFormat())
|
||||
goto return_entry;
|
||||
// TODO: Print a warning if the format changes! In this case,
|
||||
// we could reinterpret the internal texture object data to the new pixel format
|
||||
// (similiar to what is already being done in Renderer::ReinterpretPixelFormat())
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
// 2. b) For normal textures, all texture parameters need to match
|
||||
if (address == entry->addr && tex_hash == entry->hash && full_format == entry->format &&
|
||||
entry->num_mipmaps == maxlevel && entry->native_width == nativeW && entry->native_height == nativeH)
|
||||
entry->num_mipmaps > maxlevel && entry->native_width == nativeW && entry->native_height == nativeH)
|
||||
{
|
||||
goto return_entry;
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
// 3. If we reach this line, we'll have to upload the new texture data to VRAM.
|
||||
|
@ -382,7 +403,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
//
|
||||
// TODO: Don't we need to force texture decoding to RGBA8 for dynamic EFB copies?
|
||||
// TODO: Actually, it should be enough if the internal texture format matches...
|
||||
if ((entry->type == TCET_NORMAL && width == entry->virtual_width && height == entry->virtual_height && full_format == entry->format && entry->num_mipmaps == maxlevel)
|
||||
if ((entry->type == TCET_NORMAL && width == entry->virtual_width && height == entry->virtual_height
|
||||
&& full_format == entry->format && entry->num_mipmaps > maxlevel)
|
||||
|| (entry->type == TCET_EC_DYNAMIC && entry->native_width == width && entry->native_height == height))
|
||||
{
|
||||
// reuse the texture
|
||||
|
@ -395,9 +417,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
}
|
||||
}
|
||||
|
||||
bool using_custom_texture = false;
|
||||
|
||||
if (g_ActiveConfig.bHiresTextures)
|
||||
{
|
||||
// This function may modify width/height.
|
||||
pcfmt = LoadCustomTexture(tex_hash, texformat, 0, width, height);
|
||||
if (pcfmt != PC_TEX_FMT_NONE)
|
||||
{
|
||||
|
@ -428,26 +452,26 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Cleanup. Plus, we still autogenerate mipmaps in certain cases (we shouldn't do that)
|
||||
bool isPow2;
|
||||
unsigned int texLevels;
|
||||
isPow2 = !((width & (width - 1)) || (height & (height - 1)));
|
||||
texLevels = (isPow2 && maxlevel) ? GetPow2(std::max(width, height)) : !isPow2;
|
||||
texLevels = maxlevel ? std::min(texLevels, maxlevel + 1) : texLevels;
|
||||
using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels);
|
||||
UseNativeMips = UseNativeMips && !using_custom_lods && (width == nativeW && height == nativeH); // Only load native mips if their dimensions fit to our virtual texture dimensions
|
||||
texLevels = (UseNativeMips || using_custom_lods) ? texLevels : !isPow2;
|
||||
u32 texLevels = use_mipmaps ? (maxlevel + 1) : 1;
|
||||
const bool using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels);
|
||||
// Only load native mips if their dimensions fit to our virtual texture dimensions
|
||||
const bool use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH);
|
||||
texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1;
|
||||
|
||||
// create the entry/texture
|
||||
if (NULL == entry) {
|
||||
if (NULL == entry)
|
||||
{
|
||||
textures[texID] = entry = g_texture_cache->CreateTexture(width, height, expandedWidth, texLevels, pcfmt);
|
||||
|
||||
// Sometimes, we can get around recreating a texture if only the number of mip levels changes
|
||||
// e.g. if our texture cache entry got too many mipmap levels we can limit the number of used levels by setting the appropriate render states
|
||||
// Thus, we don't update this member for every Load, but just whenever the texture gets recreated
|
||||
//
|
||||
// TODO: Won't we end up recreating textures all the time because maxlevel doesn't necessarily equal texLevels?
|
||||
entry->num_mipmaps = maxlevel; // TODO: Does this actually work? We can't really adjust mipmap settings per-stage...
|
||||
// TODO: D3D9 doesn't support min_lod. We should add a workaround for that here!
|
||||
|
||||
// TODO: This is the wrong value. We should be storing the number of levels our actual texture has.
|
||||
// But that will currently make the above "existing entry" tests fail as "texLevels" is not calculated until after.
|
||||
// Currently, we might try to reuse a texture which appears to have more levels than actual, maybe..
|
||||
entry->num_mipmaps = maxlevel + 1;
|
||||
entry->type = TCET_NORMAL;
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true);
|
||||
|
@ -460,83 +484,63 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
else entry->type = TCET_NORMAL;
|
||||
|
||||
// load texture
|
||||
entry->Load(stage, width, height, expandedWidth, 0, (texLevels == 0));
|
||||
entry->Load(stage, width, height, expandedWidth, 0);
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures && !using_custom_texture)
|
||||
DumpTexture(entry, 0);
|
||||
|
||||
u32 level = 1;
|
||||
// load mips - TODO: Loading mipmaps from tmem is untested!
|
||||
if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && UseNativeMips)
|
||||
if (pcfmt != PC_TEX_FMT_NONE)
|
||||
{
|
||||
const unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(texformat);
|
||||
|
||||
unsigned int level = 1;
|
||||
unsigned int mipWidth = (width + 1) >> 1;
|
||||
unsigned int mipHeight = (height + 1) >> 1;
|
||||
|
||||
u8* ptr_even = NULL, *ptr_odd = NULL;
|
||||
if (from_tmem)
|
||||
if (use_native_mips)
|
||||
{
|
||||
ptr_even = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE + texture_size];
|
||||
ptr_odd = &texMem[bpmem.tex[stage/4].texImage2[stage%4].tmem_odd * TMEM_LINE_SIZE];
|
||||
src_data += texture_size;
|
||||
|
||||
const u8* ptr_even = NULL;
|
||||
const u8* ptr_odd = NULL;
|
||||
if (from_tmem)
|
||||
{
|
||||
ptr_even = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE + texture_size];
|
||||
ptr_odd = &texMem[bpmem.tex[stage/4].texImage2[stage%4].tmem_odd * TMEM_LINE_SIZE];
|
||||
}
|
||||
|
||||
for (; level != texLevels; ++level)
|
||||
{
|
||||
const u32 mip_width = CalculateLevelSize(width, level);
|
||||
const u32 mip_height = CalculateLevelSize(height, level);
|
||||
const u32 expanded_mip_width = (mip_width + bsw) & (~bsw);
|
||||
const u32 expanded_mip_height = (mip_height + bsh) & (~bsh);
|
||||
|
||||
const u8*& mip_src_data = from_tmem
|
||||
? ((level % 2) ? ptr_odd : ptr_even)
|
||||
: src_data;
|
||||
TexDecoder_Decode(temp, mip_src_data, expanded_mip_width, expanded_mip_height, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures);
|
||||
mip_src_data += TexDecoder_GetTextureSizeInBytes(expanded_mip_width, expanded_mip_height, texformat);
|
||||
|
||||
entry->Load(stage, mip_width, mip_height, expanded_mip_width, level);
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures)
|
||||
DumpTexture(entry, level);
|
||||
}
|
||||
}
|
||||
src_data += texture_size;
|
||||
|
||||
while ((mipHeight || mipWidth) && (level < texLevels))
|
||||
else if (using_custom_lods)
|
||||
{
|
||||
u8** ptr;
|
||||
if (from_tmem) ptr = (level % 2) ? &ptr_odd : &ptr_even;
|
||||
else ptr = &src_data;
|
||||
for (; level != texLevels; ++level)
|
||||
{
|
||||
unsigned int mip_width = CalculateLevelSize(width, level);
|
||||
unsigned int mip_height = CalculateLevelSize(height, level);
|
||||
|
||||
const unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1;
|
||||
const unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1;
|
||||
|
||||
expandedWidth = (currentWidth + bsw) & (~bsw);
|
||||
expandedHeight = (currentHeight + bsh) & (~bsh);
|
||||
|
||||
TexDecoder_Decode(temp, *ptr, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures);
|
||||
entry->Load(stage, currentWidth, currentHeight, expandedWidth, level, false);
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures)
|
||||
DumpTexture(entry, level);
|
||||
|
||||
*ptr += ((std::max(mipWidth, bsw) * std::max(mipHeight, bsh) * bsdepth) >> 1);
|
||||
mipWidth >>= 1;
|
||||
mipHeight >>= 1;
|
||||
++level;
|
||||
}
|
||||
}
|
||||
else if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && using_custom_lods)
|
||||
{
|
||||
unsigned int level = 1;
|
||||
unsigned int mipWidth = (width + 1) >> 1;
|
||||
unsigned int mipHeight = (height + 1) >> 1;
|
||||
|
||||
while ((mipHeight || mipWidth) && (level < texLevels))
|
||||
{
|
||||
unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1;
|
||||
unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1;
|
||||
|
||||
LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight);
|
||||
entry->Load(stage, currentWidth, currentHeight, currentWidth, level, false);
|
||||
|
||||
mipWidth >>= 1;
|
||||
mipHeight >>= 1;
|
||||
++level;
|
||||
LoadCustomTexture(tex_hash, texformat, level, mip_width, mip_height);
|
||||
entry->Load(stage, mip_width, mip_height, mip_width, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INCSTAT(stats.numTexturesCreated);
|
||||
SETSTAT(stats.numTexturesAlive, textures.size());
|
||||
|
||||
return_entry:
|
||||
|
||||
entry->frameCount = frameCount;
|
||||
entry->Bind(stage);
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE, true);
|
||||
|
||||
return entry;
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||
|
|
|
@ -60,26 +60,26 @@ public:
|
|||
int frameCount;
|
||||
|
||||
|
||||
void SetGeneralParameters(u32 addr, u32 size, u32 format, unsigned int num_mipmaps)
|
||||
void SetGeneralParameters(u32 _addr, u32 _size, u32 _format, unsigned int _num_mipmaps)
|
||||
{
|
||||
this->addr = addr;
|
||||
this->size_in_bytes = size;
|
||||
this->format = format;
|
||||
this->num_mipmaps = num_mipmaps;
|
||||
addr = _addr;
|
||||
size_in_bytes = _size;
|
||||
format = _format;
|
||||
num_mipmaps = _num_mipmaps;
|
||||
}
|
||||
|
||||
void SetDimensions(unsigned int native_width, unsigned int native_height, unsigned int virtual_width, unsigned int virtual_height)
|
||||
void SetDimensions(unsigned int _native_width, unsigned int _native_height, unsigned int _virtual_width, unsigned int _virtual_height)
|
||||
{
|
||||
this->native_width = native_width;
|
||||
this->native_height = native_height;
|
||||
this->virtual_width = virtual_width;
|
||||
this->virtual_height = virtual_height;
|
||||
native_width = _native_width;
|
||||
native_height = _native_height;
|
||||
virtual_width = _virtual_width;
|
||||
virtual_height = _virtual_height;
|
||||
}
|
||||
|
||||
void SetHashes(u64 hash/*, u32 pal_hash*/)
|
||||
void SetHashes(u64 _hash/*, u32 _pal_hash*/)
|
||||
{
|
||||
this->hash = hash;
|
||||
//this->pal_hash = pal_hash;
|
||||
hash = _hash;
|
||||
//pal_hash = _pal_hash;
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
virtual bool Save(const char filename[], unsigned int level) = 0;
|
||||
|
||||
virtual void Load(unsigned int stage, unsigned int width, unsigned int height,
|
||||
unsigned int expanded_width, unsigned int level, bool autogen_mips) = 0;
|
||||
unsigned int expanded_width, unsigned int level) = 0;
|
||||
virtual void FromRenderTarget(u32 dstAddr, unsigned int dstFormat,
|
||||
unsigned int srcFormat, const EFBRectangle& srcRect,
|
||||
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
|
||||
|
@ -116,7 +116,7 @@ public:
|
|||
virtual TCacheEntryBase* CreateRenderTargetTexture(unsigned int scaled_tex_w, unsigned int scaled_tex_h) = 0;
|
||||
|
||||
static TCacheEntryBase* Load(unsigned int stage, u32 address, unsigned int width, unsigned int height,
|
||||
int format, unsigned int tlutaddr, int tlutfmt, bool UseNativeMips, unsigned int maxlevel, bool from_tmem);
|
||||
int format, unsigned int tlutaddr, int tlutfmt, bool use_mipmaps, unsigned int maxlevel, bool from_tmem);
|
||||
static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
|
||||
|
||||
|
|
|
@ -692,7 +692,7 @@ inline void SetOpenMPThreadCount(int width, int height)
|
|||
if (g_ActiveConfig.bOMPDecoder && width > 127 && height > 127)
|
||||
{
|
||||
// don't span to many threads they will kill the rest of the emu :)
|
||||
omp_set_num_threads((cpu_info.num_cores + 2) / 3);
|
||||
omp_set_num_threads((omp_get_num_procs() + 2) / 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue