Merge branch 'master' into wii-network

This commit is contained in:
Matthew Parlane 2013-01-12 00:01:27 +13:00
commit 465df943a5
63 changed files with 989 additions and 913 deletions

View File

@ -1,4 +1,4 @@
# R6BE78 - Blob07 # R6BE78 - de Blob
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 3 EmulationStateId = 3
@ -15,4 +15,6 @@ PH_ZFar =
[Gecko] [Gecko]
[Video_Enhancements] [Video_Enhancements]
ForceFiltering = False ForceFiltering = False
[Video_Hacks]
EFBToTextureEnable = False
EFBCopyEnable = True

View File

@ -15,3 +15,6 @@ PH_ZFar =
[Gecko] [Gecko]
[Video_Enhancements] [Video_Enhancements]
ForceFiltering = False ForceFiltering = False
[Video_Hacks]
EFBToTextureEnable = False
EFBCopyEnable = True

View File

@ -1,4 +1,4 @@
# R6BK78 - Blob07 # R6BK78 - de Blob
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 3 EmulationStateId = 3
@ -15,3 +15,6 @@ PH_ZFar =
[Gecko] [Gecko]
[Video_Enhancements] [Video_Enhancements]
ForceFiltering = False ForceFiltering = False
[Video_Hacks]
EFBToTextureEnable = False
EFBCopyEnable = True

View File

@ -1,4 +1,4 @@
# R6BP78 - Blob07 # R6BP78 - de Blob
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 3 EmulationStateId = 3
@ -15,3 +15,6 @@ PH_ZFar =
[Gecko] [Gecko]
[Video_Enhancements] [Video_Enhancements]
ForceFiltering = False ForceFiltering = False
[Video_Hacks]
EFBToTextureEnable = False
EFBCopyEnable = True

View File

@ -1,4 +1,4 @@
# R6BX78 - Blob07 # R6BX78 - de Blob
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 3 EmulationStateId = 3
@ -15,3 +15,6 @@ PH_ZFar =
[Gecko] [Gecko]
[Video_Enhancements] [Video_Enhancements]
ForceFiltering = False ForceFiltering = False
[Video_Hacks]
EFBToTextureEnable = False
EFBCopyEnable = True

View File

@ -102,16 +102,12 @@ namespace AudioCommon
backends.push_back(BACKEND_DIRECTSOUND); backends.push_back(BACKEND_DIRECTSOUND);
if (XAudio2::isValid()) if (XAudio2::isValid())
backends.push_back(BACKEND_XAUDIO2); backends.push_back(BACKEND_XAUDIO2);
if (OpenALStream::isValid())
backends.push_back(BACKEND_OPENAL);
if (AOSound::isValid()) if (AOSound::isValid())
backends.push_back(BACKEND_AOSOUND); backends.push_back(BACKEND_AOSOUND);
if (AlsaSound::isValid()) if (AlsaSound::isValid())
backends.push_back(BACKEND_ALSA); backends.push_back(BACKEND_ALSA);
if (CoreAudioSound::isValid()) if (CoreAudioSound::isValid())
backends.push_back(BACKEND_COREAUDIO); backends.push_back(BACKEND_COREAUDIO);
if (PulseAudio::isValid())
backends.push_back(BACKEND_PULSEAUDIO);
return backends; return backends;
} }

View File

@ -19,7 +19,9 @@
#include "DebugInterface.h" #include "DebugInterface.h"
#include "BreakPoints.h" #include "BreakPoints.h"
#include "../../Core/Src/PowerPC/JitCommon/JitBase.h" #include "../../Core/Src/PowerPC/JitCommon/JitBase.h"
#include <sstream> #include <sstream>
#include <algorithm>
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
{ {
@ -109,13 +111,18 @@ void BreakPoints::Remove(u32 em_address)
} }
void BreakPoints::Clear() 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 MemChecks::TMemChecksStr MemChecks::GetStrings() const

View File

@ -24,7 +24,7 @@
// Increment this every time you change shader generation code. // Increment this every time you change shader generation code.
enum enum
{ {
LINEAR_DISKCACHE_VER = 6975 LINEAR_DISKCACHE_VER = 6979
}; };
// On disk format: // On disk format:

View File

@ -318,9 +318,12 @@ public:
mutex_type* release() mutex_type* release()
{ {
return mutex(); auto const ret = mutex();
pm = NULL; pm = NULL;
owns = false; owns = false;
return ret;
} }
bool owns_lock() const bool owns_lock() const

View File

@ -47,7 +47,6 @@
#include "VideoBackendBase.h" #include "VideoBackendBase.h"
#include "Movie.h" #include "Movie.h"
namespace BootManager namespace BootManager
{ {
@ -154,6 +153,7 @@ void Stop()
SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter; SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter;
StartUp.m_strUniqueID = "00000000";
if (config_cache.valid) if (config_cache.valid)
{ {
config_cache.valid = false; config_cache.valid = false;

View File

@ -165,10 +165,9 @@ u16 dsp_read_accelerator()
// Somehow, YN1 and YN2 must be initialized with their "loop" values, // Somehow, YN1 and YN2 must be initialized with their "loop" values,
// so yeah, it seems likely that we should raise an exception to let // so yeah, it seems likely that we should raise an exception to let
// the DSP program do that, at least if DSP_FORMAT == 0x0A. // 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. // 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); DSPCore_SetException(EXP_ACCOV);
} }

View File

@ -90,9 +90,9 @@ void GetTlutLoadData(u32 &tlutAddr, u32 &memAddr, u32 &tlutXferCount, BPMemory &
// TODO - figure out a cleaner way. // TODO - figure out a cleaner way.
if (Core::g_CoreStartupParameter.bWii) if (Core::g_CoreStartupParameter.bWii)
memAddr = bpmem.tmem_config.tlut_src << 5; memAddr = bpMem.tmem_config.tlut_src << 5;
else 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) void LoadCPReg(u32 subCmd, u32 value, CPMemory &cpMem)

View File

@ -33,7 +33,7 @@ struct MemoryUpdate
TEXTURE_MAP = 0x01, TEXTURE_MAP = 0x01,
XF_DATA = 0x02, XF_DATA = 0x02,
VERTEX_STREAM = 0x04, VERTEX_STREAM = 0x04,
TLUT = 0x08 TMEM = 0x08,
}; };
u32 fifoPosition; u32 fifoPosition;

View File

@ -114,6 +114,8 @@ void FifoRecordAnalyzer::DecodeOpcode(u8 *data)
if (bp.address == BPMEM_LOADTLUT1) if (bp.address == BPMEM_LOADTLUT1)
ProcessLoadTlut1(); ProcessLoadTlut1();
if (bp.address == BPMEM_PRELOAD_MODE)
ProcessPreloadTexture();
} }
break; break;
@ -143,7 +145,16 @@ void FifoRecordAnalyzer::ProcessLoadTlut1()
GetTlutLoadData(tlutMemAddr, memAddr, tlutXferCount, *m_BpMem); 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) void FifoRecordAnalyzer::ProcessLoadIndexedXf(u32 val, int array)

View File

@ -40,6 +40,7 @@ private:
void DecodeOpcode(u8 *data); void DecodeOpcode(u8 *data);
void ProcessLoadTlut1(); void ProcessLoadTlut1();
void ProcessPreloadTexture();
void ProcessLoadIndexedXf(u32 val, int array); void ProcessLoadIndexedXf(u32 val, int array);
void ProcessVertexArrays(u8 *data, u8 vtxAttrGroup); void ProcessVertexArrays(u8 *data, u8 vtxAttrGroup);
void ProcessTexMaps(); void ProcessTexMaps();

View File

@ -203,11 +203,9 @@ u16 AcceleratorGetSample()
// //
// On real hardware, this would raise an interrupt that is handled by the // On real hardware, this would raise an interrupt that is handled by the
// UCode. We simulate what this interrupt does here. // UCode. We simulate what this interrupt does here.
if (*acc_cur_addr >= acc_end_addr)
{
// If we are really at the end (and we don't simply have cur_addr >
// end_addr all the time), loop back to loop_addr.
if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F)) if ((*acc_cur_addr & ~0x1F) == (acc_end_addr & ~0x1F))
{
// If we are really at the end, loop back to loop_addr.
*acc_cur_addr = acc_loop_addr; *acc_cur_addr = acc_loop_addr;
if (acc_pb->audio_addr.looping) if (acc_pb->audio_addr.looping)

View File

@ -20,6 +20,7 @@
#include "ControllerInterface/ControllerInterface.h" #include "ControllerInterface/ControllerInterface.h"
#include "GCPadEmu.h" #include "GCPadEmu.h"
#include "../ConfigManager.h"
#include "../../InputCommon/Src/InputConfig.h" #include "../../InputCommon/Src/InputConfig.h"
@ -55,7 +56,7 @@ void Initialize(void* const hwnd)
g_controller_interface.Initialize(); g_controller_interface.Initialize();
// load the saved controller config // load the saved controller config
g_plugin.LoadConfig(); g_plugin.LoadConfig(true);
} }
void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus) void GetStatus(u8 _numPAD, SPADStatus* _pPADStatus)

View File

@ -5,6 +5,7 @@
#include "WiimoteReal/WiimoteReal.h" #include "WiimoteReal/WiimoteReal.h"
#include "WiimoteEmu/WiimoteEmu.h" #include "WiimoteEmu/WiimoteEmu.h"
#include "Movie.h" #include "Movie.h"
#include "../ConfigManager.h"
#include "ControllerInterface/ControllerInterface.h" #include "ControllerInterface/ControllerInterface.h"
@ -44,7 +45,7 @@ void Initialize(void* const hwnd)
g_controller_interface.SetHwnd(hwnd); g_controller_interface.SetHwnd(hwnd);
g_controller_interface.Initialize(); g_controller_interface.Initialize();
g_plugin.LoadConfig(); g_plugin.LoadConfig(false);
WiimoteReal::Initialize(); WiimoteReal::Initialize();

View File

@ -36,6 +36,11 @@ void Wiimote::RealDisconnect()
return; return;
} }
bool Wiimote::IsOpen() const
{
return IsConnected();
}
int Wiimote::IORead(unsigned char* buf) int Wiimote::IORead(unsigned char* buf)
{ {
return 0; return 0;

View File

@ -136,10 +136,10 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes)
// Connect to a wiimote with a known address. // Connect to a wiimote with a known address.
bool Wiimote::Connect() 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_family = AF_BLUETOOTH;
addr.l2_bdaddr = bdaddr; addr.l2_bdaddr = bdaddr;
addr.l2_cid = 0; addr.l2_cid = 0;
@ -195,6 +195,13 @@ void Wiimote::RealDisconnect()
if (m_wiimote_thread.joinable()) if (m_wiimote_thread.joinable())
m_wiimote_thread.join(); m_wiimote_thread.join();
Close();
}
void Wiimote::Close()
{
if (IsOpen())
{
Host_ConnectWiimote(index, false); Host_ConnectWiimote(index, false);
close(out_sock); close(out_sock);
@ -203,20 +210,21 @@ void Wiimote::RealDisconnect()
out_sock = -1; out_sock = -1;
in_sock = -1; in_sock = -1;
} }
}
bool Wiimote::IsOpen() const
{
return out_sock != -1 && in_sock != -1;
}
int Wiimote::IORead(unsigned char *buf) 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 // Block select for 1/2000th of a second
timeval tv;
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000; tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000;
fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(in_sock, &fds); FD_SET(in_sock, &fds);
@ -230,7 +238,7 @@ int Wiimote::IORead(unsigned char *buf)
return 0; return 0;
// Read the pending message into the buffer // 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) if (r == -1)
{ {
// Error reading data // Error reading data
@ -241,17 +249,17 @@ int Wiimote::IORead(unsigned char *buf)
// This can happen if the bluetooth dongle is disconnected // This can happen if the bluetooth dongle is disconnected
ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. " ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. "
"Wiimote %i will be disconnected.", index + 1); "Wiimote %i will be disconnected.", index + 1);
RealDisconnect(); Close();
} }
return 0; return 0;
} }
if (!r) else if (!r)
{ {
// Disconnect // Disconnect
RealDisconnect(); Close();
return 0;
} }
return r; return r;
} }

View File

@ -294,6 +294,11 @@ void Wiimote::RealDisconnect()
ResetEvent(&hid_overlap); ResetEvent(&hid_overlap);
} }
bool Wiimote::IsOpen() const
{
return IsConnected();
}
int Wiimote::IORead(unsigned char* buf) int Wiimote::IORead(unsigned char* buf)
{ {
DWORD b, r; DWORD b, r;

View File

@ -227,6 +227,11 @@ void Wiimote::RealDisconnect()
ichan = NULL; ichan = NULL;
} }
bool Wiimote::IsOpen() const
{
return IsConnected();
}
int Wiimote::IORead(unsigned char *buf) int Wiimote::IORead(unsigned char *buf)
{ {
int bytes; int bytes;

View File

@ -240,7 +240,7 @@ void Wiimote::Disconnect()
DisableDataReporting(); DisableDataReporting();
} }
bool Wiimote::IsConnected() bool Wiimote::IsConnected() const
{ {
return m_connected; return m_connected;
} }
@ -312,7 +312,7 @@ void Wiimote::ThreadFunc()
Rumble(); Rumble();
// main loop // main loop
while (IsConnected()) while (IsOpen())
{ {
#ifdef __APPLE__ #ifdef __APPLE__
while (Write()) {} while (Write()) {}

View File

@ -53,7 +53,8 @@ public:
bool Read(); bool Read();
bool Write(); bool Write();
bool Connect(); bool Connect();
bool IsConnected(); bool IsConnected() const;
bool IsOpen() const;
void Disconnect(); void Disconnect();
void DisableDataReporting(); void DisableDataReporting();
void Rumble(); void Rumble();
@ -72,6 +73,9 @@ public:
bdaddr_t bdaddr; // Bluetooth address bdaddr_t bdaddr; // Bluetooth address
int out_sock; // Output socket int out_sock; // Output socket
int in_sock; // Input socket int in_sock; // Input socket
void Close();
#elif defined(_WIN32) #elif defined(_WIN32)
char devicepath[255]; // Unique wiimote reference char devicepath[255]; // Unique wiimote reference
//ULONGLONG btaddr; // Bluetooth address //ULONGLONG btaddr; // Bluetooth address

View File

@ -293,7 +293,8 @@ void Interpreter::mfspr(UGeckoInstruction _inst)
case SPR_WPAR: 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(); bool wpar_empty = true; //GPFifo::IsEmpty();
if (!wpar_empty) if (!wpar_empty)
rSPR(iIndex) |= 1; // BNE = buffer not empty rSPR(iIndex) |= 1; // BNE = buffer not empty

View File

@ -296,9 +296,13 @@ bool DecompressBlobToFile(const char* infile, const char* outfile, CompressCB ca
} }
CompressedBlobReader* reader = CompressedBlobReader::Create(infile); CompressedBlobReader* reader = CompressedBlobReader::Create(infile);
if (!reader) return false; if (!reader)
return false;
File::IOFile f(outfile, "wb"); File::IOFile f(outfile, "wb");
if (!f)
return false;
const CompressedBlobHeader &header = reader->GetHeader(); const CompressedBlobHeader &header = reader->GetHeader();
u8* buffer = new u8[header.block_size]; u8* buffer = new u8[header.block_size];
int progress_monitor = max<int>(1, header.num_blocks / 100); int progress_monitor = max<int>(1, header.num_blocks / 100);

View File

@ -19,6 +19,7 @@
#include "FileUtil.h" #include "FileUtil.h"
#include <string> #include <string>
#include <vector>
#include "FileSystemGCWii.h" #include "FileSystemGCWii.h"
#include "StringUtil.h" #include "StringUtil.h"
@ -95,7 +96,7 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi
const SFileInfo* pFileInfo = FindFileInfo(_rFullPath); const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
if (!pFileInfo || pFileInfo->m_FileSize == 0) if (!pFileInfo)
return false; return false;
u64 remainingSize = pFileInfo->m_FileSize; u64 remainingSize = pFileInfo->m_FileSize;
@ -112,22 +113,17 @@ bool CFileSystemGCWii::ExportFile(const char* _rFullPath, const char* _rExportFi
// Limit read size to 128 MB // Limit read size to 128 MB
size_t readSize = (size_t)min(remainingSize, (u64)0x08000000); size_t readSize = (size_t)min(remainingSize, (u64)0x08000000);
u8* buffer = new u8[readSize]; std::vector<u8> buffer(readSize);
result = m_rVolume->Read(fileOffset, readSize, buffer); result = m_rVolume->Read(fileOffset, readSize, &buffer[0]);
if (!result) if (!result)
{
delete[] buffer;
break; break;
}
f.WriteBytes(buffer, readSize); f.WriteBytes(&buffer[0], readSize);
remainingSize -= readSize; remainingSize -= readSize;
fileOffset += readSize; fileOffset += readSize;
delete[] buffer;
} }
return result; return result;
@ -140,22 +136,20 @@ bool CFileSystemGCWii::ExportApploader(const char* _rExportFolder) const
AppSize += 0x20; // + header size AppSize += 0x20; // + header size
DEBUG_LOG(DISCIO,"AppSize -> %x", AppSize); DEBUG_LOG(DISCIO,"AppSize -> %x", AppSize);
u8* buffer = new u8[AppSize]; std::vector<u8> buffer(AppSize);
if (m_rVolume->Read(0x2440, AppSize, buffer)) if (m_rVolume->Read(0x2440, AppSize, &buffer[0]))
{ {
char exportName[512]; std::string exportName(_rExportFolder);
sprintf(exportName, "%s/apploader.img", _rExportFolder); exportName += "/apploader.img";
File::IOFile AppFile(exportName, "wb"); File::IOFile AppFile(exportName, "wb");
if (AppFile) if (AppFile)
{ {
AppFile.WriteBytes(buffer, AppSize); AppFile.WriteBytes(&buffer[0], AppSize);
delete[] buffer;
return true; return true;
} }
} }
delete[] buffer;
return false; return false;
} }
@ -182,21 +176,20 @@ bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const
DolSize = offset + size; DolSize = offset + size;
} }
u8* buffer = new u8[DolSize]; std::vector<u8> buffer(DolSize);
if (m_rVolume->Read(DolOffset, DolSize, buffer)) if (m_rVolume->Read(DolOffset, DolSize, &buffer[0]))
{ {
char exportName[512]; std::string exportName(_rExportFolder);
sprintf(exportName, "%s/boot.dol", _rExportFolder); exportName += "/boot.dol";
File::IOFile DolFile(exportName, "wb"); File::IOFile DolFile(exportName, "wb");
if (DolFile) if (DolFile)
{ {
DolFile.WriteBytes(buffer, DolSize); DolFile.WriteBytes(&buffer[0], DolSize);
delete[] buffer;
return true; return true;
} }
} }
delete[] buffer;
return false; return false;
} }

View File

