diff --git a/Data/User/GameConfig/R6BE78.ini b/Data/User/GameConfig/R6BE78.ini index 5cd3873ab9..067eae1c63 100644 --- a/Data/User/GameConfig/R6BE78.ini +++ b/Data/User/GameConfig/R6BE78.ini @@ -1,4 +1,4 @@ -# R6BE78 - Blob07 +# R6BE78 - de Blob [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 @@ -15,4 +15,6 @@ PH_ZFar = [Gecko] [Video_Enhancements] ForceFiltering = False - +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/R6BJ78.ini b/Data/User/GameConfig/R6BJ78.ini index dad405fa11..91e0a5aa71 100644 --- a/Data/User/GameConfig/R6BJ78.ini +++ b/Data/User/GameConfig/R6BJ78.ini @@ -15,3 +15,6 @@ PH_ZFar = [Gecko] [Video_Enhancements] ForceFiltering = False +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/R6BK78.ini b/Data/User/GameConfig/R6BK78.ini index 21aa5f90af..28f22a58ed 100644 --- a/Data/User/GameConfig/R6BK78.ini +++ b/Data/User/GameConfig/R6BK78.ini @@ -1,4 +1,4 @@ -# R6BK78 - Blob07 +# R6BK78 - de Blob [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 @@ -15,3 +15,6 @@ PH_ZFar = [Gecko] [Video_Enhancements] ForceFiltering = False +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/R6BP78.ini b/Data/User/GameConfig/R6BP78.ini index e49b9b4fca..4afc6d1f80 100644 --- a/Data/User/GameConfig/R6BP78.ini +++ b/Data/User/GameConfig/R6BP78.ini @@ -1,4 +1,4 @@ -# R6BP78 - Blob07 +# R6BP78 - de Blob [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 @@ -15,3 +15,6 @@ PH_ZFar = [Gecko] [Video_Enhancements] ForceFiltering = False +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Data/User/GameConfig/R6BX78.ini b/Data/User/GameConfig/R6BX78.ini index d37400d0e0..81f003a9bc 100644 --- a/Data/User/GameConfig/R6BX78.ini +++ b/Data/User/GameConfig/R6BX78.ini @@ -1,4 +1,4 @@ -# R6BX78 - Blob07 +# R6BX78 - de Blob [Core] Values set here will override the main dolphin settings. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 @@ -15,3 +15,6 @@ PH_ZFar = [Gecko] [Video_Enhancements] ForceFiltering = False +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp index 8a568448a3..b21aec45ba 100644 --- a/Source/Core/AudioCommon/Src/AudioCommon.cpp +++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp @@ -102,16 +102,12 @@ namespace AudioCommon backends.push_back(BACKEND_DIRECTSOUND); if (XAudio2::isValid()) backends.push_back(BACKEND_XAUDIO2); - if (OpenALStream::isValid()) - backends.push_back(BACKEND_OPENAL); if (AOSound::isValid()) backends.push_back(BACKEND_AOSOUND); if (AlsaSound::isValid()) backends.push_back(BACKEND_ALSA); if (CoreAudioSound::isValid()) backends.push_back(BACKEND_COREAUDIO); - if (PulseAudio::isValid()) - backends.push_back(BACKEND_PULSEAUDIO); return backends; } diff --git a/Source/Core/Common/Src/BreakPoints.cpp b/Source/Core/Common/Src/BreakPoints.cpp index 1700276d85..62fadefd4f 100644 --- a/Source/Core/Common/Src/BreakPoints.cpp +++ b/Source/Core/Common/Src/BreakPoints.cpp @@ -19,7 +19,9 @@ #include "DebugInterface.h" #include "BreakPoints.h" #include "../../Core/Src/PowerPC/JitCommon/JitBase.h" + #include +#include bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) { @@ -110,12 +112,17 @@ void BreakPoints::Remove(u32 em_address) void BreakPoints::Clear() { - for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) + if (jit) { - if (jit) - jit->GetBlockCache()->InvalidateICache(i->iAddress, 4); - m_BreakPoints.erase(i); + std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), + [](const TBreakPoint& bp) + { + jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); + } + ); } + + m_BreakPoints.clear(); } MemChecks::TMemChecksStr MemChecks::GetStrings() const diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index 4c746e9b75..9755c996bd 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -24,7 +24,7 @@ // Increment this every time you change shader generation code. enum { - LINEAR_DISKCACHE_VER = 6975 + LINEAR_DISKCACHE_VER = 6979 }; // On disk format: diff --git a/Source/Core/Common/Src/StdMutex.h b/Source/Core/Common/Src/StdMutex.h index 150d18f53e..8949e905ac 100644 --- a/Source/Core/Common/Src/StdMutex.h +++ b/Source/Core/Common/Src/StdMutex.h @@ -318,9 +318,12 @@ public: mutex_type* release() { - return mutex(); + auto const ret = mutex(); + pm = NULL; owns = false; + + return ret; } bool owns_lock() const diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index e0fac1da87..71148efabc 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -47,7 +47,6 @@ #include "VideoBackendBase.h" #include "Movie.h" - namespace BootManager { @@ -154,6 +153,7 @@ void Stop() SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter; + StartUp.m_strUniqueID = "00000000"; if (config_cache.valid) { config_cache.valid = false; diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 959997de70..5088f82031 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -141,7 +141,7 @@ struct SCoreStartupParameter int iTheme; int iPosX, iPosY, iWidth, iHeight; - + enum EBootBS2 { BOOT_DEFAULT, diff --git a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp index dcb79b7ac5..2058a92f9d 100644 --- a/Source/Core/Core/Src/DSP/DSPAccelerator.cpp +++ b/Source/Core/Core/Src/DSP/DSPAccelerator.cpp @@ -165,11 +165,10 @@ u16 dsp_read_accelerator() // Somehow, YN1 and YN2 must be initialized with their "loop" values, // so yeah, it seems likely that we should raise an exception to let // the DSP program do that, at least if DSP_FORMAT == 0x0A. - if (Address >= EndAddress) + if ((Address & ~0x1f) == (EndAddress & ~0x1f)) { // Set address back to start address. - if ((Address & ~0x1f) == (EndAddress & ~0x1f)) - Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL]; + Address = (g_dsp.ifx_regs[DSP_ACSAH] << 16) | g_dsp.ifx_regs[DSP_ACSAL]; DSPCore_SetException(EXP_ACCOV); } diff --git a/Source/Core/Core/Src/FifoPlayer/FifoAnalyzer.cpp b/Source/Core/Core/Src/FifoPlayer/FifoAnalyzer.cpp index f074b6d88b..383fcb555d 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoAnalyzer.cpp +++ b/Source/Core/Core/Src/FifoPlayer/FifoAnalyzer.cpp @@ -90,9 +90,9 @@ void GetTlutLoadData(u32 &tlutAddr, u32 &memAddr, u32 &tlutXferCount, BPMemory & // TODO - figure out a cleaner way. if (Core::g_CoreStartupParameter.bWii) - memAddr = bpmem.tmem_config.tlut_src << 5; + memAddr = bpMem.tmem_config.tlut_src << 5; else - memAddr = (bpmem.tmem_config.tlut_src & 0xFFFFF) << 5; + memAddr = (bpMem.tmem_config.tlut_src & 0xFFFFF) << 5; } void LoadCPReg(u32 subCmd, u32 value, CPMemory &cpMem) diff --git a/Source/Core/Core/Src/FifoPlayer/FifoDataFile.h b/Source/Core/Core/Src/FifoPlayer/FifoDataFile.h index a95a46c1fd..d1ae9ee886 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoDataFile.h +++ b/Source/Core/Core/Src/FifoPlayer/FifoDataFile.h @@ -33,7 +33,7 @@ struct MemoryUpdate TEXTURE_MAP = 0x01, XF_DATA = 0x02, VERTEX_STREAM = 0x04, - TLUT = 0x08 + TMEM = 0x08, }; u32 fifoPosition; diff --git a/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.cpp b/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.cpp index 1c0cd7abe1..a6467f0366 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.cpp +++ b/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.cpp @@ -114,6 +114,8 @@ void FifoRecordAnalyzer::DecodeOpcode(u8 *data) if (bp.address == BPMEM_LOADTLUT1) ProcessLoadTlut1(); + if (bp.address == BPMEM_PRELOAD_MODE) + ProcessPreloadTexture(); } break; @@ -143,7 +145,16 @@ void FifoRecordAnalyzer::ProcessLoadTlut1() GetTlutLoadData(tlutMemAddr, memAddr, tlutXferCount, *m_BpMem); - FifoRecorder::GetInstance().WriteMemory(memAddr, tlutXferCount, MemoryUpdate::TLUT); + FifoRecorder::GetInstance().WriteMemory(memAddr, tlutXferCount, MemoryUpdate::TMEM); +} + +void FifoRecordAnalyzer::ProcessPreloadTexture() +{ + BPS_TmemConfig& tmem_cfg = m_BpMem->tmem_config; + u32 tmem_addr = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; + u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE; // TODO: Should this be half size for RGBA8 preloads? + + FifoRecorder::GetInstance().WriteMemory(tmem_cfg.preload_addr << 5, size, MemoryUpdate::TMEM); } void FifoRecordAnalyzer::ProcessLoadIndexedXf(u32 val, int array) diff --git a/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.h b/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.h index 0ffc279bf3..8ef3360ce7 100644 --- a/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.h +++ b/Source/Core/Core/Src/FifoPlayer/FifoRecordAnalyzer.h @@ -40,6 +40,7 @@ private: void DecodeOpcode(u8 *data); void ProcessLoadTlut1(); + void ProcessPreloadTexture(); void ProcessLoadIndexedXf(u32 val, int array); void ProcessVertexArrays(u8 *data, u8 vtxAttrGroup); void ProcessTexMaps(); diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h index 349dc7e03b..e39b38b100 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX_Voice.h @@ -203,12 +203,10 @@ u16 AcceleratorGetSample() // // On real hardware, this would raise an interrupt that is handled by the // UCode. We simulate what this interrupt does here. - if (*acc_cur_addr >= acc_end_addr) + if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F)) { - // If we are really at the end (and we don't simply have cur_addr > - // end_addr all the time), loop back to loop_addr. - if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F)) - *acc_cur_addr = acc_loop_addr; + // If we are really at the end, loop back to loop_addr. + *acc_cur_addr = acc_loop_addr; if (acc_pb->audio_addr.looping) { diff --git a/Source/Core/Core/Src/HW/GCPad.cpp b/Source/Core/Core/Src/HW/GCPad.cpp index 68ba3ab88a..c4798b3964 100644 --- a/Source/Core/Core/Src/HW/GCPad.cpp +++ b/Source/Core/Core/Src/HW/GCPad.cpp @@ -20,6 +20,7 @@ #include "ControllerInterface/ControllerInterface.h" #include "GCPadEmu.h" +#include "../ConfigManager.h" #include "../../InputCommon/Src/InputConfig.h" @@ -55,7 +56,7 @@ void Initialize(void* const hwnd) g_controller_interface.Initialize(); // load the saved controller config - g_plugin.LoadConfig(); + g_plugin.LoadConfig(true); } void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) diff --git a/Source/Core/Core/Src/HW/Wiimote.cpp b/Source/Core/Core/Src/HW/Wiimote.cpp index 0928deffb1..59fe8b7fa5 100644 --- a/Source/Core/Core/Src/HW/Wiimote.cpp +++ b/Source/Core/Core/Src/HW/Wiimote.cpp @@ -5,6 +5,7 @@ #include "WiimoteReal/WiimoteReal.h" #include "WiimoteEmu/WiimoteEmu.h" #include "Movie.h" +#include "../ConfigManager.h" #include "ControllerInterface/ControllerInterface.h" @@ -44,7 +45,7 @@ void Initialize(void* const hwnd) g_controller_interface.SetHwnd(hwnd); g_controller_interface.Initialize(); - g_plugin.LoadConfig(); + g_plugin.LoadConfig(false); WiimoteReal::Initialize(); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 0b3d16454b..49afee8ad1 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -36,6 +36,11 @@ void Wiimote::RealDisconnect() return; } +bool Wiimote::IsOpen() const +{ + return IsConnected(); +} + int Wiimote::IORead(unsigned char* buf) { return 0; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index b01caf06c8..f56c11e248 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -136,10 +136,10 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes) // Connect to a wiimote with a known address. bool Wiimote::Connect() { - struct sockaddr_l2 addr; - - if (IsConnected()) return false; + if (IsConnected()) + return false; + sockaddr_l2 addr; addr.l2_family = AF_BLUETOOTH; addr.l2_bdaddr = bdaddr; addr.l2_cid = 0; @@ -195,28 +195,36 @@ void Wiimote::RealDisconnect() if (m_wiimote_thread.joinable()) m_wiimote_thread.join(); - Host_ConnectWiimote(index, false); + Close(); +} - close(out_sock); - close(in_sock); +void Wiimote::Close() +{ + if (IsOpen()) + { + Host_ConnectWiimote(index, false); - out_sock = -1; - in_sock = -1; + close(out_sock); + close(in_sock); + + out_sock = -1; + in_sock = -1; + } +} + +bool Wiimote::IsOpen() const +{ + return out_sock != -1 && in_sock != -1; } int Wiimote::IORead(unsigned char *buf) { - struct timeval tv; - fd_set fds; - int r; - - if (!IsConnected()) - return 0; - // Block select for 1/2000th of a second + timeval tv; tv.tv_sec = 0; tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000; + fd_set fds; FD_ZERO(&fds); FD_SET(in_sock, &fds); @@ -230,7 +238,7 @@ int Wiimote::IORead(unsigned char *buf) return 0; // Read the pending message into the buffer - r = read(in_sock, buf, MAX_PAYLOAD); + int r = read(in_sock, buf, MAX_PAYLOAD); if (r == -1) { // Error reading data @@ -241,17 +249,17 @@ int Wiimote::IORead(unsigned char *buf) // This can happen if the bluetooth dongle is disconnected ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. " "Wiimote %i will be disconnected.", index + 1); - RealDisconnect(); + Close(); } return 0; } - if (!r) + else if (!r) { // Disconnect - RealDisconnect(); - return 0; + Close(); } + return r; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index c22e1972dc..cc05bc10e1 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -294,6 +294,11 @@ void Wiimote::RealDisconnect() ResetEvent(&hid_overlap); } +bool Wiimote::IsOpen() const +{ + return IsConnected(); +} + int Wiimote::IORead(unsigned char* buf) { DWORD b, r; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 9ee39e5b92..64de880180 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -227,6 +227,11 @@ void Wiimote::RealDisconnect() ichan = NULL; } +bool Wiimote::IsOpen() const +{ + return IsConnected(); +} + int Wiimote::IORead(unsigned char *buf) { int bytes; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 204a1fc698..1f9285f37e 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -240,7 +240,7 @@ void Wiimote::Disconnect() DisableDataReporting(); } -bool Wiimote::IsConnected() +bool Wiimote::IsConnected() const { return m_connected; } @@ -312,7 +312,7 @@ void Wiimote::ThreadFunc() Rumble(); // main loop - while (IsConnected()) + while (IsOpen()) { #ifdef __APPLE__ while (Write()) {} diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index cd1080903f..15c8044acd 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -53,7 +53,8 @@ public: bool Read(); bool Write(); bool Connect(); - bool IsConnected(); + bool IsConnected() const; + bool IsOpen() const; void Disconnect(); void DisableDataReporting(); void Rumble(); @@ -72,6 +73,9 @@ public: bdaddr_t bdaddr; // Bluetooth address int out_sock; // Output socket int in_sock; // Input socket + + void Close(); + #elif defined(_WIN32) char devicepath[255]; // Unique wiimote reference //ULONGLONG btaddr; // Bluetooth address diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index bc7e37b533..5a199b56c8 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -293,7 +293,8 @@ void Interpreter::mfspr(UGeckoInstruction _inst) case SPR_WPAR: { - // If wpar_empty ever is false, Paper Mario hangs. Strange. + // TODO: If wpar_empty ever is false, Paper Mario hangs. Strange. + // Maybe WPAR is automatically flushed after a certain amount of time? bool wpar_empty = true; //GPFifo::IsEmpty(); if (!wpar_empty) rSPR(iIndex) |= 1; // BNE = buffer not empty diff --git a/Source/Core/DiscIO/Src/CompressedBlob.cpp b/Source/Core/DiscIO/Src/CompressedBlob.cpp index 1e5077b352..48ce8f10f3 100644 --- a/Source/Core/DiscIO/Src/CompressedBlob.cpp +++ b/Source/Core/DiscIO/Src/CompressedBlob.cpp @@ -296,9 +296,13 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca } CompressedBlobReader* reader = CompressedBlobReader::Create(infile); - if (!reader) return false; + if (!reader) + return false; File::IOFile f(outfile, "wb"); + if (!f) + return false; + const CompressedBlobHeader &header = reader->GetHeader(); u8* buffer = new u8[header.block_size]; int progress_monitor = max(1, header.num_blocks / 100); diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index 8f40ab2f18..6103f53e67 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -19,6 +19,7 @@ #include "FileUtil.h" #include +#include #include "FileSystemGCWii.h" #include "StringUtil.h" @@ -95,7 +96,7 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi const SFileInfo* pFileInfo = FindFileInfo(_rFullPath); - if (!pFileInfo || pFileInfo->m_FileSize == 0) + if (!pFileInfo) return false; u64 remainingSize = pFileInfo->m_FileSize; @@ -112,22 +113,17 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi // Limit read size to 128 MB size_t readSize = (size_t)min(remainingSize, (u64)0x08000000); - u8* buffer = new u8[readSize]; + std::vector buffer(readSize); - result = m_rVolume->Read(fileOffset, readSize, buffer); + result = m_rVolume->Read(fileOffset, readSize, &buffer[0]); if (!result) - { - delete[] buffer; break; - } - f.WriteBytes(buffer, readSize); + f.WriteBytes(&buffer[0], readSize); remainingSize -= readSize; fileOffset += readSize; - - delete[] buffer; } return result; @@ -140,22 +136,20 @@ bool CFileSystemGCWii::ExportApploader(const char* _rExportFolder) const AppSize += 0x20; // + header size DEBUG_LOG(DISCIO,"AppSize -> %x", AppSize); - u8* buffer = new u8[AppSize]; - if (m_rVolume->Read(0x2440, AppSize, buffer)) + std::vector buffer(AppSize); + if (m_rVolume->Read(0x2440, AppSize, &buffer[0])) { - char exportName[512]; - sprintf(exportName, "%s/apploader.img", _rExportFolder); + std::string exportName(_rExportFolder); + exportName += "/apploader.img"; File::IOFile AppFile(exportName, "wb"); if (AppFile) { - AppFile.WriteBytes(buffer, AppSize); - delete[] buffer; + AppFile.WriteBytes(&buffer[0], AppSize); return true; } } - delete[] buffer; return false; } @@ -182,21 +176,20 @@ bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const DolSize = offset + size; } - u8* buffer = new u8[DolSize]; - if (m_rVolume->Read(DolOffset, DolSize, buffer)) + std::vector buffer(DolSize); + if (m_rVolume->Read(DolOffset, DolSize, &buffer[0])) { - char exportName[512]; - sprintf(exportName, "%s/boot.dol", _rExportFolder); + std::string exportName(_rExportFolder); + exportName += "/boot.dol"; + File::IOFile DolFile(exportName, "wb"); if (DolFile) { - DolFile.WriteBytes(buffer, DolSize); - delete[] buffer; + DolFile.WriteBytes(&buffer[0], DolSize); return true; } } - delete[] buffer; return false; } diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index ce4cd9cb22..12deddb572 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -127,7 +127,7 @@ EVT_SLIDER(ID_VOLUME, CConfigMain::AudioSettingsChanged) EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::DisplaySettingsChanged) EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::DisplaySettingsChanged) EVT_CHECKBOX(ID_INTERFACE_ONSCREENDISPLAYMESSAGES, CConfigMain::DisplaySettingsChanged) -EVT_RADIOBOX(ID_INTERFACE_THEME, CConfigMain::DisplaySettingsChanged) +EVT_CHOICE(ID_INTERFACE_THEME, CConfigMain::DisplaySettingsChanged) EVT_CHOICE(ID_INTERFACE_LANG, CConfigMain::DisplaySettingsChanged) EVT_BUTTON(ID_HOTKEY_CONFIG, CConfigMain::DisplaySettingsChanged) @@ -500,10 +500,7 @@ void CConfigMain::InitializeGUITooltips() OnScreenDisplayMessages->SetToolTip(_("Show messages on the emulation screen area.\nThese messages include memory card writes, video backend and CPU information, and JIT cache clearing.")); // Display - Themes: Copyright notice - Theme->SetItemToolTip(0, _("Created by Milosz Wlazlo [miloszwl@miloszwl.com, miloszwl.deviantart.com]")); - Theme->SetItemToolTip(1, _("Created by VistaIcons.com")); - Theme->SetItemToolTip(2, _("Created by black_rider and published on ForumW.org > Web Developments")); - Theme->SetItemToolTip(3, _("Created by KDE-Look.org")); + Theme->SetToolTip(_("Boomy: Milosz Wlazlo [miloszwl@miloszwl.com]\nVista: VistaIcons.com\nX-Plastik: black_rider [ForumW.org]\nKDE: KDE-Look.org")); InterfaceLang->SetToolTip(_("Change the language of the user interface.\nRequires restart.")); @@ -579,9 +576,9 @@ void CConfigMain::CreateGUIControls() // Hotkey configuration HotkeyConfig = new wxButton(DisplayPage, ID_HOTKEY_CONFIG, _("Hotkeys"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator); - // Themes - this should really be a wxChoice... - Theme = new wxRadioBox(DisplayPage, ID_INTERFACE_THEME, _("Theme"), - wxDefaultPosition, wxDefaultSize, arrayStringFor_Themes, 1, wxRA_SPECIFY_ROWS); + // Themes + Theme = new wxChoice(DisplayPage, ID_INTERFACE_THEME, wxDefaultPosition, + wxDefaultSize, arrayStringFor_Themes, 0, wxDefaultValidator); // Interface settings ConfirmStop = new wxCheckBox(DisplayPage, ID_INTERFACE_CONFIRMSTOP, _("Confirm on Stop"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); @@ -595,13 +592,16 @@ void CConfigMain::CreateGUIControls() sInterface->Add(InterfaceLang, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); sInterface->AddStretchSpacer(); sInterface->Add(HotkeyConfig, 0, wxALIGN_RIGHT | wxALL, 5); + wxBoxSizer* scInterface = new wxBoxSizer(wxHORIZONTAL); + scInterface->Add(TEXT_BOX(DisplayPage, _("Theme:")), 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + scInterface->Add(Theme, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + scInterface->AddStretchSpacer(); sbInterface = new wxStaticBoxSizer(wxVERTICAL, DisplayPage, _("Interface Settings")); sbInterface->Add(ConfirmStop, 0, wxALL, 5); sbInterface->Add(UsePanicHandlers, 0, wxALL, 5); sbInterface->Add(OnScreenDisplayMessages, 0, wxALL, 5); - sbInterface->Add(Theme, 0, wxEXPAND | wxALL, 5); + sbInterface->Add(scInterface, 0, wxEXPAND | wxALL, 5); sbInterface->Add(sInterface, 0, wxEXPAND | wxALL, 5); - sDisplayPage = new wxBoxSizer(wxVERTICAL); sDisplayPage->Add(sbInterface, 0, wxEXPAND | wxALL, 5); DisplayPage->SetSizer(sDisplayPage); diff --git a/Source/Core/DolphinWX/Src/ConfigMain.h b/Source/Core/DolphinWX/Src/ConfigMain.h index 9b5dbf4243..0e594101df 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.h +++ b/Source/Core/DolphinWX/Src/ConfigMain.h @@ -165,7 +165,7 @@ private: wxCheckBox* ConfirmStop; wxCheckBox* UsePanicHandlers; wxCheckBox* OnScreenDisplayMessages; - wxRadioBox* Theme; + wxChoice* Theme; wxChoice* InterfaceLang; wxButton* HotkeyConfig; diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index b5caf139d6..160aaf211a 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -22,9 +22,13 @@ #include "FifoPlayer/FifoPlayer.h" #include "FifoPlayer/FifoRecorder.h" #include "OpcodeDecoding.h" + #include #include +#include +#include + DECLARE_EVENT_TYPE(RECORDING_FINISHED_EVENT, -1) DEFINE_EVENT_TYPE(RECORDING_FINISHED_EVENT) @@ -440,26 +444,22 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event) return; } - unsigned int val_length = str_search_val.Length() / 2; - u8* search_val = new u8[val_length]; + unsigned int const val_length = str_search_val.Length() / 2; + std::vector search_val(val_length); for (unsigned int i = 0; i < val_length; ++i) { wxString char_str = str_search_val.Mid(2*i, 2); - unsigned long val; + unsigned long val = 0; if (!char_str.ToULong(&val, 16)) { m_numResultsText->SetLabel(_("Invalid search string (couldn't convert to number)")); - delete[] search_val; return; } search_val[i] = (u8)val; } search_results.clear(); - u8* start_ptr; - u8* end_ptr; - - int frame_idx = m_framesList->GetSelection(); + int const frame_idx = m_framesList->GetSelection(); FifoPlayer& player = FifoPlayer::GetInstance(); const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); const FifoFrameInfo& fifo_frame = player.GetFile()->GetFrame(frame_idx); @@ -472,12 +472,13 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event) m_numResultsText->SetLabel(_("Invalid search parameters (no object selected)")); return; } - start_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx]]; - end_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx+1]]; - for (u8* ptr = start_ptr; ptr < end_ptr-val_length+1; ++ptr) + const u8* const start_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx]]; + const u8* const end_ptr = &fifo_frame.fifoData[frame.objectStarts[obj_idx+1]]; + + for (const u8* ptr = start_ptr; ptr < end_ptr-val_length+1; ++ptr) { - if (memcmp(ptr, search_val, val_length) == 0) + if (std::equal(search_val.begin(), search_val.end(), ptr)) { SearchResult result; result.frame_idx = frame_idx; @@ -496,7 +497,6 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event) search_results.push_back(result); } } - delete[] search_val; ChangeSearchResult(0); m_beginSearch->Disable(); diff --git a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp index 9372c4d644..6a30bb90a6 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/X11_Util.cpp @@ -71,38 +71,45 @@ void cX11Window::XEventThread() switch(event.type) { case KeyPress: key = XLookupKeysym((XKeyEvent*)&event, 0); - switch (key) + if (g_Config.bOSDHotKey) { - case XK_3: - OSDChoice = 1; - // Toggle native resolution - g_Config.iEFBScale = g_Config.iEFBScale + 1; - if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; - break; - case XK_4: - OSDChoice = 2; - // Toggle aspect ratio - g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; - break; - case XK_5: - OSDChoice = 3; - // Toggle EFB copy - if (!g_Config.bEFBCopyEnable || g_Config.bCopyEFBToTexture) - { - g_Config.bEFBCopyEnable ^= true; - g_Config.bCopyEFBToTexture = false; - } - else - { - g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; - } - break; - case XK_6: - OSDChoice = 4; - g_Config.bDisableFog = !g_Config.bDisableFog; - break; - default: - break; + switch (key) + { + case XK_3: + OSDChoice = 1; + // Toggle native resolution + g_Config.iEFBScale = g_Config.iEFBScale + 1; + if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; + break; + + case XK_4: + OSDChoice = 2; + // Toggle aspect ratio + g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; + break; + + case XK_5: + OSDChoice = 3; + // Toggle EFB copy + if (!g_Config.bEFBCopyEnable || g_Config.bCopyEFBToTexture) + { + g_Config.bEFBCopyEnable ^= true; + g_Config.bCopyEFBToTexture = false; + } + else + { + g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; + } + break; + + case XK_6: + OSDChoice = 4; + g_Config.bDisableFog = !g_Config.bDisableFog; + break; + + default: + break; + } } if (g_Config.bFreeLook) { diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index c67ee83ed3..2e31843ef9 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -259,6 +259,7 @@ void CGameListCtrl::BrowseForDirectory() void CGameListCtrl::Update() { + int scrollPos = wxWindow::GetScrollPos(wxVERTICAL); // Don't let the user refresh it while a game is running if (Core::GetState() != Core::CORE_UNINITIALIZED) return; @@ -363,6 +364,8 @@ void CGameListCtrl::Update() Show(); AutomaticColumnWidth(); + ScrollLines(scrollPos); + SetFocus(); } wxString NiceSizeFormat(s64 _size) @@ -1121,6 +1124,9 @@ void CGameListCtrl::CompressSelection(bool _compress) if (browseDialog.ShowModal() != wxID_OK) return; + bool all_good = true; + + { wxProgressDialog progressDialog( _compress ? _("Compressing ISO") : _("Decompressing ISO"), _("Working..."), @@ -1157,7 +1163,7 @@ void CGameListCtrl::CompressSelection(bool _compress) wxYES_NO) == wxNO) continue; - DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), + all_good &= DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), OutputFileName.c_str(), (iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0, 16384, &MultiCompressCB, &progressDialog); @@ -1185,11 +1191,16 @@ void CGameListCtrl::CompressSelection(bool _compress) wxYES_NO) == wxNO) continue; - DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), + all_good &= DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), OutputFileName.c_str(), &MultiCompressCB, &progressDialog); } m_currentItem++; } + } + + if (!all_good) + wxMessageBox(_("Dolphin was unable to complete the requested action.")); + Update(); } @@ -1249,6 +1260,9 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event)) _("Confirm File Overwrite"), wxYES_NO) == wxNO); + bool all_good = false; + + { wxProgressDialog dialog( iso->IsCompressed() ? _("Decompressing ISO") : _("Compressing ISO"), _("Working..."), @@ -1259,14 +1273,19 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event)) wxPD_SMOOTH ); + if (iso->IsCompressed()) - DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), + all_good = DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), path.char_str(), &CompressCB, &dialog); else - DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), + all_good = DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), path.char_str(), (iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0, 16384, &CompressCB, &dialog); + } + + if (!all_good) + wxMessageBox(_("Dolphin was unable to complete the requested action.")); Update(); } diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index f59c7c34c9..d99bd97e8d 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -84,7 +84,6 @@ wxString af_desc = wxTRANSLATE("Enable anisotropic filtering.\nEnhances visual q wxString aa_desc = wxTRANSLATE("Reduces the amount of aliasing caused by rasterizing 3D graphics.\nThis makes the rendered picture look less blocky.\nHeavily decreases emulation speed and sometimes causes issues.\n\nIf unsure, select None."); wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of textures generated using render to texture effects.\nRaising the internal resolution will improve the effect of this setting.\nSlightly decreases performance and possibly causes issues (although unlikely).\n\nIf unsure, leave this checked."); wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked."); -wxString pixel_depth_desc = wxTRANSLATE("Calculate depth values of 3D graphics per-pixel rather than per vertex.\nIn contrast to pixel lighting (which is merely an enhancement), per-pixel depth calculations are necessary to properly emulate a small number of games.\n\nIf unsure, leave this checked."); wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked."); wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked."); wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528."); @@ -493,7 +492,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_other->Add(CreateCheckBox(page_hacks, _("Cache Display Lists"), wxGetTranslation(dlc_desc), vconfig.bDlistCachingEnable)); szr_other->Add(CreateCheckBox(page_hacks, _("Disable Fog"), wxGetTranslation(disable_fog_desc), vconfig.bDisableFog)); - szr_other->Add(CreateCheckBox(page_hacks, _("Disable Per-Pixel Depth"), wxGetTranslation(pixel_depth_desc), vconfig.bEnablePerPixelDepth, true)); szr_other->Add(CreateCheckBox(page_hacks, _("Skip Dest. Alpha Pass"), wxGetTranslation(disable_alphapass_desc), vconfig.bDstAlphaPass)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); diff --git a/Source/Core/DolphinWX/resources/KDE.h b/Source/Core/DolphinWX/resources/KDE.h index 64d350fd2b..23fcd4272b 100644 --- a/Source/Core/DolphinWX/resources/KDE.h +++ b/Source/Core/DolphinWX/resources/KDE.h @@ -1261,442 +1261,322 @@ static const unsigned char Toolbar_Log3_png[] = { }; static const unsigned char Toolbar_Open3_png[] = { -0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, -0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, -0x00, 0x00, 0x00, 0x18, 0x08, 0x06, 0x00, 0x00, 0x00, 0xE0, -0x77, 0x3D, 0xF8, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, -0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B, 0x13, 0x01, -0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x0A, 0x4D, 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, 0x77, -0x58, 0x93, 0xF7, 0x16, 0x3E, 0xDF, 0xF7, 0x65, 0x0F, 0x56, -0x42, 0xD8, 0xF0, 0xB1, 0x97, 0x6C, 0x81, 0x00, 0x22, 0x23, -0xAC, 0x08, 0xC8, 0x10, 0x59, 0xA2, 0x10, 0x92, 0x00, 0x61, -0x84, 0x10, 0x12, 0x40, 0xC5, 0x85, 0x88, 0x0A, 0x56, 0x14, -0x15, 0x11, 0x9C, 0x48, 0x55, 0xC4, 0x82, 0xD5, 0x0A, 0x48, -0x9D, 0x88, 0xE2, 0xA0, 0x28, 0xB8, 0x67, 0x41, 0x8A, 0x88, -0x5A, 0x8B, 0x55, 0x5C, 0x38, 0xEE, 0x1F, 0xDC, 0xA7, 0xB5, -0x7D, 0x7A, 0xEF, 0xED, 0xED, 0xFB, 0xD7, 0xFB, 0xBC, 0xE7, -0x9C, 0xE7, 0xFC, 0xCE, 0x79, 0xCF, 0x0F, 0x80, 0x11, 0x12, -0x26, 0x91, 0xE6, 0xA2, 0x6A, 0x00, 0x39, 0x52, 0x85, 0x3C, -0x3A, 0xD8, 0x1F, 0x8F, 0x4F, 0x48, 0xC4, 0xC9, 0xBD, 0x80, -0x02, 0x15, 0x48, 0xE0, 0x04, 0x20, 0x10, 0xE6, 0xCB, 0xC2, -0x67, 0x05, 0xC5, 0x00, 0x00, 0xF0, 0x03, 0x79, 0x78, 0x7E, -0x74, 0xB0, 0x3F, 0xFC, 0x01, 0xAF, 0x6F, 0x00, 0x02, 0x00, -0x70, 0xD5, 0x2E, 0x24, 0x12, 0xC7, 0xE1, 0xFF, 0x83, 0xBA, -0x50, 0x26, 0x57, 0x00, 0x20, 0x91, 0x00, 0xE0, 0x22, 0x12, -0xE7, 0x0B, 0x01, 0x90, 0x52, 0x00, 0xC8, 0x2E, 0x54, 0xC8, -0x14, 0x00, 0xC8, 0x18, 0x00, 0xB0, 0x53, 0xB3, 0x64, 0x0A, -0x00, 0x94, 0x00, 0x00, 0x6C, 0x79, 0x7C, 0x42, 0x22, 0x00, -0xAA, 0x0D, 0x00, 0xEC, 0xF4, 0x49, 0x3E, 0x05, 0x00, 0xD8, -0xA9, 0x93, 0xDC, 0x17, 0x00, 0xD8, 0xA2, 0x1C, 0xA9, 0x08, -0x00, 0x8D, 0x01, 0x00, 0x99, 0x28, 0x47, 0x24, 0x02, 0x40, -0xBB, 0x00, 0x60, 0x55, 0x81, 0x52, 0x2C, 0x02, 0xC0, 0xC2, -0x00, 0xA0, 0xAC, 0x40, 0x22, 0x2E, 0x04, 0xC0, 0xAE, 0x01, -0x80, 0x59, 0xB6, 0x32, 0x47, 0x02, 0x80, 0xBD, 0x05, 0x00, -0x76, 0x8E, 0x58, 0x90, 0x0F, 0x40, 0x60, 0x00, 0x80, 0x99, -0x42, 0x2C, 0xCC, 0x00, 0x20, 0x38, 0x02, 0x00, 0x43, 0x1E, -0x13, 0xCD, 0x03, 0x20, 0x4C, 0x03, 0xA0, 0x30, 0xD2, 0xBF, -0xE0, 0xA9, 0x5F, 0x70, 0x85, 0xB8, 0x48, 0x01, 0x00, 0xC0, -0xCB, 0x95, 0xCD, 0x97, 0x4B, 0xD2, 0x33, 0x14, 0xB8, 0x95, -0xD0, 0x1A, 0x77, 0xF2, 0xF0, 0xE0, 0xE2, 0x21, 0xE2, 0xC2, -0x6C, 0xB1, 0x42, 0x61, 0x17, 0x29, 0x10, 0x66, 0x09, 0xE4, -0x22, 0x9C, 0x97, 0x9B, 0x23, 0x13, 0x48, 0xE7, 0x03, 0x4C, -0xCE, 0x0C, 0x00, 0x00, 0x1A, 0xF9, 0xD1, 0xC1, 0xFE, 0x38, -0x3F, 0x90, 0xE7, 0xE6, 0xE4, 0xE1, 0xE6, 0x66, 0xE7, 0x6C, -0xEF, 0xF4, 0xC5, 0xA2, 0xFE, 0x6B, 0xF0, 0x6F, 0x22, 0x3E, -0x21, 0xF1, 0xDF, 0xFE, 0xBC, 0x8C, 0x02, 0x04, 0x00, 0x10, -0x4E, 0xCF, 0xEF, 0xDA, 0x5F, 0xE5, 0xE5, 0xD6, 0x03, 0x70, -0xC7, 0x01, 0xB0, 0x75, 0xBF, 0x6B, 0xA9, 0x5B, 0x00, 0xDA, -0x56, 0x00, 0x68, 0xDF, 0xF9, 0x5D, 0x33, 0xDB, 0x09, 0xA0, -0x5A, 0x0A, 0xD0, 0x7A, 0xF9, 0x8B, 0x79, 0x38, 0xFC, 0x40, -0x1E, 0x9E, 0xA1, 0x50, 0xC8, 0x3C, 0x1D, 0x1C, 0x0A, 0x0B, -0x0B, 0xED, 0x25, 0x62, 0xA1, 0xBD, 0x30, 0xE3, 0x8B, 0x3E, -0xFF, 0x33, 0xE1, 0x6F, 0xE0, 0x8B, 0x7E, 0xF6, 0xFC, 0x40, -0x1E, 0xFE, 0xDB, 0x7A, 0xF0, 0x00, 0x71, 0x9A, 0x40, 0x99, -0xAD, 0xC0, 0xA3, 0x83, 0xFD, 0x71, 0x61, 0x6E, 0x76, 0xAE, -0x52, 0x8E, 0xE7, 0xCB, 0x04, 0x42, 0x31, 0x6E, 0xF7, 0xE7, -0x23, 0xFE, 0xC7, 0x85, 0x7F, 0xFD, 0x8E, 0x29, 0xD1, 0xE2, -0x34, 0xB1, 0x5C, 0x2C, 0x15, 0x8A, 0xF1, 0x58, 0x89, 0xB8, -0x50, 0x22, 0x4D, 0xC7, 0x79, 0xB9, 0x52, 0x91, 0x44, 0x21, -0xC9, 0x95, 0xE2, 0x12, 0xE9, 0x7F, 0x32, 0xF1, 0x1F, 0x96, -0xFD, 0x09, 0x93, 0x77, 0x0D, 0x00, 0xAC, 0x86, 0x4F, 0xC0, -0x4E, 0xB6, 0x07, 0xB5, 0xCB, 0x6C, 0xC0, 0x7E, 0xEE, 0x01, -0x02, 0x8B, 0x0E, 0x58, 0xD2, 0x76, 0x00, 0x40, 0x7E, 0xF3, -0x2D, 0x8C, 0x1A, 0x0B, 0x91, 0x00, 0x10, 0x67, 0x34, 0x32, -0x79, 0xF7, 0x00, 0x00, 0x93, 0xBF, 0xF9, 0x8F, 0x40, 0x2B, -0x01, 0x00, 0xCD, 0x97, 0xA4, 0xE3, 0x00, 0x00, 0xBC, 0xE8, -0x18, 0x5C, 0xA8, 0x94, 0x17, 0x4C, 0xC6, 0x08, 0x00, 0x00, -0x44, 0xA0, 0x81, 0x2A, 0xB0, 0x41, 0x07, 0x0C, 0xC1, 0x14, -0xAC, 0xC0, 0x0E, 0x9C, 0xC1, 0x1D, 0xBC, 0xC0, 0x17, 0x02, -0x61, 0x06, 0x44, 0x40, 0x0C, 0x24, 0xC0, 0x3C, 0x10, 0x42, -0x06, 0xE4, 0x80, 0x1C, 0x0A, 0xA1, 0x18, 0x96, 0x41, 0x19, -0x54, 0xC0, 0x3A, 0xD8, 0x04, 0xB5, 0xB0, 0x03, 0x1A, 0xA0, -0x11, 0x9A, 0xE1, 0x10, 0xB4, 0xC1, 0x31, 0x38, 0x0D, 0xE7, -0xE0, 0x12, 0x5C, 0x81, 0xEB, 0x70, 0x17, 0x06, 0x60, 0x18, -0x9E, 0xC2, 0x18, 0xBC, 0x86, 0x09, 0x04, 0x41, 0xC8, 0x08, -0x13, 0x61, 0x21, 0x3A, 0x88, 0x11, 0x62, 0x8E, 0xD8, 0x22, -0xCE, 0x08, 0x17, 0x99, 0x8E, 0x04, 0x22, 0x61, 0x48, 0x34, -0x92, 0x80, 0xA4, 0x20, 0xE9, 0x88, 0x14, 0x51, 0x22, 0xC5, -0xC8, 0x72, 0xA4, 0x02, 0xA9, 0x42, 0x6A, 0x91, 0x5D, 0x48, -0x23, 0xF2, 0x2D, 0x72, 0x14, 0x39, 0x8D, 0x5C, 0x40, 0xFA, -0x90, 0xDB, 0xC8, 0x20, 0x32, 0x8A, 0xFC, 0x8A, 0xBC, 0x47, -0x31, 0x94, 0x81, 0xB2, 0x51, 0x03, 0xD4, 0x02, 0x75, 0x40, -0xB9, 0xA8, 0x1F, 0x1A, 0x8A, 0xC6, 0xA0, 0x73, 0xD1, 0x74, -0x34, 0x0F, 0x5D, 0x80, 0x96, 0xA2, 0x6B, 0xD1, 0x1A, 0xB4, -0x1E, 0x3D, 0x80, 0xB6, 0xA2, 0xA7, 0xD1, 0x4B, 0xE8, 0x75, -0x74, 0x00, 0x7D, 0x8A, 0x8E, 0x63, 0x80, 0xD1, 0x31, 0x0E, -0x66, 0x8C, 0xD9, 0x61, 0x5C, 0x8C, 0x87, 0x45, 0x60, 0x89, -0x58, 0x1A, 0x26, 0xC7, 0x16, 0x63, 0xE5, 0x58, 0x35, 0x56, -0x8F, 0x35, 0x63, 0x1D, 0x58, 0x37, 0x76, 0x15, 0x1B, 0xC0, -0x9E, 0x61, 0xEF, 0x08, 0x24, 0x02, 0x8B, 0x80, 0x13, 0xEC, -0x08, 0x5E, 0x84, 0x10, 0xC2, 0x6C, 0x82, 0x90, 0x90, 0x47, -0x58, 0x4C, 0x58, 0x43, 0xA8, 0x25, 0xEC, 0x23, 0xB4, 0x12, -0xBA, 0x08, 0x57, 0x09, 0x83, 0x84, 0x31, 0xC2, 0x27, 0x22, -0x93, 0xA8, 0x4F, 0xB4, 0x25, 0x7A, 0x12, 0xF9, 0xC4, 0x78, -0x62, 0x3A, 0xB1, 0x90, 0x58, 0x46, 0xAC, 0x26, 0xEE, 0x21, -0x1E, 0x21, 0x9E, 0x25, 0x5E, 0x27, 0x0E, 0x13, 0x5F, 0x93, -0x48, 0x24, 0x0E, 0xC9, 0x92, 0xE4, 0x4E, 0x0A, 0x21, 0x25, -0x90, 0x32, 0x49, 0x0B, 0x49, 0x6B, 0x48, 0xDB, 0x48, 0x2D, -0xA4, 0x53, 0xA4, 0x3E, 0xD2, 0x10, 0x69, 0x9C, 0x4C, 0x26, -0xEB, 0x90, 0x6D, 0xC9, 0xDE, 0xE4, 0x08, 0xB2, 0x80, 0xAC, -0x20, 0x97, 0x91, 0xB7, 0x90, 0x0F, 0x90, 0x4F, 0x92, 0xFB, -0xC9, 0xC3, 0xE4, 0xB7, 0x14, 0x3A, 0xC5, 0x88, 0xE2, 0x4C, -0x09, 0xA2, 0x24, 0x52, 0xA4, 0x94, 0x12, 0x4A, 0x35, 0x65, -0x3F, 0xE5, 0x04, 0xA5, 0x9F, 0x32, 0x42, 0x99, 0xA0, 0xAA, -0x51, 0xCD, 0xA9, 0x9E, 0xD4, 0x08, 0xAA, 0x88, 0x3A, 0x9F, -0x5A, 0x49, 0x6D, 0xA0, 0x76, 0x50, 0x2F, 0x53, 0x87, 0xA9, -0x13, 0x34, 0x75, 0x9A, 0x25, 0xCD, 0x9B, 0x16, 0x43, 0xCB, -0xA4, 0x2D, 0xA3, 0xD5, 0xD0, 0x9A, 0x69, 0x67, 0x69, 0xF7, -0x68, 0x2F, 0xE9, 0x74, 0xBA, 0x09, 0xDD, 0x83, 0x1E, 0x45, -0x97, 0xD0, 0x97, 0xD2, 0x6B, 0xE8, 0x07, 0xE9, 0xE7, 0xE9, -0x83, 0xF4, 0x77, 0x0C, 0x0D, 0x86, 0x0D, 0x83, 0xC7, 0x48, -0x62, 0x28, 0x19, 0x6B, 0x19, 0x7B, 0x19, 0xA7, 0x18, 0xB7, -0x19, 0x2F, 0x99, 0x4C, 0xA6, 0x05, 0xD3, 0x97, 0x99, 0xC8, -0x54, 0x30, 0xD7, 0x32, 0x1B, 0x99, 0x67, 0x98, 0x0F, 0x98, -0x6F, 0x55, 0x58, 0x2A, 0xF6, 0x2A, 0x7C, 0x15, 0x91, 0xCA, -0x12, 0x95, 0x3A, 0x95, 0x56, 0x95, 0x7E, 0x95, 0xE7, 0xAA, -0x54, 0x55, 0x73, 0x55, 0x3F, 0xD5, 0x79, 0xAA, 0x0B, 0x54, -0xAB, 0x55, 0x0F, 0xAB, 0x5E, 0x56, 0x7D, 0xA6, 0x46, 0x55, -0xB3, 0x50, 0xE3, 0xA9, 0x09, 0xD4, 0x16, 0xAB, 0xD5, 0xA9, -0x1D, 0x55, 0xBB, 0xA9, 0x36, 0xAE, 0xCE, 0x52, 0x77, 0x52, -0x8F, 0x50, 0xCF, 0x51, 0x5F, 0xA3, 0xBE, 0x5F, 0xFD, 0x82, -0xFA, 0x63, 0x0D, 0xB2, 0x86, 0x85, 0x46, 0xA0, 0x86, 0x48, -0xA3, 0x54, 0x63, 0xB7, 0xC6, 0x19, 0x8D, 0x21, 0x16, 0xC6, -0x32, 0x65, 0xF1, 0x58, 0x42, 0xD6, 0x72, 0x56, 0x03, 0xEB, -0x2C, 0x6B, 0x98, 0x4D, 0x62, 0x5B, 0xB2, 0xF9, 0xEC, 0x4C, -0x76, 0x05, 0xFB, 0x1B, 0x76, 0x2F, 0x7B, 0x4C, 0x53, 0x43, -0x73, 0xAA, 0x66, 0xAC, 0x66, 0x91, 0x66, 0x9D, 0xE6, 0x71, -0xCD, 0x01, 0x0E, 0xC6, 0xB1, 0xE0, 0xF0, 0x39, 0xD9, 0x9C, -0x4A, 0xCE, 0x21, 0xCE, 0x0D, 0xCE, 0x7B, 0x2D, 0x03, 0x2D, -0x3F, 0x2D, 0xB1, 0xD6, 0x6A, 0xAD, 0x66, 0xAD, 0x7E, 0xAD, -0x37, 0xDA, 0x7A, 0xDA, 0xBE, 0xDA, 0x62, 0xED, 0x72, 0xED, -0x16, 0xED, 0xEB, 0xDA, 0xEF, 0x75, 0x70, 0x9D, 0x40, 0x9D, -0x2C, 0x9D, 0xF5, 0x3A, 0x6D, 0x3A, 0xF7, 0x75, 0x09, 0xBA, -0x36, 0xBA, 0x51, 0xBA, 0x85, 0xBA, 0xDB, 0x75, 0xCF, 0xEA, -0x3E, 0xD3, 0x63, 0xEB, 0x79, 0xE9, 0x09, 0xF5, 0xCA, 0xF5, -0x0E, 0xE9, 0xDD, 0xD1, 0x47, 0xF5, 0x6D, 0xF4, 0xA3, 0xF5, -0x17, 0xEA, 0xEF, 0xD6, 0xEF, 0xD1, 0x1F, 0x37, 0x30, 0x34, -0x08, 0x36, 0x90, 0x19, 0x6C, 0x31, 0x38, 0x63, 0xF0, 0xCC, -0x90, 0x63, 0xE8, 0x6B, 0x98, 0x69, 0xB8, 0xD1, 0xF0, 0x84, -0xE1, 0xA8, 0x11, 0xCB, 0x68, 0xBA, 0x91, 0xC4, 0x68, 0xA3, -0xD1, 0x49, 0xA3, 0x27, 0xB8, 0x26, 0xEE, 0x87, 0x67, 0xE3, -0x35, 0x78, 0x17, 0x3E, 0x66, 0xAC, 0x6F, 0x1C, 0x62, 0xAC, -0x34, 0xDE, 0x65, 0xDC, 0x6B, 0x3C, 0x61, 0x62, 0x69, 0x32, -0xDB, 0xA4, 0xC4, 0xA4, 0xC5, 0xE4, 0xBE, 0x29, 0xCD, 0x94, -0x6B, 0x9A, 0x66, 0xBA, 0xD1, 0xB4, 0xD3, 0x74, 0xCC, 0xCC, -0xC8, 0x2C, 0xDC, 0xAC, 0xD8, 0xAC, 0xC9, 0xEC, 0x8E, 0x39, -0xD5, 0x9C, 0x6B, 0x9E, 0x61, 0xBE, 0xD9, 0xBC, 0xDB, 0xFC, -0x8D, 0x85, 0xA5, 0x45, 0x9C, 0xC5, 0x4A, 0x8B, 0x36, 0x8B, -0xC7, 0x96, 0xDA, 0x96, 0x7C, 0xCB, 0x05, 0x96, 0x4D, 0x96, -0xF7, 0xAC, 0x98, 0x56, 0x3E, 0x56, 0x79, 0x56, 0xF5, 0x56, -0xD7, 0xAC, 0x49, 0xD6, 0x5C, 0xEB, 0x2C, 0xEB, 0x6D, 0xD6, -0x57, 0x6C, 0x50, 0x1B, 0x57, 0x9B, 0x0C, 0x9B, 0x3A, 0x9B, -0xCB, 0xB6, 0xA8, 0xAD, 0x9B, 0xAD, 0xC4, 0x76, 0x9B, 0x6D, -0xDF, 0x14, 0xE2, 0x14, 0x8F, 0x29, 0xD2, 0x29, 0xF5, 0x53, -0x6E, 0xDA, 0x31, 0xEC, 0xFC, 0xEC, 0x0A, 0xEC, 0x9A, 0xEC, -0x06, 0xED, 0x39, 0xF6, 0x61, 0xF6, 0x25, 0xF6, 0x6D, 0xF6, -0xCF, 0x1D, 0xCC, 0x1C, 0x12, 0x1D, 0xD6, 0x3B, 0x74, 0x3B, -0x7C, 0x72, 0x74, 0x75, 0xCC, 0x76, 0x6C, 0x70, 0xBC, 0xEB, -0xA4, 0xE1, 0x34, 0xC3, 0xA9, 0xC4, 0xA9, 0xC3, 0xE9, 0x57, -0x67, 0x1B, 0x67, 0xA1, 0x73, 0x9D, 0xF3, 0x35, 0x17, 0xA6, -0x4B, 0x90, 0xCB, 0x12, 0x97, 0x76, 0x97, 0x17, 0x53, 0x6D, -0xA7, 0x8A, 0xA7, 0x6E, 0x9F, 0x7A, 0xCB, 0x95, 0xE5, 0x1A, -0xEE, 0xBA, 0xD2, 0xB5, 0xD3, 0xF5, 0xA3, 0x9B, 0xBB, 0x9B, -0xDC, 0xAD, 0xD9, 0x6D, 0xD4, 0xDD, 0xCC, 0x3D, 0xC5, 0x7D, -0xAB, 0xFB, 0x4D, 0x2E, 0x9B, 0x1B, 0xC9, 0x5D, 0xC3, 0x3D, -0xEF, 0x41, 0xF4, 0xF0, 0xF7, 0x58, 0xE2, 0x71, 0xCC, 0xE3, -0x9D, 0xA7, 0x9B, 0xA7, 0xC2, 0xF3, 0x90, 0xE7, 0x2F, 0x5E, -0x76, 0x5E, 0x59, 0x5E, 0xFB, 0xBD, 0x1E, 0x4F, 0xB3, 0x9C, -0x26, 0x9E, 0xD6, 0x30, 0x6D, 0xC8, 0xDB, 0xC4, 0x5B, 0xE0, -0xBD, 0xCB, 0x7B, 0x60, 0x3A, 0x3E, 0x3D, 0x65, 0xFA, 0xCE, -0xE9, 0x03, 0x3E, 0xC6, 0x3E, 0x02, 0x9F, 0x7A, 0x9F, 0x87, -0xBE, 0xA6, 0xBE, 0x22, 0xDF, 0x3D, 0xBE, 0x23, 0x7E, 0xD6, -0x7E, 0x99, 0x7E, 0x07, 0xFC, 0x9E, 0xFB, 0x3B, 0xFA, 0xCB, -0xFD, 0x8F, 0xF8, 0xBF, 0xE1, 0x79, 0xF2, 0x16, 0xF1, 0x4E, -0x05, 0x60, 0x01, 0xC1, 0x01, 0xE5, 0x01, 0xBD, 0x81, 0x1A, -0x81, 0xB3, 0x03, 0x6B, 0x03, 0x1F, 0x04, 0x99, 0x04, 0xA5, -0x07, 0x35, 0x05, 0x8D, 0x05, 0xBB, 0x06, 0x2F, 0x0C, 0x3E, -0x15, 0x42, 0x0C, 0x09, 0x0D, 0x59, 0x1F, 0x72, 0x93, 0x6F, -0xC0, 0x17, 0xF2, 0x1B, 0xF9, 0x63, 0x33, 0xDC, 0x67, 0x2C, -0x9A, 0xD1, 0x15, 0xCA, 0x08, 0x9D, 0x15, 0x5A, 0x1B, 0xFA, -0x30, 0xCC, 0x26, 0x4C, 0x1E, 0xD6, 0x11, 0x8E, 0x86, 0xCF, -0x08, 0xDF, 0x10, 0x7E, 0x6F, 0xA6, 0xF9, 0x4C, 0xE9, 0xCC, -0xB6, 0x08, 0x88, 0xE0, 0x47, 0x6C, 0x88, 0xB8, 0x1F, 0x69, -0x19, 0x99, 0x17, 0xF9, 0x7D, 0x14, 0x29, 0x2A, 0x32, 0xAA, -0x2E, 0xEA, 0x51, 0xB4, 0x53, 0x74, 0x71, 0x74, 0xF7, 0x2C, -0xD6, 0xAC, 0xE4, 0x59, 0xFB, 0x67, 0xBD, 0x8E, 0xF1, 0x8F, -0xA9, 0x8C, 0xB9, 0x3B, 0xDB, 0x6A, 0xB6, 0x72, 0x76, 0x67, -0xAC, 0x6A, 0x6C, 0x52, 0x6C, 0x63, 0xEC, 0x9B, 0xB8, 0x80, -0xB8, 0xAA, 0xB8, 0x81, 0x78, 0x87, 0xF8, 0x45, 0xF1, 0x97, -0x12, 0x74, 0x13, 0x24, 0x09, 0xED, 0x89, 0xE4, 0xC4, 0xD8, -0xC4, 0x3D, 0x89, 0xE3, 0x73, 0x02, 0xE7, 0x6C, 0x9A, 0x33, -0x9C, 0xE4, 0x9A, 0x54, 0x96, 0x74, 0x63, 0xAE, 0xE5, 0xDC, -0xA2, 0xB9, 0x17, 0xE6, 0xE9, 0xCE, 0xCB, 0x9E, 0x77, 0x3C, -0x59, 0x35, 0x59, 0x90, 0x7C, 0x38, 0x85, 0x98, 0x12, 0x97, -0xB2, 0x3F, 0xE5, 0x83, 0x20, 0x42, 0x50, 0x2F, 0x18, 0x4F, -0xE5, 0xA7, 0x6E, 0x4D, 0x1D, 0x13, 0xF2, 0x84, 0x9B, 0x85, -0x4F, 0x45, 0xBE, 0xA2, 0x8D, 0xA2, 0x51, 0xB1, 0xB7, 0xB8, -0x4A, 0x3C, 0x92, 0xE6, 0x9D, 0x56, 0x95, 0xF6, 0x38, 0xDD, -0x3B, 0x7D, 0x43, 0xFA, 0x68, 0x86, 0x4F, 0x46, 0x75, 0xC6, -0x33, 0x09, 0x4F, 0x52, 0x2B, 0x79, 0x91, 0x19, 0x92, 0xB9, -0x23, 0xF3, 0x4D, 0x56, 0x44, 0xD6, 0xDE, 0xAC, 0xCF, 0xD9, -0x71, 0xD9, 0x2D, 0x39, 0x94, 0x9C, 0x94, 0x9C, 0xA3, 0x52, -0x0D, 0x69, 0x96, 0xB4, 0x2B, 0xD7, 0x30, 0xB7, 0x28, 0xB7, -0x4F, 0x66, 0x2B, 0x2B, 0x93, 0x0D, 0xE4, 0x79, 0xE6, 0x6D, -0xCA, 0x1B, 0x93, 0x87, 0xCA, 0xF7, 0xE4, 0x23, 0xF9, 0x73, -0xF3, 0xDB, 0x15, 0x6C, 0x85, 0x4C, 0xD1, 0xA3, 0xB4, 0x52, -0xAE, 0x50, 0x0E, 0x16, 0x4C, 0x2F, 0xA8, 0x2B, 0x78, 0x5B, -0x18, 0x5B, 0x78, 0xB8, 0x48, 0xBD, 0x48, 0x5A, 0xD4, 0x33, -0xDF, 0x66, 0xFE, 0xEA, 0xF9, 0x23, 0x0B, 0x82, 0x16, 0x7C, -0xBD, 0x90, 0xB0, 0x50, 0xB8, 0xB0, 0xB3, 0xD8, 0xB8, 0x78, -0x59, 0xF1, 0xE0, 0x22, 0xBF, 0x45, 0xBB, 0x16, 0x23, 0x8B, -0x53, 0x17, 0x77, 0x2E, 0x31, 0x5D, 0x52, 0xBA, 0x64, 0x78, -0x69, 0xF0, 0xD2, 0x7D, 0xCB, 0x68, 0xCB, 0xB2, 0x96, 0xFD, -0x50, 0xE2, 0x58, 0x52, 0x55, 0xF2, 0x6A, 0x79, 0xDC, 0xF2, -0x8E, 0x52, 0x83, 0xD2, 0xA5, 0xA5, 0x43, 0x2B, 0x82, 0x57, -0x34, 0x95, 0xA9, 0x94, 0xC9, 0xCB, 0x6E, 0xAE, 0xF4, 0x5A, -0xB9, 0x63, 0x15, 0x61, 0x95, 0x64, 0x55, 0xEF, 0x6A, 0x97, -0xD5, 0x5B, 0x56, 0x7F, 0x2A, 0x17, 0x95, 0x5F, 0xAC, 0x70, -0xAC, 0xA8, 0xAE, 0xF8, 0xB0, 0x46, 0xB8, 0xE6, 0xE2, 0x57, -0x4E, 0x5F, 0xD5, 0x7C, 0xF5, 0x79, 0x6D, 0xDA, 0xDA, 0xDE, -0x4A, 0xB7, 0xCA, 0xED, 0xEB, 0x48, 0xEB, 0xA4, 0xEB, 0x6E, -0xAC, 0xF7, 0x59, 0xBF, 0xAF, 0x4A, 0xBD, 0x6A, 0x41, 0xD5, -0xD0, 0x86, 0xF0, 0x0D, 0xAD, 0x1B, 0xF1, 0x8D, 0xE5, 0x1B, -0x5F, 0x6D, 0x4A, 0xDE, 0x74, 0xA1, 0x7A, 0x6A, 0xF5, 0x8E, -0xCD, 0xB4, 0xCD, 0xCA, 0xCD, 0x03, 0x35, 0x61, 0x35, 0xED, -0x5B, 0xCC, 0xB6, 0xAC, 0xDB, 0xF2, 0xA1, 0x36, 0xA3, 0xF6, -0x7A, 0x9D, 0x7F, 0x5D, 0xCB, 0x56, 0xFD, 0xAD, 0xAB, 0xB7, -0xBE, 0xD9, 0x26, 0xDA, 0xD6, 0xBF, 0xDD, 0x77, 0x7B, 0xF3, -0x0E, 0x83, 0x1D, 0x15, 0x3B, 0xDE, 0xEF, 0x94, 0xEC, 0xBC, -0xB5, 0x2B, 0x78, 0x57, 0x6B, 0xBD, 0x45, 0x7D, 0xF5, 0x6E, -0xD2, 0xEE, 0x82, 0xDD, 0x8F, 0x1A, 0x62, 0x1B, 0xBA, 0xBF, -0xE6, 0x7E, 0xDD, 0xB8, 0x47, 0x77, 0x4F, 0xC5, 0x9E, 0x8F, -0x7B, 0xA5, 0x7B, 0x07, 0xF6, 0x45, 0xEF, 0xEB, 0x6A, 0x74, -0x6F, 0x6C, 0xDC, 0xAF, 0xBF, 0xBF, 0xB2, 0x09, 0x6D, 0x52, -0x36, 0x8D, 0x1E, 0x48, 0x3A, 0x70, 0xE5, 0x9B, 0x80, 0x6F, -0xDA, 0x9B, 0xED, 0x9A, 0x77, 0xB5, 0x70, 0x5A, 0x2A, 0x0E, -0xC2, 0x41, 0xE5, 0xC1, 0x27, 0xDF, 0xA6, 0x7C, 0x7B, 0xE3, -0x50, 0xE8, 0xA1, 0xCE, 0xC3, 0xDC, 0xC3, 0xCD, 0xDF, 0x99, -0x7F, 0xB7, 0xF5, 0x08, 0xEB, 0x48, 0x79, 0x2B, 0xD2, 0x3A, -0xBF, 0x75, 0xAC, 0x2D, 0xA3, 0x6D, 0xA0, 0x3D, 0xA1, 0xBD, -0xEF, 0xE8, 0x8C, 0xA3, 0x9D, 0x1D, 0x5E, 0x1D, 0x47, 0xBE, -0xB7, 0xFF, 0x7E, 0xEF, 0x31, 0xE3, 0x63, 0x75, 0xC7, 0x35, -0x8F, 0x57, 0x9E, 0xA0, 0x9D, 0x28, 0x3D, 0xF1, 0xF9, 0xE4, -0x82, 0x93, 0xE3, 0xA7, 0x64, 0xA7, 0x9E, 0x9D, 0x4E, 0x3F, -0x3D, 0xD4, 0x99, 0xDC, 0x79, 0xF7, 0x4C, 0xFC, 0x99, 0x6B, -0x5D, 0x51, 0x5D, 0xBD, 0x67, 0x43, 0xCF, 0x9E, 0x3F, 0x17, -0x74, 0xEE, 0x4C, 0xB7, 0x5F, 0xF7, 0xC9, 0xF3, 0xDE, 0xE7, -0x8F, 0x5D, 0xF0, 0xBC, 0x70, 0xF4, 0x22, 0xF7, 0x62, 0xDB, -0x25, 0xB7, 0x4B, 0xAD, 0x3D, 0xAE, 0x3D, 0x47, 0x7E, 0x70, -0xFD, 0xE1, 0x48, 0xAF, 0x5B, 0x6F, 0xEB, 0x65, 0xF7, 0xCB, -0xED, 0x57, 0x3C, 0xAE, 0x74, 0xF4, 0x4D, 0xEB, 0x3B, 0xD1, -0xEF, 0xD3, 0x7F, 0xFA, 0x6A, 0xC0, 0xD5, 0x73, 0xD7, 0xF8, -0xD7, 0x2E, 0x5D, 0x9F, 0x79, 0xBD, 0xEF, 0xC6, 0xEC, 0x1B, -0xB7, 0x6E, 0x26, 0xDD, 0x1C, 0xB8, 0x25, 0xBA, 0xF5, 0xF8, -0x76, 0xF6, 0xED, 0x17, 0x77, 0x0A, 0xEE, 0x4C, 0xDC, 0x5D, -0x7A, 0x8F, 0x78, 0xAF, 0xFC, 0xBE, 0xDA, 0xFD, 0xEA, 0x07, -0xFA, 0x0F, 0xEA, 0x7F, 0xB4, 0xFE, 0xB1, 0x65, 0xC0, 0x6D, -0xE0, 0xF8, 0x60, 0xC0, 0x60, 0xCF, 0xC3, 0x59, 0x0F, 0xEF, -0x0E, 0x09, 0x87, 0x9E, 0xFE, 0x94, 0xFF, 0xD3, 0x87, 0xE1, -0xD2, 0x47, 0xCC, 0x47, 0xD5, 0x23, 0x46, 0x23, 0x8D, 0x8F, -0x9D, 0x1F, 0x1F, 0x1B, 0x0D, 0x1A, 0xBD, 0xF2, 0x64, 0xCE, -0x93, 0xE1, 0xA7, 0xB2, 0xA7, 0x13, 0xCF, 0xCA, 0x7E, 0x56, -0xFF, 0x79, 0xEB, 0x73, 0xAB, 0xE7, 0xDF, 0xFD, 0xE2, 0xFB, -0x4B, 0xCF, 0x58, 0xFC, 0xD8, 0xF0, 0x0B, 0xF9, 0x8B, 0xCF, -0xBF, 0xAE, 0x79, 0xA9, 0xF3, 0x72, 0xEF, 0xAB, 0xA9, 0xAF, -0x3A, 0xC7, 0x23, 0xC7, 0x1F, 0xBC, 0xCE, 0x79, 0x3D, 0xF1, -0xA6, 0xFC, 0xAD, 0xCE, 0xDB, 0x7D, 0xEF, 0xB8, 0xEF, 0xBA, -0xDF, 0xC7, 0xBD, 0x1F, 0x99, 0x28, 0xFC, 0x40, 0xFE, 0x50, -0xF3, 0xD1, 0xFA, 0x63, 0xC7, 0xA7, 0xD0, 0x4F, 0xF7, 0x3E, -0xE7, 0x7C, 0xFE, 0xFC, 0x2F, 0xF7, 0x84, 0xF3, 0xFB, 0x25, -0xD2, 0x9F, 0x33, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, -0x41, 0x00, 0x00, 0xB1, 0x8E, 0x7C, 0xFB, 0x51, 0x93, 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, 0x06, 0x23, 0x49, 0x44, 0x41, -0x54, 0x78, 0xDA, 0x64, 0x96, 0x4B, 0x6C, 0x5D, 0x47, 0x19, -0xC7, 0x7F, 0x73, 0x66, 0xCE, 0x39, 0xF7, 0xDC, 0x97, 0xEF, -0xBD, 0x7E, 0x25, 0x7E, 0x34, 0x71, 0x1C, 0xDB, 0xB1, 0x93, -0x34, 0xB8, 0x09, 0x45, 0x11, 0xB4, 0x42, 0x3C, 0x04, 0x24, -0x08, 0x95, 0xAA, 0x6C, 0x11, 0x3B, 0x24, 0x58, 0xB0, 0x62, -0xC1, 0x06, 0x58, 0x95, 0x15, 0x6B, 0x04, 0x95, 0x90, 0x22, -0x45, 0x42, 0x20, 0x84, 0x84, 0x5A, 0x90, 0xA2, 0xB4, 0xA1, -0x0A, 0x10, 0xDA, 0xF4, 0x45, 0x5A, 0x35, 0x4D, 0x1B, 0x39, -0x76, 0xDD, 0xD8, 0x71, 0x62, 0xFB, 0x3A, 0xBE, 0xCF, 0x73, -0xCE, 0xCC, 0x9C, 0x61, 0x71, 0x93, 0x6B, 0x94, 0x8C, 0x34, -0xCB, 0xF9, 0xFF, 0xBE, 0xEF, 0xFF, 0x9F, 0x4F, 0x33, 0xE2, -0xE7, 0x3F, 0x7E, 0x96, 0x47, 0x97, 0xD6, 0x29, 0x23, 0x23, -0xFB, 0xC9, 0x9C, 0xE0, 0xE0, 0xF4, 0x1C, 0x4F, 0x9D, 0x38, -0xC6, 0xC5, 0x0B, 0x2F, 0xB3, 0xBE, 0xD9, 0xE0, 0x9B, 0x67, -0x5E, 0xE0, 0xED, 0x37, 0xFE, 0xE5, 0xE5, 0x72, 0xB2, 0x36, -0x36, 0x31, 0x39, 0x5A, 0xAB, 0x96, 0xC6, 0x47, 0x07, 0x6B, -0xFB, 0xEE, 0x6D, 0x6D, 0xD5, 0x56, 0x3E, 0xBD, 0x5D, 0xA9, -0xD5, 0x2A, 0x33, 0x33, 0xB3, 0x4F, 0xFE, 0xF6, 0xC0, 0x89, -0xE7, 0x2E, 0x03, 0x28, 0x6B, 0xED, 0x63, 0x00, 0x6B, 0x2D, -0xA9, 0x36, 0x44, 0xB9, 0xD2, 0x50, 0x2E, 0x0C, 0x8F, 0x26, -0x49, 0xF7, 0xD0, 0xC2, 0xC2, 0xFC, 0xD4, 0x91, 0x2C, 0x3B, -0x34, 0x56, 0xCD, 0x0E, 0x7D, 0xF7, 0xEC, 0xE9, 0x7D, 0xBE, -0xF2, 0x46, 0xF3, 0x39, 0x3F, 0x9F, 0x68, 0x4D, 0x92, 0xA6, -0xCC, 0x1E, 0x1C, 0xE1, 0xE9, 0x93, 0x47, 0xE8, 0xEE, 0x6E, -0xE0, 0xA2, 0x91, 0xAB, 0x40, 0x0F, 0x10, 0x45, 0xD1, 0x63, -0x00, 0x63, 0x2C, 0xE3, 0x63, 0xFB, 0x5E, 0x3C, 0xF3, 0xF5, -0x67, 0x7E, 0xA6, 0xA4, 0xC5, 0x59, 0xCD, 0xD4, 0xC4, 0x1C, -0x41, 0xA8, 0xC8, 0x3A, 0x0D, 0x3C, 0xE9, 0x83, 0x2F, 0xA9, -0x6F, 0xB5, 0x48, 0x8C, 0x47, 0x21, 0x0A, 0x09, 0x03, 0x87, -0x6E, 0xDE, 0xA5, 0xB9, 0xB3, 0x85, 0xEF, 0xEB, 0x38, 0xFF, -0x40, 0x4B, 0xD5, 0x06, 0x47, 0x1F, 0x03, 0x48, 0xBF, 0xC8, -0xC4, 0xD8, 0xE8, 0xE9, 0xEA, 0x50, 0x48, 0xBC, 0xB3, 0x8B, -0x11, 0x90, 0xB4, 0x76, 0xE9, 0x36, 0x1C, 0x42, 0x08, 0x8A, -0x05, 0xC9, 0xD6, 0x7A, 0x9D, 0xE5, 0x3B, 0x1D, 0x8E, 0x1F, -0x99, 0x24, 0xF0, 0x0C, 0xD6, 0x81, 0x36, 0x19, 0x5A, 0x5B, -0xA4, 0x49, 0xD4, 0x43, 0x2D, 0x2F, 0xCB, 0x2C, 0x8F, 0x6E, -0xC8, 0x88, 0x93, 0xA4, 0x9B, 0x34, 0xDA, 0x74, 0x93, 0x94, -0x34, 0x4D, 0x31, 0x5A, 0xE3, 0x32, 0x8B, 0x92, 0x82, 0x77, -0x3E, 0xB8, 0xC5, 0x4B, 0x7F, 0xB8, 0xC4, 0x67, 0xEB, 0x9B, -0xE4, 0x23, 0x1F, 0xEB, 0x00, 0x04, 0x36, 0xCB, 0xB0, 0xD6, -0x10, 0xC7, 0xCD, 0xC2, 0x43, 0x80, 0xEA, 0xB4, 0x9B, 0x8F, -0x75, 0xD0, 0x6A, 0xB6, 0x48, 0x92, 0x34, 0x76, 0x59, 0x86, -0x6F, 0x3B, 0x28, 0x61, 0x70, 0x08, 0xA4, 0x10, 0x04, 0x04, -0x2C, 0x2D, 0xAD, 0xB2, 0x76, 0xA7, 0xCE, 0xD1, 0xF9, 0x59, -0x10, 0x02, 0x01, 0x38, 0xC0, 0x1A, 0x83, 0x31, 0x06, 0x52, -0x9D, 0xDF, 0x03, 0x6C, 0xAF, 0x3E, 0x22, 0xEF, 0xB8, 0xBF, -0xBD, 0x03, 0xF1, 0x13, 0xDD, 0x90, 0x2E, 0x2B, 0xED, 0x3C, -0x1B, 0xBA, 0x46, 0x9C, 0x85, 0x28, 0x09, 0x83, 0x61, 0x8A, -0xF1, 0x96, 0x28, 0x87, 0x06, 0x29, 0x0C, 0x08, 0xAF, 0x77, -0xCA, 0x39, 0x8C, 0x36, 0x68, 0x9D, 0xA2, 0x04, 0x61, 0x1F, -0x10, 0x8F, 0x3E, 0x72, 0x4D, 0x85, 0x24, 0xAA, 0x34, 0x69, -0x88, 0x4A, 0xE7, 0xC2, 0xE6, 0x51, 0xAE, 0x37, 0x07, 0x89, -0x5D, 0xD4, 0xEB, 0x40, 0x4A, 0x72, 0x4E, 0xB2, 0x12, 0x37, -0xD9, 0xD4, 0x1B, 0x58, 0xA7, 0x00, 0x0B, 0x42, 0x90, 0xD9, -0x0C, 0xA3, 0x13, 0x4C, 0x9A, 0x20, 0x70, 0xFD, 0x0C, 0x94, -0x37, 0x7D, 0xE6, 0xFF, 0xC4, 0x05, 0x3A, 0x8E, 0x19, 0xAC, -0x0D, 0x2D, 0x6C, 0x57, 0x2A, 0xDF, 0x5B, 0xEF, 0x14, 0xC9, -0x85, 0x96, 0x8A, 0xB0, 0x48, 0xCF, 0x43, 0x2A, 0x50, 0xBE, -0x22, 0xF3, 0x4B, 0xDC, 0xF6, 0x66, 0x69, 0x88, 0x2A, 0x08, -0x8D, 0x00, 0xB2, 0xCC, 0xA2, 0x8D, 0x46, 0x6B, 0x8D, 0x73, -0xCE, 0xEB, 0x03, 0xB6, 0x57, 0x3E, 0x7C, 0xA8, 0x4E, 0x9A, -0x74, 0x29, 0x16, 0xCB, 0xC1, 0xC0, 0xF4, 0xA1, 0x3F, 0xF9, -0x03, 0x83, 0x03, 0x79, 0x93, 0x20, 0x85, 0x87, 0x10, 0x3E, -0x4A, 0x4A, 0x94, 0x52, 0x28, 0x3F, 0xA0, 0x10, 0x0A, 0xF2, -0xBE, 0xC0, 0x93, 0xF2, 0x81, 0xA9, 0x3D, 0xFF, 0xB5, 0xD6, -0x68, 0x9D, 0xE2, 0x32, 0x27, 0xFA, 0x80, 0x8D, 0xE5, 0x9B, -0x08, 0x1C, 0x38, 0x47, 0xAB, 0xD5, 0x60, 0xF1, 0xCB, 0xDF, -0xFE, 0x49, 0x6D, 0x74, 0xFC, 0x68, 0xB7, 0xD3, 0x40, 0x2A, -0x09, 0xC2, 0xC3, 0xF7, 0x43, 0xF0, 0x14, 0x78, 0x92, 0x20, -0x0C, 0x50, 0x4A, 0x21, 0xA5, 0x87, 0xF7, 0xB0, 0x4E, 0xE7, -0xD0, 0x5A, 0x63, 0xB4, 0xC6, 0xE8, 0x04, 0x27, 0x9C, 0xEB, -0x03, 0xA4, 0x0A, 0x90, 0xCA, 0xA7, 0xDD, 0xB8, 0x4F, 0x90, -0x2B, 0x30, 0x79, 0x78, 0xEE, 0x79, 0xA5, 0x04, 0x81, 0x54, -0x48, 0x21, 0x50, 0x41, 0x48, 0xAC, 0x53, 0x76, 0x37, 0x6F, -0x83, 0x17, 0x50, 0xA8, 0x0E, 0x21, 0xA4, 0x4F, 0x2E, 0x97, -0x43, 0x3E, 0xE8, 0x20, 0xCB, 0x32, 0x8C, 0x4E, 0x31, 0x46, -0xA3, 0xD3, 0x14, 0x21, 0xBC, 0xBD, 0x0E, 0xBA, 0x5B, 0xB7, -0x69, 0xBA, 0x80, 0xEA, 0xE4, 0x0C, 0x81, 0x92, 0xE3, 0xC5, -0x52, 0xF9, 0xA8, 0xC2, 0x23, 0x0B, 0x42, 0x94, 0x92, 0x78, -0x32, 0xA0, 0xBD, 0x71, 0x8B, 0x62, 0xFD, 0x2D, 0xC6, 0xFD, -0x2D, 0xB6, 0xBB, 0x73, 0xB4, 0x9A, 0x96, 0x4E, 0xDC, 0xAB, -0x18, 0x4F, 0x62, 0x6D, 0xD6, 0xAB, 0x3E, 0xED, 0x65, 0x60, -0x8D, 0x95, 0x7D, 0x40, 0x7B, 0x67, 0x93, 0x0F, 0xDF, 0x7F, -0x9F, 0x7D, 0xD3, 0x2B, 0x1C, 0x39, 0xFD, 0x35, 0x55, 0x2C, -0x95, 0xA5, 0x1F, 0xFA, 0x78, 0x12, 0x82, 0x30, 0x04, 0x99, -0x23, 0xAF, 0x34, 0x03, 0x7E, 0x97, 0x31, 0x77, 0x8B, 0xC8, -0x8B, 0xB0, 0x6D, 0x9F, 0xAD, 0xED, 0x1D, 0x42, 0x19, 0x41, -0x4E, 0xA1, 0xD3, 0x14, 0xAD, 0x53, 0x8C, 0xD5, 0x64, 0x36, -0x23, 0xEE, 0x34, 0xFB, 0x73, 0xE0, 0xE5, 0x8B, 0x65, 0xA2, -0x42, 0x91, 0x5B, 0xD7, 0xDE, 0xE2, 0xF5, 0x3F, 0x9F, 0xB3, -0xC6, 0xE8, 0x9D, 0x91, 0xD1, 0x22, 0x61, 0x18, 0x92, 0xC6, -0x09, 0x9B, 0xF7, 0xEE, 0xD2, 0x35, 0x3E, 0x69, 0x34, 0xCE, -0x5A, 0xF9, 0x59, 0xBA, 0xC5, 0x29, 0x72, 0xBE, 0xA2, 0x5A, -0x29, 0xF2, 0xF1, 0x86, 0xA3, 0xBD, 0xD1, 0x45, 0x7A, 0x19, -0xC6, 0x18, 0x8C, 0xD6, 0xD8, 0xCC, 0x90, 0xC6, 0xAD, 0x52, -0x1F, 0xB0, 0xBA, 0xBA, 0x1A, 0x6D, 0xD7, 0x77, 0x26, 0x93, -0x8C, 0xD9, 0x9D, 0x7B, 0xEB, 0xD1, 0xDB, 0x97, 0x5F, 0xFB, -0xA4, 0x93, 0xC0, 0xCA, 0xCA, 0xA7, 0x2C, 0xAF, 0x2C, 0xB3, -0xB9, 0xB1, 0x46, 0xE2, 0x95, 0x68, 0x15, 0x8F, 0xD1, 0x2A, -0x9F, 0xA4, 0x5D, 0x3A, 0x45, 0x2A, 0x0A, 0x0C, 0x97, 0x7C, -0xDE, 0x5C, 0x36, 0xBC, 0xFA, 0xDF, 0x6D, 0x8A, 0xA1, 0xEC, -0x65, 0xA0, 0x7B, 0x90, 0x2C, 0xB3, 0xFD, 0x41, 0xF3, 0xE6, -0xE6, 0xE6, 0xD2, 0x6A, 0xB5, 0x1A, 0x00, 0xE3, 0x80, 0xFA, -0xEB, 0xB9, 0xDF, 0xBC, 0xFA, 0xD1, 0xF5, 0x25, 0x3C, 0x3F, -0x20, 0x97, 0xCB, 0x51, 0xAD, 0x54, 0x18, 0x28, 0x15, 0x90, -0xD1, 0x30, 0x71, 0xEE, 0x20, 0xAE, 0x30, 0xC6, 0xEC, 0xB1, -0x45, 0xCA, 0x03, 0x15, 0x02, 0xFF, 0xC1, 0x04, 0x1B, 0xBD, -0xB7, 0xB5, 0x06, 0xE7, 0xFC, 0x3E, 0x60, 0x6C, 0x6C, 0xCC, -0x4E, 0x4C, 0x4C, 0x2C, 0x01, 0x6D, 0xE0, 0xF0, 0xD2, 0x07, -0xEF, 0x5C, 0xBD, 0xF4, 0xC7, 0xDF, 0x5D, 0x19, 0x1A, 0xDD, -0x4F, 0x75, 0x70, 0x84, 0x7C, 0x3E, 0x22, 0x9F, 0xCF, 0x53, -0x2C, 0x84, 0x44, 0x21, 0xF8, 0xD2, 0x30, 0xBD, 0x70, 0x8C, -0xCA, 0xF0, 0x08, 0xD6, 0x68, 0x3C, 0xCF, 0xEB, 0xF9, 0xAF, -0x7B, 0x39, 0x58, 0xA3, 0x01, 0xFA, 0x21, 0x7B, 0xE7, 0xCF, -0x9F, 0xE7, 0xE6, 0xCD, 0x9B, 0xE4, 0x72, 0x39, 0x0D, 0x8C, -0x02, 0xDE, 0xD6, 0x7B, 0xAF, 0xDC, 0xF4, 0xD6, 0xDF, 0xC5, -0x8B, 0x6A, 0x0C, 0xEC, 0x1B, 0x27, 0x97, 0x2F, 0x20, 0x7D, -0x85, 0x27, 0x3D, 0x1C, 0xA0, 0x8D, 0x41, 0x86, 0x79, 0x9C, -0x8C, 0x48, 0xB5, 0xEE, 0xF9, 0x6F, 0x0C, 0xD6, 0x18, 0xAC, -0xD1, 0x64, 0x26, 0xD9, 0xB3, 0x48, 0x29, 0x85, 0x52, 0x4A, -0x6A, 0xAD, 0xE7, 0x41, 0x94, 0x81, 0xDA, 0xF8, 0xFE, 0xA1, -0xD2, 0x33, 0x63, 0x1D, 0x76, 0xFF, 0xF9, 0x6B, 0x3E, 0xFB, -0xE8, 0x3D, 0x12, 0xF2, 0x78, 0x85, 0x01, 0xFC, 0x62, 0x05, -0x55, 0x2C, 0x91, 0x05, 0x05, 0x3A, 0xED, 0x0E, 0xC9, 0xD2, -0x6B, 0x70, 0x7F, 0x19, 0xE3, 0x14, 0x46, 0x1B, 0xD2, 0xB8, -0x8B, 0xD1, 0x09, 0x61, 0xA1, 0xB2, 0xD3, 0xBF, 0xA6, 0xD5, -0x6A, 0x95, 0x34, 0x4D, 0x6D, 0xBD, 0x5E, 0xFF, 0x0F, 0xB8, -0xEF, 0x03, 0x63, 0xB1, 0x51, 0x51, 0x6E, 0x68, 0x8E, 0x03, -0xF1, 0x4B, 0xDC, 0xBA, 0xF4, 0x0A, 0x9B, 0xFB, 0xBF, 0x84, -0xA8, 0x4E, 0xE3, 0x54, 0x1E, 0x61, 0x63, 0xB2, 0xC6, 0x0A, -0xE1, 0xC7, 0x57, 0x98, 0x70, 0x4B, 0x4E, 0x8A, 0xC3, 0x24, -0x26, 0x13, 0x49, 0xB7, 0x45, 0xBB, 0xB1, 0xC5, 0xA1, 0x13, -0x5F, 0xBD, 0x36, 0xF5, 0xE4, 0x37, 0x7E, 0xD0, 0x07, 0x4C, -0x4F, 0x4F, 0xE3, 0x9C, 0x63, 0x66, 0x66, 0x66, 0xF9, 0xC6, -0x8D, 0x1B, 0x17, 0xD7, 0xD6, 0xD6, 0x5E, 0x88, 0xF2, 0xE1, -0x81, 0x9D, 0x56, 0x4A, 0x33, 0xB6, 0x0C, 0x07, 0xDB, 0xA4, -0x77, 0xFE, 0x02, 0x5B, 0x03, 0xC8, 0xA8, 0x42, 0xA1, 0x50, -0x5E, 0x3E, 0x7E, 0xFC, 0xF8, 0xEB, 0xE7, 0x6E, 0x96, 0x97, -0x7E, 0xF5, 0xB7, 0x65, 0xB9, 0x70, 0xAA, 0xFB, 0xDC, 0x17, -0xB3, 0xEE, 0x62, 0xF3, 0xFE, 0x26, 0xD3, 0x4F, 0x9D, 0xB9, -0x32, 0x77, 0xEA, 0xEC, 0x57, 0xC0, 0x25, 0x7D, 0xC0, 0xFC, -0xFC, 0x3C, 0x42, 0x08, 0x86, 0x87, 0x87, 0x09, 0xC3, 0xF0, -0xCA, 0xDA, 0xDA, 0xDA, 0xDD, 0x8B, 0xFF, 0x78, 0xBB, 0xF1, -0x85, 0xDF, 0xFF, 0xE2, 0xF9, 0x93, 0xB3, 0xC3, 0xC7, 0xF4, -0xFE, 0xC9, 0x6B, 0xD5, 0xE1, 0x03, 0xFF, 0xB6, 0x26, 0xBE, -0x3A, 0x39, 0xF7, 0xF4, 0x1B, 0x59, 0x96, 0x7D, 0x32, 0xF8, -0xC4, 0x38, 0x8D, 0x97, 0x37, 0x01, 0xCA, 0x8D, 0xDD, 0xFA, -0x77, 0x92, 0x56, 0x95, 0xE9, 0xC5, 0x6F, 0x5D, 0x98, 0x5A, -0x3C, 0x7B, 0xA6, 0xDB, 0xB8, 0x97, 0x21, 0x0D, 0x7B, 0x0F, -0x4E, 0xA7, 0xD3, 0x7B, 0x87, 0xA5, 0xA4, 0x5E, 0xAF, 0x33, -0x35, 0x35, 0xB5, 0xD4, 0x4E, 0xBC, 0x5F, 0xFE, 0xFD, 0xF2, -0x8D, 0x17, 0x7F, 0xF4, 0xD3, 0xF3, 0x95, 0x4E, 0xDB, 0xDE, -0xD3, 0xBA, 0xC3, 0xED, 0x1B, 0x6F, 0x82, 0x8C, 0x30, 0x69, -0x93, 0xE6, 0xEA, 0x12, 0xF3, 0x47, 0x0E, 0xF3, 0xB9, 0xC5, -0xCF, 0x37, 0xA6, 0xA6, 0x0E, 0x9C, 0x1F, 0x59, 0x38, 0x7B, -0x7D, 0x24, 0x3F, 0xF9, 0xC3, 0xA4, 0xDB, 0xCC, 0x74, 0xDA, -0x25, 0xC8, 0xEF, 0x7D, 0x24, 0xFE, 0x37, 0x00, 0x7B, 0x59, -0x0C, 0x33, 0xED, 0xB3, 0xBB, 0x03, 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, 0x16, 0x00, 0x00, 0x00, 0x16, 0x08, 0x06, +0x00, 0x00, 0x00, 0xc4, 0xb4, 0x6c, 0x3b, 0x00, 0x00, 0x0a, 0x39, 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, 0x48, +0xc7, 0x9d, 0x96, 0x77, 0x54, 0x54, 0xd7, 0x16, 0x87, 0xcf, 0xbd, 0x77, 0x7a, +0xa1, 0xcd, 0x30, 0xd2, 0x19, 0x7a, 0x93, 0x2e, 0x30, 0x80, 0xf4, 0x2e, 0x20, +0x1d, 0x04, 0x51, 0x18, 0x66, 0x06, 0x18, 0xca, 0x00, 0xc3, 0x0c, 0x4d, 0x6c, +0x88, 0xa8, 0x40, 0x44, 0x11, 0x11, 0x01, 0x45, 0x90, 0xa0, 0x80, 0x01, 0xa3, +0xa1, 0x48, 0xac, 0x88, 0x62, 0x21, 0x28, 0xa8, 0x60, 0x0f, 0x48, 0x10, 0x50, +0x62, 0x30, 0x8a, 0xa8, 0xa8, 0x64, 0x46, 0xd6, 0x4a, 0x7c, 0x79, 0x79, 0xef, +0xe5, 0xe5, 0xf7, 0xc7, 0xbd, 0xdf, 0xda, 0x67, 0xef, 0x73, 0xf7, 0xd9, 0x7b, +0x9f, 0xb5, 0x2e, 0x00, 0x24, 0x4f, 0x1f, 0x2e, 0x2f, 0x05, 0x96, 0x02, 0x20, +0x99, 0x27, 0xe0, 0x07, 0x7a, 0x38, 0xd3, 0x57, 0x85, 0x47, 0xd0, 0xb1, 0xfd, +0x00, 0x06, 0x78, 0x80, 0x01, 0xa6, 0x00, 0x30, 0x59, 0xe9, 0xa9, 0xbe, 0x41, +0xee, 0xc1, 0x40, 0x24, 0x2f, 0x37, 0x17, 0x7a, 0xba, 0xc8, 0x09, 0xfc, 0x8b, +0xde, 0x0c, 0x01, 0x48, 0xfc, 0xbe, 0x65, 0xe8, 0xe9, 0x4f, 0xa7, 0x83, 0xff, +0x4f, 0xd2, 0xac, 0x54, 0xbe, 0x00, 0x00, 0xc8, 0x5f, 0xc4, 0xe6, 0x6c, 0x4e, +0x3a, 0x4b, 0xc4, 0xf9, 0x22, 0x4e, 0xca, 0x14, 0xa4, 0x8a, 0xed, 0x33, 0x22, +0xa6, 0xc6, 0x24, 0x8a, 0x19, 0x46, 0x89, 0x99, 0x2f, 0x4a, 0x50, 0xc4, 0x72, +0x62, 0x8e, 0x5b, 0xe4, 0xa5, 0x9f, 0x7d, 0x16, 0xd9, 0x51, 0xcc, 0xec, 0x64, +0x1e, 0x5b, 0xc4, 0xe2, 0x9c, 0x53, 0xd9, 0xc9, 0x6c, 0x31, 0xf7, 0x88, 0x78, +0x7b, 0x86, 0x90, 0x23, 0x62, 0xc4, 0x47, 0xc4, 0x05, 0x19, 0x5c, 0x4e, 0xa6, +0x88, 0x6f, 0x8b, 0x58, 0x33, 0x49, 0x98, 0xcc, 0x15, 0xf1, 0x5b, 0x71, 0x6c, +0x32, 0x87, 0x99, 0x0e, 0x00, 0x8a, 0x24, 0xb6, 0x0b, 0x38, 0xac, 0x78, 0x11, +0x9b, 0x88, 0x98, 0xc4, 0x0f, 0x0e, 0x74, 0x11, 0xf1, 0x72, 0x00, 0x70, 0xa4, +0xb8, 0x2f, 0x38, 0xe6, 0x0b, 0x16, 0x70, 0xb2, 0x04, 0xe2, 0x43, 0xb9, 0xa4, +0xa4, 0x66, 0xf3, 0xb9, 0x71, 0xf1, 0x02, 0xba, 0x2e, 0x4b, 0x8f, 0x6e, 0x6a, +0x6d, 0xcd, 0xa0, 0x7b, 0x72, 0x32, 0x93, 0x38, 0x02, 0x81, 0xa1, 0x3f, 0x93, +0x95, 0xc8, 0xe4, 0xb3, 0xe9, 0x2e, 0x29, 0xc9, 0xa9, 0x4c, 0x5e, 0x36, 0x00, +0x8b, 0x67, 0xfe, 0x2c, 0x19, 0x71, 0x6d, 0xe9, 0xa2, 0x22, 0x5b, 0x9a, 0x5a, +0x5b, 0x5a, 0x1a, 0x9a, 0x19, 0x99, 0x7e, 0x51, 0xa8, 0xff, 0xba, 0xf8, 0x37, +0x25, 0xee, 0xed, 0x22, 0xbd, 0x0a, 0xf8, 0xdc, 0x33, 0x88, 0xd6, 0xf7, 0x87, +0xed, 0xaf, 0xfc, 0x52, 0xea, 0x00, 0x60, 0xcc, 0x8a, 0x6a, 0xb3, 0xeb, 0x0f, +0x5b, 0xcc, 0x7e, 0x00, 0x3a, 0xb6, 0x02, 0x20, 0x77, 0xff, 0x0f, 0x9b, 0xe6, +0x21, 0x00, 0x24, 0x45, 0x7d, 0x6b, 0xbf, 0xf1, 0xc5, 0x79, 0x68, 0xe2, 0x79, +0x89, 0x17, 0x08, 0x52, 0x6d, 0x8c, 0x8d, 0x33, 0x33, 0x33, 0x8d, 0xb8, 0x1c, +0x96, 0x91, 0xb8, 0xa0, 0xbf, 0xeb, 0x7f, 0x3a, 0xfc, 0x0d, 0x7d, 0xf1, 0x3d, +0x23, 0xf1, 0x76, 0xbf, 0x97, 0x87, 0xee, 0xca, 0x89, 0x65, 0x0a, 0x93, 0x04, +0x74, 0x71, 0xdd, 0x58, 0x29, 0x49, 0x29, 0x42, 0x3e, 0x3d, 0x3d, 0x95, 0xc9, +0xe2, 0xd0, 0x0d, 0xff, 0x3c, 0xc4, 0xff, 0x38, 0xf0, 0xaf, 0xf3, 0x58, 0x1a, +0xc8, 0x89, 0xe5, 0xf0, 0x39, 0x3c, 0x51, 0x44, 0xa8, 0x68, 0xca, 0xb8, 0xbc, +0x38, 0x51, 0xbb, 0x79, 0x6c, 0xae, 0x80, 0x9b, 0xc2, 0xa3, 0x73, 0x79, 0xff, +0xa9, 0x89, 0xff, 0x30, 0xec, 0x4f, 0x5a, 0x9c, 0x6b, 0x91, 0x28, 0xf5, 0x9f, +0x00, 0x35, 0xca, 0x08, 0x48, 0xdd, 0xa0, 0x02, 0xe4, 0xe7, 0x3e, 0x80, 0xa2, +0x10, 0x01, 0x12, 0x79, 0x50, 0xdc, 0xf5, 0xdf, 0xfb, 0xe6, 0x83, 0x0f, 0x05, +0xe2, 0x9b, 0x17, 0xa6, 0x3a, 0xb1, 0x38, 0xf7, 0x9f, 0x05, 0xfd, 0xfb, 0xae, +0x70, 0x89, 0xf8, 0x91, 0xce, 0x8d, 0xfb, 0x1c, 0xe7, 0x12, 0x18, 0x4c, 0x67, +0x09, 0xf9, 0x19, 0x8b, 0x6b, 0xe2, 0x6b, 0x09, 0xd0, 0x80, 0x00, 0x24, 0x01, +0x15, 0xc8, 0x03, 0x15, 0xa0, 0x01, 0x74, 0x81, 0x21, 0x30, 0x03, 0x56, 0xc0, +0x16, 0x38, 0x02, 0x37, 0xb0, 0x02, 0xf8, 0x81, 0x60, 0x10, 0x0e, 0xd6, 0x02, +0x16, 0x88, 0x07, 0xc9, 0x80, 0x0f, 0x32, 0x41, 0x2e, 0xd8, 0x0c, 0x0a, 0x40, +0x11, 0xd8, 0x05, 0xf6, 0x82, 0x4a, 0x50, 0x03, 0xea, 0x41, 0x23, 0x68, 0x01, +0x27, 0x40, 0x07, 0x38, 0x0d, 0x2e, 0x80, 0xcb, 0xe0, 0x3a, 0xb8, 0x09, 0xee, +0x80, 0x07, 0x60, 0x04, 0x8c, 0x83, 0xe7, 0x60, 0x06, 0xbc, 0x01, 0xf3, 0x10, +0x04, 0x61, 0x21, 0x32, 0x44, 0x81, 0xe4, 0x21, 0x55, 0x48, 0x0b, 0x32, 0x80, +0xcc, 0x20, 0x06, 0x64, 0x0f, 0xb9, 0x41, 0x3e, 0x50, 0x20, 0x14, 0x0e, 0x45, +0x43, 0x71, 0x10, 0x0f, 0x12, 0x42, 0xb9, 0xd0, 0x16, 0xa8, 0x08, 0x2a, 0x85, +0x2a, 0xa1, 0x5a, 0xa8, 0x11, 0xfa, 0x16, 0x3a, 0x05, 0x5d, 0x80, 0xae, 0x42, +0x03, 0xd0, 0x3d, 0x68, 0x14, 0x9a, 0x82, 0x7e, 0x85, 0xde, 0xc3, 0x08, 0x4c, +0x82, 0xa9, 0xb0, 0x32, 0xac, 0x0d, 0x1b, 0xc3, 0x0c, 0xd8, 0x09, 0xf6, 0x86, +0x83, 0xe1, 0x35, 0x70, 0x1c, 0x9c, 0x06, 0xe7, 0xc0, 0xf9, 0xf0, 0x4e, 0xb8, +0x02, 0xae, 0x83, 0x8f, 0xc1, 0xed, 0xf0, 0x05, 0xf8, 0x3a, 0x7c, 0x07, 0x1e, +0x81, 0x9f, 0xc3, 0xb3, 0x08, 0x40, 0x88, 0x08, 0x0d, 0x51, 0x43, 0x0c, 0x11, +0x06, 0xe2, 0x82, 0xf8, 0x21, 0x11, 0x48, 0x2c, 0xc2, 0x47, 0x36, 0x20, 0x85, +0x48, 0x39, 0x52, 0x87, 0xb4, 0x20, 0x5d, 0x48, 0x2f, 0x72, 0x0b, 0x19, 0x41, +0xa6, 0x91, 0x77, 0x28, 0x0c, 0x8a, 0x82, 0xa2, 0xa3, 0x0c, 0x51, 0xb6, 0x28, +0x4f, 0x54, 0x08, 0x8a, 0x85, 0x4a, 0x43, 0x6d, 0x40, 0x15, 0xa3, 0x2a, 0x51, +0x47, 0x51, 0xed, 0xa8, 0x1e, 0xd4, 0x2d, 0xd4, 0x28, 0x6a, 0x06, 0xf5, 0x09, +0x4d, 0x46, 0x2b, 0xa1, 0x0d, 0xd0, 0x36, 0x68, 0x2f, 0xf4, 0x2a, 0x74, 0x1c, +0x3a, 0x13, 0x5d, 0x80, 0x2e, 0x47, 0x37, 0xa0, 0xdb, 0xd0, 0x97, 0xd0, 0x77, +0xd0, 0xe3, 0xe8, 0x37, 0x18, 0x0c, 0x86, 0x86, 0xd1, 0xc1, 0x58, 0x61, 0x3c, +0x31, 0xe1, 0x98, 0x04, 0xcc, 0x3a, 0x4c, 0x31, 0xe6, 0x00, 0xa6, 0x15, 0x73, +0x1e, 0x33, 0x80, 0x19, 0xc3, 0xcc, 0x62, 0xb1, 0x58, 0x79, 0xac, 0x01, 0xd6, +0x0e, 0xeb, 0x87, 0x65, 0x62, 0x05, 0xd8, 0x02, 0xec, 0x7e, 0xec, 0x31, 0xec, +0x39, 0xec, 0x20, 0x76, 0x1c, 0xfb, 0x16, 0x47, 0xc4, 0xa9, 0xe2, 0xcc, 0x70, +0xee, 0xb8, 0x08, 0x1c, 0x0f, 0x97, 0x87, 0x2b, 0xc7, 0x35, 0xe1, 0xce, 0xe2, +0x06, 0x71, 0x13, 0xb8, 0x79, 0xbc, 0x14, 0x5e, 0x0b, 0x6f, 0x83, 0xf7, 0xc3, +0xb3, 0xf1, 0xd9, 0xf8, 0x12, 0x7c, 0x3d, 0xbe, 0x0b, 0x7f, 0x03, 0x3f, 0x8e, +0x9f, 0x27, 0x48, 0x13, 0x74, 0x08, 0x76, 0x84, 0x60, 0x42, 0x02, 0x61, 0x33, +0xa1, 0x82, 0xd0, 0x42, 0xb8, 0x44, 0x78, 0x48, 0x78, 0x45, 0x24, 0x12, 0xd5, +0x89, 0xd6, 0xc4, 0x00, 0x22, 0x97, 0xb8, 0x89, 0x58, 0x41, 0x3c, 0x4e, 0xbc, +0x42, 0x1c, 0x25, 0xbe, 0x23, 0xc9, 0x90, 0xf4, 0x49, 0x2e, 0xa4, 0x48, 0x92, +0x90, 0xb4, 0x93, 0x74, 0x84, 0x74, 0x9e, 0x74, 0x8f, 0xf4, 0x8a, 0x4c, 0x26, +0x6b, 0x93, 0x1d, 0xc9, 0x11, 0x64, 0x01, 0x79, 0x27, 0xb9, 0x91, 0x7c, 0x91, +0xfc, 0x98, 0xfc, 0x56, 0x82, 0x22, 0x61, 0x24, 0xe1, 0x25, 0xc1, 0x96, 0xd8, +0x28, 0x51, 0x25, 0xd1, 0x2e, 0x31, 0x28, 0xf1, 0x42, 0x12, 0x2f, 0xa9, 0x25, +0xe9, 0x24, 0xb9, 0x56, 0x32, 0x47, 0xb2, 0x5c, 0xf2, 0xa4, 0xe4, 0x0d, 0xc9, +0x69, 0x29, 0xbc, 0x94, 0xb6, 0x94, 0x8b, 0x14, 0x53, 0x6a, 0x83, 0x54, 0x95, +0xd4, 0x29, 0xa9, 0x61, 0xa9, 0x59, 0x69, 0x8a, 0xb4, 0xa9, 0xb4, 0x9f, 0x74, +0xb2, 0x74, 0xb1, 0x74, 0x93, 0xf4, 0x55, 0xe9, 0x49, 0x19, 0xac, 0x8c, 0xb6, +0x8c, 0x9b, 0x0c, 0x5b, 0x26, 0x5f, 0xe6, 0xb0, 0xcc, 0x45, 0x99, 0x31, 0x0a, +0x42, 0xd1, 0xa0, 0xb8, 0x50, 0x58, 0x94, 0x2d, 0x94, 0x7a, 0xca, 0x25, 0xca, +0x38, 0x15, 0x43, 0xd5, 0xa1, 0x7a, 0x51, 0x13, 0xa8, 0x45, 0xd4, 0x6f, 0xa8, +0xfd, 0xd4, 0x19, 0x59, 0x19, 0xd9, 0x65, 0xb2, 0xa1, 0xb2, 0x59, 0xb2, 0x55, +0xb2, 0x67, 0x64, 0x47, 0x68, 0x08, 0x4d, 0x9b, 0xe6, 0x45, 0x4b, 0xa2, 0x95, +0xd0, 0x4e, 0xd0, 0x86, 0x68, 0xef, 0x97, 0x28, 0x2f, 0x71, 0x5a, 0xc2, 0x59, +0xb2, 0x63, 0x49, 0xcb, 0x92, 0xc1, 0x25, 0x73, 0x72, 0x8a, 0x72, 0x8e, 0x72, +0x1c, 0xb9, 0x42, 0xb9, 0x56, 0xb9, 0x3b, 0x72, 0xef, 0xe5, 0xe9, 0xf2, 0x6e, +0xf2, 0x89, 0xf2, 0xbb, 0xe5, 0x3b, 0xe4, 0x1f, 0x29, 0xa0, 0x14, 0xf4, 0x15, +0x02, 0x14, 0x32, 0x15, 0x0e, 0x2a, 0x5c, 0x52, 0x98, 0x56, 0xa4, 0x2a, 0xda, +0x2a, 0xb2, 0x14, 0x0b, 0x15, 0x4f, 0x28, 0xde, 0x57, 0x82, 0x95, 0xf4, 0x95, +0x02, 0x95, 0xd6, 0x29, 0x1d, 0x56, 0xea, 0x53, 0x9a, 0x55, 0x56, 0x51, 0xf6, +0x50, 0x4e, 0x55, 0xde, 0xaf, 0x7c, 0x51, 0x79, 0x5a, 0x85, 0xa6, 0xe2, 0xa8, +0x92, 0xa0, 0x52, 0xa6, 0x72, 0x56, 0x65, 0x4a, 0x95, 0xa2, 0x6a, 0xaf, 0xca, +0x55, 0x2d, 0x53, 0x3d, 0xa7, 0xfa, 0x8c, 0x2e, 0x4b, 0x77, 0xa2, 0x27, 0xd1, +0x2b, 0xe8, 0x3d, 0xf4, 0x19, 0x35, 0x25, 0x35, 0x4f, 0x35, 0xa1, 0x5a, 0xad, +0x5a, 0xbf, 0xda, 0xbc, 0xba, 0x8e, 0x7a, 0x88, 0x7a, 0x9e, 0x7a, 0xab, 0xfa, +0x23, 0x0d, 0x82, 0x06, 0x43, 0x23, 0x56, 0xa3, 0x4c, 0xa3, 0x5b, 0x63, 0x46, +0x53, 0x55, 0xd3, 0x57, 0x33, 0x57, 0xb3, 0x59, 0xf3, 0xbe, 0x16, 0x5e, 0x8b, +0xa1, 0x15, 0xaf, 0xb5, 0x4f, 0xab, 0x57, 0x6b, 0x4e, 0x5b, 0x47, 0x3b, 0x4c, +0x7b, 0x9b, 0x76, 0x87, 0xf6, 0xa4, 0x8e, 0x9c, 0x8e, 0x97, 0x4e, 0x8e, 0x4e, +0xb3, 0xce, 0x43, 0x5d, 0xb2, 0xae, 0x83, 0x6e, 0x9a, 0x6e, 0x9d, 0xee, 0x6d, +0x3d, 0x8c, 0x1e, 0x43, 0x2f, 0x51, 0xef, 0x80, 0xde, 0x4d, 0x7d, 0x58, 0xdf, +0x42, 0x3f, 0x5e, 0xbf, 0x4a, 0xff, 0x86, 0x01, 0x6c, 0x60, 0x69, 0xc0, 0x35, +0x38, 0x60, 0x30, 0xb0, 0x14, 0xbd, 0xd4, 0x7a, 0x29, 0x6f, 0x69, 0xdd, 0xd2, +0x61, 0x43, 0x92, 0xa1, 0x93, 0x61, 0x86, 0x61, 0xb3, 0xe1, 0xa8, 0x11, 0xcd, +0xc8, 0xc7, 0x28, 0xcf, 0xa8, 0xc3, 0xe8, 0x85, 0xb1, 0xa6, 0x71, 0x84, 0xf1, +0x6e, 0xe3, 0x5e, 0xe3, 0x4f, 0x26, 0x16, 0x26, 0x49, 0x26, 0xf5, 0x26, 0x0f, +0x4c, 0x65, 0x4c, 0x57, 0x98, 0xe6, 0x99, 0x76, 0x99, 0xfe, 0x6a, 0xa6, 0x6f, +0xc6, 0x32, 0xab, 0x32, 0xbb, 0x6d, 0x4e, 0x36, 0x77, 0x37, 0xdf, 0x68, 0xde, +0x69, 0xfe, 0x72, 0x99, 0xc1, 0x32, 0xce, 0xb2, 0x83, 0xcb, 0xee, 0x5a, 0x50, +0x2c, 0x7c, 0x2d, 0xb6, 0x59, 0x74, 0x5b, 0x7c, 0xb4, 0xb4, 0xb2, 0xe4, 0x5b, +0xb6, 0x58, 0x4e, 0x59, 0x69, 0x5a, 0x45, 0x5b, 0x55, 0x5b, 0x0d, 0x33, 0xa8, +0x0c, 0x7f, 0x46, 0x31, 0xe3, 0x8a, 0x35, 0xda, 0xda, 0xd9, 0x7a, 0xa3, 0xf5, +0x69, 0xeb, 0x77, 0x36, 0x96, 0x36, 0x02, 0x9b, 0x13, 0x36, 0xbf, 0xd8, 0x1a, +0xda, 0x26, 0xda, 0x36, 0xd9, 0x4e, 0x2e, 0xd7, 0x59, 0xce, 0x59, 0x5e, 0xbf, +0x7c, 0xcc, 0x4e, 0xdd, 0x8e, 0x69, 0x57, 0x6b, 0x37, 0x62, 0x4f, 0xb7, 0x8f, +0xb6, 0x3f, 0x64, 0x3f, 0xe2, 0xa0, 0xe6, 0xc0, 0x74, 0xa8, 0x73, 0x78, 0xe2, +0xa8, 0xe1, 0xc8, 0x76, 0x6c, 0x70, 0x9c, 0x70, 0xd2, 0x73, 0x4a, 0x70, 0x3a, +0xe6, 0xf4, 0xc2, 0xd9, 0xc4, 0x99, 0xef, 0xdc, 0xe6, 0x3c, 0xe7, 0x62, 0xe3, +0xb2, 0xde, 0xe5, 0xbc, 0x2b, 0xe2, 0xea, 0xe1, 0x5a, 0xe8, 0xda, 0xef, 0x26, +0xe3, 0x16, 0xe2, 0x56, 0xe9, 0xf6, 0xd8, 0x5d, 0xdd, 0x3d, 0xce, 0xbd, 0xd9, +0x7d, 0xc6, 0xc3, 0xc2, 0x63, 0x9d, 0xc7, 0x79, 0x4f, 0xb4, 0xa7, 0xb7, 0xe7, +0x6e, 0xcf, 0x61, 0x2f, 0x65, 0x2f, 0x96, 0x57, 0xa3, 0xd7, 0xcc, 0x0a, 0xab, +0x15, 0xeb, 0x57, 0xf4, 0x78, 0x93, 0xbc, 0x83, 0xbc, 0x2b, 0xbd, 0x9f, 0xf8, +0xe8, 0xfb, 0xf0, 0x7d, 0xba, 0x7c, 0x61, 0xdf, 0x15, 0xbe, 0x7b, 0x7c, 0x1f, +0xae, 0xd4, 0x5a, 0xc9, 0x5b, 0xd9, 0xe1, 0x07, 0xfc, 0xbc, 0xfc, 0xf6, 0xf8, +0x3d, 0xf2, 0xd7, 0xf1, 0x4f, 0xf3, 0xff, 0x3e, 0x00, 0x13, 0xe0, 0x1f, 0x50, +0x15, 0xf0, 0x34, 0xd0, 0x34, 0x30, 0x37, 0xb0, 0x37, 0x88, 0x12, 0x14, 0x15, +0xd4, 0x14, 0xf4, 0x26, 0xd8, 0x39, 0xb8, 0x24, 0xf8, 0x41, 0x88, 0x6e, 0x88, +0x30, 0xa4, 0x3b, 0x54, 0x32, 0x34, 0x32, 0xb4, 0x31, 0x74, 0x2e, 0xcc, 0x35, +0xac, 0x34, 0x6c, 0x64, 0x95, 0xf1, 0xaa, 0xf5, 0xab, 0xae, 0x87, 0x2b, 0x84, +0x73, 0xc3, 0x3b, 0x23, 0xb0, 0x11, 0xa1, 0x11, 0x0d, 0x11, 0xb3, 0xab, 0xdd, +0x56, 0xef, 0x5d, 0x3d, 0x1e, 0x69, 0x11, 0x59, 0x10, 0x39, 0xb4, 0x46, 0x67, +0x4d, 0xd6, 0x9a, 0xab, 0x6b, 0x15, 0xd6, 0x26, 0xad, 0x3d, 0x13, 0x25, 0x19, +0xc5, 0x8c, 0x3a, 0x19, 0x8d, 0x8e, 0x0e, 0x8b, 0x6e, 0x8a, 0xfe, 0xc0, 0xf4, +0x63, 0xd6, 0x31, 0x67, 0x63, 0xbc, 0x62, 0xaa, 0x63, 0x66, 0x58, 0x2e, 0xac, +0x7d, 0xac, 0xe7, 0x6c, 0x47, 0x76, 0x19, 0x7b, 0x8a, 0x63, 0xc7, 0x29, 0xe5, +0x4c, 0xc4, 0xda, 0xc5, 0x96, 0xc6, 0x4e, 0xc6, 0xd9, 0xc5, 0xed, 0x89, 0x9b, +0x8a, 0x77, 0x88, 0x2f, 0x8f, 0x9f, 0xe6, 0xba, 0x70, 0x2b, 0xb9, 0x2f, 0x13, +0x3c, 0x13, 0x6a, 0x12, 0xe6, 0x12, 0xfd, 0x12, 0x8f, 0x24, 0x2e, 0x24, 0x85, +0x25, 0xb5, 0x26, 0xe3, 0x92, 0xa3, 0x93, 0x4f, 0xf1, 0x64, 0x78, 0x89, 0xbc, +0x9e, 0x14, 0x95, 0x94, 0xac, 0x94, 0x81, 0x54, 0x83, 0xd4, 0x82, 0xd4, 0x91, +0x34, 0x9b, 0xb4, 0xbd, 0x69, 0x33, 0x7c, 0x6f, 0x7e, 0x43, 0x3a, 0x94, 0xbe, +0x26, 0xbd, 0x53, 0x40, 0x15, 0xfd, 0x4c, 0xf5, 0x09, 0x75, 0x85, 0x5b, 0x85, +0xa3, 0x19, 0xf6, 0x19, 0x55, 0x19, 0x6f, 0x33, 0x43, 0x33, 0x4f, 0x66, 0x49, +0x67, 0xf1, 0xb2, 0xfa, 0xb2, 0xf5, 0xb3, 0x77, 0x64, 0x4f, 0xe4, 0xb8, 0xe7, +0x7c, 0xbd, 0x0e, 0xb5, 0x8e, 0xb5, 0xae, 0x3b, 0x57, 0x2d, 0x77, 0x73, 0xee, +0xe8, 0x7a, 0xa7, 0xf5, 0xb5, 0x1b, 0xa0, 0x0d, 0x31, 0x1b, 0xba, 0x37, 0x6a, +0x6c, 0xcc, 0xdf, 0x38, 0xbe, 0xc9, 0x63, 0xd3, 0xd1, 0xcd, 0x84, 0xcd, 0x89, +0x9b, 0x7f, 0xc8, 0x33, 0xc9, 0x2b, 0xcd, 0x7b, 0xbd, 0x25, 0x6c, 0x4b, 0x57, +0xbe, 0x72, 0xfe, 0xa6, 0xfc, 0xb1, 0xad, 0x1e, 0x5b, 0x9b, 0x0b, 0x24, 0x0a, +0xf8, 0x05, 0xc3, 0xdb, 0x6c, 0xb7, 0xd5, 0x6c, 0x47, 0x6d, 0xe7, 0x6e, 0xef, +0xdf, 0x61, 0xbe, 0x63, 0xff, 0x8e, 0x4f, 0x85, 0xec, 0xc2, 0x6b, 0x45, 0x26, +0x45, 0xe5, 0x45, 0x1f, 0x8a, 0x59, 0xc5, 0xd7, 0xbe, 0x32, 0xfd, 0xaa, 0xe2, +0xab, 0x85, 0x9d, 0xb1, 0x3b, 0xfb, 0x4b, 0x2c, 0x4b, 0x0e, 0xee, 0xc2, 0xec, +0xe2, 0xed, 0x1a, 0xda, 0xed, 0xb0, 0xfb, 0x68, 0xa9, 0x74, 0x69, 0x4e, 0xe9, +0xd8, 0x1e, 0xdf, 0x3d, 0xed, 0x65, 0xf4, 0xb2, 0xc2, 0xb2, 0xd7, 0x7b, 0xa3, +0xf6, 0x5e, 0x2d, 0x5f, 0x56, 0x5e, 0xb3, 0x8f, 0xb0, 0x4f, 0xb8, 0x6f, 0xa4, +0xc2, 0xa7, 0xa2, 0x73, 0xbf, 0xe6, 0xfe, 0x5d, 0xfb, 0x3f, 0x54, 0xc6, 0x57, +0xde, 0xa9, 0x72, 0xae, 0x6a, 0xad, 0x56, 0xaa, 0xde, 0x51, 0x3d, 0x77, 0x80, +0x7d, 0x60, 0xf0, 0xa0, 0xe3, 0xc1, 0x96, 0x1a, 0xe5, 0x9a, 0xa2, 0x9a, 0xf7, +0x87, 0xb8, 0x87, 0xee, 0xd6, 0x7a, 0xd4, 0xb6, 0xd7, 0x69, 0xd7, 0x95, 0x1f, +0xc6, 0x1c, 0xce, 0x38, 0xfc, 0xb4, 0x3e, 0xb4, 0xbe, 0xf7, 0x6b, 0xc6, 0xd7, +0x8d, 0x0d, 0x0a, 0x0d, 0x45, 0x0d, 0x1f, 0x8f, 0xf0, 0x8e, 0x8c, 0x1c, 0x0d, +0x3c, 0xda, 0xd3, 0x68, 0xd5, 0xd8, 0xd8, 0xa4, 0xd4, 0x54, 0xd2, 0x0c, 0x37, +0x0b, 0x9b, 0xa7, 0x8e, 0x45, 0x1e, 0xbb, 0xf9, 0x8d, 0xeb, 0x37, 0x9d, 0x2d, +0x86, 0x2d, 0xb5, 0xad, 0xb4, 0xd6, 0xa2, 0xe3, 0xe0, 0xb8, 0xf0, 0xf8, 0xb3, +0x6f, 0xa3, 0xbf, 0x1d, 0x3a, 0xe1, 0x7d, 0xa2, 0xfb, 0x24, 0xe3, 0x64, 0xcb, +0x77, 0x5a, 0xdf, 0x55, 0xb7, 0x51, 0xda, 0x0a, 0xdb, 0xa1, 0xf6, 0xec, 0xf6, +0x99, 0x8e, 0xf8, 0x8e, 0x91, 0xce, 0xf0, 0xce, 0x81, 0x53, 0x2b, 0x4e, 0x75, +0x77, 0xd9, 0x76, 0xb5, 0x7d, 0x6f, 0xf4, 0xfd, 0x91, 0xd3, 0x6a, 0xa7, 0xab, +0xce, 0xc8, 0x9e, 0x29, 0x39, 0x4b, 0x38, 0x9b, 0x7f, 0x76, 0xe1, 0x5c, 0xce, +0xb9, 0xd9, 0xf3, 0xa9, 0xe7, 0xa7, 0x2f, 0xc4, 0x5d, 0x18, 0xeb, 0x8e, 0xea, +0x7e, 0x70, 0x71, 0xd5, 0xc5, 0xdb, 0x3d, 0x01, 0x3d, 0xfd, 0x97, 0xbc, 0x2f, +0x5d, 0xb9, 0xec, 0x7e, 0xf9, 0x62, 0xaf, 0x53, 0xef, 0xb9, 0x2b, 0x76, 0x57, +0x4e, 0x5f, 0xb5, 0xb9, 0x7a, 0xea, 0x1a, 0xe3, 0x5a, 0xc7, 0x75, 0xcb, 0xeb, +0xed, 0x7d, 0x16, 0x7d, 0x6d, 0x3f, 0x58, 0xfc, 0xd0, 0xd6, 0x6f, 0xd9, 0xdf, +0x7e, 0xc3, 0xea, 0x46, 0xe7, 0x4d, 0xeb, 0x9b, 0x5d, 0x03, 0xcb, 0x07, 0xce, +0x0e, 0x3a, 0x0c, 0x5e, 0xb8, 0xe5, 0x7a, 0xeb, 0xf2, 0x6d, 0xaf, 0xdb, 0xd7, +0xef, 0xac, 0xbc, 0x33, 0x30, 0x14, 0x32, 0x74, 0x77, 0x38, 0x72, 0x78, 0xe4, +0x2e, 0xfb, 0xee, 0xe4, 0xbd, 0xa4, 0x7b, 0x2f, 0xef, 0x67, 0xdc, 0x9f, 0x7f, +0xb0, 0xe9, 0x21, 0xfa, 0x61, 0xe1, 0x23, 0xa9, 0x47, 0xe5, 0x8f, 0x95, 0x1e, +0xd7, 0xfd, 0xa8, 0xf7, 0x63, 0xeb, 0x88, 0xe5, 0xc8, 0x99, 0x51, 0xd7, 0xd1, +0xbe, 0x27, 0x41, 0x4f, 0x1e, 0x8c, 0xb1, 0xc6, 0x9e, 0xff, 0x94, 0xfe, 0xd3, +0x87, 0xf1, 0xfc, 0xa7, 0xe4, 0xa7, 0xe5, 0x13, 0xaa, 0x13, 0x8d, 0x93, 0x66, +0x93, 0xa7, 0xa7, 0xdc, 0xa7, 0x6e, 0x3e, 0x5b, 0xfd, 0x6c, 0xfc, 0x79, 0xea, +0xf3, 0xf9, 0xe9, 0x82, 0x9f, 0xa5, 0x7f, 0xae, 0x7e, 0xa1, 0xfb, 0xe2, 0xbb, +0x5f, 0x1c, 0x7f, 0xe9, 0x9b, 0x59, 0x35, 0x33, 0xfe, 0x92, 0xff, 0x72, 0xe1, +0xd7, 0xe2, 0x57, 0xf2, 0xaf, 0x8e, 0xbc, 0x5e, 0xf6, 0xba, 0x7b, 0xd6, 0x7f, +0xf6, 0xf1, 0x9b, 0xe4, 0x37, 0xf3, 0x73, 0x85, 0x6f, 0xe5, 0xdf, 0x1e, 0x7d, +0xc7, 0x78, 0xd7, 0xfb, 0x3e, 0xec, 0xfd, 0xc4, 0x7c, 0xe6, 0x07, 0xec, 0x87, +0x8a, 0x8f, 0x7a, 0x1f, 0xbb, 0x3e, 0x79, 0x7f, 0x7a, 0xb8, 0x90, 0xbc, 0xb0, +0xf0, 0x1b, 0xf7, 0x84, 0xf3, 0xfb, 0xe2, 0xe6, 0x1d, 0xc2, 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, 0x01, 0x0a, 0x02, 0x35, 0x0f, 0x01, 0xa3, 0x67, 0xcc, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, +0xbd, 0xa7, 0x93, 0x00, 0x00, 0x05, 0x50, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, +0x6d, 0xc1, 0x5b, 0x88, 0x5c, 0x67, 0x01, 0xc0, 0xf1, 0xff, 0x77, 0x39, 0xe7, +0xcc, 0x7d, 0x76, 0xb2, 0xd9, 0xfb, 0x36, 0xdb, 0x24, 0x9b, 0xa4, 0x4d, 0x2f, +0xd1, 0x98, 0x62, 0x09, 0xb6, 0x25, 0x12, 0xd4, 0x3e, 0x28, 0x42, 0xd1, 0x80, +0x16, 0x5f, 0x4a, 0xa5, 0x0f, 0x56, 0x51, 0x1f, 0x6a, 0x11, 0x45, 0xa8, 0x45, +0x04, 0xb5, 0x68, 0xf1, 0x45, 0x9f, 0x0a, 0xb1, 0x52, 0x41, 0x6c, 0x20, 0x50, +0x7c, 0xb0, 0x68, 0x2c, 0x69, 0x5a, 0x6a, 0xb5, 0xe2, 0x62, 0x53, 0x4c, 0x8d, +0xb9, 0x6c, 0x92, 0x4e, 0x76, 0x27, 0x3b, 0xb3, 0x3b, 0x67, 0xce, 0x77, 0x75, +0x26, 0x2c, 0x18, 0x64, 0x7f, 0x3f, 0xc1, 0xff, 0x39, 0xfe, 0xd3, 0xc7, 0x79, +0xf4, 0x6b, 0xbf, 0x64, 0xe4, 0x17, 0x3f, 0xfa, 0x8a, 0xb8, 0xff, 0xbe, 0x03, +0xa2, 0xb3, 0x72, 0x59, 0x38, 0x6b, 0xc5, 0xee, 0x5d, 0x3b, 0xc5, 0xf2, 0xf2, +0x55, 0xdd, 0x5e, 0xed, 0x4e, 0xb4, 0xc6, 0xc7, 0x67, 0xc7, 0x5b, 0x63, 0xf3, +0x52, 0x30, 0xf5, 0xfe, 0xf9, 0x0b, 0x63, 0x4a, 0xca, 0xfd, 0xf3, 0x3b, 0x76, +0x9f, 0x98, 0x9c, 0x9c, 0xff, 0xdd, 0xe4, 0xde, 0xa3, 0x56, 0xb0, 0x85, 0x1f, +0x7e, 0xeb, 0xd3, 0xfa, 0xd0, 0x81, 0x7b, 0xa6, 0xd3, 0x72, 0xf5, 0xae, 0xe9, +0xa9, 0x89, 0xbd, 0xbd, 0x6e, 0x67, 0x97, 0x75, 0x76, 0x71, 0x7e, 0x66, 0x7a, +0xb7, 0x92, 0xcc, 0xa4, 0x89, 0x1a, 0xd3, 0x5a, 0x90, 0x17, 0x16, 0x81, 0xa2, +0x35, 0xbe, 0x8d, 0x68, 0xd6, 0xb0, 0x62, 0xf2, 0xf9, 0x98, 0x4e, 0x3d, 0x55, +0x9b, 0x3d, 0x98, 0x6b, 0xb6, 0x30, 0xd6, 0x68, 0x1e, 0x59, 0x58, 0x98, 0x39, +0x3e, 0x3d, 0xd1, 0x98, 0xf4, 0x76, 0xc0, 0x6d, 0x33, 0xf3, 0xa4, 0x59, 0x42, +0xc8, 0x7b, 0xa8, 0x34, 0xc3, 0x78, 0x4f, 0xbb, 0xdd, 0x8f, 0xa5, 0x52, 0x49, +0x54, 0x4a, 0x8a, 0x58, 0x74, 0x58, 0x5b, 0xbd, 0x4e, 0xac, 0x54, 0x72, 0xad, +0x27, 0x22, 0x43, 0x9a, 0x2d, 0xcc, 0xcd, 0x4e, 0x4f, 0xd5, 0xeb, 0x49, 0x96, +0x48, 0x87, 0x8f, 0x91, 0x41, 0xaf, 0x4b, 0x7f, 0x2d, 0x22, 0xb5, 0xc2, 0xf5, +0x06, 0x9c, 0x3d, 0xb7, 0x4c, 0x56, 0x69, 0x8a, 0x83, 0xfb, 0x9b, 0x58, 0x5b, +0xe0, 0x7c, 0xc4, 0xb9, 0x40, 0xb4, 0x45, 0x2a, 0x4c, 0x4f, 0x30, 0x24, 0xd9, +0xc2, 0x7a, 0x3f, 0x1f, 0x0c, 0xd6, 0x07, 0xc6, 0xe4, 0x39, 0xc2, 0xae, 0xa3, +0xc2, 0x06, 0x99, 0xc8, 0xa9, 0x48, 0xc3, 0xa9, 0x33, 0x4b, 0xbc, 0xfc, 0xfb, +0xb7, 0x30, 0xc6, 0x22, 0x12, 0x45, 0x8c, 0x82, 0x10, 0x22, 0xce, 0x3b, 0x8c, +0x19, 0x54, 0xf3, 0x7e, 0x57, 0x30, 0xa4, 0xd9, 0x42, 0xb1, 0xd1, 0xb1, 0x29, +0x7d, 0x17, 0x5d, 0x89, 0xce, 0x40, 0x53, 0x84, 0x04, 0xa5, 0x04, 0x35, 0x17, +0x58, 0x5d, 0xb9, 0x81, 0x70, 0x39, 0x49, 0x22, 0x41, 0x08, 0x46, 0x82, 0xf7, +0x58, 0x6b, 0x40, 0xf9, 0x92, 0xf0, 0x5e, 0x30, 0xa4, 0xb9, 0xc5, 0x0f, 0x5e, +0x3a, 0xc5, 0xd3, 0xc7, 0x1e, 0x84, 0x7c, 0x75, 0xe3, 0x72, 0xbf, 0x36, 0x68, +0x9b, 0xdd, 0x5c, 0xc8, 0xc7, 0x30, 0x21, 0x41, 0x29, 0x49, 0x3d, 0xf5, 0x5c, +0x88, 0xd7, 0xb0, 0x72, 0x15, 0x11, 0x03, 0x23, 0x11, 0xf0, 0xce, 0x61, 0x8b, +0x02, 0x9d, 0x85, 0x54, 0x4a, 0xc1, 0x88, 0x66, 0xd3, 0x93, 0xcf, 0x3c, 0xc7, +0xd3, 0xc7, 0x1e, 0x64, 0xa4, 0x73, 0xd7, 0xd7, 0xef, 0x3d, 0x6d, 0xc7, 0xe7, +0x6c, 0xa8, 0x83, 0x02, 0xa9, 0x05, 0x51, 0x6b, 0x7a, 0x3a, 0x61, 0x99, 0x05, +0xae, 0xc7, 0x35, 0x0a, 0x51, 0x01, 0xe1, 0x20, 0x82, 0x75, 0x16, 0x6b, 0x0a, +0x54, 0x08, 0x52, 0x10, 0x05, 0x43, 0x9a, 0x4d, 0xd3, 0xfb, 0x0e, 0x31, 0xf2, +0xb3, 0x93, 0x67, 0x1e, 0xd2, 0xb5, 0xd6, 0x37, 0xd0, 0xa5, 0x34, 0x8d, 0x16, +0x25, 0x04, 0x5a, 0x29, 0x92, 0x44, 0x23, 0x55, 0x42, 0x39, 0x53, 0x90, 0xd4, +0x08, 0x32, 0x01, 0x02, 0x21, 0x06, 0x9c, 0xb3, 0x18, 0x6b, 0x48, 0x7d, 0x10, +0x31, 0x70, 0x93, 0x66, 0xd3, 0xb7, 0x3f, 0xff, 0x00, 0x5f, 0xfa, 0xe6, 0xf7, +0xa6, 0x62, 0x14, 0x4f, 0xd4, 0x6b, 0xb5, 0x39, 0x67, 0x0b, 0x84, 0xd0, 0x31, +0x49, 0x52, 0x21, 0x75, 0x06, 0x52, 0x51, 0x4a, 0x34, 0xa9, 0x56, 0x24, 0x0a, +0x84, 0xe0, 0xa6, 0xe0, 0x3d, 0xd6, 0x58, 0x9c, 0x29, 0xf0, 0xd1, 0x83, 0xe4, +0x26, 0xc9, 0xd0, 0x23, 0x4f, 0x7e, 0x87, 0x91, 0x03, 0x87, 0x8f, 0xdc, 0x56, +0x6d, 0x36, 0x8e, 0xa4, 0x5a, 0x91, 0x4a, 0x19, 0xab, 0x59, 0x26, 0x84, 0x80, +0x4e, 0xfb, 0x22, 0x2b, 0xd7, 0x2e, 0x71, 0x63, 0xa3, 0x87, 0x4a, 0x4a, 0x94, +0x4a, 0x25, 0xa4, 0x94, 0x10, 0x23, 0xce, 0x59, 0xac, 0x35, 0x18, 0x53, 0x40, +0x8c, 0x48, 0xa9, 0x18, 0xd1, 0x0c, 0xfd, 0xf6, 0xf9, 0x67, 0x18, 0xf1, 0xde, +0xef, 0xa9, 0x64, 0xe5, 0xa9, 0x44, 0x69, 0x54, 0xb9, 0x2c, 0x92, 0xac, 0xc2, +0xda, 0xf2, 0xfb, 0x94, 0xdb, 0xa7, 0xd9, 0xa1, 0x2f, 0xd1, 0xde, 0xb8, 0x93, +0xde, 0xba, 0x21, 0x1f, 0x58, 0x42, 0x08, 0x20, 0x24, 0xce, 0x3a, 0x9c, 0x31, +0x58, 0x63, 0x71, 0xce, 0x2b, 0xef, 0x3c, 0x23, 0x9a, 0xff, 0x11, 0x69, 0x9a, +0xaa, 0x4a, 0xad, 0x4a, 0x92, 0xa5, 0x08, 0x40, 0x66, 0x55, 0xca, 0x49, 0xa4, +0x92, 0x59, 0xa6, 0xfc, 0x65, 0x52, 0xdd, 0xc4, 0xac, 0x47, 0x6e, 0xac, 0xf5, +0x48, 0xf4, 0x14, 0x48, 0xb0, 0x45, 0x81, 0x75, 0x86, 0xe0, 0x3d, 0x45, 0xde, +0xaf, 0x6c, 0xf4, 0x56, 0x05, 0x43, 0x72, 0xef, 0xde, 0xbd, 0x42, 0x29, 0x95, +0x00, 0xc9, 0xf9, 0xb3, 0x4b, 0xb9, 0x54, 0xbe, 0xa8, 0x37, 0xca, 0x0c, 0xf2, +0x01, 0xd7, 0x96, 0x2f, 0xd1, 0xcd, 0x23, 0x79, 0x79, 0x81, 0x0b, 0xad, 0x4f, +0xb2, 0x5e, 0xbf, 0x93, 0x72, 0x9a, 0x50, 0xae, 0x56, 0xf9, 0xdb, 0xb9, 0x82, +0xfe, 0xca, 0x00, 0x29, 0x03, 0xd6, 0x58, 0x9c, 0xb7, 0x38, 0x9b, 0xd7, 0xcc, +0xa0, 0x27, 0x19, 0xd2, 0x49, 0x92, 0x64, 0x43, 0xf3, 0xfd, 0x7e, 0xbf, 0xfc, +0xea, 0xcb, 0xbf, 0xee, 0xcd, 0xec, 0xdc, 0x75, 0x6e, 0xe7, 0xfe, 0x0f, 0xed, +0xbf, 0x72, 0xe9, 0x62, 0x8c, 0x21, 0x08, 0x9d, 0x55, 0x18, 0xd4, 0xee, 0x60, +0x23, 0x15, 0xa8, 0xac, 0x46, 0x56, 0xeb, 0x50, 0xcd, 0x7a, 0x9c, 0x39, 0x37, +0xe0, 0xf0, 0x9e, 0x0d, 0xe6, 0x6b, 0x01, 0x6b, 0x0c, 0xd6, 0x58, 0x82, 0xf7, +0x69, 0x0c, 0x81, 0x11, 0xbd, 0xb8, 0xb8, 0x58, 0x5c, 0xbd, 0x7a, 0xb5, 0x3f, +0x34, 0xf7, 0xf7, 0xd7, 0xff, 0xd8, 0xbf, 0xfd, 0xee, 0x8f, 0x9c, 0xaa, 0x8e, +0xcf, 0xde, 0xd1, 0xda, 0x3e, 0x29, 0xb1, 0x06, 0x95, 0x68, 0xa4, 0xca, 0x08, +0x2a, 0x25, 0x2d, 0x67, 0xdc, 0x7b, 0xe8, 0x7e, 0xba, 0x9d, 0x15, 0xa4, 0x5f, +0x47, 0x10, 0x31, 0xc6, 0x60, 0x9d, 0xc1, 0x59, 0x43, 0x8c, 0x51, 0x0b, 0x10, +0x0c, 0xc9, 0x13, 0x27, 0x4e, 0xc4, 0x95, 0x95, 0x95, 0x2b, 0x4a, 0x29, 0x07, +0x4c, 0xbe, 0xfd, 0xca, 0xaf, 0xde, 0x5e, 0x3d, 0xfb, 0xc6, 0xf9, 0x46, 0x73, +0x9c, 0xe6, 0xd4, 0x1c, 0xb5, 0x7a, 0x83, 0x4a, 0x39, 0xa1, 0x94, 0x06, 0x94, +0x70, 0x6c, 0x9b, 0x9e, 0xa6, 0xdc, 0x68, 0xe1, 0xd1, 0xf8, 0x10, 0xb0, 0xb6, +0xc0, 0x59, 0x8b, 0xb3, 0x86, 0xe8, 0x5d, 0x1a, 0xbc, 0x15, 0x0c, 0x49, 0x86, +0x4a, 0x43, 0xc0, 0x0e, 0xa0, 0x25, 0xdd, 0x7a, 0xb2, 0xa8, 0x2f, 0x9a, 0xf2, +0xd5, 0xd7, 0x58, 0xbb, 0x7e, 0x99, 0x90, 0x8d, 0xa1, 0x1a, 0xdb, 0x48, 0xeb, +0xe3, 0xe8, 0x7a, 0x03, 0xab, 0xaa, 0xb1, 0x30, 0x0e, 0xf3, 0xc1, 0x7b, 0xb8, +0xbc, 0x8b, 0xf3, 0x22, 0x3a, 0x63, 0xa2, 0x19, 0x6c, 0x20, 0x94, 0xd2, 0x49, +0x56, 0x66, 0x44, 0x33, 0xe4, 0xbd, 0x77, 0xde, 0xfb, 0x15, 0x60, 0x31, 0x88, +0x54, 0x4e, 0x4c, 0x2f, 0x24, 0xb3, 0xee, 0x5d, 0x2e, 0xbe, 0xfe, 0x02, 0xed, +0xd9, 0x07, 0x48, 0x26, 0xf6, 0x80, 0xae, 0x44, 0x7c, 0x5f, 0x0c, 0xae, 0x9f, +0x13, 0xd9, 0x7f, 0x4e, 0x52, 0xc9, 0xaf, 0x10, 0xfd, 0x3c, 0x85, 0x0d, 0xf4, +0x3a, 0xd7, 0x44, 0x73, 0x62, 0x81, 0x52, 0x75, 0xec, 0xd9, 0x6d, 0xb3, 0xfb, +0xba, 0x0c, 0x69, 0x86, 0xec, 0x50, 0xab, 0xd5, 0x7a, 0xb3, 0xd7, 0x5b, 0x9f, +0x4d, 0x12, 0xfd, 0x99, 0x3c, 0x96, 0xb6, 0x17, 0xb6, 0x4b, 0x63, 0xe3, 0x1d, +0xcc, 0x3f, 0xdf, 0x81, 0x7f, 0x4f, 0xa2, 0x2a, 0x2d, 0x51, 0xa9, 0x34, 0xd6, +0xe6, 0xe6, 0xe7, 0x5e, 0xfb, 0x6b, 0xa7, 0x7d, 0x69, 0xe9, 0x5f, 0xed, 0xf1, +0xcf, 0xe6, 0xf6, 0x21, 0x5d, 0xb4, 0x27, 0x2a, 0x63, 0x33, 0x45, 0x6b, 0x7a, +0xf1, 0xcb, 0xf7, 0x7c, 0xec, 0xd8, 0x8b, 0x69, 0x73, 0x8f, 0xff, 0xea, 0x87, +0x41, 0x0c, 0x11, 0x63, 0x64, 0x53, 0x5d, 0xa7, 0xd9, 0x27, 0x1e, 0x3b, 0x76, +0xe4, 0x89, 0x47, 0x8e, 0xec, 0x38, 0x5a, 0x4e, 0xc2, 0x8d, 0x52, 0x6d, 0xfb, +0x9f, 0x83, 0xb7, 0xa7, 0xab, 0xcd, 0xc9, 0xd3, 0x97, 0x97, 0xfe, 0xb4, 0x74, +0xdf, 0x47, 0x0f, 0x9b, 0xa3, 0x8f, 0xbf, 0x60, 0x17, 0xe6, 0x9b, 0x1f, 0xff, +0xc2, 0xa7, 0xf6, 0xfd, 0xe6, 0xd0, 0xdd, 0x0b, 0x74, 0x6c, 0xf3, 0xb1, 0x83, +0x0f, 0x3f, 0xf5, 0x12, 0x9b, 0xba, 0x1f, 0x2c, 0x71, 0xd3, 0xdc, 0xdc, 0x1c, +0xb7, 0x10, 0x07, 0x16, 0xb7, 0xa5, 0xef, 0xbe, 0x79, 0x7c, 0xea, 0xca, 0x3f, +0x5e, 0xac, 0xfd, 0xe5, 0xe4, 0xf7, 0xd5, 0xd2, 0x1f, 0x7e, 0x2c, 0x63, 0xff, +0x3d, 0x6e, 0xf5, 0x93, 0xef, 0x7e, 0x71, 0xc7, 0x1b, 0xaf, 0x3c, 0xf7, 0x73, +0x77, 0xed, 0xd5, 0x47, 0xd9, 0xf4, 0xec, 0xe7, 0xa0, 0x7b, 0xe5, 0x2d, 0x46, +0xfe, 0x0b, 0x23, 0x6d, 0x86, 0x4b, 0xa3, 0xa1, 0xde, 0x64, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char Toolbar_Options3_png[] = { diff --git a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp index c2030a059d..fa30ba5c62 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/Xlib/Xlib.cpp @@ -116,8 +116,7 @@ KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* key ControlState KeyboardMouse::Key::GetState() const { const KeyCode shift = XKeysymToKeycode(m_display, XK_Shift_L); - return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0 - && (m_keyboard[shift / 8] & (1 << (shift % 8))) == 0; + return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0; } ControlState KeyboardMouse::Button::GetState() const diff --git a/Source/Core/InputCommon/Src/InputConfig.cpp b/Source/Core/InputCommon/Src/InputConfig.cpp index b9d2a93b99..1988a9ebb7 100644 --- a/Source/Core/InputCommon/Src/InputConfig.cpp +++ b/Source/Core/InputCommon/Src/InputConfig.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "InputConfig.h" +#include "../../Core/Src/ConfigManager.h" InputPlugin::~InputPlugin() { @@ -26,18 +27,58 @@ InputPlugin::~InputPlugin() delete *i; } -bool InputPlugin::LoadConfig() +bool InputPlugin::LoadConfig(bool isGC) { IniFile inifile; + IniFile game_ini; + bool useProfile[4] = {false, false, false, false}; + std::string num[4] = {"1", "2", "3", "4"}; + std::string profile[4]; + std::string path; + + if (SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() != "00000000") + { + std::string type; + if (isGC) + { + type = "Pad"; + path = "Profiles/GCPad/"; + } + else + { + type = "Wiimote"; + path = "Profiles/Wiimote/"; + } + game_ini.Load(File::GetUserPath(D_GAMECONFIG_IDX) + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".ini"); + for (int i = 0; i < 4; i++) + { + if (game_ini.Exists("Controls", (type + "Profile" + num[i]).c_str())) + { + game_ini.Get("Controls", (type + "Profile" + num[i]).c_str(), &profile[i]); + if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini")) + useProfile[i] = true; + else + PanicAlertT("Selected controller profile does not exist"); + } + } + } + if (inifile.Load(File::GetUserPath(D_CONFIG_IDX) + ini_name + ".ini")) { std::vector< ControllerEmu* >::const_iterator i = controllers.begin(), e = controllers.end(); - for (; i!=e; ++i) + for (int n = 0; i!=e; ++i, ++n) { // load settings from ini - (*i)->LoadConfig(inifile.GetOrCreateSection((*i)->GetName().c_str())); + if (useProfile[n]) + { + IniFile profile_ini; + profile_ini.Load(File::GetUserPath(D_CONFIG_IDX) + path + profile[n] + ".ini"); + (*i)->LoadConfig(profile_ini.GetOrCreateSection("Profile")); + } + else + (*i)->LoadConfig(inifile.GetOrCreateSection((*i)->GetName().c_str())); // update refs (*i)->UpdateReferences(g_controller_interface); } diff --git a/Source/Core/InputCommon/Src/InputConfig.h b/Source/Core/InputCommon/Src/InputConfig.h index 4d25334ce7..71505bb935 100644 --- a/Source/Core/InputCommon/Src/InputConfig.h +++ b/Source/Core/InputCommon/Src/InputConfig.h @@ -42,7 +42,7 @@ public: ~InputPlugin(); - bool LoadConfig(); + bool LoadConfig(bool isGC); void SaveConfig(); std::vector< ControllerEmu* > controllers; diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index c452b238b6..ca0e748cb0 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -151,3 +151,38 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size #undef SET_REG_NAME } } + +AlphaTest::TEST_RESULT AlphaTest::TestResult() +{ + switch(logic) + { + case 0: // AND + if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) + return PASS; + if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER) + return FAIL; + break; + + case 1: // OR + if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS) + return PASS; + if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER) + return FAIL; + break; + + case 2: // XOR + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + return PASS; + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + return FAIL; + break; + + case 3: // XNOR + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS)) + return FAIL; + if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)) + return PASS; + break; + } + return UNDETERMINED; +} diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index 9284674aa1..85e95f4f8b 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -793,7 +793,7 @@ union PE_CONTROL { u32 pixel_format : 3; // PIXELFMT_X u32 zformat : 3; // Z Compression for 16bit Z format - u32 zcomploc : 1; // 1: before tex stage + u32 early_ztest : 1; // 1: before tex stage u32 unused : 17; u32 rid : 8; }; @@ -857,7 +857,7 @@ union TevKSel int getKA(int i) {return i?kasel1:kasel0;} }; -union AlphaFunc +union AlphaTest { struct { @@ -868,6 +868,15 @@ union AlphaFunc u32 logic : 2; }; u32 hex; + + enum TEST_RESULT + { + UNDETERMINED = 0, + FAIL = 1, + PASS = 2, + }; + + TEST_RESULT TestResult(); }; union UPE_Copy @@ -981,7 +990,7 @@ struct BPMemory TevReg tevregs[4]; //0xE0 FogRangeParams fogRange; FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2 - AlphaFunc alphaFunc; //0xF3 + AlphaTest alpha_test; //0xF3 ZTex1 ztex1; //0xf4,0xf5 ZTex2 ztex2; TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index 0bde9cc613..c975b12240 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -357,9 +357,9 @@ void BPWritten(const BPCmd& bp) PixelShaderManager::SetFogColorChanged(); break; case BPMEM_ALPHACOMPARE: // Compare Alpha Values - PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0, - bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic); - PixelShaderManager::SetAlpha(bpmem.alphaFunc); + PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0, + bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic); + PixelShaderManager::SetAlpha(bpmem.alpha_test); break; case BPMEM_BIAS: // BIAS PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias); @@ -497,18 +497,39 @@ void BPWritten(const BPCmd& bp) // if this is different from 0, manual TMEM management is used (GX_PreloadEntireTexture). if (bp.newvalue != 0) { - // NOTE(neobrain): Apparently tmemodd doesn't affect hardware behavior at all (libogc uses it just as a buffer and switches its contents with tmemeven whenever this is called) + // TODO: Not quite sure if this is completely correct (likely not) + // NOTE: libogc's implementation of GX_PreloadEntireTexture seems flawed, so it's not necessarily a good reference for RE'ing this feature. + BPS_TmemConfig& tmem_cfg = bpmem.tmem_config; - u8* ram_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); - u32 tmem_addr = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; - u32 size = tmem_cfg.preload_tile_info.count * 32; + u8* src_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); // TODO: Should we add mask here on GC? + u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE; + u32 tmem_addr_even = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; - // Check if the game has overflowed TMEM, and copy up to the limit. - // Paper Mario does this when entering the Great Boogly Tree (Chap 2) - if ((tmem_addr + size) > TMEM_SIZE) - size = TMEM_SIZE - tmem_addr; + if (tmem_cfg.preload_tile_info.type != 3) + { + if (tmem_addr_even + size > TMEM_SIZE) + size = TMEM_SIZE - tmem_addr_even; - memcpy(texMem + tmem_addr, ram_ptr, size); + memcpy(texMem + tmem_addr_even, src_ptr, size); + } + else // RGBA8 tiles (and CI14, but that might just be stupid libogc!) + { + // AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for everything + u32 tmem_addr_odd = tmem_cfg.preload_tmem_odd * TMEM_LINE_SIZE; + + for (int i = 0; i < tmem_cfg.preload_tile_info.count; ++i) + { + if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE || + tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE) + break; + + memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE); + memcpy(texMem + tmem_addr_odd, src_ptr + TMEM_LINE_SIZE, TMEM_LINE_SIZE); + tmem_addr_even += TMEM_LINE_SIZE; + tmem_addr_odd += TMEM_LINE_SIZE; + src_ptr += TMEM_LINE_SIZE * 2; + } + } } break; diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index cc48276253..fdb5f21a51 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -27,7 +27,6 @@ #include "VideoConfig.h" #include "NativeVertexFormat.h" -static int AlphaPreTest(); static void StageHash(int stage, u32* out) { @@ -109,29 +108,17 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4 uid->values[0] |= dstAlphaMode << 8; // 2 - bool DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth; - - uid->values[0] |= DepthTextureEnable << 10; // 1 - bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; - uid->values[0] |= enablePL << 11; // 1 + uid->values[0] |= enablePL << 10; // 1 - if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 12; // 4 - u32 alphaPreTest = AlphaPreTest()+1; + if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4 - uid->values[0] |= alphaPreTest << 16; // 2 - - if (alphaPreTest == 1 || (alphaPreTest && !DepthTextureEnable && dstAlphaMode == DSTALPHA_ALPHA_PASS)) - { - // Courtesy of PreAlphaTest, we're done already ;) - // NOTE: The comment header of generated shaders depends on the value of bpmem.genmode.numindstages.. shouldnt really bother about that though. - uid->num_values = 1; - return; - } + AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult(); + uid->values[0] |= alphaPreTest << 15; // 2 // numtexgens should be <= 8 for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) - uid->values[0] |= xfregs.texMtxInfo[i].projection << (18+i); // 1 + uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1 uid->values[1] = bpmem.genMode.numindstages; // 3 u32 indirectStagesUsed = 0; @@ -160,28 +147,21 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo ptr += 4; // max: ptr = &uid->values[66] } - ptr[0] |= bpmem.alphaFunc.comp0; // 3 - ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3 - ptr[0] |= bpmem.alphaFunc.logic << 6; // 2 + ptr[0] |= bpmem.alpha_test.comp0; // 3 + ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3 + ptr[0] |= bpmem.alpha_test.logic << 6; // 2 - if (alphaPreTest == 0 || alphaPreTest == 2) - { - ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3 - if (DepthTextureEnable) - { - ptr[0] |= bpmem.ztex2.op << 11; // 2 - ptr[0] |= bpmem.zcontrol.zcomploc << 13; // 1 - ptr[0] |= bpmem.zmode.testenable << 14; // 1 - ptr[0] |= bpmem.zmode.updateenable << 15; // 1 - } - } + ptr[0] |= bpmem.ztex2.op << 8; // 2 + ptr[0] |= bpmem.zcontrol.early_ztest << 10; // 1 + ptr[0] |= bpmem.zmode.testenable << 11; // 1 + ptr[0] |= bpmem.zmode.updateenable << 12; // 1 if (dstAlphaMode != DSTALPHA_ALPHA_PASS) { if (bpmem.fog.c_proj_fsel.fsel != 0) { - ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1 - ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1 + ptr[0] |= bpmem.fog.c_proj_fsel.proj << 13; // 1 + ptr[0] |= bpmem.fogRange.Base.Enabled << 14; // 1 } } @@ -204,9 +184,8 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.ztex2.hex; // 2 *ptr++ = bpmem.zcontrol.hex; // 3 *ptr++ = bpmem.zmode.hex; // 4 - *ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5 - *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6 - *ptr++ = xfregs.numTexGen.hex; // 7 + *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 5 + *ptr++ = xfregs.numTexGen.hex; // 6 if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { @@ -218,28 +197,28 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u } for (unsigned int i = 0; i < 8; ++i) - *ptr++ = xfregs.texMtxInfo[i].hex; // 8-15 + *ptr++ = xfregs.texMtxInfo[i].hex; // 7-14 for (unsigned int i = 0; i < 16; ++i) - *ptr++ = bpmem.tevind[i].hex; // 16-31 + *ptr++ = bpmem.tevind[i].hex; // 15-30 - *ptr++ = bpmem.tevindref.hex; // 32 + *ptr++ = bpmem.tevindref.hex; // 31 for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times { - *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i - *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i - *ptr++ = bpmem.tevind[i].hex; // 35+5*i - *ptr++ = bpmem.tevksel[i/2].hex; // 36+5*i - *ptr++ = bpmem.tevorders[i/2].hex; // 37+5*i + *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i + *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i + *ptr++ = bpmem.tevind[i].hex; // 34+5*i + *ptr++ = bpmem.tevksel[i/2].hex; // 35+5*i + *ptr++ = bpmem.tevorders[i/2].hex; // 36+5*i } - ptr = &uid->values[113]; + ptr = &uid->values[112]; - *ptr++ = bpmem.alphaFunc.hex; // 113 + *ptr++ = bpmem.alpha_test.hex; // 112 - *ptr++ = bpmem.fog.c_proj_fsel.hex; // 114 - *ptr++ = bpmem.fogRange.Base.hex; // 115 + *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113 + *ptr++ = bpmem.fogRange.Base.hex; // 114 _assert_((ptr - uid->values) == uid->GetNumValues()); } @@ -481,7 +460,6 @@ static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "7.0f" }; static char swapModeTable[4][5]; static char text[16384]; -static bool DepthTextureEnable; struct RegisterState { @@ -528,7 +506,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; } } - DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth ; // Declare samplers if(ApiType != API_D3D11) @@ -584,14 +561,14 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType { WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", - DepthTextureEnable ? "\n out float depth : DEPTH," : "", + "\n out float depth : DEPTH,", ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS"); } else { WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", - DepthTextureEnable ? "\n out float depth : SV_Depth," : ""); + "\n out float depth : SV_Depth,"); } WRITE(p, " in float4 colors_0 : COLOR0,\n"); @@ -622,32 +599,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType } WRITE(p, " ) {\n"); - int Pretest = AlphaPreTest(); - if(Pretest >= 0 && !DepthTextureEnable) - { - if (!Pretest) - { - // alpha test will always fail, so restart the shader and just make it an empty function - WRITE(p, "ocol0 = 0;\n"); - if(DepthTextureEnable) - WRITE(p, "depth = 1.f;\n"); - if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) - WRITE(p, "ocol1 = 0;\n"); - WRITE(p, "discard;\n"); - if(ApiType != API_D3D11) - WRITE(p, "return;\n"); - } - else if (dstAlphaMode == DSTALPHA_ALPHA_PASS) - { - WRITE(p, " ocol0 = " I_ALPHA"[0].aaaa;\n"); - } - if(!Pretest || dstAlphaMode == DSTALPHA_ALPHA_PASS) - { - WRITE(p, "}\n"); - return text; - } - } - WRITE(p, " float4 c0 = " I_COLORS"[1], c1 = " I_COLORS"[2], c2 = " I_COLORS"[3], prev = float4(0.0f, 0.0f, 0.0f, 0.0f), textemp = float4(0.0f, 0.0f, 0.0f, 0.0f), rastemp = float4(0.0f, 0.0f, 0.0f, 0.0f), konsttemp = float4(0.0f, 0.0f, 0.0f, 0.0f);\n" " float3 comp16 = float3(1.0f, 255.0f, 0.0f), comp24 = float3(1.0f, 255.0f, 255.0f*255.0f);\n" " float4 alphabump=float4(0.0f,0.0f,0.0f,0.0f);\n" @@ -755,34 +706,26 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); - if(Pretest == -1) - { + AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); + if (Pretest == AlphaTest::UNDETERMINED) WriteAlphaTest(p, ApiType, dstAlphaMode); - } - if((bpmem.fog.c_proj_fsel.fsel != 0) || DepthTextureEnable) - { - // the screen space depth value = far z + (clip z / clip w) * z range - WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); - } + // the screen space depth value = far z + (clip z / clip w) * z range + WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); - if (DepthTextureEnable) + // Note: depth textures are disabled if early depth test is enabled + if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... - if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - if (bpmem.ztex2.op == ZTEXTURE_ADD) - WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w + zCoord;\n"); - else - WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w;\n"); + WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", + (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : ""); - // scale to make result from frac correct - WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); - WRITE(p, "zCoord = frac(zCoord);\n"); - WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); - } - WRITE(p, "depth = zCoord;\n"); + // scale to make result from frac correct + WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); + WRITE(p, "zCoord = frac(zCoord);\n"); + WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); } + WRITE(p, "depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); @@ -1192,39 +1135,6 @@ static const char *tevAlphaFunclogicTable[] = " != ", // xor " == " // xnor }; -static int AlphaPreTest() -{ - u32 op = bpmem.alphaFunc.logic; - u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1}; - - // First kill all the simple cases - switch(op) - { - case 0: // AND - if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return true; - if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return false; - break; - case 1: // OR - if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return true; - if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return false; - break; - case 2: // XOR - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) - return true; - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) - return false; - break; - case 3: // XNOR - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) - return false; - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) - return true; - break; - default: PanicAlert("bad logic for alpha test? %08x", op); - } - return -1; -} - static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) { @@ -1237,34 +1147,31 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode // using discard then return works the same in cg and dx9 but not in dx11 WRITE(p, "if(!( "); - int compindex = bpmem.alphaFunc.comp0 % 8; + int compindex = bpmem.alpha_test.comp0; WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table - WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alphaFunc.logic % 4]);//lookup the logic op + WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op - compindex = bpmem.alphaFunc.comp1 % 8; + compindex = bpmem.alpha_test.comp1; WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table WRITE(p, ")) {\n"); WRITE(p, "ocol0 = 0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) WRITE(p, "ocol1 = 0;\n"); - if (DepthTextureEnable) - WRITE(p, "depth = 1.f;\n"); + WRITE(p, "depth = 1.f;\n"); - // HAXX: zcomploc is a way to control whether depth test is done before - // or after texturing and alpha test. PC GPU does depth test before texturing ONLY if depth value is - // not updated during shader execution. + // HAXX: zcomploc (aka early_ztest) is a way to control whether depth test is done before + // or after texturing and alpha test. PC GPUs have no way to support this + // feature properly as of 2012: depth buffer and depth test are not + // programmable and the depth test is always done after texturing. + // Most importantly, PC GPUs do not allow writing to the z buffer without + // writing a color value (unless color writing is disabled altogether). // We implement "depth test before texturing" by discarding the fragment // when the alpha test fail. This is not a correct implementation because - // even if the depth test fails the fragment could be alpha blended. - // this implemnetation is a trick to keep speed. - // the correct, but slow, way to implement a correct zComploc is : - // 1 - if zcomplock is enebled make a first pass, with color channel write disabled updating only - // depth channel. - // 2 - in the next pass disable depth chanel update, but proccess the color data normally - // this way is the only CORRECT way to emulate perfectly the zcomplock behaviour - if (!(bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable)) + // even if the depth test fails the fragment could be alpha blended, but + // we don't have a choice. + if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { WRITE(p, "discard;\n"); if (ApiType != API_D3D11) @@ -1272,7 +1179,6 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode } WRITE(p, "}\n"); - } static const char *tevFogFuncsTable[] = diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index 31242a916e..9c8bfce256 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -45,7 +45,7 @@ #define C_PMATERIALS (C_PLIGHTS + 40) #define C_PENVCONST_END (C_PMATERIALS + 4) #define PIXELSHADERUID_MAX_VALUES 70 -#define PIXELSHADERUID_MAX_VALUES_SAFE 120 +#define PIXELSHADERUID_MAX_VALUES_SAFE 115 // DO NOT make anything in this class virtual. template diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index 258ec04413..eaaf99fbc8 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -373,7 +373,7 @@ void PixelShaderManager::SetColorChanged(int type, int num, bool high) PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]); } -void PixelShaderManager::SetAlpha(const AlphaFunc& alpha) +void PixelShaderManager::SetAlpha(const AlphaTest& alpha) { if ((alpha.hex & 0xffff) != lastAlpha) { diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index a336287a6f..12d749c871 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -38,7 +38,7 @@ public: // constant management, should be called after memory is committed static void SetColorChanged(int type, int index, bool high); - static void SetAlpha(const AlphaFunc& alpha); + static void SetAlpha(const AlphaTest& alpha); static void SetDestAlpha(const ConstantAlpha& alpha); static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt); static void SetZTextureBias(u32 bias); diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp index 577570c568..8e1d012fa2 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.cpp +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -91,6 +91,9 @@ Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false) #if defined _WIN32 || defined HAVE_LIBAV bAVIDumping = false; #endif + + OSDChoice = 0; + OSDTime = 0; } Renderer::~Renderer() @@ -263,108 +266,109 @@ void Renderer::SetScreenshot(const char *filename) // Create On-Screen-Messages void Renderer::DrawDebugText() { + if (!g_Config.bOSDHotKey) + return; + // OSD Menu messages - if (g_ActiveConfig.bOSDHotKey) + if (OSDChoice > 0) { - if (OSDChoice > 0) - { - OSDTime = Common::Timer::GetTimeMs() + 3000; - OSDChoice = -OSDChoice; - } - if ((u32)OSDTime > Common::Timer::GetTimeMs()) - { - const char* res_text = ""; - switch (g_ActiveConfig.iEFBScale) - { - case 0: - res_text = "Auto (fractional)"; - break; - case 1: - res_text = "Auto (integral)"; - break; - case 2: - res_text = "Native"; - break; - case 3: - res_text = "1.5x"; - break; - case 4: - res_text = "2x"; - break; - case 5: - res_text = "2.5x"; - break; - case 6: - res_text = "3x"; - break; - case 7: - res_text = "4x"; - break; - } - - const char* ar_text = ""; - switch(g_ActiveConfig.iAspectRatio) - { - case ASPECT_AUTO: - ar_text = "Auto"; - break; - case ASPECT_FORCE_16_9: - ar_text = "16:9"; - break; - case ASPECT_FORCE_4_3: - ar_text = "4:3"; - break; - case ASPECT_STRETCH: - ar_text = "Stretch"; - break; - } - - const char* const efbcopy_text = g_ActiveConfig.bEFBCopyEnable ? - (g_ActiveConfig.bCopyEFBToTexture ? "to Texture" : "to RAM") : "Disabled"; - - // The rows - const std::string lines[] = - { - std::string("3: Internal Resolution: ") + res_text, - std::string("4: Aspect Ratio: ") + ar_text + (g_ActiveConfig.bCrop ? " (crop)" : ""), - std::string("5: Copy EFB: ") + efbcopy_text, - std::string("6: Fog: ") + (g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"), - }; - - enum { lines_count = sizeof(lines)/sizeof(*lines) }; - - std::string final_yellow, final_cyan; - - // If there is more text than this we will have a collision - if (g_ActiveConfig.bShowFPS) - { - final_yellow = final_cyan = "\n\n"; - } - - // The latest changed setting in yellow - for (int i = 0; i != lines_count; ++i) - { - if (OSDChoice == -i - 1) - final_yellow += lines[i]; - final_yellow += '\n'; - } - - // The other settings in cyan - for (int i = 0; i != lines_count; ++i) - { - if (OSDChoice != -i - 1) - final_cyan += lines[i]; - final_cyan += '\n'; - } - - // Render a shadow - g_renderer->RenderText(final_cyan.c_str(), 21, 21, 0xDD000000); - g_renderer->RenderText(final_yellow.c_str(), 21, 21, 0xDD000000); - //and then the text - g_renderer->RenderText(final_cyan.c_str(), 20, 20, 0xFF00FFFF); - g_renderer->RenderText(final_yellow.c_str(), 20, 20, 0xFFFFFF00); - } + OSDTime = Common::Timer::GetTimeMs() + 3000; + OSDChoice = -OSDChoice; } + + if ((u32)OSDTime <= Common::Timer::GetTimeMs()) + return; + + const char* res_text = ""; + switch (g_ActiveConfig.iEFBScale) + { + case 0: + res_text = "Auto (fractional)"; + break; + case 1: + res_text = "Auto (integral)"; + break; + case 2: + res_text = "Native"; + break; + case 3: + res_text = "1.5x"; + break; + case 4: + res_text = "2x"; + break; + case 5: + res_text = "2.5x"; + break; + case 6: + res_text = "3x"; + break; + case 7: + res_text = "4x"; + break; + } + + const char* ar_text = ""; + switch(g_ActiveConfig.iAspectRatio) + { + case ASPECT_AUTO: + ar_text = "Auto"; + break; + case ASPECT_FORCE_16_9: + ar_text = "16:9"; + break; + case ASPECT_FORCE_4_3: + ar_text = "4:3"; + break; + case ASPECT_STRETCH: + ar_text = "Stretch"; + break; + } + + const char* const efbcopy_text = g_ActiveConfig.bEFBCopyEnable ? + (g_ActiveConfig.bCopyEFBToTexture ? "to Texture" : "to RAM") : "Disabled"; + + // The rows + const std::string lines[] = + { + std::string("3: Internal Resolution: ") + res_text, + std::string("4: Aspect Ratio: ") + ar_text + (g_ActiveConfig.bCrop ? " (crop)" : ""), + std::string("5: Copy EFB: ") + efbcopy_text, + std::string("6: Fog: ") + (g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"), + }; + + enum { lines_count = sizeof(lines)/sizeof(*lines) }; + + std::string final_yellow, final_cyan; + + // If there is more text than this we will have a collision + if (g_ActiveConfig.bShowFPS) + { + final_yellow = final_cyan = "\n\n"; + } + + // The latest changed setting in yellow + for (int i = 0; i != lines_count; ++i) + { + if (OSDChoice == -i - 1) + final_yellow += lines[i]; + final_yellow += '\n'; + } + + // The other settings in cyan + for (int i = 0; i != lines_count; ++i) + { + if (OSDChoice != -i - 1) + final_cyan += lines[i]; + final_cyan += '\n'; + } + + // Render a shadow + g_renderer->RenderText(final_cyan.c_str(), 21, 21, 0xDD000000); + g_renderer->RenderText(final_yellow.c_str(), 21, 21, 0xDD000000); + //and then the text + g_renderer->RenderText(final_cyan.c_str(), 20, 20, 0xFF00FFFF); + g_renderer->RenderText(final_yellow.c_str(), 20, 20, 0xFFFFFF00); } // TODO: remove diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index 4da80c9752..5376577cbd 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -39,7 +39,7 @@ // TODO: Move these out of here. extern int frameCount; -extern int OSDChoice, OSDTime; +extern int OSDChoice; extern bool bLastFrameDumped; diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 9fc18ef1bd..e0fc11fe1b 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -204,12 +204,16 @@ void TextureCache::ClearRenderTargets() iter = textures.begin(), tcend = textures.end(); - for (; iter!=tcend; ++iter) + while (iter != tcend) + { if (iter->second->type == TCET_EC_VRAM) { delete iter->second; textures.erase(iter++); } + else + ++iter; + } } bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels) @@ -329,6 +333,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, 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); if (isPaletteTexture) { @@ -409,10 +414,19 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage, } } - // TODO: RGBA8 textures are stored non-continuously in tmem, that might cause problems here when preloading is enabled if (!using_custom_texture) - pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth, - expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); + { + if (!(texformat == GX_TF_RGBA8 && from_tmem)) + { + pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth, + expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); + } + else + { + u8* src_data_gb = &texMem[bpmem.tex[stage/4].texImage2[stage%4].tmem_odd * TMEM_LINE_SIZE]; + pcfmt = TexDecoder_DecodeRGBA8FromTmem(temp, src_data, src_data_gb, expandedWidth, expandedHeight); + } + } // TODO: Cleanup. Plus, we still autogenerate mipmaps in certain cases (we shouldn't do that) bool isPow2; diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp index 180c901730..44efcf8bae 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp @@ -2515,6 +2515,40 @@ void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth } } +void TexDecoder_DecodeTexelRGBA8FromTmem(u8 *dst, const u8 *src_ar, const u8* src_gb, int s, int t, int imageWidth) +{ + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; // TODO: Looks wrong. Shouldn't this be ((imageWidth-1)>>2)+1 ? + u32 base_ar = (tBlk * widthBlks + sBlk) << 4; + u32 base_gb = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blk_off = (blkT << 2) + blkS; + + u32 offset_ar = (base_ar + blk_off) << 1; + u32 offset_gb = (base_gb + blk_off) << 1; + const u8* val_addr_ar = src_ar + offset_ar; + const u8* val_addr_gb = src_gb + offset_gb; + + dst[3] = val_addr_ar[0]; // A + dst[0] = val_addr_ar[1]; // R + dst[1] = val_addr_gb[0]; // G + dst[2] = val_addr_gb[1]; // B +} + +PC_TexFormat TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8 *src_ar, const u8 *src_gb, int width, int height) +{ + // TODO for someone who cares: Make this less slow! + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + TexDecoder_DecodeTexelRGBA8FromTmem(dst, src_ar, src_gb, x, y, width-1); + dst += 4; + } + + return PC_TEX_FMT_RGBA32; +} const char* texfmt[] = { // pixel diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.h b/Source/Core/VideoCommon/Src/TextureDecoder.h index 1901c86d27..fae70897f5 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.h +++ b/Source/Core/VideoCommon/Src/TextureDecoder.h @@ -86,6 +86,8 @@ enum PC_TexFormat PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt,bool rgbaOnly = false); PC_TexFormat GetPC_TexFormat(int texformat, int tlutfmt); void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth, int texformat, int tlutaddr, int tlutfmt); +void TexDecoder_DecodeTexelRGBA8FromTmem(u8 *dst, const u8 *src_ar, const u8* src_gb, int s, int t, int imageWidth); +PC_TexFormat TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8 *src_ar, const u8 *src_gb, int width, int height); void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center); #endif diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 5be72e4fcf..cd5a01c6b3 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -202,7 +202,7 @@ void VertexManager::Flush() } PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, - bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); + bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alpha_test.hex>>16)&0xff); #endif u32 usedtextures = 0; diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 07ace04b97..cad117c2c8 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -465,6 +465,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed + // TODO: Can probably be dropped? if (is_d3d) { WRITE(p, "o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); diff --git a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp index d960710ada..84340c6b98 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderManager.cpp @@ -169,14 +169,24 @@ void VertexShaderManager::Shutdown() void VertexShaderManager::Dirty() { - nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256; - nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96; - nPostTransformMatricesChanged[0] = 0; nPostTransformMatricesChanged[1] = 256; - nLightsChanged[0] = 0; nLightsChanged[1] = 0x80; + nTransformMatricesChanged[0] = 0; + nTransformMatricesChanged[1] = 256; + + nNormalMatricesChanged[0] = 0; + nNormalMatricesChanged[1] = 96; + + nPostTransformMatricesChanged[0] = 0; + nPostTransformMatricesChanged[1] = 256; + + nLightsChanged[0] = 0; + nLightsChanged[1] = 0x80; + bPosNormalMatrixChanged = true; - bTexMatricesChanged[0] = bTexMatricesChanged[1] = true; + bTexMatricesChanged[0] = true; + bTexMatricesChanged[1] = true; + bProjectionChanged = true; - bPosNormalMatrixChanged = bTexMatricesChanged[0] = bTexMatricesChanged[1] = true; + nMaterialsChanged = 15; } diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index c702b577e2..7418d60741 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -75,7 +75,6 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation, 200); iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0); - iniFile.Get("Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth, 0); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "EFBScale", &iEFBScale, 2); // native @@ -134,7 +133,6 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Settings", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation); iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle); iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting); - iniFile.GetIfExists("Video_Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth); iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode); iniFile.GetIfExists("Video_Settings", "EFBScale", &iEFBScale); // integral iniFile.GetIfExists("Video_Settings", "DstAlphaPass", &bDstAlphaPass); @@ -203,7 +201,6 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation); iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting); - iniFile.Set("Settings", "EnablePerPixelDepth", bEnablePerPixelDepth); iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); @@ -269,7 +266,6 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation); SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting); - SET_IF_DIFFERS("Video_Settings", "EnablePerPixelDepth", bEnablePerPixelDepth); SET_IF_DIFFERS("Video_Settings", "MSAA", iMultisampleMode); SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index fe883e0dbe..4364bea6ea 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -133,7 +133,6 @@ struct VideoConfig bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess bool bUseBBox; bool bEnablePixelLighting; - bool bEnablePerPixelDepth; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 830f16a9f6..44eaaf5dcf 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -471,10 +471,13 @@ void Renderer::SetColorMask() { // Only enable alpha channel if it's supported by the current EFB format UINT8 color_mask = 0; - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA; - if (bpmem.blendmode.colorupdate) - color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; + if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) + { + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA; + if (bpmem.blendmode.colorupdate) + color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; + } gx_state.blenddc.RenderTarget[0].RenderTargetWriteMask = color_mask; } @@ -907,10 +910,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons Core::Callback_VideoCopiedToXFB(false); return; } - // this function is called after the XFB field is changed, not after - // EFB is copied to XFB. In this way, flickering is reduced in games - // and seems to also give more FPS in ZTP + if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index a26b041ba0..f750313642 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -428,10 +428,13 @@ void Renderer::SetColorMask() { // Only enable alpha channel if it's supported by the current EFB format DWORD color_mask = 0; - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (bpmem.blendmode.colorupdate) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) + { + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + color_mask = D3DCOLORWRITEENABLE_ALPHA; + if (bpmem.blendmode.colorupdate) + color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + } D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); } @@ -844,9 +847,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons Core::Callback_VideoCopiedToXFB(false); return; } - // this function is called after the XFB field is changed, not after - // EFB is copied to XFB. In this way, flickering is reduced in games - // and seems to also give more FPS in ZTP if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; @@ -1201,6 +1201,7 @@ void Renderer::ApplyState(bool bUseDstAlpha) { if (bUseDstAlpha) { + // TODO: WTF is this crap? We're enabling color writing regardless of the actual GPU state here... D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); if(bpmem.zmode.testenable && bpmem.zmode.updateenable) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index e2fff07b10..e3c35a6511 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -646,10 +646,13 @@ void Renderer::SetColorMask() { // Only enable alpha channel if it's supported by the current EFB format GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE; - if (bpmem.blendmode.colorupdate) - ColorMask = GL_TRUE; - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - AlphaMask = GL_TRUE; + if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) + { + if (bpmem.blendmode.colorupdate) + ColorMask = GL_TRUE; + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + AlphaMask = GL_TRUE; + } glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask); } @@ -1013,9 +1016,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons Core::Callback_VideoCopiedToXFB(false); return; } - // this function is called after the XFB field is changed, not after - // EFB is copied to XFB. In this way, flickering is reduced in games - // and seems to also give more FPS in ZTP if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 501c4969e5..ce33247d7c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -128,8 +128,8 @@ void VertexManager::vFlush() xfregs.postMtxInfo[i].index, xfregs.postMtxInfo[i].normalize); } - PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, - bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); + PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphatest=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, + bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alpha_test.hex>>16)&0xff); #endif (void)GL_REPORT_ERROR(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp index 3db8c5d493..6a17a40eb1 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp @@ -115,18 +115,39 @@ void SWBPWritten(int address, int newvalue) case BPMEM_PRELOAD_MODE: if (newvalue != 0) { - // NOTE(neobrain): Apparently tmemodd doesn't affect hardware behavior at all (libogc uses it just as a buffe$ + // TODO: Not quite sure if this is completely correct (likely not) + // NOTE: libogc's implementation of GX_PreloadEntireTexture seems flawed, so it's not necessarily a good reference for RE'ing this feature. + BPS_TmemConfig& tmem_cfg = bpmem.tmem_config; - u8* ram_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); - u32 tmem_addr = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; - u32 size = tmem_cfg.preload_tile_info.count * 32; + u8* src_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); // TODO: Should we add mask here on GC? + u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE; + u32 tmem_addr_even = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; - // Check if the game has overflowed TMEM, and copy up to the limit. - // Paper Mario does this when entering the Great Boogly Tree (Chap 2) - if ((tmem_addr + size) > TMEM_SIZE) - size = TMEM_SIZE - tmem_addr; + if (tmem_cfg.preload_tile_info.type != 3) + { + if (tmem_addr_even + size > TMEM_SIZE) + size = TMEM_SIZE - tmem_addr_even; - memcpy(texMem + tmem_addr, ram_ptr, size); + memcpy(texMem + tmem_addr_even, src_ptr, size); + } + else // RGBA8 tiles (and CI14, but that might just be stupid libogc!) + { + // AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for everything + u32 tmem_addr_odd = tmem_cfg.preload_tmem_odd * TMEM_LINE_SIZE; + + for (int i = 0; i < tmem_cfg.preload_tile_info.count; ++i) + { + if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE || + tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE) + break; + + memcpy(texMem + tmem_addr_even, src_ptr, TMEM_LINE_SIZE); + memcpy(texMem + tmem_addr_odd, src_ptr + TMEM_LINE_SIZE, TMEM_LINE_SIZE); + tmem_addr_even += TMEM_LINE_SIZE; + tmem_addr_odd += TMEM_LINE_SIZE; + src_ptr += TMEM_LINE_SIZE * 2; + } + } } break; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index c212c93601..45c744ee81 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -125,7 +125,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi) if (z < 0 || z > 0x00ffffff) return; - if (bpmem.zcontrol.zcomploc && bpmem.zmode.testenable) + if (bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { // early z if (!EfbInterface::ZCompare(x, y, z)) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index c67ee53837..b10f5a2676 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -433,10 +433,10 @@ static bool AlphaCompare(int alpha, int ref, int comp) static bool AlphaTest(int alpha) { - bool comp0 = AlphaCompare(alpha, bpmem.alphaFunc.ref0, bpmem.alphaFunc.comp0); - bool comp1 = AlphaCompare(alpha, bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp1); + bool comp0 = AlphaCompare(alpha, bpmem.alpha_test.ref0, bpmem.alpha_test.comp0); + bool comp1 = AlphaCompare(alpha, bpmem.alpha_test.ref1, bpmem.alpha_test.comp1); - switch (bpmem.alphaFunc.logic) { + switch (bpmem.alpha_test.logic) { case 0: return comp0 && comp1; // and case 1: return comp0 || comp1; // or case 2: return comp0 ^ comp1; // xor @@ -784,7 +784,7 @@ void Tev::Draw() output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8; } - if (!bpmem.zcontrol.zcomploc && bpmem.zmode.testenable) + if (!bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) return; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/TextureSampler.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/TextureSampler.cpp index 66b6b68e22..56101dc69d 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/TextureSampler.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/TextureSampler.cpp @@ -120,10 +120,12 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample) TexImage0& ti0 = texUnit.texImage0[subTexmap]; TexTLUT& texTlut = texUnit.texTlut[subTexmap]; - u8 *imageSrc; + u8 *imageSrc, *imageSrcOdd = NULL; if (texUnit.texImage1[subTexmap].image_type) { imageSrc = &texMem[texUnit.texImage1[subTexmap].tmem_even * TMEM_LINE_SIZE]; + if (ti0.format == GX_TF_RGBA8) + imageSrcOdd = &texMem[texUnit.texImage2[subTexmap].tmem_odd * TMEM_LINE_SIZE]; } else { @@ -190,17 +192,34 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample) WrapCoord(imageSPlus1, tm0.wrap_s, imageWidth); WrapCoord(imageTPlus1, tm0.wrap_t, imageHeight); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); - SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT)); + if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type)) + { + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); - AddTexel(sampledTex, texel, (fractS) * (128 - fractT)); + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + AddTexel(sampledTex, texel, (fractS) * (128 - fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); - AddTexel(sampledTex, texel, (128 - fractS) * (fractT)); + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + AddTexel(sampledTex, texel, (128 - fractS) * (fractT)); - TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); - AddTexel(sampledTex, texel, (fractS) * (fractT)); + TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + AddTexel(sampledTex, texel, (fractS) * (fractT)); + } + else + { + TexDecoder_DecodeTexelRGBA8FromTmem(sampledTex, imageSrc, imageSrcOdd, imageS, imageT, imageWidth); + SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT)); + + TexDecoder_DecodeTexelRGBA8FromTmem(sampledTex, imageSrc, imageSrcOdd, imageSPlus1, imageT, imageWidth); + AddTexel(sampledTex, texel, (fractS) * (128 - fractT)); + + TexDecoder_DecodeTexelRGBA8FromTmem(sampledTex, imageSrc, imageSrcOdd, imageS, imageTPlus1, imageWidth); + AddTexel(sampledTex, texel, (128 - fractS) * (fractT)); + + TexDecoder_DecodeTexelRGBA8FromTmem(sampledTex, imageSrc, imageSrcOdd, imageSPlus1, imageTPlus1, imageWidth); + AddTexel(sampledTex, texel, (fractS) * (fractT)); + } sample[0] = (u8)(texel[0] >> 14); sample[1] = (u8)(texel[1] >> 14); @@ -217,7 +236,10 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample) WrapCoord(imageS, tm0.wrap_s, imageWidth); WrapCoord(imageT, tm0.wrap_t, imageHeight); - TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type)) + TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); + else + TexDecoder_DecodeTexelRGBA8FromTmem(sample, imageSrc, imageSrcOdd, imageS, imageT, imageWidth); } }