@ -127,7 +127,7 @@ EVT_SLIDER(ID_VOLUME, CConfigMain::AudioSettingsChanged)
EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::DisplaySettingsChanged) EVT_CHECKBOX(ID_INTERFACE_CONFIRMSTOP, CConfigMain::DisplaySettingsChanged)
EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::DisplaySettingsChanged) EVT_CHECKBOX(ID_INTERFACE_USEPANICHANDLERS, CConfigMain::DisplaySettingsChanged)
EVT_CHECKBOX(ID_INTERFACE_ONSCREENDISPLAYMESSAGES, 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_CHOICE(ID_INTERFACE_LANG, CConfigMain::DisplaySettingsChanged)
EVT_BUTTON(ID_HOTKEY_CONFIG, 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.")); 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 // Display - Themes: Copyright notice
Theme->SetItemToolTip(0, _("Created by Milosz Wlazlo [miloszwl@miloszwl.com, miloszwl.deviantart.com]")); Theme->SetToolTip(_("Boomy: Milosz Wlazlo [miloszwl@miloszwl.com]\nVista: VistaIcons.com\nX-Plastik: black_rider [ForumW.org]\nKDE: KDE-Look.org"));
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"));
InterfaceLang->SetToolTip(_("Change the language of the user interface.\nRequires restart.")); InterfaceLang->SetToolTip(_("Change the language of the user interface.\nRequires restart."));
@ -579,9 +576,9 @@ void CConfigMain::CreateGUIControls()
// Hotkey configuration // Hotkey configuration
HotkeyConfig = new wxButton(DisplayPage, ID_HOTKEY_CONFIG, _("Hotkeys"), HotkeyConfig = new wxButton(DisplayPage, ID_HOTKEY_CONFIG, _("Hotkeys"),
wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator);
// Themes - this should really be a wxChoice... // Themes
Theme = new wxRadioBox(DisplayPage, ID_INTERFACE_THEME, _("Theme"), Theme = new wxChoice(DisplayPage, ID_INTERFACE_THEME, wxDefaultPosition,
wxDefaultPosition, wxDefaultSize, arrayStringFor_Themes, 1, wxRA_SPECIFY_ROWS); wxDefaultSize, arrayStringFor_Themes, 0, wxDefaultValidator);
// Interface settings // Interface settings
ConfirmStop = new wxCheckBox(DisplayPage, ID_INTERFACE_CONFIRMSTOP, _("Confirm on Stop"), ConfirmStop = new wxCheckBox(DisplayPage, ID_INTERFACE_CONFIRMSTOP, _("Confirm on Stop"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
@ -595,13 +592,16 @@ void CConfigMain::CreateGUIControls()
sInterface->Add(InterfaceLang, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); sInterface->Add(InterfaceLang, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
sInterface->AddStretchSpacer(); sInterface->AddStretchSpacer();
sInterface->Add(HotkeyConfig, 0, wxALIGN_RIGHT | wxALL, 5); 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 = new wxStaticBoxSizer(wxVERTICAL, DisplayPage, _("Interface Settings"));
sbInterface->Add(ConfirmStop, 0, wxALL, 5); sbInterface->Add(ConfirmStop, 0, wxALL, 5);
sbInterface->Add(UsePanicHandlers, 0, wxALL, 5); sbInterface->Add(UsePanicHandlers, 0, wxALL, 5);
sbInterface->Add(OnScreenDisplayMessages, 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); sbInterface->Add(sInterface, 0, wxEXPAND | wxALL, 5);
sDisplayPage = new wxBoxSizer(wxVERTICAL); sDisplayPage = new wxBoxSizer(wxVERTICAL);
sDisplayPage->Add(sbInterface, 0, wxEXPAND | wxALL, 5); sDisplayPage->Add(sbInterface, 0, wxEXPAND | wxALL, 5);
DisplayPage->SetSizer(sDisplayPage); DisplayPage->SetSizer(sDisplayPage);

View File

@ -165,7 +165,7 @@ private:
wxCheckBox* ConfirmStop; wxCheckBox* ConfirmStop;
wxCheckBox* UsePanicHandlers; wxCheckBox* UsePanicHandlers;
wxCheckBox* OnScreenDisplayMessages; wxCheckBox* OnScreenDisplayMessages;
wxRadioBox* Theme; wxChoice* Theme;
wxChoice* InterfaceLang; wxChoice* InterfaceLang;
wxButton* HotkeyConfig; wxButton* HotkeyConfig;

View File

@ -22,9 +22,13 @@
#include "FifoPlayer/FifoPlayer.h" #include "FifoPlayer/FifoPlayer.h"
#include "FifoPlayer/FifoRecorder.h" #include "FifoPlayer/FifoRecorder.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <algorithm>
#include <vector>
DECLARE_EVENT_TYPE(RECORDING_FINISHED_EVENT, -1) DECLARE_EVENT_TYPE(RECORDING_FINISHED_EVENT, -1)
DEFINE_EVENT_TYPE(RECORDING_FINISHED_EVENT) DEFINE_EVENT_TYPE(RECORDING_FINISHED_EVENT)
@ -440,26 +444,22 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event)
return; return;
} }
unsigned int val_length = str_search_val.Length() / 2; unsigned int const val_length = str_search_val.Length() / 2;
u8* search_val = new u8[val_length]; std::vector<u8> search_val(val_length);
for (unsigned int i = 0; i < val_length; ++i) for (unsigned int i = 0; i < val_length; ++i)
{ {
wxString char_str = str_search_val.Mid(2*i, 2); wxString char_str = str_search_val.Mid(2*i, 2);
unsigned long val; unsigned long val = 0;
if (!char_str.ToULong(&val, 16)) if (!char_str.ToULong(&val, 16))
{ {
m_numResultsText->SetLabel(_("Invalid search string (couldn't convert to number)")); m_numResultsText->SetLabel(_("Invalid search string (couldn't convert to number)"));
delete[] search_val;
return; return;
} }
search_val[i] = (u8)val; search_val[i] = (u8)val;
} }
search_results.clear(); search_results.clear();
u8* start_ptr; int const frame_idx = m_framesList->GetSelection();
u8* end_ptr;
int frame_idx = m_framesList->GetSelection();
FifoPlayer& player = FifoPlayer::GetInstance(); FifoPlayer& player = FifoPlayer::GetInstance();
const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx); const AnalyzedFrameInfo& frame = player.GetAnalyzedFrameInfo(frame_idx);
const FifoFrameInfo& fifo_frame = player.GetFile()->GetFrame(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)")); m_numResultsText->SetLabel(_("Invalid search parameters (no object selected)"));
return; 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; SearchResult result;
result.frame_idx = frame_idx; result.frame_idx = frame_idx;
@ -496,7 +497,6 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event)
search_results.push_back(result); search_results.push_back(result);
} }
} }
delete[] search_val;
ChangeSearchResult(0); ChangeSearchResult(0);
m_beginSearch->Disable(); m_beginSearch->Disable();

View File

@ -71,6 +71,8 @@ void cX11Window::XEventThread()
switch(event.type) { switch(event.type) {
case KeyPress: case KeyPress:
key = XLookupKeysym((XKeyEvent*)&event, 0); key = XLookupKeysym((XKeyEvent*)&event, 0);
if (g_Config.bOSDHotKey)
{
switch (key) switch (key)
{ {
case XK_3: case XK_3:
@ -79,11 +81,13 @@ void cX11Window::XEventThread()
g_Config.iEFBScale = g_Config.iEFBScale + 1; g_Config.iEFBScale = g_Config.iEFBScale + 1;
if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0; if (g_Config.iEFBScale > 7) g_Config.iEFBScale = 0;
break; break;
case XK_4: case XK_4:
OSDChoice = 2; OSDChoice = 2;
// Toggle aspect ratio // Toggle aspect ratio
g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3; g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
break; break;
case XK_5: case XK_5:
OSDChoice = 3; OSDChoice = 3;
// Toggle EFB copy // Toggle EFB copy
@ -97,13 +101,16 @@ void cX11Window::XEventThread()
g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture; g_Config.bCopyEFBToTexture = !g_Config.bCopyEFBToTexture;
} }
break; break;
case XK_6: case XK_6:
OSDChoice = 4; OSDChoice = 4;
g_Config.bDisableFog = !g_Config.bDisableFog; g_Config.bDisableFog = !g_Config.bDisableFog;
break; break;
default: default:
break; break;
} }
}
if (g_Config.bFreeLook) if (g_Config.bFreeLook)
{ {
static float debugSpeed = 1.0f; static float debugSpeed = 1.0f;

View File

@ -259,6 +259,7 @@ void CGameListCtrl::BrowseForDirectory()
void CGameListCtrl::Update() void CGameListCtrl::Update()
{ {
int scrollPos = wxWindow::GetScrollPos(wxVERTICAL);
// Don't let the user refresh it while a game is running // Don't let the user refresh it while a game is running
if (Core::GetState() != Core::CORE_UNINITIALIZED) if (Core::GetState() != Core::CORE_UNINITIALIZED)
return; return;
@ -363,6 +364,8 @@ void CGameListCtrl::Update()
Show(); Show();
AutomaticColumnWidth(); AutomaticColumnWidth();
ScrollLines(scrollPos);
SetFocus();
} }
wxString NiceSizeFormat(s64 _size) wxString NiceSizeFormat(s64 _size)
@ -1121,6 +1124,9 @@ void CGameListCtrl::CompressSelection(bool _compress)
if (browseDialog.ShowModal() != wxID_OK) if (browseDialog.ShowModal() != wxID_OK)
return; return;
bool all_good = true;
{
wxProgressDialog progressDialog( wxProgressDialog progressDialog(
_compress ? _("Compressing ISO") : _("Decompressing ISO"), _compress ? _("Compressing ISO") : _("Decompressing ISO"),
_("Working..."), _("Working..."),
@ -1157,7 +1163,7 @@ void CGameListCtrl::CompressSelection(bool _compress)
wxYES_NO) == wxNO) wxYES_NO) == wxNO)
continue; continue;
DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), all_good &= DiscIO::CompressFileToBlob(iso->GetFileName().c_str(),
OutputFileName.c_str(), OutputFileName.c_str(),
(iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0, (iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0,
16384, &MultiCompressCB, &progressDialog); 16384, &MultiCompressCB, &progressDialog);
@ -1185,11 +1191,16 @@ void CGameListCtrl::CompressSelection(bool _compress)
wxYES_NO) == wxNO) wxYES_NO) == wxNO)
continue; continue;
DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), all_good &= DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(),
OutputFileName.c_str(), &MultiCompressCB, &progressDialog); OutputFileName.c_str(), &MultiCompressCB, &progressDialog);
} }
m_currentItem++; m_currentItem++;
} }
}
if (!all_good)
wxMessageBox(_("Dolphin was unable to complete the requested action."));
Update(); Update();
} }
@ -1249,6 +1260,9 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event))
_("Confirm File Overwrite"), _("Confirm File Overwrite"),
wxYES_NO) == wxNO); wxYES_NO) == wxNO);
bool all_good = false;
{
wxProgressDialog dialog( wxProgressDialog dialog(
iso->IsCompressed() ? _("Decompressing ISO") : _("Compressing ISO"), iso->IsCompressed() ? _("Decompressing ISO") : _("Compressing ISO"),
_("Working..."), _("Working..."),
@ -1259,14 +1273,19 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event))
wxPD_SMOOTH wxPD_SMOOTH
); );
if (iso->IsCompressed()) if (iso->IsCompressed())
DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(), all_good = DiscIO::DecompressBlobToFile(iso->GetFileName().c_str(),
path.char_str(), &CompressCB, &dialog); path.char_str(), &CompressCB, &dialog);
else else
DiscIO::CompressFileToBlob(iso->GetFileName().c_str(), all_good = DiscIO::CompressFileToBlob(iso->GetFileName().c_str(),
path.char_str(), path.char_str(),
(iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0, (iso->GetPlatform() == GameListItem::WII_DISC) ? 1 : 0,
16384, &CompressCB, &dialog); 16384, &CompressCB, &dialog);
}
if (!all_good)
wxMessageBox(_("Dolphin was unable to complete the requested action."));
Update(); Update();
} }

View File

@ -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 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 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_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 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 _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."); 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, _("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 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, _("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, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL));
szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder));

View File

@ -1261,442 +1261,322 @@ static const unsigned char Toolbar_Log3_png[] = {
}; };
static const unsigned char Toolbar_Open3_png[] = { static const unsigned char Toolbar_Open3_png[] = {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x18, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x08, 0x06,
0x00, 0x00, 0x00, 0x18, 0x08, 0x06, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xc4, 0xb4, 0x6c, 0x3b, 0x00, 0x00, 0x0a, 0x39, 0x69, 0x43,
0x77, 0x3D, 0xF8, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x43, 0x50, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x49,
0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B, 0x13, 0x01, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48,
0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x0A, 0x4D, 0x69, 0x43, 0xc7, 0x9d, 0x96, 0x77, 0x54, 0x54, 0xd7, 0x16, 0x87, 0xcf, 0xbd, 0x77, 0x7a,
0x43, 0x50, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F, 0xa1, 0xcd, 0x30, 0xd2, 0x19, 0x7a, 0x93, 0x2e, 0x30, 0x80, 0xf4, 0x2e, 0x20,
0x70, 0x20, 0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6F, 0x66, 0x1d, 0x04, 0x51, 0x18, 0x66, 0x06, 0x18, 0xca, 0x00, 0xc3, 0x0c, 0x4d, 0x6c,
0x69, 0x6C, 0x65, 0x00, 0x00, 0x78, 0xDA, 0x9D, 0x53, 0x77, 0x88, 0xa8, 0x40, 0x44, 0x11, 0x11, 0x01, 0x45, 0x90, 0xa0, 0x80, 0x01, 0xa3,
0x58, 0x93, 0xF7, 0x16, 0x3E, 0xDF, 0xF7, 0x65, 0x0F, 0x56, 0xa1, 0x48, 0xac, 0x88, 0x62, 0x21, 0x28, 0xa8, 0x60, 0x0f, 0x48, 0x10, 0x50,
0x42, 0xD8, 0xF0, 0xB1, 0x97, 0x6C, 0x81, 0x00, 0x22, 0x23, 0x62, 0x30, 0x8a, 0xa8, 0xa8, 0x64, 0x46, 0xd6, 0x4a, 0x7c, 0x79, 0x79, 0xef,
0xAC, 0x08, 0xC8, 0x10, 0x59, 0xA2, 0x10, 0x92, 0x00, 0x61, 0xe5, 0xe5, 0xf7, 0xc7, 0xbd, 0xdf, 0xda, 0x67, 0xef, 0x73, 0xf7, 0xd9, 0x7b,
0x84, 0x10, 0x12, 0x40, 0xC5, 0x85, 0x88, 0x0A, 0x56, 0x14, 0x9f, 0xb5, 0x2e, 0x00, 0x24, 0x4f, 0x1f, 0x2e, 0x2f, 0x05, 0x96, 0x02, 0x20,
0x15, 0x11, 0x9C, 0x48, 0x55, 0xC4, 0x82, 0xD5, 0x0A, 0x48, 0x99, 0x27, 0xe0, 0x07, 0x7a, 0x38, 0xd3, 0x57, 0x85, 0x47, 0xd0, 0xb1, 0xfd,
0x9D, 0x88, 0xE2, 0xA0, 0x28, 0xB8, 0x67, 0x41, 0x8A, 0x88, 0x00, 0x06, 0x78, 0x80, 0x01, 0xa6, 0x00, 0x30, 0x59, 0xe9, 0xa9, 0xbe, 0x41,
0x5A, 0x8B, 0x55, 0x5C, 0x38, 0xEE, 0x1F, 0xDC, 0xA7, 0xB5, 0xee, 0xc1, 0x40, 0x24, 0x2f, 0x37, 0x17, 0x7a, 0xba, 0xc8, 0x09, 0xfc, 0x8b,
0x7D, 0x7A, 0xEF, 0xED, 0xED, 0xFB, 0xD7, 0xFB, 0xBC, 0xE7, 0xde, 0x0c, 0x01, 0x48, 0xfc, 0xbe, 0x65, 0xe8, 0xe9, 0x4f, 0xa7, 0x83, 0xff,
0x9C, 0xE7, 0xFC, 0xCE, 0x79, 0xCF, 0x0F, 0x80, 0x11, 0x12, 0x4f, 0xd2, 0xac, 0x54, 0xbe, 0x00, 0x00, 0xc8, 0x5f, 0xc4, 0xe6, 0x6c, 0x4e,
0x26, 0x91, 0xE6, 0xA2, 0x6A, 0x00, 0x39, 0x52, 0x85, 0x3C, 0x3a, 0x4b, 0xc4, 0xf9, 0x22, 0x4e, 0xca, 0x14, 0xa4, 0x8a, 0xed, 0x33, 0x22,
0x3A, 0xD8, 0x1F, 0x8F, 0x4F, 0x48, 0xC4, 0xC9, 0xBD, 0x80, 0xa6, 0xc6, 0x24, 0x8a, 0x19, 0x46, 0x89, 0x99, 0x2f, 0x4a, 0x50, 0xc4, 0x72,
0x02, 0x15, 0x48, 0xE0, 0x04, 0x20, 0x10, 0xE6, 0xCB, 0xC2, 0x62, 0x8e, 0x5b, 0xe4, 0xa5, 0x9f, 0x7d, 0x16, 0xd9, 0x51, 0xcc, 0xec, 0x64,
0x67, 0x05, 0xC5, 0x00, 0x00, 0xF0, 0x03, 0x79, 0x78, 0x7E, 0x1e, 0x5b, 0xc4, 0xe2, 0x9c, 0x53, 0xd9, 0xc9, 0x6c, 0x31, 0xf7, 0x88, 0x78,
0x74, 0xB0, 0x3F, 0xFC, 0x01, 0xAF, 0x6F, 0x00, 0x02, 0x00, 0x7b, 0x86, 0x90, 0x23, 0x62, 0xc4, 0x47, 0xc4, 0x05, 0x19, 0x5c, 0x4e, 0xa6,
0x70, 0xD5, 0x2E, 0x24, 0x12, 0xC7, 0xE1, 0xFF, 0x83, 0xBA, 0x88, 0x6f, 0x8b, 0x58, 0x33, 0x49, 0x98, 0xcc, 0x15, 0xf1, 0x5b, 0x71, 0x6c,
0x50, 0x26, 0x57, 0x00, 0x20, 0x91, 0x00, 0xE0, 0x22, 0x12, 0x32, 0x87, 0x99, 0x0e, 0x00, 0x8a, 0x24, 0xb6, 0x0b, 0x38, 0xac, 0x78, 0x11,
0xE7, 0x0B, 0x01, 0x90, 0x52, 0x00, 0xC8, 0x2E, 0x54, 0xC8, 0x9b, 0x88, 0x98, 0xc4, 0x0f, 0x0e, 0x74, 0x11, 0xf1, 0x72, 0x00, 0x70, 0xa4,
0x14, 0x00, 0xC8, 0x18, 0x00, 0xB0, 0x53, 0xB3, 0x64, 0x0A, 0xb8, 0x2f, 0x38, 0xe6, 0x0b, 0x16, 0x70, 0xb2, 0x04, 0xe2, 0x43, 0xb9, 0xa4,
0x00, 0x94, 0x00, 0x00, 0x6C, 0x79, 0x7C, 0x42, 0x22, 0x00, 0xa4, 0x66, 0xf3, 0xb9, 0x71, 0xf1, 0x02, 0xba, 0x2e, 0x4b, 0x8f, 0x6e, 0x6a,
0xAA, 0x0D, 0x00, 0xEC, 0xF4, 0x49, 0x3E, 0x05, 0x00, 0xD8, 0x6d, 0xcd, 0xa0, 0x7b, 0x72, 0x32, 0x93, 0x38, 0x02, 0x81, 0xa1, 0x3f, 0x93,
0xA9, 0x93, 0xDC, 0x17, 0x00, 0xD8, 0xA2, 0x1C, 0xA9, 0x08, 0x95, 0xc8, 0xe4, 0xb3, 0xe9, 0x2e, 0x29, 0xc9, 0xa9, 0x4c, 0x5e, 0x36, 0x00,
0x00, 0x8D, 0x01, 0x00, 0x99, 0x28, 0x47, 0x24, 0x02, 0x40, 0x8b, 0x67, 0xfe, 0x2c, 0x19, 0x71, 0x6d, 0xe9, 0xa2, 0x22, 0x5b, 0x9a, 0x5a,
0xBB, 0x00, 0x60, 0x55, 0x81, 0x52, 0x2C, 0x02, 0xC0, 0xC2, 0x5b, 0x5a, 0x1a, 0x9a, 0x19, 0x99, 0x7e, 0x51, 0xa8, 0xff, 0xba, 0xf8, 0x37,
0x00, 0xA0, 0xAC, 0x40, 0x22, 0x2E, 0x04, 0xC0, 0xAE, 0x01, 0x25, 0xee, 0xed, 0x22, 0xbd, 0x0a, 0xf8, 0xdc, 0x33, 0x88, 0xd6, 0xf7, 0x87,
0x80, 0x59, 0xB6, 0x32, 0x47, 0x02, 0x80, 0xBD, 0x05, 0x00, 0xed, 0xaf, 0xfc, 0x52, 0xea, 0x00, 0x60, 0xcc, 0x8a, 0x6a, 0xb3, 0xeb, 0x0f,
0x76, 0x8E, 0x58, 0x90, 0x0F, 0x40, 0x60, 0x00, 0x80, 0x99, 0x5b, 0xcc, 0x7e, 0x00, 0x3a, 0xb6, 0x02, 0x20, 0x77, 0xff, 0x0f, 0x9b, 0xe6,
0x42, 0x2C, 0xCC, 0x00, 0x20, 0x38, 0x02, 0x00, 0x43, 0x1E, 0x21, 0x00, 0x24, 0x45, 0x7d, 0x6b, 0xbf, 0xf1, 0xc5, 0x79, 0x68, 0xe2, 0x79,
0x13, 0xCD, 0x03, 0x20, 0x4C, 0x03, 0xA0, 0x30, 0xD2, 0xBF, 0x89, 0x17, 0x08, 0x52, 0x6d, 0x8c, 0x8d, 0x33, 0x33, 0x33, 0x8d, 0xb8, 0x1c,
0xE0, 0xA9, 0x5F, 0x70, 0x85, 0xB8, 0x48, 0x01, 0x00, 0xC0, 0x96, 0x91, 0xb8, 0xa0, 0xbf, 0xeb, 0x7f, 0x3a, 0xfc, 0x0d, 0x7d, 0xf1, 0x3d,
0xCB, 0x95, 0xCD, 0x97, 0x4B, 0xD2, 0x33, 0x14, 0xB8, 0x95, 0x23, 0xf1, 0x76, 0xbf, 0x97, 0x87, 0xee, 0xca, 0x89, 0x65, 0x0a, 0x93, 0x04,
0xD0, 0x1A, 0x77, 0xF2, 0xF0, 0xE0, 0xE2, 0x21, 0xE2, 0xC2, 0x74, 0x71, 0xdd, 0x58, 0x29, 0x49, 0x29, 0x42, 0x3e, 0x3d, 0x3d, 0x95, 0xc9,
0x6C, 0xB1, 0x42, 0x61, 0x17, 0x29, 0x10, 0x66, 0x09, 0xE4, 0xe2, 0xd0, 0x0d, 0xff, 0x3c, 0xc4, 0xff, 0x38, 0xf0, 0xaf, 0xf3, 0x58, 0x1a,
0x22, 0x9C, 0x97, 0x9B, 0x23, 0x13, 0x48, 0xE7, 0x03, 0x4C, 0xc8, 0x89, 0xe5, 0xf0, 0x39, 0x3c, 0x51, 0x44, 0xa8, 0x68, 0xca, 0xb8, 0xbc,
0xCE, 0x0C, 0x00, 0x00, 0x1A, 0xF9, 0xD1, 0xC1, 0xFE, 0x38, 0x38, 0x51, 0xbb, 0x79, 0x6c, 0xae, 0x80, 0x9b, 0xc2, 0xa3, 0x73, 0x79, 0xff,
0x3F, 0x90, 0xE7, 0xE6, 0xE4, 0xE1, 0xE6, 0x66, 0xE7, 0x6C, 0xa9, 0x89, 0xff, 0x30, 0xec, 0x4f, 0x5a, 0x9c, 0x6b, 0x91, 0x28, 0xf5, 0x9f,
0xEF, 0xF4, 0xC5, 0xA2, 0xFE, 0x6B, 0xF0, 0x6F, 0x22, 0x3E, 0x00, 0x35, 0xca, 0x08, 0x48, 0xdd, 0xa0, 0x02, 0xe4, 0xe7, 0x3e, 0x80, 0xa2,
0x21, 0xF1, 0xDF, 0xFE, 0xBC, 0x8C, 0x02, 0x04, 0x00, 0x10, 0x10, 0x01, 0x12, 0x79, 0x50, 0xdc, 0xf5, 0xdf, 0xfb, 0xe6, 0x83, 0x0f, 0x05,
0x4E, 0xCF, 0xEF, 0xDA, 0x5F, 0xE5, 0xE5, 0xD6, 0x03, 0x70, 0xe2, 0x9b, 0x17, 0xa6, 0x3a, 0xb1, 0x38, 0xf7, 0x9f, 0x05, 0xfd, 0xfb, 0xae,
0xC7, 0x01, 0xB0, 0x75, 0xBF, 0x6B, 0xA9, 0x5B, 0x00, 0xDA, 0x70, 0x89, 0xf8, 0x91, 0xce, 0x8d, 0xfb, 0x1c, 0xe7, 0x12, 0x18, 0x4c, 0x67,
0x56, 0x00, 0x68, 0xDF, 0xF9, 0x5D, 0x33, 0xDB, 0x09, 0xA0, 0x09, 0xf9, 0x19, 0x8b, 0x6b, 0xe2, 0x6b, 0x09, 0xd0, 0x80, 0x00, 0x24, 0x01,
0x5A, 0x0A, 0xD0, 0x7A, 0xF9, 0x8B, 0x79, 0x38, 0xFC, 0x40, 0x15, 0xc8, 0x03, 0x15, 0xa0, 0x01, 0x74, 0x81, 0x21, 0x30, 0x03, 0x56, 0xc0,
0x1E, 0x9E, 0xA1, 0x50, 0xC8, 0x3C, 0x1D, 0x1C, 0x0A, 0x0B, 0x16, 0x38, 0x02, 0x37, 0xb0, 0x02, 0xf8, 0x81, 0x60, 0x10, 0x0e, 0xd6, 0x02,
0x0B, 0xED, 0x25, 0x62, 0xA1, 0xBD, 0x30, 0xE3, 0x8B, 0x3E, 0x16, 0x88, 0x07, 0xc9, 0x80, 0x0f, 0x32, 0x41, 0x2e, 0xd8, 0x0c, 0x0a, 0x40,
0xFF, 0x33, 0xE1, 0x6F, 0xE0, 0x8B, 0x7E, 0xF6, 0xFC, 0x40, 0x11, 0xd8, 0x05, 0xf6, 0x82, 0x4a, 0x50, 0x03, 0xea, 0x41, 0x23, 0x68, 0x01,
0x1E, 0xFE, 0xDB, 0x7A, 0xF0, 0x00, 0x71, 0x9A, 0x40, 0x99, 0x27, 0x40, 0x07, 0x38, 0x0d, 0x2e, 0x80, 0xcb, 0xe0, 0x3a, 0xb8, 0x09, 0xee,
0xAD, 0xC0, 0xA3, 0x83, 0xFD, 0x71, 0x61, 0x6E, 0x76, 0xAE, 0x80, 0x07, 0x60, 0x04, 0x8c, 0x83, 0xe7, 0x60, 0x06, 0xbc, 0x01, 0xf3, 0x10,
0x52, 0x8E, 0xE7, 0xCB, 0x04, 0x42, 0x31, 0x6E, 0xF7, 0xE7, 0x04, 0x61, 0x21, 0x32, 0x44, 0x81, 0xe4, 0x21, 0x55, 0x48, 0x0b, 0x32, 0x80,
0x23, 0xFE, 0xC7, 0x85, 0x7F, 0xFD, 0x8E, 0x29, 0xD1, 0xE2, 0xcc, 0x20, 0x06, 0x64, 0x0f, 0xb9, 0x41, 0x3e, 0x50, 0x20, 0x14, 0x0e, 0x45,
0x34, 0xB1, 0x5C, 0x2C, 0x15, 0x8A, 0xF1, 0x58, 0x89, 0xB8, 0x43, 0x71, 0x10, 0x0f, 0x12, 0x42, 0xb9, 0xd0, 0x16, 0xa8, 0x08, 0x2a, 0x85,
0x50, 0x22, 0x4D, 0xC7, 0x79, 0xB9, 0x52, 0x91, 0x44, 0x21, 0x2a, 0xa1, 0x5a, 0xa8, 0x11, 0xfa, 0x16, 0x3a, 0x05, 0x5d, 0x80, 0xae, 0x42,
0xC9, 0x95, 0xE2, 0x12, 0xE9, 0x7F, 0x32, 0xF1, 0x1F, 0x96, 0x03, 0xd0, 0x3d, 0x68, 0x14, 0x9a, 0x82, 0x7e, 0x85, 0xde, 0xc3, 0x08, 0x4c,
0xFD, 0x09, 0x93, 0x77, 0x0D, 0x00, 0xAC, 0x86, 0x4F, 0xC0, 0x82, 0xa9, 0xb0, 0x32, 0xac, 0x0d, 0x1b, 0xc3, 0x0c, 0xd8, 0x09, 0xf6, 0x86,
0x4E, 0xB6, 0x07, 0xB5, 0xCB, 0x6C, 0xC0, 0x7E, 0xEE, 0x01, 0x83, 0xe1, 0x35, 0x70, 0x1c, 0x9c, 0x06, 0xe7, 0xc0, 0xf9, 0xf0, 0x4e, 0xb8,
0x02, 0x8B, 0x0E, 0x58, 0xD2, 0x76, 0x00, 0x40, 0x7E, 0xF3, 0x02, 0xae, 0x83, 0x8f, 0xc1, 0xed, 0xf0, 0x05, 0xf8, 0x3a, 0x7c, 0x07, 0x1e,
0x2D, 0x8C, 0x1A, 0x0B, 0x91, 0x00, 0x10, 0x67, 0x34, 0x32, 0x81, 0x9f, 0xc3, 0xb3, 0x08, 0x40, 0x88, 0x08, 0x0d, 0x51, 0x43, 0x0c, 0x11,
0x79, 0xF7, 0x00, 0x00, 0x93, 0xBF, 0xF9, 0x8F, 0x40, 0x2B, 0x06, 0xe2, 0x82, 0xf8, 0x21, 0x11, 0x48, 0x2c, 0xc2, 0x47, 0x36, 0x20, 0x85,
0x01, 0x00, 0xCD, 0x97, 0xA4, 0xE3, 0x00, 0x00, 0xBC, 0xE8, 0x48, 0x39, 0x52, 0x87, 0xb4, 0x20, 0x5d, 0x48, 0x2f, 0x72, 0x0b, 0x19, 0x41,
0x18, 0x5C, 0xA8, 0x94, 0x17, 0x4C, 0xC6, 0x08, 0x00, 0x00, 0xa6, 0x91, 0x77, 0x28, 0x0c, 0x8a, 0x82, 0xa2, 0xa3, 0x0c, 0x51, 0xb6, 0x28,
0x44, 0xA0, 0x81, 0x2A, 0xB0, 0x41, 0x07, 0x0C, 0xC1, 0x14, 0x4f, 0x54, 0x08, 0x8a, 0x85, 0x4a, 0x43, 0x6d, 0x40, 0x15, 0xa3, 0x2a, 0x51,
0xAC, 0xC0, 0x0E, 0x9C, 0xC1, 0x1D, 0xBC, 0xC0, 0x17, 0x02, 0x47, 0x51, 0xed, 0xa8, 0x1e, 0xd4, 0x2d, 0xd4, 0x28, 0x6a, 0x06, 0xf5, 0x09,
0x61, 0x06, 0x44, 0x40, 0x0C, 0x24, 0xC0, 0x3C, 0x10, 0x42, 0x4d, 0x46, 0x2b, 0xa1, 0x0d, 0xd0, 0x36, 0x68, 0x2f, 0xf4, 0x2a, 0x74, 0x1c,
0x06, 0xE4, 0x80, 0x1C, 0x0A, 0xA1, 0x18, 0x96, 0x41, 0x19, 0x3a, 0x13, 0x5d, 0x80, 0x2e, 0x47, 0x37, 0xa0, 0xdb, 0xd0, 0x97, 0xd0, 0x77,
0x54, 0xC0, 0x3A, 0xD8, 0x04, 0xB5, 0xB0, 0x03, 0x1A, 0xA0, 0xd0, 0xe3, 0xe8, 0x37, 0x18, 0x0c, 0x86, 0x86, 0xd1, 0xc1, 0x58, 0x61, 0x3c,
0x11, 0x9A, 0xE1, 0x10, 0xB4, 0xC1, 0x31, 0x38, 0x0D, 0xE7, 0x31, 0xe1, 0x98, 0x04, 0xcc, 0x3a, 0x4c, 0x31, 0xe6, 0x00, 0xa6, 0x15, 0x73,
0xE0, 0x12, 0x5C, 0x81, 0xEB, 0x70, 0x17, 0x06, 0x60, 0x18, 0x1e, 0x33, 0x80, 0x19, 0xc3, 0xcc, 0x62, 0xb1, 0x58, 0x79, 0xac, 0x01, 0xd6,
0x9E, 0xC2, 0x18, 0xBC, 0x86, 0x09, 0x04, 0x41, 0xC8, 0x08, 0x0e, 0xeb, 0x87, 0x65, 0x62, 0x05, 0xd8, 0x02, 0xec, 0x7e, 0xec, 0x31, 0xec,
0x13, 0x61, 0x21, 0x3A, 0x88, 0x11, 0x62, 0x8E, 0xD8, 0x22, 0x39, 0xec, 0x20, 0x76, 0x1c, 0xfb, 0x16, 0x47, 0xc4, 0xa9, 0xe2, 0xcc, 0x70,
0xCE, 0x08, 0x17, 0x99, 0x8E, 0x04, 0x22, 0x61, 0x48, 0x34, 0xee, 0xb8, 0x08, 0x1c, 0x0f, 0x97, 0x87, 0x2b, 0xc7, 0x35, 0xe1, 0xce, 0xe2,
0x92, 0x80, 0xA4, 0x20, 0xE9, 0x88, 0x14, 0x51, 0x22, 0xC5, 0x06, 0x71, 0x13, 0xb8, 0x79, 0xbc, 0x14, 0x5e, 0x0b, 0x6f, 0x83, 0xf7, 0xc3,
0xC8, 0x72, 0xA4, 0x02, 0xA9, 0x42, 0x6A, 0x91, 0x5D, 0x48, 0xb3, 0xf1, 0xd9, 0xf8, 0x12, 0x7c, 0x3d, 0xbe, 0x0b, 0x7f, 0x03, 0x3f, 0x8e,
0x23, 0xF2, 0x2D, 0x72, 0x14, 0x39, 0x8D, 0x5C, 0x40, 0xFA, 0x9f, 0x27, 0x48, 0x13, 0x74, 0x08, 0x76, 0x84, 0x60, 0x42, 0x02, 0x61, 0x33,
0x90, 0xDB, 0xC8, 0x20, 0x32, 0x8A, 0xFC, 0x8A, 0xBC, 0x47, 0xa1, 0x82, 0xd0, 0x42, 0xb8, 0x44, 0x78, 0x48, 0x78, 0x45, 0x24, 0x12, 0xd5,
0x31, 0x94, 0x81, 0xB2, 0x51, 0x03, 0xD4, 0x02, 0x75, 0x40, 0x89, 0xd6, 0xc4, 0x00, 0x22, 0x97, 0xb8, 0x89, 0x58, 0x41, 0x3c, 0x4e, 0xbc,
0xB9, 0xA8, 0x1F, 0x1A, 0x8A, 0xC6, 0xA0, 0x73, 0xD1, 0x74, 0x42, 0x1c, 0x25, 0xbe, 0x23, 0xc9, 0x90, 0xf4, 0x49, 0x2e, 0xa4, 0x48, 0x92,
0x34, 0x0F, 0x5D, 0x80, 0x96, 0xA2, 0x6B, 0xD1, 0x1A, 0xB4, 0x90, 0xb4, 0x93, 0x74, 0x84, 0x74, 0x9e, 0x74, 0x8f, 0xf4, 0x8a, 0x4c, 0x26,
0x1E, 0x3D, 0x80, 0xB6, 0xA2, 0xA7, 0xD1, 0x4B, 0xE8, 0x75, 0x6b, 0x93, 0x1d, 0xc9, 0x11, 0x64, 0x01, 0x79, 0x27, 0xb9, 0x91, 0x7c, 0x91,
0x74, 0x00, 0x7D, 0x8A, 0x8E, 0x63, 0x80, 0xD1, 0x31, 0x0E, 0xfc, 0x98, 0xfc, 0x56, 0x82, 0x22, 0x61, 0x24, 0xe1, 0x25, 0xc1, 0x96, 0xd8,
0x66, 0x8C, 0xD9, 0x61, 0x5C, 0x8C, 0x87, 0x45, 0x60, 0x89, 0x28, 0x51, 0x25, 0xd1, 0x2e, 0x31, 0x28, 0xf1, 0x42, 0x12, 0x2f, 0xa9, 0x25,
0x58, 0x1A, 0x26, 0xC7, 0x16, 0x63, 0xE5, 0x58, 0x35, 0x56, 0xe9, 0x24, 0xb9, 0x56, 0x32, 0x47, 0xb2, 0x5c, 0xf2, 0xa4, 0xe4, 0x0d, 0xc9,
0x8F, 0x35, 0x63, 0x1D, 0x58, 0x37, 0x76, 0x15, 0x1B, 0xC0, 0x69, 0x29, 0xbc, 0x94, 0xb6, 0x94, 0x8b, 0x14, 0x53, 0x6a, 0x83, 0x54, 0x95,
0x9E, 0x61, 0xEF, 0x08, 0x24, 0x02, 0x8B, 0x80, 0x13, 0xEC, 0xd4, 0x29, 0xa9, 0x61, 0xa9, 0x59, 0x69, 0x8a, 0xb4, 0xa9, 0xb4, 0x9f, 0x74,
0x08, 0x5E, 0x84, 0x10, 0xC2, 0x6C, 0x82, 0x90, 0x90, 0x47, 0xb2, 0x74, 0xb1, 0x74, 0x93, 0xf4, 0x55, 0xe9, 0x49, 0x19, 0xac, 0x8c, 0xb6,
0x58, 0x4C, 0x58, 0x43, 0xA8, 0x25, 0xEC, 0x23, 0xB4, 0x12, 0x8c, 0x9b, 0x0c, 0x5b, 0x26, 0x5f, 0xe6, 0xb0, 0xcc, 0x45, 0x99, 0x31, 0x0a,
0xBA, 0x08, 0x57, 0x09, 0x83, 0x84, 0x31, 0xC2, 0x27, 0x22, 0x42, 0xd1, 0xa0, 0xb8, 0x50, 0x58, 0x94, 0x2d, 0x94, 0x7a, 0xca, 0x25, 0xca,
0x93, 0xA8, 0x4F, 0xB4, 0x25, 0x7A, 0x12, 0xF9, 0xC4, 0x78, 0x38, 0x15, 0x43, 0xd5, 0xa1, 0x7a, 0x51, 0x13, 0xa8, 0x45, 0xd4, 0x6f, 0xa8,
0x62, 0x3A, 0xB1, 0x90, 0x58, 0x46, 0xAC, 0x26, 0xEE, 0x21, 0xfd, 0xd4, 0x19, 0x59, 0x19, 0xd9, 0x65, 0xb2, 0xa1, 0xb2, 0x59, 0xb2, 0x55,
0x1E, 0x21, 0x9E, 0x25, 0x5E, 0x27, 0x0E, 0x13, 0x5F, 0x93, 0xb2, 0x67, 0x64, 0x47, 0x68, 0x08, 0x4d, 0x9b, 0xe6, 0x45, 0x4b, 0xa2, 0x95,
0x48, 0x24, 0x0E, 0xC9, 0x92, 0xE4, 0x4E, 0x0A, 0x21, 0x25, 0xd0, 0x4e, 0xd0, 0x86, 0x68, 0xef, 0x97, 0x28, 0x2f, 0x71, 0x5a, 0xc2, 0x59,
0x90, 0x32, 0x49, 0x0B, 0x49, 0x6B, 0x48, 0xDB, 0x48, 0x2D, 0xb2, 0x63, 0x49, 0xcb, 0x92, 0xc1, 0x25, 0x73, 0x72, 0x8a, 0x72, 0x8e, 0x72,
0xA4, 0x53, 0xA4, 0x3E, 0xD2, 0x10, 0x69, 0x9C, 0x4C, 0x26, 0x1c, 0xb9, 0x42, 0xb9, 0x56, 0xb9, 0x3b, 0x72, 0xef, 0xe5, 0xe9, 0xf2, 0x6e,
0xEB, 0x90, 0x6D, 0xC9, 0xDE, 0xE4, 0x08, 0xB2, 0x80, 0xAC, 0xf2, 0x89, 0xf2, 0xbb, 0xe5, 0x3b, 0xe4, 0x1f, 0x29, 0xa0, 0x14, 0xf4, 0x15,
0x20, 0x97, 0x91, 0xB7, 0x90, 0x0F, 0x90, 0x4F, 0x92, 0xFB, 0x02, 0x14, 0x32, 0x15, 0x0e, 0x2a, 0x5c, 0x52, 0x98, 0x56, 0xa4, 0x2a, 0xda,
0xC9, 0xC3, 0xE4, 0xB7, 0x14, 0x3A, 0xC5, 0x88, 0xE2, 0x4C, 0x2a, 0xb2, 0x14, 0x0b, 0x15, 0x4f, 0x28, 0xde, 0x57, 0x82, 0x95, 0xf4, 0x95,
0x09, 0xA2, 0x24, 0x52, 0xA4, 0x94, 0x12, 0x4A, 0x35, 0x65, 0x02, 0x95, 0xd6, 0x29, 0x1d, 0x56, 0xea, 0x53, 0x9a, 0x55, 0x56, 0x51, 0xf6,
0x3F, 0xE5, 0x04, 0xA5, 0x9F, 0x32, 0x42, 0x99, 0xA0, 0xAA, 0x50, 0x4e, 0x55, 0xde, 0xaf, 0x7c, 0x51, 0x79, 0x5a, 0x85, 0xa6, 0xe2, 0xa8,
0x51, 0xCD, 0xA9, 0x9E, 0xD4, 0x08, 0xAA, 0x88, 0x3A, 0x9F, 0x92, 0xa0, 0x52, 0xa6, 0x72, 0x56, 0x65, 0x4a, 0x95, 0xa2, 0x6a, 0xaf, 0xca,
0x5A, 0x49, 0x6D, 0xA0, 0x76, 0x50, 0x2F, 0x53, 0x87, 0xA9, 0x55, 0x2d, 0x53, 0x3d, 0xa7, 0xfa, 0x8c, 0x2e, 0x4b, 0x77, 0xa2, 0x27, 0xd1,
0x13, 0x34, 0x75, 0x9A, 0x25, 0xCD, 0x9B, 0x16, 0x43, 0xCB, 0x2b, 0xe8, 0x3d, 0xf4, 0x19, 0x35, 0x25, 0x35, 0x4f, 0x35, 0xa1, 0x5a, 0xad,
0xA4, 0x2D, 0xA3, 0xD5, 0xD0, 0x9A, 0x69, 0x67, 0x69, 0xF7, 0x5a, 0xbf, 0xda, 0xbc, 0xba, 0x8e, 0x7a, 0x88, 0x7a, 0x9e, 0x7a, 0xab, 0xfa,
0x68, 0x2F, 0xE9, 0x74, 0xBA, 0x09, 0xDD, 0x83, 0x1E, 0x45, 0x23, 0x0d, 0x82, 0x06, 0x43, 0x23, 0x56, 0xa3, 0x4c, 0xa3, 0x5b, 0x63, 0x46,
0x97, 0xD0, 0x97, 0xD2, 0x6B, 0xE8, 0x07, 0xE9, 0xE7, 0xE9, 0x53, 0x55, 0xd3, 0x57, 0x33, 0x57, 0xb3, 0x59, 0xf3, 0xbe, 0x16, 0x5e, 0x8b,
0x83, 0xF4, 0x77, 0x0C, 0x0D, 0x86, 0x0D, 0x83, 0xC7, 0x48, 0xa1, 0x15, 0xaf, 0xb5, 0x4f, 0xab, 0x57, 0x6b, 0x4e, 0x5b, 0x47, 0x3b, 0x4c,
0x62, 0x28, 0x19, 0x6B, 0x19, 0x7B, 0x19, 0xA7, 0x18, 0xB7, 0x7b, 0x9b, 0x76, 0x87, 0xf6, 0xa4, 0x8e, 0x9c, 0x8e, 0x97, 0x4e, 0x8e, 0x4e,
0x19, 0x2F, 0x99, 0x4C, 0xA6, 0x05, 0xD3, 0x97, 0x99, 0xC8, 0xb3, 0xce, 0x43, 0x5d, 0xb2, 0xae, 0x83, 0x6e, 0x9a, 0x6e, 0x9d, 0xee, 0x6d,
0x54, 0x30, 0xD7, 0x32, 0x1B, 0x99, 0x67, 0x98, 0x0F, 0x98, 0x3d, 0x8c, 0x1e, 0x43, 0x2f, 0x51, 0xef, 0x80, 0xde, 0x4d, 0x7d, 0x58, 0xdf,
0x6F, 0x55, 0x58, 0x2A, 0xF6, 0x2A, 0x7C, 0x15, 0x91, 0xCA, 0x42, 0x3f, 0x5e, 0xbf, 0x4a, 0xff, 0x86, 0x01, 0x6c, 0x60, 0x69, 0xc0, 0x35,
0x12, 0x95, 0x3A, 0x95, 0x56, 0x95, 0x7E, 0x95, 0xE7, 0xAA, 0x38, 0x60, 0x30, 0xb0, 0x14, 0xbd, 0xd4, 0x7a, 0x29, 0x6f, 0x69, 0xdd, 0xd2,
0x54, 0x55, 0x73, 0x55, 0x3F, 0xD5, 0x79, 0xAA, 0x0B, 0x54, 0x61, 0x43, 0x92, 0xa1, 0x93, 0x61, 0x86, 0x61, 0xb3, 0xe1, 0xa8, 0x11, 0xcd,
0xAB, 0x55, 0x0F, 0xAB, 0x5E, 0x56, 0x7D, 0xA6, 0x46, 0x55, 0xc8, 0xc7, 0x28, 0xcf, 0xa8, 0xc3, 0xe8, 0x85, 0xb1, 0xa6, 0x71, 0x84, 0xf1,
0xB3, 0x50, 0xE3, 0xA9, 0x09, 0xD4, 0x16, 0xAB, 0xD5, 0xA9, 0x6e, 0xe3, 0x5e, 0xe3, 0x4f, 0x26, 0x16, 0x26, 0x49, 0x26, 0xf5, 0x26, 0x0f,
0x1D, 0x55, 0xBB, 0xA9, 0x36, 0xAE, 0xCE, 0x52, 0x77, 0x52, 0x4c, 0x65, 0x4c, 0x57, 0x98, 0xe6, 0x99, 0x76, 0x99, 0xfe, 0x6a, 0xa6, 0x6f,
0x8F, 0x50, 0xCF, 0x51, 0x5F, 0xA3, 0xBE, 0x5F, 0xFD, 0x82, 0xc6, 0x32, 0xab, 0x32, 0xbb, 0x6d, 0x4e, 0x36, 0x77, 0x37, 0xdf, 0x68, 0xde,
0xFA, 0x63, 0x0D, 0xB2, 0x86, 0x85, 0x46, 0xA0, 0x86, 0x48, 0x69, 0xfe, 0x72, 0x99, 0xc1, 0x32, 0xce, 0xb2, 0x83, 0xcb, 0xee, 0x5a, 0x50,
0xA3, 0x54, 0x63, 0xB7, 0xC6, 0x19, 0x8D, 0x21, 0x16, 0xC6, 0x2c, 0x7c, 0x2d, 0xb6, 0x59, 0x74, 0x5b, 0x7c, 0xb4, 0xb4, 0xb2, 0xe4, 0x5b,
0x32, 0x65, 0xF1, 0x58, 0x42, 0xD6, 0x72, 0x56, 0x03, 0xEB, 0xb6, 0x58, 0x4e, 0x59, 0x69, 0x5a, 0x45, 0x5b, 0x55, 0x5b, 0x0d, 0x33, 0xa8,
0x2C, 0x6B, 0x98, 0x4D, 0x62, 0x5B, 0xB2, 0xF9, 0xEC, 0x4C, 0x0c, 0x7f, 0x46, 0x31, 0xe3, 0x8a, 0x35, 0xda, 0xda, 0xd9, 0x7a, 0xa3, 0xf5,
0x76, 0x05, 0xFB, 0x1B, 0x76, 0x2F, 0x7B, 0x4C, 0x53, 0x43, 0x69, 0xeb, 0x77, 0x36, 0x96, 0x36, 0x02, 0x9b, 0x13, 0x36, 0xbf, 0xd8, 0x1a,
0x73, 0xAA, 0x66, 0xAC, 0x66, 0x91, 0x66, 0x9D, 0xE6, 0x71, 0xda, 0x26, 0xda, 0x36, 0xd9, 0x4e, 0x2e, 0xd7, 0x59, 0xce, 0x59, 0x5e, 0xbf,
0xCD, 0x01, 0x0E, 0xC6, 0xB1, 0xE0, 0xF0, 0x39, 0xD9, 0x9C, 0x7c, 0xcc, 0x4e, 0xdd, 0x8e, 0x69, 0x57, 0x6b, 0x37, 0x62, 0x4f, 0xb7, 0x8f,
0x4A, 0xCE, 0x21, 0xCE, 0x0D, 0xCE, 0x7B, 0x2D, 0x03, 0x2D, 0xb6, 0x3f, 0x64, 0x3f, 0xe2, 0xa0, 0xe6, 0xc0, 0x74, 0xa8, 0x73, 0x78, 0xe2,
0x3F, 0x2D, 0xB1, 0xD6, 0x6A, 0xAD, 0x66, 0xAD, 0x7E, 0xAD, 0xa8, 0xe1, 0xc8, 0x76, 0x6c, 0x70, 0x9c, 0x70, 0xd2, 0x73, 0x4a, 0x70, 0x3a,
0x37, 0xDA, 0x7A, 0xDA, 0xBE, 0xDA, 0x62, 0xED, 0x72, 0xED, 0xe6, 0xf4, 0xc2, 0xd9, 0xc4, 0x99, 0xef, 0xdc, 0xe6, 0x3c, 0xe7, 0x62, 0xe3,
0x16, 0xED, 0xEB, 0xDA, 0xEF, 0x75, 0x70, 0x9D, 0x40, 0x9D, 0xb2, 0xde, 0xe5, 0xbc, 0x2b, 0xe2, 0xea, 0xe1, 0x5a, 0xe8, 0xda, 0xef, 0x26,
0x2C, 0x9D, 0xF5, 0x3A, 0x6D, 0x3A, 0xF7, 0x75, 0x09, 0xBA, 0xe3, 0x16, 0xe2, 0x56, 0xe9, 0xf6, 0xd8, 0x5d, 0xdd, 0x3d, 0xce, 0xbd, 0xd9,
0x36, 0xBA, 0x51, 0xBA, 0x85, 0xBA, 0xDB, 0x75, 0xCF, 0xEA, 0x7d, 0xc6, 0xc3, 0xc2, 0x63, 0x9d, 0xc7, 0x79, 0x4f, 0xb4, 0xa7, 0xb7, 0xe7,
0x3E, 0xD3, 0x63, 0xEB, 0x79, 0xE9, 0x09, 0xF5, 0xCA, 0xF5, 0x6e, 0xcf, 0x61, 0x2f, 0x65, 0x2f, 0x96, 0x57, 0xa3, 0xd7, 0xcc, 0x0a, 0xab,
0x0E, 0xE9, 0xDD, 0xD1, 0x47, 0xF5, 0x6D, 0xF4, 0xA3, 0xF5, 0x15, 0xeb, 0x57, 0xf4, 0x78, 0x93, 0xbc, 0x83, 0xbc, 0x2b, 0xbd, 0x9f, 0xf8,
0x17, 0xEA, 0xEF, 0xD6, 0xEF, 0xD1, 0x1F, 0x37, 0x30, 0x34, 0xe8, 0xfb, 0xf0, 0x7d, 0xba, 0x7c, 0x61, 0xdf, 0x15, 0xbe, 0x7b, 0x7c, 0x1f,
0x08, 0x36, 0x90, 0x19, 0x6C, 0x31, 0x38, 0x63, 0xF0, 0xCC, 0xae, 0xd4, 0x5a, 0xc9, 0x5b, 0xd9, 0xe1, 0x07, 0xfc, 0xbc, 0xfc, 0xf6, 0xf8,
0x90, 0x63, 0xE8, 0x6B, 0x98, 0x69, 0xB8, 0xD1, 0xF0, 0x84, 0x3d, 0xf2, 0xd7, 0xf1, 0x4f, 0xf3, 0xff, 0x3e, 0x00, 0x13, 0xe0, 0x1f, 0x50,
0xE1, 0xA8, 0x11, 0xCB, 0x68, 0xBA, 0x91, 0xC4, 0x68, 0xA3, 0x15, 0xf0, 0x34, 0xd0, 0x34, 0x30, 0x37, 0xb0, 0x37, 0x88, 0x12, 0x14, 0x15,
0xD1, 0x49, 0xA3, 0x27, 0xB8, 0x26, 0xEE, 0x87, 0x67, 0xE3, 0xd4, 0x14, 0xf4, 0x26, 0xd8, 0x39, 0xb8, 0x24, 0xf8, 0x41, 0x88, 0x6e, 0x88,
0x35, 0x78, 0x17, 0x3E, 0x66, 0xAC, 0x6F, 0x1C, 0x62, 0xAC, 0x30, 0xa4, 0x3b, 0x54, 0x32, 0x34, 0x32, 0xb4, 0x31, 0x74, 0x2e, 0xcc, 0x35,
0x34, 0xDE, 0x65, 0xDC, 0x6B, 0x3C, 0x61, 0x62, 0x69, 0x32, 0xac, 0x34, 0x6c, 0x64, 0x95, 0xf1, 0xaa, 0xf5, 0xab, 0xae, 0x87, 0x2b, 0x84,
0xDB, 0xA4, 0xC4, 0xA4, 0xC5, 0xE4, 0xBE, 0x29, 0xCD, 0x94, 0x73, 0xc3, 0x3b, 0x23, 0xb0, 0x11, 0xa1, 0x11, 0x0d, 0x11, 0xb3, 0xab, 0xdd,
0x6B, 0x9A, 0x66, 0xBA, 0xD1, 0xB4, 0xD3, 0x74, 0xCC, 0xCC, 0x56, 0xef, 0x5d, 0x3d, 0x1e, 0x69, 0x11, 0x59, 0x10, 0x39, 0xb4, 0x46, 0x67,
0xC8, 0x2C, 0xDC, 0xAC, 0xD8, 0xAC, 0xC9, 0xEC, 0x8E, 0x39, 0x4d, 0xd6, 0x9a, 0xab, 0x6b, 0x15, 0xd6, 0x26, 0xad, 0x3d, 0x13, 0x25, 0x19,
0xD5, 0x9C, 0x6B, 0x9E, 0x61, 0xBE, 0xD9, 0xBC, 0xDB, 0xFC, 0xc5, 0x8c, 0x3a, 0x19, 0x8d, 0x8e, 0x0e, 0x8b, 0x6e, 0x8a, 0xfe, 0xc0, 0xf4,
0x8D, 0x85, 0xA5, 0x45, 0x9C, 0xC5, 0x4A, 0x8B, 0x36, 0x8B, 0x63, 0xd6, 0x31, 0x67, 0x63, 0xbc, 0x62, 0xaa, 0x63, 0x66, 0x58, 0x2e, 0xac,
0xC7, 0x96, 0xDA, 0x96, 0x7C, 0xCB, 0x05, 0x96, 0x4D, 0x96, 0x7d, 0xac, 0xe7, 0x6c, 0x47, 0x76, 0x19, 0x7b, 0x8a, 0x63, 0xc7, 0x29, 0xe5,
0xF7, 0xAC, 0x98, 0x56, 0x3E, 0x56, 0x79, 0x56, 0xF5, 0x56, 0x4c, 0xc4, 0xda, 0xc5, 0x96, 0xc6, 0x4e, 0xc6, 0xd9, 0xc5, 0xed, 0x89, 0x9b,
0xD7, 0xAC, 0x49, 0xD6, 0x5C, 0xEB, 0x2C, 0xEB, 0x6D, 0xD6, 0x8a, 0x77, 0x88, 0x2f, 0x8f, 0x9f, 0xe6, 0xba, 0x70, 0x2b, 0xb9, 0x2f, 0x13,
0x57, 0x6C, 0x50, 0x1B, 0x57, 0x9B, 0x0C, 0x9B, 0x3A, 0x9B, 0x3c, 0x13, 0x6a, 0x12, 0xe6, 0x12, 0xfd, 0x12, 0x8f, 0x24, 0x2e, 0x24, 0x85,
0xCB, 0xB6, 0xA8, 0xAD, 0x9B, 0xAD, 0xC4, 0x76, 0x9B, 0x6D, 0x25, 0xb5, 0x26, 0xe3, 0x92, 0xa3, 0x93, 0x4f, 0xf1, 0x64, 0x78, 0x89, 0xbc,
0xDF, 0x14, 0xE2, 0x14, 0x8F, 0x29, 0xD2, 0x29, 0xF5, 0x53, 0x9e, 0x14, 0x95, 0x94, 0xac, 0x94, 0x81, 0x54, 0x83, 0xd4, 0x82, 0xd4, 0x91,
0x6E, 0xDA, 0x31, 0xEC, 0xFC, 0xEC, 0x0A, 0xEC, 0x9A, 0xEC, 0x34, 0x9b, 0xb4, 0xbd, 0x69, 0x33, 0x7c, 0x6f, 0x7e, 0x43, 0x3a, 0x94, 0xbe,
0x06, 0xED, 0x39, 0xF6, 0x61, 0xF6, 0x25, 0xF6, 0x6D, 0xF6, 0x26, 0xbd, 0x53, 0x40, 0x15, 0xfd, 0x4c, 0xf5, 0x09, 0x75, 0x85, 0x5b, 0x85,
0xCF, 0x1D, 0xCC, 0x1C, 0x12, 0x1D, 0xD6, 0x3B, 0x74, 0x3B, 0xa3, 0x19, 0xf6, 0x19, 0x55, 0x19, 0x6f, 0x33, 0x43, 0x33, 0x4f, 0x66, 0x49,
0x7C, 0x72, 0x74, 0x75, 0xCC, 0x76, 0x6C, 0x70, 0xBC, 0xEB, 0x67, 0xf1, 0xb2, 0xfa, 0xb2, 0xf5, 0xb3, 0x77, 0x64, 0x4f, 0xe4, 0xb8, 0xe7,
0xA4, 0xE1, 0x34, 0xC3, 0xA9, 0xC4, 0xA9, 0xC3, 0xE9, 0x57, 0x7c, 0xbd, 0x0e, 0xb5, 0x8e, 0xb5, 0xae, 0x3b, 0x57, 0x2d, 0x77, 0x73, 0xee,
0x67, 0x1B, 0x67, 0xA1, 0x73, 0x9D, 0xF3, 0x35, 0x17, 0xA6, 0xe8, 0x7a, 0xa7, 0xf5, 0xb5, 0x1b, 0xa0, 0x0d, 0x31, 0x1b, 0xba, 0x37, 0x6a,
0x4B, 0x90, 0xCB, 0x12, 0x97, 0x76, 0x97, 0x17, 0x53, 0x6D, 0x6c, 0xcc, 0xdf, 0x38, 0xbe, 0xc9, 0x63, 0xd3, 0xd1, 0xcd, 0x84, 0xcd, 0x89,
0xA7, 0x8A, 0xA7, 0x6E, 0x9F, 0x7A, 0xCB, 0x95, 0xE5, 0x1A, 0x9b, 0x7f, 0xc8, 0x33, 0xc9, 0x2b, 0xcd, 0x7b, 0xbd, 0x25, 0x6c, 0x4b, 0x57,
0xEE, 0xBA, 0xD2, 0xB5, 0xD3, 0xF5, 0xA3, 0x9B, 0xBB, 0x9B, 0xbe, 0x72, 0xfe, 0xa6, 0xfc, 0xb1, 0xad, 0x1e, 0x5b, 0x9b, 0x0b, 0x24, 0x0a,
0xDC, 0xAD, 0xD9, 0x6D, 0xD4, 0xDD, 0xCC, 0x3D, 0xC5, 0x7D, 0xf8, 0x05, 0xc3, 0xdb, 0x6c, 0xb7, 0xd5, 0x6c, 0x47, 0x6d, 0xe7, 0x6e, 0xef,
0xAB, 0xFB, 0x4D, 0x2E, 0x9B, 0x1B, 0xC9, 0x5D, 0xC3, 0x3D, 0xdf, 0x61, 0xbe, 0x63, 0xff, 0x8e, 0x4f, 0x85, 0xec, 0xc2, 0x6b, 0x45, 0x26,
0xEF, 0x41, 0xF4, 0xF0, 0xF7, 0x58, 0xE2, 0x71, 0xCC, 0xE3, 0x45, 0xe5, 0x45, 0x1f, 0x8a, 0x59, 0xc5, 0xd7, 0xbe, 0x32, 0xfd, 0xaa, 0xe2,
0x9D, 0xA7, 0x9B, 0xA7, 0xC2, 0xF3, 0x90, 0xE7, 0x2F, 0x5E, 0xab, 0x85, 0x9d, 0xb1, 0x3b, 0xfb, 0x4b, 0x2c, 0x4b, 0x0e, 0xee, 0xc2, 0xec,
0x76, 0x5E, 0x59, 0x5E, 0xFB, 0xBD, 0x1E, 0x4F, 0xB3, 0x9C, 0xe2, 0xed, 0x1a, 0xda, 0xed, 0xb0, 0xfb, 0x68, 0xa9, 0x74, 0x69, 0x4e, 0xe9,
0x26, 0x9E, 0xD6, 0x30, 0x6D, 0xC8, 0xDB, 0xC4, 0x5B, 0xE0, 0xd8, 0x1e, 0xdf, 0x3d, 0xed, 0x65, 0xf4, 0xb2, 0xc2, 0xb2, 0xd7, 0x7b, 0xa3,
0xBD, 0xCB, 0x7B, 0x60, 0x3A, 0x3E, 0x3D, 0x65, 0xFA, 0xCE, 0xf6, 0x5e, 0x2d, 0x5f, 0x56, 0x5e, 0xb3, 0x8f, 0xb0, 0x4f, 0xb8, 0x6f, 0xa4,
0xE9, 0x03, 0x3E, 0xC6, 0x3E, 0x02, 0x9F, 0x7A, 0x9F, 0x87, 0xc2, 0xa7, 0xa2, 0x73, 0xbf, 0xe6, 0xfe, 0x5d, 0xfb, 0x3f, 0x54, 0xc6, 0x57,
0xBE, 0xA6, 0xBE, 0x22, 0xDF, 0x3D, 0xBE, 0x23, 0x7E, 0xD6, 0xde, 0xa9, 0x72, 0xae, 0x6a, 0xad, 0x56, 0xaa, 0xde, 0x51, 0x3d, 0x77, 0x80,
0x7E, 0x99, 0x7E, 0x07, 0xFC, 0x9E, 0xFB, 0x3B, 0xFA, 0xCB, 0x7d, 0x60, 0xf0, 0xa0, 0xe3, 0xc1, 0x96, 0x1a, 0xe5, 0x9a, 0xa2, 0x9a, 0xf7,
0xFD, 0x8F, 0xF8, 0xBF, 0xE1, 0x79, 0xF2, 0x16, 0xF1, 0x4E, 0x87, 0xb8, 0x87, 0xee, 0xd6, 0x7a, 0xd4, 0xb6, 0xd7, 0x69, 0xd7, 0x95, 0x1f,
0x05, 0x60, 0x01, 0xC1, 0x01, 0xE5, 0x01, 0xBD, 0x81, 0x1A, 0xc6, 0x1c, 0xce, 0x38, 0xfc, 0xb4, 0x3e, 0xb4, 0xbe, 0xf7, 0x6b, 0xc6, 0xd7,
0x81, 0xB3, 0x03, 0x6B, 0x03, 0x1F, 0x04, 0x99, 0x04, 0xA5, 0x8d, 0x0d, 0x0a, 0x0d, 0x45, 0x0d, 0x1f, 0x8f, 0xf0, 0x8e, 0x8c, 0x1c, 0x0d,
0x07, 0x35, 0x05, 0x8D, 0x05, 0xBB, 0x06, 0x2F, 0x0C, 0x3E, 0x3c, 0xda, 0xd3, 0x68, 0xd5, 0xd8, 0xd8, 0xa4, 0xd4, 0x54, 0xd2, 0x0c, 0x37,
0x15, 0x42, 0x0C, 0x09, 0x0D, 0x59, 0x1F, 0x72, 0x93, 0x6F, 0x0b, 0x9b, 0xa7, 0x8e, 0x45, 0x1e, 0xbb, 0xf9, 0x8d, 0xeb, 0x37, 0x9d, 0x2d,
0xC0, 0x17, 0xF2, 0x1B, 0xF9, 0x63, 0x33, 0xDC, 0x67, 0x2C, 0x86, 0x2d, 0xb5, 0xad, 0xb4, 0xd6, 0xa2, 0xe3, 0xe0, 0xb8, 0xf0, 0xf8, 0xb3,
0x9A, 0xD1, 0x15, 0xCA, 0x08, 0x9D, 0x15, 0x5A, 0x1B, 0xFA, 0x6f, 0xa3, 0xbf, 0x1d, 0x3a, 0xe1, 0x7d, 0xa2, 0xfb, 0x24, 0xe3, 0x64, 0xcb,
0x30, 0xCC, 0x26, 0x4C, 0x1E, 0xD6, 0x11, 0x8E, 0x86, 0xCF, 0x77, 0x5a, 0xdf, 0x55, 0xb7, 0x51, 0xda, 0x0a, 0xdb, 0xa1, 0xf6, 0xec, 0xf6,
0x08, 0xDF, 0x10, 0x7E, 0x6F, 0xA6, 0xF9, 0x4C, 0xE9, 0xCC, 0x99, 0x8e, 0xf8, 0x8e, 0x91, 0xce, 0xf0, 0xce, 0x81, 0x53, 0x2b, 0x4e, 0x75,
0xB6, 0x08, 0x88, 0xE0, 0x47, 0x6C, 0x88, 0xB8, 0x1F, 0x69, 0x77, 0xd9, 0x76, 0xb5, 0x7d, 0x6f, 0xf4, 0xfd, 0x91, 0xd3, 0x6a, 0xa7, 0xab,
0x19, 0x99, 0x17, 0xF9, 0x7D, 0x14, 0x29, 0x2A, 0x32, 0xAA, 0xce, 0xc8, 0x9e, 0x29, 0x39, 0x4b, 0x38, 0x9b, 0x7f, 0x76, 0xe1, 0x5c, 0xce,
0x2E, 0xEA, 0x51, 0xB4, 0x53, 0x74, 0x71, 0x74, 0xF7, 0x2C, 0xb9, 0xd9, 0xf3, 0xa9, 0xe7, 0xa7, 0x2f, 0xc4, 0x5d, 0x18, 0xeb, 0x8e, 0xea,
0xD6, 0xAC, 0xE4, 0x59, 0xFB, 0x67, 0xBD, 0x8E, 0xF1, 0x8F, 0x7e, 0x70, 0x71, 0xd5, 0xc5, 0xdb, 0x3d, 0x01, 0x3d, 0xfd, 0x97, 0xbc, 0x2f,
0xA9, 0x8C, 0xB9, 0x3B, 0xDB, 0x6A, 0xB6, 0x72, 0x76, 0x67, 0x5d, 0xb9, 0xec, 0x7e, 0xf9, 0x62, 0xaf, 0x53, 0xef, 0xb9, 0x2b, 0x76, 0x57,
0xAC, 0x6A, 0x6C, 0x52, 0x6C, 0x63, 0xEC, 0x9B, 0xB8, 0x80, 0x4e, 0x5f, 0xb5, 0xb9, 0x7a, 0xea, 0x1a, 0xe3, 0x5a, 0xc7, 0x75, 0xcb, 0xeb,
0xB8, 0xAA, 0xB8, 0x81, 0x78, 0x87, 0xF8, 0x45, 0xF1, 0x97, 0xed, 0x7d, 0x16, 0x7d, 0x6d, 0x3f, 0x58, 0xfc, 0xd0, 0xd6, 0x6f, 0xd9, 0xdf,
0x12, 0x74, 0x13, 0x24, 0x09, 0xED, 0x89, 0xE4, 0xC4, 0xD8, 0x7e, 0xc3, 0xea, 0x46, 0xe7, 0x4d, 0xeb, 0x9b, 0x5d, 0x03, 0xcb, 0x07, 0xce,
0xC4, 0x3D, 0x89, 0xE3, 0x73, 0x02, 0xE7, 0x6C, 0x9A, 0x33, 0x0e, 0x3a, 0x0c, 0x5e, 0xb8, 0xe5, 0x7a, 0xeb, 0xf2, 0x6d, 0xaf, 0xdb, 0xd7,
0x9C, 0xE4, 0x9A, 0x54, 0x96, 0x74, 0x63, 0xAE, 0xE5, 0xDC, 0xef, 0xac, 0xbc, 0x33, 0x30, 0x14, 0x32, 0x74, 0x77, 0x38, 0x72, 0x78, 0xe4,
0xA2, 0xB9, 0x17, 0xE6, 0xE9, 0xCE, 0xCB, 0x9E, 0x77, 0x3C, 0x2e, 0xfb, 0xee, 0xe4, 0xbd, 0xa4, 0x7b, 0x2f, 0xef, 0x67, 0xdc, 0x9f, 0x7f,
0x59, 0x35, 0x59, 0x90, 0x7C, 0x38, 0x85, 0x98, 0x12, 0x97, 0xb0, 0xe9, 0x21, 0xfa, 0x61, 0xe1, 0x23, 0xa9, 0x47, 0xe5, 0x8f, 0x95, 0x1e,
0xB2, 0x3F, 0xE5, 0x83, 0x20, 0x42, 0x50, 0x2F, 0x18, 0x4F, 0xd7, 0xfd, 0xa8, 0xf7, 0x63, 0xeb, 0x88, 0xe5, 0xc8, 0x99, 0x51, 0xd7, 0xd1,
0xE5, 0xA7, 0x6E, 0x4D, 0x1D, 0x13, 0xF2, 0x84, 0x9B, 0x85, 0xbe, 0x27, 0x41, 0x4f, 0x1e, 0x8c, 0xb1, 0xc6, 0x9e, 0xff, 0x94, 0xfe, 0xd3,
0x4F, 0x45, 0xBE, 0xA2, 0x8D, 0xA2, 0x51, 0xB1, 0xB7, 0xB8, 0x87, 0xf1, 0xfc, 0xa7, 0xe4, 0xa7, 0xe5, 0x13, 0xaa, 0x13, 0x8d, 0x93, 0x66,
0x4A, 0x3C, 0x92, 0xE6, 0x9D, 0x56, 0x95, 0xF6, 0x38, 0xDD, 0x93, 0xa7, 0xa7, 0xdc, 0xa7, 0x6e, 0x3e, 0x5b, 0xfd, 0x6c, 0xfc, 0x79, 0xea,
0x3B, 0x7D, 0x43, 0xFA, 0x68, 0x86, 0x4F, 0x46, 0x75, 0xC6, 0xf3, 0xf9, 0xe9, 0x82, 0x9f, 0xa5, 0x7f, 0xae, 0x7e, 0xa1, 0xfb, 0xe2, 0xbb,
0x33, 0x09, 0x4F, 0x52, 0x2B, 0x79, 0x91, 0x19, 0x92, 0xB9, 0x5f, 0x1c, 0x7f, 0xe9, 0x9b, 0x59, 0x35, 0x33, 0xfe, 0x92, 0xff, 0x72, 0xe1,
0x23, 0xF3, 0x4D, 0x56, 0x44, 0xD6, 0xDE, 0xAC, 0xCF, 0xD9, 0xd7, 0xe2, 0x57, 0xf2, 0xaf, 0x8e, 0xbc, 0x5e, 0xf6, 0xba, 0x7b, 0xd6, 0x7f,
0x71, 0xD9, 0x2D, 0x39, 0x94, 0x9C, 0x94, 0x9C, 0xA3, 0x52, 0xf6, 0xf1, 0x9b, 0xe4, 0x37, 0xf3, 0x73, 0x85, 0x6f, 0xe5, 0xdf, 0x1e, 0x7d,
0x0D, 0x69, 0x96, 0xB4, 0x2B, 0xD7, 0x30, 0xB7, 0x28, 0xB7, 0xc7, 0x78, 0xd7, 0xfb, 0x3e, 0xec, 0xfd, 0xc4, 0x7c, 0xe6, 0x07, 0xec, 0x87,
0x4F, 0x66, 0x2B, 0x2B, 0x93, 0x0D, 0xE4, 0x79, 0xE6, 0x6D, 0x8a, 0x8f, 0x7a, 0x1f, 0xbb, 0x3e, 0x79, 0x7f, 0x7a, 0xb8, 0x90, 0xbc, 0xb0,
0xCA, 0x1B, 0x93, 0x87, 0xCA, 0xF7, 0xE4, 0x23, 0xF9, 0x73, 0xf0, 0x1b, 0xf7, 0x84, 0xf3, 0xfb, 0xe2, 0xe6, 0x1d, 0xc2, 0x00, 0x00, 0x00,
0xF3, 0xDB, 0x15, 0x6C, 0x85, 0x4C, 0xD1, 0xA3, 0xB4, 0x52, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13,
0xAE, 0x50, 0x0E, 0x16, 0x4C, 0x2F, 0xA8, 0x2B, 0x78, 0x5B, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45,
0x18, 0x5B, 0x78, 0xB8, 0x48, 0xBD, 0x48, 0x5A, 0xD4, 0x33, 0x07, 0xdd, 0x01, 0x0a, 0x02, 0x35, 0x0f, 0x01, 0xa3, 0x67, 0xcc, 0x00, 0x00,
0xDF, 0x66, 0xFE, 0xEA, 0xF9, 0x23, 0x0B, 0x82, 0x16, 0x7C, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0,
0xBD, 0x90, 0xB0, 0x50, 0xB8, 0xB0, 0xB3, 0xD8, 0xB8, 0x78, 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x05, 0x50, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19,
0x59, 0xF1, 0xE0, 0x22, 0xBF, 0x45, 0xBB, 0x16, 0x23, 0x8B, 0x6d, 0xc1, 0x5b, 0x88, 0x5c, 0x67, 0x01, 0xc0, 0xf1, 0xff, 0x77, 0x39, 0xe7,
0x53, 0x17, 0x77, 0x2E, 0x31, 0x5D, 0x52, 0xBA, 0x64, 0x78, 0xcc, 0x7d, 0x76, 0xb2, 0xd9, 0xfb, 0x36, 0xdb, 0x24, 0x9b, 0xa4, 0x4d, 0x2f,
0x69, 0xF0, 0xD2, 0x7D, 0xCB, 0x68, 0xCB, 0xB2, 0x96, 0xFD, 0xd1, 0x98, 0x62, 0x09, 0xb6, 0x25, 0x12, 0xd4, 0x3e, 0x28, 0x42, 0xd1, 0x80,
0x50, 0xE2, 0x58, 0x52, 0x55, 0xF2, 0x6A, 0x79, 0xDC, 0xF2, 0x16, 0x5f, 0x4a, 0xa5, 0x0f, 0x56, 0x51, 0x1f, 0x6a, 0x11, 0x45, 0xa8, 0x45,
0x8E, 0x52, 0x83, 0xD2, 0xA5, 0xA5, 0x43, 0x2B, 0x82, 0x57, 0x04, 0xb5, 0x68, 0xf1, 0x45, 0x9f, 0x0a, 0xb1, 0x52, 0x41, 0x6c, 0x20, 0x50,
0x34, 0x95, 0xA9, 0x94, 0xC9, 0xCB, 0x6E, 0xAE, 0xF4, 0x5A, 0x7c, 0xb0, 0x68, 0x2c, 0x69, 0x5a, 0x6a, 0xb5, 0xe2, 0x62, 0x53, 0x4c, 0x8d,
0xB9, 0x63, 0x15, 0x61, 0x95, 0x64, 0x55, 0xEF, 0x6A, 0x97, 0xb9, 0x6c, 0x92, 0x4e, 0x76, 0x27, 0x3b, 0xb3, 0x3b, 0x67, 0xce, 0x77, 0x75,
0xD5, 0x5B, 0x56, 0x7F, 0x2A, 0x17, 0x95, 0x5F, 0xAC, 0x70, 0x26, 0x2c, 0x18, 0x64, 0x7f, 0x3f, 0xc1, 0xff, 0x39, 0xfe, 0xd3, 0xc7, 0x79,
0xAC, 0xA8, 0xAE, 0xF8, 0xB0, 0x46, 0xB8, 0xE6, 0xE2, 0x57, 0xf4, 0x6b, 0xbf, 0x64, 0xe4, 0x17, 0x3f, 0xfa, 0x8a, 0xb8, 0xff, 0xbe, 0x03,
0x4E, 0x5F, 0xD5, 0x7C, 0xF5, 0x79, 0x6D, 0xDA, 0xDA, 0xDE, 0xa2, 0xb3, 0x72, 0x59, 0x38, 0x6b, 0xc5, 0xee, 0x5d, 0x3b, 0xc5, 0xf2, 0xf2,
0x4A, 0xB7, 0xCA, 0xED, 0xEB, 0x48, 0xEB, 0xA4, 0xEB, 0x6E, 0x55, 0xdd, 0x5e, 0xed, 0x4e, 0xb4, 0xc6, 0xc7, 0x67, 0xc7, 0x5b, 0x63, 0xf3,
0xAC, 0xF7, 0x59, 0xBF, 0xAF, 0x4A, 0xBD, 0x6A, 0x41, 0xD5, 0x52, 0x30, 0xf5, 0xfe, 0xf9, 0x0b, 0x63, 0x4a, 0xca, 0xfd, 0xf3, 0x3b, 0x76,
0xD0, 0x86, 0xF0, 0x0D, 0xAD, 0x1B, 0xF1, 0x8D, 0xE5, 0x1B, 0x9f, 0x98, 0x9c, 0x9c, 0xff, 0xdd, 0xe4, 0xde, 0xa3, 0x56, 0xb0, 0x85, 0x1f,
0x5F, 0x6D, 0x4A, 0xDE, 0x74, 0xA1, 0x7A, 0x6A, 0xF5, 0x8E, 0x7e, 0xeb, 0xd3, 0xfa, 0xd0, 0x81, 0x7b, 0xa6, 0xd3, 0x72, 0xf5, 0xae, 0xe9,
0xCD, 0xB4, 0xCD, 0xCA, 0xCD, 0x03, 0x35, 0x61, 0x35, 0xED, 0xa9, 0x89, 0xbd, 0xbd, 0x6e, 0x67, 0x97, 0x75, 0x76, 0x71, 0x7e, 0x66, 0x7a,
0x5B, 0xCC, 0xB6, 0xAC, 0xDB, 0xF2, 0xA1, 0x36, 0xA3, 0xF6, 0xb7, 0x92, 0xcc, 0xa4, 0x89, 0x1a, 0xd3, 0x5a, 0x90, 0x17, 0x16, 0x81, 0xa2,
0x7A, 0x9D, 0x7F, 0x5D, 0xCB, 0x56, 0xFD, 0xAD, 0xAB, 0xB7, 0x35, 0xbe, 0x8d, 0x68, 0xd6, 0xb0, 0x62, 0xf2, 0xf9, 0x98, 0x4e, 0x3d, 0x55,
0xBE, 0xD9, 0x26, 0xDA, 0xD6, 0xBF, 0xDD, 0x77, 0x7B, 0xF3, 0x9b, 0x3d, 0x98, 0x6b, 0xb6, 0x30, 0xd6, 0x68, 0x1e, 0x59, 0x58, 0x98, 0x39,
0x0E, 0x83, 0x1D, 0x15, 0x3B, 0xDE, 0xEF, 0x94, 0xEC, 0xBC, 0x3e, 0x3d, 0xd1, 0x98, 0xf4, 0x76, 0xc0, 0x6d, 0x33, 0xf3, 0xa4, 0x59, 0x42,
0xB5, 0x2B, 0x78, 0x57, 0x6B, 0xBD, 0x45, 0x7D, 0xF5, 0x6E, 0xc8, 0x7b, 0xa8, 0x34, 0xc3, 0x78, 0x4f, 0xbb, 0xdd, 0x8f, 0xa5, 0x52, 0x49,
0xD2, 0xEE, 0x82, 0xDD, 0x8F, 0x1A, 0x62, 0x1B, 0xBA, 0xBF, 0x54, 0x4a, 0x8a, 0x58, 0x74, 0x58, 0x5b, 0xbd, 0x4e, 0xac, 0x54, 0x72, 0xad,
0xE6, 0x7E, 0xDD, 0xB8, 0x47, 0x77, 0x4F, 0xC5, 0x9E, 0x8F, 0x27, 0x22, 0x43, 0x9a, 0x2d, 0xcc, 0xcd, 0x4e, 0x4f, 0xd5, 0xeb, 0x49, 0x96,
0x7B, 0xA5, 0x7B, 0x07, 0xF6, 0x45, 0xEF, 0xEB, 0x6A, 0x74, 0x48, 0x87, 0x8f, 0x91, 0x41, 0xaf, 0x4b, 0x7f, 0x2d, 0x22, 0xb5, 0xc2, 0xf5,
0x6F, 0x6C, 0xDC, 0xAF, 0xBF, 0xBF, 0xB2, 0x09, 0x6D, 0x52, 0x06, 0x9c, 0x3d, 0xb7, 0x4c, 0x56, 0x69, 0x8a, 0x83, 0xfb, 0x9b, 0x58, 0x5b,
0x36, 0x8D, 0x1E, 0x48, 0x3A, 0x70, 0xE5, 0x9B, 0x80, 0x6F, 0xe0, 0x7c, 0xc4, 0xb9, 0x40, 0xb4, 0x45, 0x2a, 0x4c, 0x4f, 0x30, 0x24, 0xd9,
0xDA, 0x9B, 0xED, 0x9A, 0x77, 0xB5, 0x70, 0x5A, 0x2A, 0x0E, 0xc2, 0x7a, 0x3f, 0x1f, 0x0c, 0xd6, 0x07, 0xc6, 0xe4, 0x39, 0xc2, 0xae, 0xa3,
0xC2, 0x41, 0xE5, 0xC1, 0x27, 0xDF, 0xA6, 0x7C, 0x7B, 0xE3, 0xc2, 0x06, 0x99, 0xc8, 0xa9, 0x48, 0xc3, 0xa9, 0x33, 0x4b, 0xbc, 0xfc, 0xfb,
0x50, 0xE8, 0xA1, 0xCE, 0xC3, 0xDC, 0xC3, 0xCD, 0xDF, 0x99, 0xb7, 0x30, 0xc6, 0x22, 0x12, 0x45, 0x8c, 0x82, 0x10, 0x22, 0xce, 0x3b, 0x8c,
0x7F, 0xB7, 0xF5, 0x08, 0xEB, 0x48, 0x79, 0x2B, 0xD2, 0x3A, 0x19, 0x54, 0xf3, 0x7e, 0x57, 0x30, 0xa4, 0xd9, 0x42, 0xb1, 0xd1, 0xb1, 0x29,
0xBF, 0x75, 0xAC, 0x2D, 0xA3, 0x6D, 0xA0, 0x3D, 0xA1, 0xBD, 0x7d, 0x17, 0x5d, 0x89, 0xce, 0x40, 0x53, 0x84, 0x04, 0xa5, 0x04, 0x35, 0x17,
0xEF, 0xE8, 0x8C, 0xA3, 0x9D, 0x1D, 0x5E, 0x1D, 0x47, 0xBE, 0x58, 0x5d, 0xb9, 0x81, 0x70, 0x39, 0x49, 0x22, 0x41, 0x08, 0x46, 0x82, 0xf7,
0xB7, 0xFF, 0x7E, 0xEF, 0x31, 0xE3, 0x63, 0x75, 0xC7, 0x35, 0x58, 0x6b, 0x40, 0xf9, 0x92, 0xf0, 0x5e, 0x30, 0xa4, 0xb9, 0xc5, 0x0f, 0x5e,
0x8F, 0x57, 0x9E, 0xA0, 0x9D, 0x28, 0x3D, 0xF1, 0xF9, 0xE4, 0x3a, 0xc5, 0xd3, 0xc7, 0x1e, 0x84, 0x7c, 0x75, 0xe3, 0x72, 0xbf, 0x36, 0x68,
0x82, 0x93, 0xE3, 0xA7, 0x64, 0xA7, 0x9E, 0x9D, 0x4E, 0x3F, 0x9b, 0xdd, 0x5c, 0xc8, 0xc7, 0x30, 0x21, 0x41, 0x29, 0x49, 0x3d, 0xf5, 0x5c,
0x3D, 0xD4, 0x99, 0xDC, 0x79, 0xF7, 0x4C, 0xFC, 0x99, 0x6B, 0x88, 0xd7, 0xb0, 0x72, 0x15, 0x11, 0x03, 0x23, 0x11, 0xf0, 0xce, 0x61, 0x8b,
0x5D, 0x51, 0x5D, 0xBD, 0x67, 0x43, 0xCF, 0x9E, 0x3F, 0x17, 0x02, 0x9d, 0x85, 0x54, 0x4a, 0xc1, 0x88, 0x66, 0xd3, 0x93, 0xcf, 0x3c, 0xc7,
0x74, 0xEE, 0x4C, 0xB7, 0x5F, 0xF7, 0xC9, 0xF3, 0xDE, 0xE7, 0xd3, 0xc7, 0x1e, 0x64, 0xa4, 0x73, 0xd7, 0xd7, 0xef, 0x3d, 0x6d, 0xc7, 0xe7,
0x8F, 0x5D, 0xF0, 0xBC, 0x70, 0xF4, 0x22, 0xF7, 0x62, 0xDB, 0x6c, 0xa8, 0x83, 0x02, 0xa9, 0x05, 0x51, 0x6b, 0x7a, 0x3a, 0x61, 0x99, 0x05,
0x25, 0xB7, 0x4B, 0xAD, 0x3D, 0xAE, 0x3D, 0x47, 0x7E, 0x70, 0xae, 0xc7, 0x35, 0x0a, 0x51, 0x01, 0xe1, 0x20, 0x82, 0x75, 0x16, 0x6b, 0x0a,
0xFD, 0xE1, 0x48, 0xAF, 0x5B, 0x6F, 0xEB, 0x65, 0xF7, 0xCB, 0x54, 0x08, 0x52, 0x10, 0x05, 0x43, 0x9a, 0x4d, 0xd3, 0xfb, 0x0e, 0x31, 0xf2,
0xED, 0x57, 0x3C, 0xAE, 0x74, 0xF4, 0x4D, 0xEB, 0x3B, 0xD1, 0xb3, 0x93, 0x67, 0x1e, 0xd2, 0xb5, 0xd6, 0x37, 0xd0, 0xa5, 0x34, 0x8d, 0x16,
0xEF, 0xD3, 0x7F, 0xFA, 0x6A, 0xC0, 0xD5, 0x73, 0xD7, 0xF8, 0x25, 0x04, 0x5a, 0x29, 0x92, 0x44, 0x23, 0x55, 0x42, 0x39, 0x53, 0x90, 0xd4,
0xD7, 0x2E, 0x5D, 0x9F, 0x79, 0xBD, 0xEF, 0xC6, 0xEC, 0x1B, 0x08, 0x32, 0x01, 0x02, 0x21, 0x06, 0x9c, 0xb3, 0x18, 0x6b, 0x48, 0x7d, 0x10,
0xB7, 0x6E, 0x26, 0xDD, 0x1C, 0xB8, 0x25, 0xBA, 0xF5, 0xF8, 0x31, 0x70, 0x93, 0x66, 0xd3, 0xb7, 0x3f, 0xff, 0x00, 0x5f, 0xfa, 0xe6, 0xf7,
0x76, 0xF6, 0xED, 0x17, 0x77, 0x0A, 0xEE, 0x4C, 0xDC, 0x5D, 0xa6, 0x62, 0x14, 0x4f, 0xd4, 0x6b, 0xb5, 0x39, 0x67, 0x0b, 0x84, 0xd0, 0x31,
0x7A, 0x8F, 0x78, 0xAF, 0xFC, 0xBE, 0xDA, 0xFD, 0xEA, 0x07, 0x49, 0x52, 0x21, 0x75, 0x06, 0x52, 0x51, 0x4a, 0x34, 0xa9, 0x56, 0x24, 0x0a,
0xFA, 0x0F, 0xEA, 0x7F, 0xB4, 0xFE, 0xB1, 0x65, 0xC0, 0x6D, 0x84, 0xe0, 0xa6, 0xe0, 0x3d, 0xd6, 0x58, 0x9c, 0x29, 0xf0, 0xd1, 0x83, 0xe4,
0xE0, 0xF8, 0x60, 0xC0, 0x60, 0xCF, 0xC3, 0x59, 0x0F, 0xEF, 0x26, 0xc9, 0xd0, 0x23, 0x4f, 0x7e, 0x87, 0x91, 0x03, 0x87, 0x8f, 0xdc, 0x56,
0x0E, 0x09, 0x87, 0x9E, 0xFE, 0x94, 0xFF, 0xD3, 0x87, 0xE1, 0x6d, 0x36, 0x8e, 0xa4, 0x5a, 0x91, 0x4a, 0x19, 0xab, 0x59, 0x26, 0x84, 0x80,
0xD2, 0x47, 0xCC, 0x47, 0xD5, 0x23, 0x46, 0x23, 0x8D, 0x8F, 0x4e, 0xfb, 0x22, 0x2b, 0xd7, 0x2e, 0x71, 0x63, 0xa3, 0x87, 0x4a, 0x4a, 0x94,
0x9D, 0x1F, 0x1F, 0x1B, 0x0D, 0x1A, 0xBD, 0xF2, 0x64, 0xCE, 0x4a, 0x25, 0xa4, 0x94, 0x10, 0x23, 0xce, 0x59, 0xac, 0x35, 0x18, 0x53, 0x40,
0x93, 0xE1, 0xA7, 0xB2, 0xA7, 0x13, 0xCF, 0xCA, 0x7E, 0x56, 0x8c, 0x48, 0xa9, 0x18, 0xd1, 0x0c, 0xfd, 0xf6, 0xf9, 0x67, 0x18, 0xf1, 0xde,
0xFF, 0x79, 0xEB, 0x73, 0xAB, 0xE7, 0xDF, 0xFD, 0xE2, 0xFB, 0xef, 0xa9, 0x64, 0xe5, 0xa9, 0x44, 0x69, 0x54, 0xb9, 0x2c, 0x92, 0xac, 0xc2,
0x4B, 0xCF, 0x58, 0xFC, 0xD8, 0xF0, 0x0B, 0xF9, 0x8B, 0xCF, 0xda, 0xf2, 0xfb, 0x94, 0xdb, 0xa7, 0xd9, 0xa1, 0x2f, 0xd1, 0xde, 0xb8, 0x93,
0xBF, 0xAE, 0x79, 0xA9, 0xF3, 0x72, 0xEF, 0xAB, 0xA9, 0xAF, 0xde, 0xba, 0x21, 0x1f, 0x58, 0x42, 0x08, 0x20, 0x24, 0xce, 0x3a, 0x9c, 0x31,
0x3A, 0xC7, 0x23, 0xC7, 0x1F, 0xBC, 0xCE, 0x79, 0x3D, 0xF1, 0x58, 0x63, 0x71, 0xce, 0x2b, 0xef, 0x3c, 0x23, 0x9a, 0xff, 0x11, 0x69, 0x9a,
0xA6, 0xFC, 0xAD, 0xCE, 0xDB, 0x7D, 0xEF, 0xB8, 0xEF, 0xBA, 0xaa, 0x4a, 0xad, 0x4a, 0x92, 0xa5, 0x08, 0x40, 0x66, 0x55, 0xca, 0x49, 0xa4,
0xDF, 0xC7, 0xBD, 0x1F, 0x99, 0x28, 0xFC, 0x40, 0xFE, 0x50, 0x92, 0x59, 0xa6, 0xfc, 0x65, 0x52, 0xdd, 0xc4, 0xac, 0x47, 0x6e, 0xac, 0xf5,
0xF3, 0xD1, 0xFA, 0x63, 0xC7, 0xA7, 0xD0, 0x4F, 0xF7, 0x3E, 0x48, 0xf4, 0x14, 0x48, 0xb0, 0x45, 0x81, 0x75, 0x86, 0xe0, 0x3d, 0x45, 0xde,
0xE7, 0x7C, 0xFE, 0xFC, 0x2F, 0xF7, 0x84, 0xF3, 0xFB, 0x25, 0xaf, 0x6c, 0xf4, 0x56, 0x05, 0x43, 0x72, 0xef, 0xde, 0xbd, 0x42, 0x29, 0x95,
0xD2, 0x9F, 0x33, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, 0x00, 0xc9, 0xf9, 0xb3, 0x4b, 0xb9, 0x54, 0xbe, 0xa8, 0x37, 0xca, 0x0c, 0xf2,
0x41, 0x00, 0x00, 0xB1, 0x8E, 0x7C, 0xFB, 0x51, 0x93, 0x00, 0x01, 0xd7, 0x96, 0x2f, 0xd1, 0xcd, 0x23, 0x79, 0x79, 0x81, 0x0b, 0xad, 0x4f,
0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4D, 0x00, 0x00, 0x7A, 0xb2, 0x5e, 0xbf, 0x93, 0x72, 0x9a, 0x50, 0xae, 0x56, 0xf9, 0xdb, 0xb9, 0x82,
0x25, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xF9, 0xFF, 0x00, 0xfe, 0xca, 0x00, 0x29, 0x03, 0xd6, 0x58, 0x9c, 0xb7, 0x38, 0x9b, 0xd7, 0xcc,
0x00, 0x80, 0xE9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xEA, 0xa0, 0x27, 0x19, 0xd2, 0x49, 0x92, 0x64, 0x43, 0xf3, 0xfd, 0x7e, 0xbf, 0xfc,
0x60, 0x00, 0x00, 0x3A, 0x98, 0x00, 0x00, 0x17, 0x6F, 0x92, 0xea, 0xcb, 0xbf, 0xee, 0xcd, 0xec, 0xdc, 0x75, 0x6e, 0xe7, 0xfe, 0x0f, 0xed,
0x5F, 0xC5, 0x46, 0x00, 0x00, 0x06, 0x23, 0x49, 0x44, 0x41, 0xbf, 0x72, 0xe9, 0x62, 0x8c, 0x21, 0x08, 0x9d, 0x55, 0x18, 0xd4, 0xee, 0x60,
0x54, 0x78, 0xDA, 0x64, 0x96, 0x4B, 0x6C, 0x5D, 0x47, 0x19, 0x23, 0x15, 0xa8, 0xac, 0x46, 0x56, 0xeb, 0x50, 0xcd, 0x7a, 0x9c, 0x39, 0x37,
0xC7, 0x7F, 0x73, 0x66, 0xCE, 0x39, 0xF7, 0xDC, 0x97, 0xEF, 0xe0, 0xf0, 0x9e, 0x0d, 0xe6, 0x6b, 0x01, 0x6b, 0x0c, 0xd6, 0x58, 0x82, 0xf7,
0xBD, 0x7E, 0x25, 0x7E, 0x34, 0x71, 0x1C, 0xDB, 0xB1, 0x93, 0x69, 0x0c, 0x81, 0x11, 0xbd, 0xb8, 0xb8, 0x58, 0x5c, 0xbd, 0x7a, 0xb5, 0x3f,
0x34, 0xB8, 0x09, 0x45, 0x11, 0xB4, 0x42, 0x3C, 0x04, 0x24, 0x34, 0xf7, 0xf7, 0xd7, 0xff, 0xd8, 0xbf, 0xfd, 0xee, 0x8f, 0x9c, 0xaa, 0x8e,
0x08, 0x95, 0xAA, 0x6C, 0x11, 0x3B, 0x24, 0x58, 0xB0, 0x62, 0xcf, 0xde, 0xd1, 0xda, 0x3e, 0x29, 0xb1, 0x06, 0x95, 0x68, 0xa4, 0xca, 0x08,
0xC1, 0x06, 0x58, 0x95, 0x15, 0x6B, 0x04, 0x95, 0x90, 0x22, 0x2a, 0x25, 0x2d, 0x67, 0xdc, 0x7b, 0xe8, 0x7e, 0xba, 0x9d, 0x15, 0xa4, 0x5f,
0x45, 0x42, 0x20, 0x84, 0x84, 0x5A, 0x90, 0xA2, 0xB4, 0xA1, 0x47, 0x10, 0x31, 0xc6, 0x60, 0x9d, 0xc1, 0x59, 0x43, 0x8c, 0x51, 0x0b, 0x10,
0x0A, 0x10, 0xDA, 0xF4, 0x45, 0x5A, 0x35, 0x4D, 0x1B, 0x39, 0x0c, 0xc9, 0x13, 0x27, 0x4e, 0xc4, 0x95, 0x95, 0x95, 0x2b, 0x4a, 0x29, 0x07,
0x76, 0xDD, 0xD8, 0x71, 0x62, 0xFB, 0x3A, 0xBE, 0xCF, 0x73, 0x4c, 0xbe, 0xfd, 0xca, 0xaf, 0xde, 0x5e, 0x3d, 0xfb, 0xc6, 0xf9, 0x46, 0x73,
0xCE, 0xCC, 0x9C, 0x61, 0x71, 0x93, 0x6B, 0x94, 0x8C, 0x34, 0x9c, 0xe6, 0xd4, 0x1c, 0xb5, 0x7a, 0x83, 0x4a, 0x39, 0xa1, 0x94, 0x06, 0x94,
0xCB, 0xF9, 0xFF, 0xBE, 0xEF, 0xFF, 0x9F, 0x4F, 0x33, 0xE2, 0x70, 0x6c, 0x9b, 0x9e, 0xa6, 0xdc, 0x68, 0xe1, 0xd1, 0xf8, 0x10, 0xb0, 0xb6,
0xE7, 0x3F, 0x7E, 0x96, 0x47, 0x97, 0xD6, 0x29, 0x23, 0x23, 0xc0, 0x59, 0x8b, 0xb3, 0x86, 0xe8, 0x5d, 0x1a, 0xbc, 0x15, 0x0c, 0x49, 0x86,
0xFB, 0xC9, 0x9C, 0xE0, 0xE0, 0xF4, 0x1C, 0x4F, 0x9D, 0x38, 0x4a, 0x43, 0xc0, 0x0e, 0xa0, 0x25, 0xdd, 0x7a, 0xb2, 0xa8, 0x2f, 0x9a, 0xf2,
0xC6, 0xC5, 0x0B, 0x2F, 0xB3, 0xBE, 0xD9, 0xE0, 0x9B, 0x67, 0xd5, 0xd7, 0x58, 0xbb, 0x7e, 0x99, 0x90, 0x8d, 0xa1, 0x1a, 0xdb, 0x48, 0xeb,
0x5E, 0xE0, 0xED, 0x37, 0xFE, 0xE5, 0xE5, 0x72, 0xB2, 0x36, 0xe3, 0xe8, 0x7a, 0x03, 0xab, 0xaa, 0xb1, 0x30, 0x0e, 0xf3, 0xc1, 0x7b, 0xb8,
0x36, 0x31, 0x39, 0x5A, 0xAB, 0x96, 0xC6, 0x47, 0x07, 0x6B, 0xbc, 0x8b, 0xf3, 0x22, 0x3a, 0x63, 0xa2, 0x19, 0x6c, 0x20, 0x94, 0xd2, 0x49,
0xFB, 0xEE, 0x6D, 0x6D, 0xD5, 0x56, 0x3E, 0xBD, 0x5D, 0xA9, 0x56, 0x66, 0x44, 0x33, 0xe4, 0xbd, 0x77, 0xde, 0xfb, 0x15, 0x60, 0x31, 0x88,
0xD5, 0x2A, 0x33, 0x33, 0xB3, 0x4F, 0xFE, 0xF6, 0xC0, 0x89, 0x54, 0x4e, 0x4c, 0x2f, 0x24, 0xb3, 0xee, 0x5d, 0x2e, 0xbe, 0xfe, 0x02, 0xed,
0xE7, 0x2E, 0x03, 0x28, 0x6B, 0xED, 0x63, 0x00, 0x6B, 0x2D, 0xd9, 0x07, 0x48, 0x26, 0xf6, 0x80, 0xae, 0x44, 0x7c, 0x5f, 0x0c, 0xae, 0x9f,
0xA9, 0x36, 0x44, 0xB9, 0xD2, 0x50, 0x2E, 0x0C, 0x8F, 0x26, 0x13, 0xd9, 0x7f, 0x4e, 0x52, 0xc9, 0xaf, 0x10, 0xfd, 0x3c, 0x85, 0x0d, 0xf4,
0x49, 0xF7, 0xD0, 0xC2, 0xC2, 0xFC, 0xD4, 0x91, 0x2C, 0x3B, 0x3a, 0xd7, 0x44, 0x73, 0x62, 0x81, 0x52, 0x75, 0xec, 0xd9, 0x6d, 0xb3, 0xfb,
0x34, 0x56, 0xCD, 0x0E, 0x7D, 0xF7, 0xEC, 0xE9, 0x7D, 0xBE, 0xba, 0x0c, 0x69, 0x86, 0xec, 0x50, 0xab, 0xd5, 0x7a, 0xb3, 0xd7, 0x5b, 0x9f,
0xF2, 0x46, 0xF3, 0x39, 0x3F, 0x9F, 0x68, 0x4D, 0x92, 0xA6, 0x4d, 0x12, 0xfd, 0x99, 0x3c, 0x96, 0xb6, 0x17, 0xb6, 0x4b, 0x63, 0xe3, 0x1d,
0xCC, 0x1E, 0x1C, 0xE1, 0xE9, 0x93, 0x47, 0xE8, 0xEE, 0x6E, 0xcc, 0x3f, 0xdf, 0x81, 0x7f, 0x4f, 0xa2, 0x2a, 0x2d, 0x51, 0xa9, 0x34, 0xd6,
0xE0, 0xA2, 0x91, 0xAB, 0x40, 0x0F, 0x10, 0x45, 0xD1, 0x63, 0xe6, 0xe6, 0xe7, 0x5e, 0xfb, 0x6b, 0xa7, 0x7d, 0x69, 0xe9, 0x5f, 0xed, 0xf1,
0x00, 0x63, 0x2C, 0xE3, 0x63, 0xFB, 0x5E, 0x3C, 0xF3, 0xF5, 0xcf, 0xe6, 0xf6, 0x21, 0x5d, 0xb4, 0x27, 0x2a, 0x63, 0x33, 0x45, 0x6b, 0x7a,
0x67, 0x7E, 0xA6, 0xA4, 0xC5, 0x59, 0xCD, 0xD4, 0xC4, 0x1C, 0xf1, 0xcb, 0xf7, 0x7c, 0xec, 0xd8, 0x8b, 0x69, 0x73, 0x8f, 0xff, 0xea, 0x87,
0x41, 0xA8, 0xC8, 0x3A, 0x0D, 0x3C, 0xE9, 0x83, 0x2F, 0xA9, 0x41, 0x0c, 0x11, 0x63, 0x64, 0x53, 0x5d, 0xa7, 0xd9, 0x27, 0x1e, 0x3b, 0x76,
0x6F, 0xB5, 0x48, 0x8C, 0x47, 0x21, 0x0A, 0x09, 0x03, 0x87, 0xe4, 0x89, 0x47, 0x8e, 0xec, 0x38, 0x5a, 0x4e, 0xc2, 0x8d, 0x52, 0x6d, 0xfb,
0x6E, 0xDE, 0xA5, 0xB9, 0xB3, 0x85, 0xEF, 0xEB, 0x38, 0xFF, 0x9f, 0x83, 0xb7, 0xa7, 0xab, 0xcd, 0xc9, 0xd3, 0x97, 0x97, 0xfe, 0xb4, 0x74,
0x40, 0x4B, 0xD5, 0x06, 0x47, 0x1F, 0x03, 0x48, 0xBF, 0xC8, 0xdf, 0x47, 0x0f, 0x9b, 0xa3, 0x8f, 0xbf, 0x60, 0x17, 0xe6, 0x9b, 0x1f, 0xff,
0xC4, 0xD8, 0xE8, 0xE9, 0xEA, 0x50, 0x48, 0xBC, 0xB3, 0x8B, 0xc2, 0xa7, 0xf6, 0xfd, 0xe6, 0xd0, 0xdd, 0x0b, 0x74, 0x6c, 0xf3, 0xb1, 0x83,
0x11, 0x90, 0xB4, 0x76, 0xE9, 0x36, 0x1C, 0x42, 0x08, 0x8A, 0x0f, 0x3f, 0xf5, 0x12, 0x9b, 0xba, 0x1f, 0x2c, 0x71, 0xd3, 0xdc, 0xdc, 0x1c,
0x05, 0xC9, 0xD6, 0x7A, 0x9D, 0xE5, 0x3B, 0x1D, 0x8E, 0x1F, 0xb7, 0x10, 0x07, 0x16, 0xb7, 0xa5, 0xef, 0xbe, 0x79, 0x7c, 0xea, 0xca, 0x3f,
0x99, 0x24, 0xF0, 0x0C, 0xD6, 0x81, 0x36, 0x19, 0x5A, 0x5B, 0x5e, 0xac, 0xfd, 0xe5, 0xe4, 0xf7, 0xd5, 0xd2, 0x1f, 0x7e, 0x2c, 0x63, 0xff,
0xA4, 0x49, 0xD4, 0x43, 0x2D, 0x2F, 0xCB, 0x2C, 0x8F, 0x6E, 0x3d, 0x6e, 0xf5, 0x93, 0xef, 0x7e, 0x71, 0xc7, 0x1b, 0xaf, 0x3c, 0xf7, 0x73,
0xC8, 0x88, 0x93, 0xA4, 0x9B, 0x34, 0xDA, 0x74, 0x93, 0x94, 0x77, 0xed, 0xd5, 0x47, 0xd9, 0xf4, 0xec, 0xe7, 0xa0, 0x7b, 0xe5, 0x2d, 0x46,
0x34, 0x4D, 0x31, 0x5A, 0xE3, 0x32, 0x8B, 0x92, 0x82, 0x77, 0xfe, 0x0b, 0x23, 0x6d, 0x86, 0x4b, 0xa3, 0xa1, 0xde, 0x64, 0x00, 0x00, 0x00,
0x3E, 0xB8, 0xC5, 0x4B, 0x7F, 0xB8, 0xC4, 0x67, 0xEB, 0x9B, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
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
}; };
static const unsigned char Toolbar_Options3_png[] = { static const unsigned char Toolbar_Options3_png[] = {

View File

@ -116,8 +116,7 @@ KeyboardMouse::Key::Key(Display* const display, KeyCode keycode, const char* key
ControlState KeyboardMouse::Key::GetState() const ControlState KeyboardMouse::Key::GetState() const
{ {
const KeyCode shift = XKeysymToKeycode(m_display, XK_Shift_L); const KeyCode shift = XKeysymToKeycode(m_display, XK_Shift_L);
return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0 return (m_keyboard[m_keycode / 8] & (1 << (m_keycode % 8))) != 0;
&& (m_keyboard[shift / 8] & (1 << (shift % 8))) == 0;
} }
ControlState KeyboardMouse::Button::GetState() const ControlState KeyboardMouse::Button::GetState() const

View File

@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "InputConfig.h" #include "InputConfig.h"
#include "../../Core/Src/ConfigManager.h"
InputPlugin::~InputPlugin() InputPlugin::~InputPlugin()
{ {
@ -26,17 +27,57 @@ InputPlugin::~InputPlugin()
delete *i; delete *i;
} }
bool InputPlugin::LoadConfig() bool InputPlugin::LoadConfig(bool isGC)
{ {
IniFile inifile; 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")) if (inifile.Load(File::GetUserPath(D_CONFIG_IDX) + ini_name + ".ini"))
{ {
std::vector< ControllerEmu* >::const_iterator std::vector< ControllerEmu* >::const_iterator
i = controllers.begin(), i = controllers.begin(),
e = controllers.end(); e = controllers.end();
for (; i!=e; ++i) for (int n = 0; i!=e; ++i, ++n)
{ {
// load settings from ini // load settings from ini
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())); (*i)->LoadConfig(inifile.GetOrCreateSection((*i)->GetName().c_str()));
// update refs // update refs
(*i)->UpdateReferences(g_controller_interface); (*i)->UpdateReferences(g_controller_interface);

View File

@ -42,7 +42,7 @@ public:
~InputPlugin(); ~InputPlugin();
bool LoadConfig(); bool LoadConfig(bool isGC);
void SaveConfig(); void SaveConfig();
std::vector< ControllerEmu* > controllers; std::vector< ControllerEmu* > controllers;

View File

@ -151,3 +151,38 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
#undef SET_REG_NAME #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;
}

View File

@ -793,7 +793,7 @@ union PE_CONTROL
{ {
u32 pixel_format : 3; // PIXELFMT_X u32 pixel_format : 3; // PIXELFMT_X
u32 zformat : 3; // Z Compression for 16bit Z format 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 unused : 17;
u32 rid : 8; u32 rid : 8;
}; };
@ -857,7 +857,7 @@ union TevKSel
int getKA(int i) {return i?kasel1:kasel0;} int getKA(int i) {return i?kasel1:kasel0;}
}; };
union AlphaFunc union AlphaTest
{ {
struct struct
{ {
@ -868,6 +868,15 @@ union AlphaFunc
u32 logic : 2; u32 logic : 2;
}; };
u32 hex; u32 hex;
enum TEST_RESULT
{
UNDETERMINED = 0,
FAIL = 1,
PASS = 2,
};
TEST_RESULT TestResult();
}; };
union UPE_Copy union UPE_Copy
@ -981,7 +990,7 @@ struct BPMemory
TevReg tevregs[4]; //0xE0 TevReg tevregs[4]; //0xE0
FogRangeParams fogRange; FogRangeParams fogRange;
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2 FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaFunc alphaFunc; //0xF3 AlphaTest alpha_test; //0xF3
ZTex1 ztex1; //0xf4,0xf5 ZTex1 ztex1; //0xf4,0xf5
ZTex2 ztex2; ZTex2 ztex2;
TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd

View File

@ -357,9 +357,9 @@ void BPWritten(const BPCmd& bp)
PixelShaderManager::SetFogColorChanged(); PixelShaderManager::SetFogColorChanged();
break; break;
case BPMEM_ALPHACOMPARE: // Compare Alpha Values case BPMEM_ALPHACOMPARE: // Compare Alpha Values
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0, PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0,
bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic); bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic);
PixelShaderManager::SetAlpha(bpmem.alphaFunc); PixelShaderManager::SetAlpha(bpmem.alpha_test);
break; break;
case BPMEM_BIAS: // BIAS case BPMEM_BIAS: // BIAS
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.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 this is different from 0, manual TMEM management is used (GX_PreloadEntireTexture).
if (bp.newvalue != 0) 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; BPS_TmemConfig& tmem_cfg = bpmem.tmem_config;
u8* ram_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); u8* src_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); // TODO: Should we add mask here on GC?
u32 tmem_addr = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE;
u32 size = tmem_cfg.preload_tile_info.count * 32; 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. if (tmem_cfg.preload_tile_info.type != 3)
// Paper Mario does this when entering the Great Boogly Tree (Chap 2) {
if ((tmem_addr + size) > TMEM_SIZE) if (tmem_addr_even + size > TMEM_SIZE)
size = TMEM_SIZE - tmem_addr; 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; break;

View File

@ -27,7 +27,6 @@
#include "VideoConfig.h" #include "VideoConfig.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
static int AlphaPreTest();
static void StageHash(int stage, u32* out) 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] |= bpmem.genMode.numtexgens << 4; // 4
uid->values[0] |= dstAlphaMode << 8; // 2 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; 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 if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
u32 alphaPreTest = AlphaPreTest()+1;
uid->values[0] |= alphaPreTest << 16; // 2 AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult();
uid->values[0] |= alphaPreTest << 15; // 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;
}
// numtexgens should be <= 8 // numtexgens should be <= 8
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) 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 uid->values[1] = bpmem.genMode.numindstages; // 3
u32 indirectStagesUsed = 0; u32 indirectStagesUsed = 0;
@ -160,28 +147,21 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
ptr += 4; // max: ptr = &uid->values[66] ptr += 4; // max: ptr = &uid->values[66]
} }
ptr[0] |= bpmem.alphaFunc.comp0; // 3 ptr[0] |= bpmem.alpha_test.comp0; // 3
ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3 ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3
ptr[0] |= bpmem.alphaFunc.logic << 6; // 2 ptr[0] |= bpmem.alpha_test.logic << 6; // 2
if (alphaPreTest == 0 || alphaPreTest == 2) ptr[0] |= bpmem.ztex2.op << 8; // 2
{ ptr[0] |= bpmem.zcontrol.early_ztest << 10; // 1
ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3 ptr[0] |= bpmem.zmode.testenable << 11; // 1
if (DepthTextureEnable) ptr[0] |= bpmem.zmode.updateenable << 12; // 1
{
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
}
}
if (dstAlphaMode != DSTALPHA_ALPHA_PASS) if (dstAlphaMode != DSTALPHA_ALPHA_PASS)
{ {
if (bpmem.fog.c_proj_fsel.fsel != 0) if (bpmem.fog.c_proj_fsel.fsel != 0)
{ {
ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1 ptr[0] |= bpmem.fog.c_proj_fsel.proj << 13; // 1
ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 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.ztex2.hex; // 2
*ptr++ = bpmem.zcontrol.hex; // 3 *ptr++ = bpmem.zcontrol.hex; // 3
*ptr++ = bpmem.zmode.hex; // 4 *ptr++ = bpmem.zmode.hex; // 4
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5 *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 5
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6 *ptr++ = xfregs.numTexGen.hex; // 6
*ptr++ = xfregs.numTexGen.hex; // 7
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) 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) 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) 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 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].colorC.hex; // 32+5*i
*ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i
*ptr++ = bpmem.tevind[i].hex; // 35+5*i *ptr++ = bpmem.tevind[i].hex; // 34+5*i
*ptr++ = bpmem.tevksel[i/2].hex; // 36+5*i *ptr++ = bpmem.tevksel[i/2].hex; // 35+5*i
*ptr++ = bpmem.tevorders[i/2].hex; // 37+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.fog.c_proj_fsel.hex; // 113
*ptr++ = bpmem.fogRange.Base.hex; // 115 *ptr++ = bpmem.fogRange.Base.hex; // 114
_assert_((ptr - uid->values) == uid->GetNumValues()); _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 swapModeTable[4][5];
static char text[16384]; static char text[16384];
static bool DepthTextureEnable;
struct RegisterState struct RegisterState
{ {
@ -528,7 +506,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; 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 // Declare samplers
if(ApiType != API_D3D11) 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", WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", 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"); ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS");
} }
else else
{ {
WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", 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," : "", 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"); WRITE(p, " in float4 colors_0 : COLOR0,\n");
@ -622,32 +599,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
} }
WRITE(p, " ) {\n"); 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" 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" " 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" " float4 alphabump=float4(0.0f,0.0f,0.0f,0.0f);\n"
@ -755,26 +706,19 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); 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); 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 // 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"); 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... // 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) WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n",
{ (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : "");
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");
// scale to make result from frac correct // scale to make result from frac correct
WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n");
@ -782,7 +726,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n");
} }
WRITE(p, "depth = zCoord;\n"); WRITE(p, "depth = zCoord;\n");
}
if (dstAlphaMode == DSTALPHA_ALPHA_PASS) if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n");
@ -1192,39 +1135,6 @@ static const char *tevAlphaFunclogicTable[] =
" != ", // xor " != ", // xor
" == " // xnor " == " // 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) 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 // using discard then return works the same in cg and dx9 but not in dx11
WRITE(p, "if(!( "); 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, 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, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table
WRITE(p, ")) {\n"); WRITE(p, ")) {\n");
WRITE(p, "ocol0 = 0;\n"); WRITE(p, "ocol0 = 0;\n");
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "ocol1 = 0;\n"); 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 // HAXX: zcomploc (aka early_ztest) 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 // or after texturing and alpha test. PC GPUs have no way to support this
// not updated during shader execution. // 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 // We implement "depth test before texturing" by discarding the fragment
// when the alpha test fail. This is not a correct implementation because // when the alpha test fail. This is not a correct implementation because
// even if the depth test fails the fragment could be alpha blended. // even if the depth test fails the fragment could be alpha blended, but
// this implemnetation is a trick to keep speed. // we don't have a choice.
// the correct, but slow, way to implement a correct zComploc is : if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable))
// 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))
{ {
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
if (ApiType != API_D3D11) if (ApiType != API_D3D11)
@ -1272,7 +1179,6 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
} }
WRITE(p, "}\n"); WRITE(p, "}\n");
} }
static const char *tevFogFuncsTable[] = static const char *tevFogFuncsTable[] =

View File

@ -45,7 +45,7 @@
#define C_PMATERIALS (C_PLIGHTS + 40) #define C_PMATERIALS (C_PLIGHTS + 40)
#define C_PENVCONST_END (C_PMATERIALS + 4) #define C_PENVCONST_END (C_PMATERIALS + 4)
#define PIXELSHADERUID_MAX_VALUES 70 #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. // DO NOT make anything in this class virtual.
template<bool safe> template<bool safe>

View File

@ -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]); 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) if ((alpha.hex & 0xffff) != lastAlpha)
{ {

View File

@ -38,7 +38,7 @@ public:
// constant management, should be called after memory is committed // constant management, should be called after memory is committed
static void SetColorChanged(int type, int index, bool high); 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 SetDestAlpha(const ConstantAlpha& alpha);
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt); static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
static void SetZTextureBias(u32 bias); static void SetZTextureBias(u32 bias);

View File

@ -91,6 +91,9 @@ Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false)
#if defined _WIN32 || defined HAVE_LIBAV #if defined _WIN32 || defined HAVE_LIBAV
bAVIDumping = false; bAVIDumping = false;
#endif #endif
OSDChoice = 0;
OSDTime = 0;
} }
Renderer::~Renderer() Renderer::~Renderer()
@ -263,16 +266,19 @@ void Renderer::SetScreenshot(const char *filename)
// Create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugText() void Renderer::DrawDebugText()
{ {
if (!g_Config.bOSDHotKey)
return;
// OSD Menu messages // OSD Menu messages
if (g_ActiveConfig.bOSDHotKey)
{
if (OSDChoice > 0) if (OSDChoice > 0)
{ {
OSDTime = Common::Timer::GetTimeMs() + 3000; OSDTime = Common::Timer::GetTimeMs() + 3000;
OSDChoice = -OSDChoice; OSDChoice = -OSDChoice;
} }
if ((u32)OSDTime > Common::Timer::GetTimeMs())
{ if ((u32)OSDTime <= Common::Timer::GetTimeMs())
return;
const char* res_text = ""; const char* res_text = "";
switch (g_ActiveConfig.iEFBScale) switch (g_ActiveConfig.iEFBScale)
{ {
@ -364,8 +370,6 @@ void Renderer::DrawDebugText()
g_renderer->RenderText(final_cyan.c_str(), 20, 20, 0xFF00FFFF); g_renderer->RenderText(final_cyan.c_str(), 20, 20, 0xFF00FFFF);
g_renderer->RenderText(final_yellow.c_str(), 20, 20, 0xFFFFFF00); g_renderer->RenderText(final_yellow.c_str(), 20, 20, 0xFFFFFF00);
} }
}
}
// TODO: remove // TODO: remove
extern bool g_aspect_wide; extern bool g_aspect_wide;

View File

@ -39,7 +39,7 @@
// TODO: Move these out of here. // TODO: Move these out of here.
extern int frameCount; extern int frameCount;
extern int OSDChoice, OSDTime; extern int OSDChoice;
extern bool bLastFrameDumped; extern bool bLastFrameDumped;

View File

@ -204,12 +204,16 @@ void TextureCache::ClearRenderTargets()
iter = textures.begin(), iter = textures.begin(),
tcend = textures.end(); tcend = textures.end();
for (; iter!=tcend; ++iter) while (iter != tcend)
{
if (iter->second->type == TCET_EC_VRAM) if (iter->second->type == TCET_EC_VRAM)
{ {
delete iter->second; delete iter->second;
textures.erase(iter++); textures.erase(iter++);
} }
else
++iter;
}
} }
bool TextureCache::CheckForCustomTextureLODs(u64 tex_hash, int texformat, unsigned int levels) 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]; if (from_tmem) src_data = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE];
else src_data = Memory::GetPointer(address); 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); tex_hash = GetHash64(src_data, texture_size, g_ActiveConfig.iSafeTextureCache_ColorSamples);
if (isPaletteTexture) 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) if (!using_custom_texture)
{
if (!(texformat == GX_TF_RGBA8 && from_tmem))
{
pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth, pcfmt = TexDecoder_Decode(temp, src_data, expandedWidth,
expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures); 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) // TODO: Cleanup. Plus, we still autogenerate mipmaps in certain cases (we shouldn't do that)
bool isPow2; bool isPow2;

View File

@ -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[] = { const char* texfmt[] = {
// pixel // pixel

View File

@ -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 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); 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_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); void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center);
#endif #endif

View File

@ -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, 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 #endif
u32 usedtextures = 0; u32 usedtextures = 0;

View File

@ -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 //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 //if not early z culling will improve speed
// TODO: Can probably be dropped?
if (is_d3d) if (is_d3d)
{ {
WRITE(p, "o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); WRITE(p, "o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n");

View File

@ -169,14 +169,24 @@ void VertexShaderManager::Shutdown()
void VertexShaderManager::Dirty() void VertexShaderManager::Dirty()
{ {
nTransformMatricesChanged[0] = 0; nTransformMatricesChanged[1] = 256; nTransformMatricesChanged[0] = 0;
nNormalMatricesChanged[0] = 0; nNormalMatricesChanged[1] = 96; nTransformMatricesChanged[1] = 256;
nPostTransformMatricesChanged[0] = 0; nPostTransformMatricesChanged[1] = 256;
nLightsChanged[0] = 0; nLightsChanged[1] = 0x80; nNormalMatricesChanged[0] = 0;
nNormalMatricesChanged[1] = 96;
nPostTransformMatricesChanged[0] = 0;
nPostTransformMatricesChanged[1] = 256;
nLightsChanged[0] = 0;
nLightsChanged[1] = 0x80;
bPosNormalMatrixChanged = true; bPosNormalMatrixChanged = true;
bTexMatricesChanged[0] = bTexMatricesChanged[1] = true; bTexMatricesChanged[0] = true;
bTexMatricesChanged[1] = true;
bProjectionChanged = true; bProjectionChanged = true;
bPosNormalMatrixChanged = bTexMatricesChanged[0] = bTexMatricesChanged[1] = true;
nMaterialsChanged = 15; nMaterialsChanged = 15;
} }

View File

@ -75,7 +75,6 @@ void VideoConfig::Load(const char *ini_file)
iniFile.Get("Settings", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation, 200); iniFile.Get("Settings", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation, 200);
iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0);
iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0); iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0);
iniFile.Get("Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth, 0);
iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0);
iniFile.Get("Settings", "EFBScale", &iEFBScale, 2); // native 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", "AnaglyphStereoSeparation", &iAnaglyphStereoSeparation);
iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle); iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle);
iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting); iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting);
iniFile.GetIfExists("Video_Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth);
iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode); iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode);
iniFile.GetIfExists("Video_Settings", "EFBScale", &iEFBScale); // integral iniFile.GetIfExists("Video_Settings", "EFBScale", &iEFBScale); // integral
iniFile.GetIfExists("Video_Settings", "DstAlphaPass", &bDstAlphaPass); 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", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation);
iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle);
iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting); iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting);
iniFile.Set("Settings", "EnablePerPixelDepth", bEnablePerPixelDepth);
iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); 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", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation);
SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle);
SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting); 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", "MSAA", iMultisampleMode);
SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral
SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass); SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass);

View File

@ -133,7 +133,6 @@ struct VideoConfig
bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess
bool bUseBBox; bool bUseBBox;
bool bEnablePixelLighting; bool bEnablePixelLighting;
bool bEnablePerPixelDepth;
int iLog; // CONF_ bits int iLog; // CONF_ bits
int iSaveTargetId; // TODO: Should be dropped int iSaveTargetId; // TODO: Should be dropped

View File

@ -471,10 +471,13 @@ void Renderer::SetColorMask()
{ {
// Only enable alpha channel if it's supported by the current EFB format // Only enable alpha channel if it's supported by the current EFB format
UINT8 color_mask = 0; UINT8 color_mask = 0;
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
{
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA; color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
if (bpmem.blendmode.colorupdate) if (bpmem.blendmode.colorupdate)
color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE; 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; 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); Core::Callback_VideoCopiedToXFB(false);
return; 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; u32 xfbCount = 0;
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)

View File

@ -428,10 +428,13 @@ void Renderer::SetColorMask()
{ {
// Only enable alpha channel if it's supported by the current EFB format // Only enable alpha channel if it's supported by the current EFB format
DWORD color_mask = 0; DWORD color_mask = 0;
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
{
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
color_mask = D3DCOLORWRITEENABLE_ALPHA; color_mask = D3DCOLORWRITEENABLE_ALPHA;
if (bpmem.blendmode.colorupdate) if (bpmem.blendmode.colorupdate)
color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
}
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); 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); Core::Callback_VideoCopiedToXFB(false);
return; 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; if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0; u32 xfbCount = 0;
@ -1201,6 +1201,7 @@ void Renderer::ApplyState(bool bUseDstAlpha)
{ {
if (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_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
if(bpmem.zmode.testenable && bpmem.zmode.updateenable) if(bpmem.zmode.testenable && bpmem.zmode.updateenable)

View File

@ -646,10 +646,13 @@ void Renderer::SetColorMask()
{ {
// Only enable alpha channel if it's supported by the current EFB format // Only enable alpha channel if it's supported by the current EFB format
GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE; GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE;
if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL)
{
if (bpmem.blendmode.colorupdate) if (bpmem.blendmode.colorupdate)
ColorMask = GL_TRUE; ColorMask = GL_TRUE;
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
AlphaMask = GL_TRUE; AlphaMask = GL_TRUE;
}
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask); 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); Core::Callback_VideoCopiedToXFB(false);
return; 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; if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0; u32 xfbCount = 0;

View File

@ -128,8 +128,8 @@ void VertexManager::vFlush()
xfregs.postMtxInfo[i].index, xfregs.postMtxInfo[i].normalize); 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, 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.alphaFunc.hex>>16)&0xff); bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alpha_test.hex>>16)&0xff);
#endif #endif
(void)GL_REPORT_ERROR(); (void)GL_REPORT_ERROR();

View File

@ -115,18 +115,39 @@ void SWBPWritten(int address, int newvalue)
case BPMEM_PRELOAD_MODE: case BPMEM_PRELOAD_MODE:
if (newvalue != 0) 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; BPS_TmemConfig& tmem_cfg = bpmem.tmem_config;
u8* ram_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); u8* src_ptr = Memory::GetPointer(tmem_cfg.preload_addr << 5); // TODO: Should we add mask here on GC?
u32 tmem_addr = tmem_cfg.preload_tmem_even * TMEM_LINE_SIZE; u32 size = tmem_cfg.preload_tile_info.count * TMEM_LINE_SIZE;
u32 size = tmem_cfg.preload_tile_info.count * 32; 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. if (tmem_cfg.preload_tile_info.type != 3)
// Paper Mario does this when entering the Great Boogly Tree (Chap 2) {
if ((tmem_addr + size) > TMEM_SIZE) if (tmem_addr_even + size > TMEM_SIZE)
size = TMEM_SIZE - tmem_addr; 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; break;

View File

@ -125,7 +125,7 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi)
if (z < 0 || z > 0x00ffffff) if (z < 0 || z > 0x00ffffff)
return; return;
if (bpmem.zcontrol.zcomploc && bpmem.zmode.testenable) if (bpmem.zcontrol.early_ztest && bpmem.zmode.testenable)
{ {
// early z // early z
if (!EfbInterface::ZCompare(x, y, z)) if (!EfbInterface::ZCompare(x, y, z))

View File

@ -433,10 +433,10 @@ static bool AlphaCompare(int alpha, int ref, int comp)
static bool AlphaTest(int alpha) static bool AlphaTest(int alpha)
{ {
bool comp0 = AlphaCompare(alpha, bpmem.alphaFunc.ref0, bpmem.alphaFunc.comp0); bool comp0 = AlphaCompare(alpha, bpmem.alpha_test.ref0, bpmem.alpha_test.comp0);
bool comp1 = AlphaCompare(alpha, bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp1); 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 0: return comp0 && comp1; // and
case 1: return comp0 || comp1; // or case 1: return comp0 || comp1; // or
case 2: return comp0 ^ comp1; // xor 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; 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])) if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2]))
return; return;

View File

@ -120,10 +120,12 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample)
TexImage0& ti0 = texUnit.texImage0[subTexmap]; TexImage0& ti0 = texUnit.texImage0[subTexmap];
TexTLUT& texTlut = texUnit.texTlut[subTexmap]; TexTLUT& texTlut = texUnit.texTlut[subTexmap];
u8 *imageSrc; u8 *imageSrc, *imageSrcOdd = NULL;
if (texUnit.texImage1[subTexmap].image_type) if (texUnit.texImage1[subTexmap].image_type)
{ {
imageSrc = &texMem[texUnit.texImage1[subTexmap].tmem_even * TMEM_LINE_SIZE]; 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 else
{ {
@ -190,6 +192,8 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample)
WrapCoord(imageSPlus1, tm0.wrap_s, imageWidth); WrapCoord(imageSPlus1, tm0.wrap_s, imageWidth);
WrapCoord(imageTPlus1, tm0.wrap_t, imageHeight); WrapCoord(imageTPlus1, tm0.wrap_t, imageHeight);
if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type))
{
TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format);
SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT)); SetTexel(sampledTex, texel, (128 - fractS) * (128 - fractT));
@ -201,6 +205,21 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample)
TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); TexDecoder_DecodeTexel(sampledTex, imageSrc, imageSPlus1, imageTPlus1, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format);
AddTexel(sampledTex, texel, (fractS) * (fractT)); 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[0] = (u8)(texel[0] >> 14);
sample[1] = (u8)(texel[1] >> 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(imageS, tm0.wrap_s, imageWidth);
WrapCoord(imageT, tm0.wrap_t, imageHeight); WrapCoord(imageT, tm0.wrap_t, imageHeight);
if (!(ti0.format == GX_TF_RGBA8 && texUnit.texImage1[subTexmap].image_type))
TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format); TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, ti0.format, tlutAddress, texTlut.tlut_format);
else
TexDecoder_DecodeTexelRGBA8FromTmem(sample, imageSrc, imageSrcOdd, imageS, imageT, imageWidth);
} }
} }