mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-29 20:28:56 +00:00
Merge branch 'master' into wii-network
Conflicts: Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
This commit is contained in:
commit
c30b8c9eae
136 changed files with 1076 additions and 1371 deletions
|
@ -200,6 +200,7 @@ void OpenALStream::SoundLoop()
|
|||
u64 num_samples_to_render = (audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond();
|
||||
|
||||
unsigned int numSamples = (unsigned int)num_samples_to_render;
|
||||
unsigned int minSamples = surround_capable ? 240 : 0; // DPL2 accepts 240 samples minimum (FWRDURATION)
|
||||
|
||||
numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples;
|
||||
numSamples = m_mixer->Mix(realtimeBuffer, numSamples);
|
||||
|
@ -236,9 +237,15 @@ void OpenALStream::SoundLoop()
|
|||
// Adjust SETTING_SEQUENCE_MS to balance between lag vs hollow audio
|
||||
soundTouch.setSetting(SETTING_SEQUENCE_MS, (int)(1 / (rate * rate)));
|
||||
soundTouch.setTempo(rate);
|
||||
if (rate > 10)
|
||||
{
|
||||
soundTouch.clear();
|
||||
}
|
||||
}
|
||||
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS);
|
||||
if (nSamples > 0)
|
||||
|
||||
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * OAL_MAX_BUFFERS);
|
||||
|
||||
if (nSamples > minSamples)
|
||||
{
|
||||
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
|
||||
if (iBuffersFilled == 0)
|
||||
|
|
|
@ -205,14 +205,7 @@ void CPUInfo::Detect()
|
|||
// Turn the cpu info into a string we can show
|
||||
std::string CPUInfo::Summarize()
|
||||
{
|
||||
std::string sum;
|
||||
if (num_cores == 1)
|
||||
sum = StringFromFormat("%s, %i core", cpu_string, num_cores);
|
||||
else
|
||||
{
|
||||
sum = StringFromFormat("%s, %i cores", cpu_string, num_cores);
|
||||
if (HTT) sum += StringFromFormat(" (%i logical threads per physical core)", logical_cpu_count);
|
||||
}
|
||||
std::string sum(cpu_string);
|
||||
if (bSSE) sum += ", SSE";
|
||||
if (bSSE2) sum += ", SSE2";
|
||||
if (bSSE3) sum += ", SSE3";
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
|
@ -196,8 +197,9 @@ bool CreateFullPath(const std::string &fullPath)
|
|||
// we're done, yay!
|
||||
if (position == fullPath.npos)
|
||||
return true;
|
||||
|
||||
std::string subPath = fullPath.substr(0, position);
|
||||
|
||||
// Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
|
||||
std::string const subPath(fullPath.substr(0, position + 1));
|
||||
if (!File::IsDirectory(subPath))
|
||||
File::CreateDir(subPath);
|
||||
|
||||
|
@ -775,6 +777,24 @@ IOFile::~IOFile()
|
|||
Close();
|
||||
}
|
||||
|
||||
IOFile::IOFile(IOFile&& other)
|
||||
: m_file(NULL), m_good(true)
|
||||
{
|
||||
Swap(other);
|
||||
}
|
||||
|
||||
IOFile& IOFile::operator=(IOFile&& other)
|
||||
{
|
||||
IOFile((IOFile&&)other).Swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void IOFile::Swap(IOFile& other)
|
||||
{
|
||||
std::swap(m_file, other.m_file);
|
||||
std::swap(m_good, other.m_good);
|
||||
}
|
||||
|
||||
bool IOFile::Open(const std::string& filename, const char openmode[])
|
||||
{
|
||||
Close();
|
||||
|
|
|
@ -151,7 +151,7 @@ bool ReadFileToString(bool text_file, const char *filename, std::string &str);
|
|||
// simple wrapper for cstdlib file functions to
|
||||
// hopefully will make error checking easier
|
||||
// and make forgetting an fclose() harder
|
||||
class IOFile : NonCopyable
|
||||
class IOFile
|
||||
{
|
||||
public:
|
||||
IOFile();
|
||||
|
@ -159,6 +159,11 @@ public:
|
|||
IOFile(const std::string& filename, const char openmode[]);
|
||||
|
||||
~IOFile();
|
||||
|
||||
IOFile(IOFile&& other);
|
||||
IOFile& operator=(IOFile&& other);
|
||||
|
||||
void Swap(IOFile& other);
|
||||
|
||||
bool Open(const std::string& filename, const char openmode[]);
|
||||
bool Close();
|
||||
|
@ -213,6 +218,7 @@ public:
|
|||
void Clear() { m_good = true; std::clearerr(m_file); }
|
||||
|
||||
private:
|
||||
IOFile(const IOFile&) /*= delete*/;
|
||||
IOFile& operator=(const IOFile&) /*= delete*/;
|
||||
|
||||
std::FILE* m_file;
|
||||
|
|
|
@ -98,8 +98,8 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
|
|||
client_running = false;
|
||||
clientThread.join();
|
||||
|
||||
recv_fifo = std::queue<u8>();
|
||||
send_fifo = std::queue<u8>();
|
||||
recv_fifo = std::deque<u8>();
|
||||
send_fifo = std::deque<u8>();
|
||||
}
|
||||
clientThread = std::thread(std::mem_fun(&GeckoSockServer::ClientThread), this);
|
||||
client_count++;
|
||||
|
@ -120,28 +120,39 @@ void GeckoSockServer::ClientThread()
|
|||
|
||||
while (client_running)
|
||||
{
|
||||
u8 data;
|
||||
std::size_t got = 0;
|
||||
bool did_nothing = true;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(transfer_lock);
|
||||
|
||||
if (client.Receive((char*)&data, sizeof(data), got)
|
||||
== sf::Socket::Disconnected)
|
||||
// what's an ideal buffer size?
|
||||
char data[128];
|
||||
std::size_t got = 0;
|
||||
|
||||
if (client.Receive(&data[0], ARRAYSIZE(data), got) == sf::Socket::Disconnected)
|
||||
client_running = false;
|
||||
if (got)
|
||||
recv_fifo.push(data);
|
||||
|
||||
if (send_fifo.size())
|
||||
|
||||
if (got != 0)
|
||||
{
|
||||
if (client.Send((char*)&send_fifo.front(), sizeof(u8))
|
||||
== sf::Socket::Disconnected)
|
||||
did_nothing = false;
|
||||
|
||||
recv_fifo.insert(recv_fifo.end(), &data[0], &data[got]);
|
||||
}
|
||||
|
||||
if (!send_fifo.empty())
|
||||
{
|
||||
did_nothing = false;
|
||||
|
||||
std::vector<char> packet(send_fifo.begin(), send_fifo.end());
|
||||
send_fifo.clear();
|
||||
|
||||
if (client.Send(&packet[0], packet.size()) == sf::Socket::Disconnected)
|
||||
client_running = false;
|
||||
send_fifo.pop();
|
||||
}
|
||||
} // unlock transfer
|
||||
|
||||
SLEEP(1);
|
||||
if (did_nothing)
|
||||
Common::YieldCPU();
|
||||
}
|
||||
|
||||
client.Close();
|
||||
|
@ -180,7 +191,7 @@ void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
|
|||
if (!recv_fifo.empty())
|
||||
{
|
||||
_uData = 0x08000000 | (recv_fifo.front() << 16);
|
||||
recv_fifo.pop();
|
||||
recv_fifo.pop_front();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -190,7 +201,7 @@ void CEXIGecko::ImmReadWrite(u32 &_uData, u32 _uSize)
|
|||
case CMD_SEND:
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(transfer_lock);
|
||||
send_fifo.push(_uData >> 20);
|
||||
send_fifo.push_back(_uData >> 20);
|
||||
_uData = 0x04000000;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "SFML/Network.hpp"
|
||||
#include "Thread.h"
|
||||
|
||||
#include <deque>
|
||||
#include <queue>
|
||||
|
||||
class GeckoSockServer
|
||||
|
@ -36,8 +38,8 @@ public:
|
|||
std::thread clientThread;
|
||||
std::mutex transfer_lock;
|
||||
|
||||
std::queue<u8> send_fifo;
|
||||
std::queue<u8> recv_fifo;
|
||||
std::deque<u8> send_fifo;
|
||||
std::deque<u8> recv_fifo;
|
||||
|
||||
private:
|
||||
static int client_count;
|
||||
|
|
|
@ -374,7 +374,7 @@ void ExecuteCommand(u32 _Address)
|
|||
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
|
||||
|
||||
|
||||
WARN_LOG(WII_IPC_HLE, "Tried to open %s as %d", DeviceName.c_str(), DeviceID);
|
||||
WARN_LOG(WII_IPC_HLE, "Trying to open %s as %d", DeviceName.c_str(), DeviceID);
|
||||
if (DeviceID >= 0)
|
||||
{
|
||||
if (DeviceName.find("/dev/es") == 0)
|
||||
|
|
|
@ -477,7 +477,7 @@ int CWII_IPC_HLE_Device_di::GetCmdDelay(u32 _CommandAddress)
|
|||
u32 const Size = Memory::Read_U32(BufferIn + 0x04);
|
||||
// Delay depends on size of read, that makes sense, right?
|
||||
// More than ~1150K "bytes / sec" hangs NSMBWii on boot.
|
||||
// Less than ~800K "bytes / sec" hangs DKCR randomly.
|
||||
// Less than ~800K "bytes / sec" hangs DKCR randomly (ok, probably not true)
|
||||
return SystemTimers::GetTicksPerSecond() / 975000 * Size;
|
||||
break;
|
||||
}
|
||||
|
@ -498,7 +498,8 @@ int CWII_IPC_HLE_Device_di::GetCmdDelay(u32 _CommandAddress)
|
|||
// case DVDLowClosePartition:
|
||||
default:
|
||||
// ranom numbers here!
|
||||
return SystemTimers::GetTicksPerSecond() / 1500;
|
||||
// More than ~1/2000th of a second hangs DKCR with DSP HLE, maybe.
|
||||
return SystemTimers::GetTicksPerSecond() / 15000;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,17 +28,16 @@
|
|||
|
||||
static Common::replace_v replacements;
|
||||
|
||||
// This is used by several of the FileIO and /dev/fs functions
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
||||
// This is used by several of the FileIO and /dev/fs functions
|
||||
std::string HLE_IPC_BuildFilename(std::string path_wii, int _size)
|
||||
{
|
||||
std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
|
||||
std::string path_wii(_pFilename);
|
||||
|
||||
if ((path_wii.length() > 0) && (path_wii[1] == '0'))
|
||||
path_full += std::string("/title"); // this looks and feel like a hack...
|
||||
|
||||
// Replaces chars that FAT32 can't support with strings defined in /sys/replace
|
||||
for (Common::replace_v::const_iterator i = replacements.begin(); i != replacements.end(); ++i)
|
||||
for (auto i = replacements.begin(); i != replacements.end(); ++i)
|
||||
{
|
||||
for (size_t j = 0; (j = path_wii.find(i->first, j)) != path_wii.npos; ++j)
|
||||
path_wii.replace(j, 1, i->second);
|
||||
|
@ -82,9 +81,8 @@ void HLE_IPC_CreateVirtualFATFilesystem()
|
|||
}
|
||||
}
|
||||
|
||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
|
||||
, m_pFileHandle(NULL)
|
||||
, m_Mode(0)
|
||||
, m_SeekPos(0)
|
||||
{
|
||||
|
@ -108,12 +106,9 @@ bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce)
|
|||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||
{
|
||||
{
|
||||
m_Mode = _Mode;
|
||||
u32 ReturnValue = 0;
|
||||
|
||||
// close the file handle if we get a reopen
|
||||
//m_pFileHandle.Close();
|
||||
|
||||
static const char* const Modes[] =
|
||||
{
|
||||
|
@ -122,20 +117,19 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
"Write only",
|
||||
"Read and Write"
|
||||
};
|
||||
|
||||
m_Filename = std::string(HLE_IPC_BuildFilename(m_Name.c_str(), 64));
|
||||
|
||||
m_filepath = HLE_IPC_BuildFilename(m_Name, 64);
|
||||
|
||||
// The file must exist before we can open it
|
||||
// It should be created by ISFS_CreateFile, not here
|
||||
if (File::Exists(m_Filename))
|
||||
if (File::Exists(m_filepath))
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
|
||||
ReturnValue = m_DeviceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], m_Filename.c_str());
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[_Mode], m_filepath.c_str());
|
||||
ReturnValue = FS_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
|
@ -145,54 +139,43 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||
{
|
||||
const char* open_mode = "";
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case ISFS_OPEN_READ:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "rb");
|
||||
open_mode = "rb";
|
||||
break;
|
||||
}
|
||||
|
||||
case ISFS_OPEN_WRITE:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
break;
|
||||
}
|
||||
case ISFS_OPEN_RW:
|
||||
{
|
||||
m_pFileHandle.Open(m_Filename, "r+b");
|
||||
open_mode = "r+b";
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_pFileHandle.IsOpen();
|
||||
|
||||
return File::IOFile(m_filepath, open_mode);
|
||||
}
|
||||
|
||||
void CWII_IPC_HLE_Device_FileIO::CloseFile()
|
||||
{
|
||||
m_pFileHandle.Close();
|
||||
}
|
||||
|
||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
{
|
||||
u32 ReturnValue = FS_RESULT_FATAL;
|
||||
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
ReturnValue = FS_RESULT_FATAL;
|
||||
|
||||
const s64 fileSize = m_pFileHandle.GetSize();
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx) (%08X)", SeekPosition, Mode, m_Name.c_str(), fileSize, m_DeviceID);
|
||||
switch (Mode){
|
||||
const u64 fileSize = file.GetSize();
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||
switch (Mode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if ((SeekPosition >=0) && (SeekPosition <= fileSize))
|
||||
|
@ -229,7 +212,6 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
|||
break;
|
||||
}
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -247,18 +229,18 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
if (m_Mode == ISFS_OPEN_WRITE)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to read 0x%x bytes to 0x%08x on write-only file %s", Size, Address, m_Name.c_str());
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str());
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle.GetHandle());
|
||||
if (ReturnValue != Size && ferror(m_pFileHandle.GetHandle()))
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle());
|
||||
if (ReturnValue != Size && ferror(file.GetHandle()))
|
||||
{
|
||||
ReturnValue = FS_EACCESS;
|
||||
}
|
||||
|
@ -268,7 +250,6 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
}
|
||||
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -287,23 +268,22 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
if (m_Mode == ISFS_OPEN_READ)
|
||||
{
|
||||
WARN_LOG(WII_IPC_FILEIO, "FileIO: Attempted to write 0x%x bytes from 0x%08x to read-only file %s", Size, Address, m_Name.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str());
|
||||
m_pFileHandle.Seek(m_SeekPos, SEEK_SET);
|
||||
if (m_pFileHandle.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
file.Seek(m_SeekPos, SEEK_SET);
|
||||
if (file.WriteBytes(Memory::GetPointer(Address), Size))
|
||||
{
|
||||
ReturnValue = Size;
|
||||
m_SeekPos += Size;
|
||||
}
|
||||
}
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,17 +308,15 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
|||
{
|
||||
case ISFS_IOCTL_GETFILESTATS:
|
||||
{
|
||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||
if (OpenFile())
|
||||
if (auto file = OpenFile())
|
||||
{
|
||||
u32 m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||
u32 m_FileLength = (u32)file.GetSize();
|
||||
|
||||
const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
INFO_LOG(WII_IPC_FILEIO, " File: %s, Length: %i, Pos: %i", m_Name.c_str(), m_FileLength, m_SeekPos);
|
||||
|
||||
Memory::Write_U32(m_FileLength, BufferOut);
|
||||
Memory::Write_U32(m_SeekPos, BufferOut+4);
|
||||
CloseFile();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -364,30 +342,8 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p)
|
|||
{
|
||||
DoStateShared(p);
|
||||
|
||||
bool have_file_handle = (m_pFileHandle != 0);
|
||||
s32 seek = (have_file_handle) ? (s32)m_pFileHandle.Tell() : 0;
|
||||
|
||||
p.Do(have_file_handle);
|
||||
p.Do(m_Mode);
|
||||
p.Do(seek);
|
||||
p.Do(m_SeekPos);
|
||||
p.Do(m_Filename);
|
||||
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
{
|
||||
int mode = m_Mode;
|
||||
bool active = m_Active;
|
||||
if (have_file_handle)
|
||||
{
|
||||
Open(0, m_Mode);
|
||||
_dbg_assert_msg_(WII_IPC_HLE, m_pFileHandle, "bad filehandle");
|
||||
}
|
||||
else
|
||||
Close(0, true);
|
||||
m_Mode = mode;
|
||||
m_Active = active;
|
||||
}
|
||||
|
||||
if (have_file_handle)
|
||||
m_pFileHandle.Seek(seek, SEEK_SET);
|
||||
|
||||
m_filepath = HLE_IPC_BuildFilename(m_Name, 64);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "WII_IPC_HLE_Device.h"
|
||||
#include "FileUtil.h"
|
||||
|
||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size);
|
||||
std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size);
|
||||
void HLE_IPC_CreateVirtualFATFilesystem();
|
||||
|
||||
class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device
|
||||
|
@ -39,8 +39,7 @@ public:
|
|||
bool IOCtl(u32 _CommandAddress);
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
bool OpenFile();
|
||||
void CloseFile();
|
||||
File::IOFile OpenFile();
|
||||
|
||||
private:
|
||||
enum
|
||||
|
@ -76,12 +75,10 @@ private:
|
|||
ISFS_IOCTL_SHUTDOWN
|
||||
};
|
||||
|
||||
File::IOFile m_pFileHandle;
|
||||
u32 m_Mode;
|
||||
|
||||
u32 m_SeekPos;
|
||||
|
||||
std::string m_Filename;
|
||||
|
||||
std::string m_filepath;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -428,7 +428,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B
|
|||
File::CreateFullPath(FilenameRename);
|
||||
|
||||
// if there is already a file, delete it
|
||||
if (File::Exists(FilenameRename))
|
||||
if (File::Exists(Filename) && File::Exists(FilenameRename))
|
||||
{
|
||||
File::Delete(FilenameRename);
|
||||
}
|
||||
|
|
|
@ -338,7 +338,7 @@ void Jit64::WriteRfiExitDestInEAX()
|
|||
Cleanup();
|
||||
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
|
||||
SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
|
||||
JMP(asm_routines.dispatcher, true);
|
||||
JMP(asm_routines.outerLoop, true);
|
||||
}
|
||||
|
||||
void Jit64::WriteExceptionExit()
|
||||
|
|
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
static const u32 STATE_VERSION = 12;
|
||||
static const u32 STATE_VERSION = 13;
|
||||
|
||||
struct StateHeader
|
||||
{
|
||||
|
|
|
@ -215,7 +215,7 @@ bool CNANDContentLoader::Initialize(const std::string& _rName)
|
|||
{
|
||||
std::string TMDFileName(m_Path);
|
||||
|
||||
if (File::IsDirectory(TMDFileName))
|
||||
if ('/' == *TMDFileName.rbegin())
|
||||
TMDFileName += "title.tmd";
|
||||
else
|
||||
m_Path = TMDFileName.substr(0, TMDFileName.find("title.tmd"));
|
||||
|
|
|
@ -620,6 +620,7 @@ void CConfigMain::CreateGUIControls()
|
|||
{
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name = theme_selection->GetStringSelection();
|
||||
main_frame->InitBitmaps();
|
||||
main_frame->UpdateGameList();
|
||||
}));
|
||||
|
||||
auto const scInterface = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
|
|
@ -624,7 +624,9 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
|||
int stream_size = Common::swap16(objectdata);
|
||||
objectdata += 2;
|
||||
wxString newLabel = wxString::Format(wxT("%08X: %02X %04X "), obj_offset, cmd, stream_size);
|
||||
if ((objectdata_end - objectdata) % stream_size) newLabel += _("NOTE: Stream size doesn't match actual data length\n");
|
||||
if (stream_size && ((objectdata_end - objectdata) % stream_size))
|
||||
newLabel += _("NOTE: Stream size doesn't match actual data length\n");
|
||||
|
||||
while (objectdata < objectdata_end)
|
||||
{
|
||||
newLabel += wxString::Format(wxT("%02X"), *objectdata++);
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
#ifndef _INTERFACEGLX_H_
|
||||
#define _INTERFACEGLX_H_
|
||||
#ifndef _INTERFACEEGL_H_
|
||||
#define _INTERFACEEGL_H_
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#ifdef USE_GLES
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "FileSearch.h"
|
||||
#include "CompressedBlob.h"
|
||||
#include "ChunkFile.h"
|
||||
#include "../resources/no_banner.cpp"
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#define CACHE_REVISION 0x10F
|
||||
|
||||
|
@ -174,10 +174,16 @@ GameListItem::GameListItem(const std::string& _rFileName)
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string theme = SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name + "/";
|
||||
std::string dir = File::GetUserPath(D_THEMES_IDX) + theme;
|
||||
|
||||
#if !defined(_WIN32)
|
||||
// If theme does not exist in user's dir load from shared directory
|
||||
if (!File::Exists(dir))
|
||||
dir = SHARED_USER_DIR THEMES_DIR "/" + theme;
|
||||
#endif
|
||||
// default banner
|
||||
wxMemoryInputStream istream(no_banner_png, sizeof no_banner_png);
|
||||
wxImage iNoBanner(istream, wxBITMAP_TYPE_PNG);
|
||||
m_Image = iNoBanner;
|
||||
m_Image = wxImage(dir + "nobanner.png", wxBITMAP_TYPE_PNG);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -519,7 +519,7 @@ wxStaticBoxSizer* ControlDialog::CreateControlChooser(GamepadPage* const parent)
|
|||
button_sizer->Add(add_button, 1, 0, 5);
|
||||
}
|
||||
|
||||
range_slider = new wxSlider(this, -1, SLIDER_TICK_COUNT, 0, SLIDER_TICK_COUNT * 5, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/);
|
||||
range_slider = new wxSlider(this, -1, SLIDER_TICK_COUNT, -SLIDER_TICK_COUNT * 5, SLIDER_TICK_COUNT * 5, wxDefaultPosition, wxDefaultSize, wxSL_TOP | wxSL_LABELS /*| wxSL_AUTOTICKS*/);
|
||||
|
||||
range_slider->SetValue((int)(control_reference->range * SLIDER_TICK_COUNT));
|
||||
|
||||
|
|
|
@ -1,279 +0,0 @@
|
|||
static const unsigned char no_banner_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0xed, 0xc0, 0x7d, 0x54, 0x00, 0x00, 0x00,
|
||||
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
|
||||
0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x0a, 0x4f, 0x69, 0x43,
|
||||
0x43, 0x50, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20,
|
||||
0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00,
|
||||
0x00, 0x78, 0xda, 0x9d, 0x53, 0x67, 0x54, 0x53, 0xe9, 0x16, 0x3d, 0xf7,
|
||||
0xde, 0xf4, 0x42, 0x4b, 0x88, 0x80, 0x94, 0x4b, 0x6f, 0x52, 0x15, 0x08,
|
||||
0x20, 0x52, 0x42, 0x8b, 0x80, 0x14, 0x91, 0x26, 0x2a, 0x21, 0x09, 0x10,
|
||||
0x4a, 0x88, 0x21, 0xa1, 0xd9, 0x15, 0x51, 0xc1, 0x11, 0x45, 0x45, 0x04,
|
||||
0x1b, 0xc8, 0xa0, 0x88, 0x03, 0x8e, 0x8e, 0x80, 0x8c, 0x15, 0x51, 0x2c,
|
||||
0x0c, 0x8a, 0x0a, 0xd8, 0x07, 0xe4, 0x21, 0xa2, 0x8e, 0x83, 0xa3, 0x88,
|
||||
0x8a, 0xca, 0xfb, 0xe1, 0x7b, 0xa3, 0x6b, 0xd6, 0xbc, 0xf7, 0xe6, 0xcd,
|
||||
0xfe, 0xb5, 0xd7, 0x3e, 0xe7, 0xac, 0xf3, 0x9d, 0xb3, 0xcf, 0x07, 0xc0,
|
||||
0x08, 0x0c, 0x96, 0x48, 0x33, 0x51, 0x35, 0x80, 0x0c, 0xa9, 0x42, 0x1e,
|
||||
0x11, 0xe0, 0x83, 0xc7, 0xc4, 0xc6, 0xe1, 0xe4, 0x2e, 0x40, 0x81, 0x0a,
|
||||
0x24, 0x70, 0x00, 0x10, 0x08, 0xb3, 0x64, 0x21, 0x73, 0xfd, 0x23, 0x01,
|
||||
0x00, 0xf8, 0x7e, 0x3c, 0x3c, 0x2b, 0x22, 0xc0, 0x07, 0xbe, 0x00, 0x01,
|
||||
0x78, 0xd3, 0x0b, 0x08, 0x00, 0xc0, 0x4d, 0x9b, 0xc0, 0x30, 0x1c, 0x87,
|
||||
0xff, 0x0f, 0xea, 0x42, 0x99, 0x5c, 0x01, 0x80, 0x84, 0x01, 0xc0, 0x74,
|
||||
0x91, 0x38, 0x4b, 0x08, 0x80, 0x14, 0x00, 0x40, 0x7a, 0x8e, 0x42, 0xa6,
|
||||
0x00, 0x40, 0x46, 0x01, 0x80, 0x9d, 0x98, 0x26, 0x53, 0x00, 0xa0, 0x04,
|
||||
0x00, 0x60, 0xcb, 0x63, 0x62, 0xe3, 0x00, 0x50, 0x2d, 0x00, 0x60, 0x27,
|
||||
0x7f, 0xe6, 0xd3, 0x00, 0x80, 0x9d, 0xf8, 0x99, 0x7b, 0x01, 0x00, 0x5b,
|
||||
0x94, 0x21, 0x15, 0x01, 0xa0, 0x91, 0x00, 0x20, 0x13, 0x65, 0x88, 0x44,
|
||||
0x00, 0x68, 0x3b, 0x00, 0xac, 0xcf, 0x56, 0x8a, 0x45, 0x00, 0x58, 0x30,
|
||||
0x00, 0x14, 0x66, 0x4b, 0xc4, 0x39, 0x00, 0xd8, 0x2d, 0x00, 0x30, 0x49,
|
||||
0x57, 0x66, 0x48, 0x00, 0xb0, 0xb7, 0x00, 0xc0, 0xce, 0x10, 0x0b, 0xb2,
|
||||
0x00, 0x08, 0x0c, 0x00, 0x30, 0x51, 0x88, 0x85, 0x29, 0x00, 0x04, 0x7b,
|
||||
0x00, 0x60, 0xc8, 0x23, 0x23, 0x78, 0x00, 0x84, 0x99, 0x00, 0x14, 0x46,
|
||||
0xf2, 0x57, 0x3c, 0xf1, 0x2b, 0xae, 0x10, 0xe7, 0x2a, 0x00, 0x00, 0x78,
|
||||
0x99, 0xb2, 0x3c, 0xb9, 0x24, 0x39, 0x45, 0x81, 0x5b, 0x08, 0x2d, 0x71,
|
||||
0x07, 0x57, 0x57, 0x2e, 0x1e, 0x28, 0xce, 0x49, 0x17, 0x2b, 0x14, 0x36,
|
||||
0x61, 0x02, 0x61, 0x9a, 0x40, 0x2e, 0xc2, 0x79, 0x99, 0x19, 0x32, 0x81,
|
||||
0x34, 0x0f, 0xe0, 0xf3, 0xcc, 0x00, 0x00, 0xa0, 0x91, 0x15, 0x11, 0xe0,
|
||||
0x83, 0xf3, 0xfd, 0x78, 0xce, 0x0e, 0xae, 0xce, 0xce, 0x36, 0x8e, 0xb6,
|
||||
0x0e, 0x5f, 0x2d, 0xea, 0xbf, 0x06, 0xff, 0x22, 0x62, 0x62, 0xe3, 0xfe,
|
||||
0xe5, 0xcf, 0xab, 0x70, 0x40, 0x00, 0x00, 0xe1, 0x74, 0x7e, 0xd1, 0xfe,
|
||||
0x2c, 0x2f, 0xb3, 0x1a, 0x80, 0x3b, 0x06, 0x80, 0x6d, 0xfe, 0xa2, 0x25,
|
||||
0xee, 0x04, 0x68, 0x5e, 0x0b, 0xa0, 0x75, 0xf7, 0x8b, 0x66, 0xb2, 0x0f,
|
||||
0x40, 0xb5, 0x00, 0xa0, 0xe9, 0xda, 0x57, 0xf3, 0x70, 0xf8, 0x7e, 0x3c,
|
||||
0x3c, 0x45, 0xa1, 0x90, 0xb9, 0xd9, 0xd9, 0xe5, 0xe4, 0xe4, 0xd8, 0x4a,
|
||||
0xc4, 0x42, 0x5b, 0x61, 0xca, 0x57, 0x7d, 0xfe, 0x67, 0xc2, 0x5f, 0xc0,
|
||||
0x57, 0xfd, 0x6c, 0xf9, 0x7e, 0x3c, 0xfc, 0xf7, 0xf5, 0xe0, 0xbe, 0xe2,
|
||||
0x24, 0x81, 0x32, 0x5d, 0x81, 0x47, 0x04, 0xf8, 0xe0, 0xc2, 0xcc, 0xf4,
|
||||
0x4c, 0xa5, 0x1c, 0xcf, 0x92, 0x09, 0x84, 0x62, 0xdc, 0xe6, 0x8f, 0x47,
|
||||
0xfc, 0xb7, 0x0b, 0xff, 0xfc, 0x1d, 0xd3, 0x22, 0xc4, 0x49, 0x62, 0xb9,
|
||||
0x58, 0x2a, 0x14, 0xe3, 0x51, 0x12, 0x71, 0x8e, 0x44, 0x9a, 0x8c, 0xf3,
|
||||
0x32, 0xa5, 0x22, 0x89, 0x42, 0x92, 0x29, 0xc5, 0x25, 0xd2, 0xff, 0x64,
|
||||
0xe2, 0xdf, 0x2c, 0xfb, 0x03, 0x3e, 0xdf, 0x35, 0x00, 0xb0, 0x6a, 0x3e,
|
||||
0x01, 0x7b, 0x91, 0x2d, 0xa8, 0x5d, 0x63, 0x03, 0xf6, 0x4b, 0x27, 0x10,
|
||||
0x58, 0x74, 0xc0, 0xe2, 0xf7, 0x00, 0x00, 0xf2, 0xbb, 0x6f, 0xc1, 0xd4,
|
||||
0x28, 0x08, 0x03, 0x80, 0x68, 0x83, 0xe1, 0xcf, 0x77, 0xff, 0xef, 0x3f,
|
||||
0xfd, 0x47, 0xa0, 0x25, 0x00, 0x80, 0x66, 0x49, 0x92, 0x71, 0x00, 0x00,
|
||||
0x5e, 0x44, 0x24, 0x2e, 0x54, 0xca, 0xb3, 0x3f, 0xc7, 0x08, 0x00, 0x00,
|
||||
0x44, 0xa0, 0x81, 0x2a, 0xb0, 0x41, 0x1b, 0xf4, 0xc1, 0x18, 0x2c, 0xc0,
|
||||
0x06, 0x1c, 0xc1, 0x05, 0xdc, 0xc1, 0x0b, 0xfc, 0x60, 0x36, 0x84, 0x42,
|
||||
0x24, 0xc4, 0xc2, 0x42, 0x10, 0x42, 0x0a, 0x64, 0x80, 0x1c, 0x72, 0x60,
|
||||
0x29, 0xac, 0x82, 0x42, 0x28, 0x86, 0xcd, 0xb0, 0x1d, 0x2a, 0x60, 0x2f,
|
||||
0xd4, 0x40, 0x1d, 0x34, 0xc0, 0x51, 0x68, 0x86, 0x93, 0x70, 0x0e, 0x2e,
|
||||
0xc2, 0x55, 0xb8, 0x0e, 0x3d, 0x70, 0x0f, 0xfa, 0x61, 0x08, 0x9e, 0xc1,
|
||||
0x28, 0xbc, 0x81, 0x09, 0x04, 0x41, 0xc8, 0x08, 0x13, 0x61, 0x21, 0xda,
|
||||
0x88, 0x01, 0x62, 0x8a, 0x58, 0x23, 0x8e, 0x08, 0x17, 0x99, 0x85, 0xf8,
|
||||
0x21, 0xc1, 0x48, 0x04, 0x12, 0x8b, 0x24, 0x20, 0xc9, 0x88, 0x14, 0x51,
|
||||
0x22, 0x4b, 0x91, 0x35, 0x48, 0x31, 0x52, 0x8a, 0x54, 0x20, 0x55, 0x48,
|
||||
0x1d, 0xf2, 0x3d, 0x72, 0x02, 0x39, 0x87, 0x5c, 0x46, 0xba, 0x91, 0x3b,
|
||||
0xc8, 0x00, 0x32, 0x82, 0xfc, 0x86, 0xbc, 0x47, 0x31, 0x94, 0x81, 0xb2,
|
||||
0x51, 0x3d, 0xd4, 0x0c, 0xb5, 0x43, 0xb9, 0xa8, 0x37, 0x1a, 0x84, 0x46,
|
||||
0xa2, 0x0b, 0xd0, 0x64, 0x74, 0x31, 0x9a, 0x8f, 0x16, 0xa0, 0x9b, 0xd0,
|
||||
0x72, 0xb4, 0x1a, 0x3d, 0x8c, 0x36, 0xa1, 0xe7, 0xd0, 0xab, 0x68, 0x0f,
|
||||
0xda, 0x8f, 0x3e, 0x43, 0xc7, 0x30, 0xc0, 0xe8, 0x18, 0x07, 0x33, 0xc4,
|
||||
0x6c, 0x30, 0x2e, 0xc6, 0xc3, 0x42, 0xb1, 0x38, 0x2c, 0x09, 0x93, 0x63,
|
||||
0xcb, 0xb1, 0x22, 0xac, 0x0c, 0xab, 0xc6, 0x1a, 0xb0, 0x56, 0xac, 0x03,
|
||||
0xbb, 0x89, 0xf5, 0x63, 0xcf, 0xb1, 0x77, 0x04, 0x12, 0x81, 0x45, 0xc0,
|
||||
0x09, 0x36, 0x04, 0x77, 0x42, 0x20, 0x61, 0x1e, 0x41, 0x48, 0x58, 0x4c,
|
||||
0x58, 0x4e, 0xd8, 0x48, 0xa8, 0x20, 0x1c, 0x24, 0x34, 0x11, 0xda, 0x09,
|
||||
0x37, 0x09, 0x03, 0x84, 0x51, 0xc2, 0x27, 0x22, 0x93, 0xa8, 0x4b, 0xb4,
|
||||
0x26, 0xba, 0x11, 0xf9, 0xc4, 0x18, 0x62, 0x32, 0x31, 0x87, 0x58, 0x48,
|
||||
0x2c, 0x23, 0xd6, 0x12, 0x8f, 0x13, 0x2f, 0x10, 0x7b, 0x88, 0x43, 0xc4,
|
||||
0x37, 0x24, 0x12, 0x89, 0x43, 0x32, 0x27, 0xb9, 0x90, 0x02, 0x49, 0xb1,
|
||||
0xa4, 0x54, 0xd2, 0x12, 0xd2, 0x46, 0xd2, 0x6e, 0x52, 0x23, 0xe9, 0x2c,
|
||||
0xa9, 0x9b, 0x34, 0x48, 0x1a, 0x23, 0x93, 0xc9, 0xda, 0x64, 0x6b, 0xb2,
|
||||
0x07, 0x39, 0x94, 0x2c, 0x20, 0x2b, 0xc8, 0x85, 0xe4, 0x9d, 0xe4, 0xc3,
|
||||
0xe4, 0x33, 0xe4, 0x1b, 0xe4, 0x21, 0xf2, 0x5b, 0x0a, 0x9d, 0x62, 0x40,
|
||||
0x71, 0xa4, 0xf8, 0x53, 0xe2, 0x28, 0x52, 0xca, 0x6a, 0x4a, 0x19, 0xe5,
|
||||
0x10, 0xe5, 0x34, 0xe5, 0x06, 0x65, 0x98, 0x32, 0x41, 0x55, 0xa3, 0x9a,
|
||||
0x52, 0xdd, 0xa8, 0xa1, 0x54, 0x11, 0x35, 0x8f, 0x5a, 0x42, 0xad, 0xa1,
|
||||
0xb6, 0x52, 0xaf, 0x51, 0x87, 0xa8, 0x13, 0x34, 0x75, 0x9a, 0x39, 0xcd,
|
||||
0x83, 0x16, 0x49, 0x4b, 0xa5, 0xad, 0xa2, 0x95, 0xd3, 0x1a, 0x68, 0x17,
|
||||
0x68, 0xf7, 0x69, 0xaf, 0xe8, 0x74, 0xba, 0x11, 0xdd, 0x95, 0x1e, 0x4e,
|
||||
0x97, 0xd0, 0x57, 0xd2, 0xcb, 0xe9, 0x47, 0xe8, 0x97, 0xe8, 0x03, 0xf4,
|
||||
0x77, 0x0c, 0x0d, 0x86, 0x15, 0x83, 0xc7, 0x88, 0x67, 0x28, 0x19, 0x9b,
|
||||
0x18, 0x07, 0x18, 0x67, 0x19, 0x77, 0x18, 0xaf, 0x98, 0x4c, 0xa6, 0x19,
|
||||
0xd3, 0x8b, 0x19, 0xc7, 0x54, 0x30, 0x37, 0x31, 0xeb, 0x98, 0xe7, 0x99,
|
||||
0x0f, 0x99, 0x6f, 0x55, 0x58, 0x2a, 0xb6, 0x2a, 0x7c, 0x15, 0x91, 0xca,
|
||||
0x0a, 0x95, 0x4a, 0x95, 0x26, 0x95, 0x1b, 0x2a, 0x2f, 0x54, 0xa9, 0xaa,
|
||||
0xa6, 0xaa, 0xde, 0xaa, 0x0b, 0x55, 0xf3, 0x55, 0xcb, 0x54, 0x8f, 0xa9,
|
||||
0x5e, 0x53, 0x7d, 0xae, 0x46, 0x55, 0x33, 0x53, 0xe3, 0xa9, 0x09, 0xd4,
|
||||
0x96, 0xab, 0x55, 0xaa, 0x9d, 0x50, 0xeb, 0x53, 0x1b, 0x53, 0x67, 0xa9,
|
||||
0x3b, 0xa8, 0x87, 0xaa, 0x67, 0xa8, 0x6f, 0x54, 0x3f, 0xa4, 0x7e, 0x59,
|
||||
0xfd, 0x89, 0x06, 0x59, 0xc3, 0x4c, 0xc3, 0x4f, 0x43, 0xa4, 0x51, 0xa0,
|
||||
0xb1, 0x5f, 0xe3, 0xbc, 0xc6, 0x20, 0x0b, 0x63, 0x19, 0xb3, 0x78, 0x2c,
|
||||
0x21, 0x6b, 0x0d, 0xab, 0x86, 0x75, 0x81, 0x35, 0xc4, 0x26, 0xb1, 0xcd,
|
||||
0xd9, 0x7c, 0x76, 0x2a, 0xbb, 0x98, 0xfd, 0x1d, 0xbb, 0x8b, 0x3d, 0xaa,
|
||||
0xa9, 0xa1, 0x39, 0x43, 0x33, 0x4a, 0x33, 0x57, 0xb3, 0x52, 0xf3, 0x94,
|
||||
0x66, 0x3f, 0x07, 0xe3, 0x98, 0x71, 0xf8, 0x9c, 0x74, 0x4e, 0x09, 0xe7,
|
||||
0x28, 0xa7, 0x97, 0xf3, 0x7e, 0x8a, 0xde, 0x14, 0xef, 0x29, 0xe2, 0x29,
|
||||
0x1b, 0xa6, 0x34, 0x4c, 0xb9, 0x31, 0x65, 0x5c, 0x6b, 0xaa, 0x96, 0x97,
|
||||
0x96, 0x58, 0xab, 0x48, 0xab, 0x51, 0xab, 0x47, 0xeb, 0xbd, 0x36, 0xae,
|
||||
0xed, 0xa7, 0x9d, 0xa6, 0xbd, 0x45, 0xbb, 0x59, 0xfb, 0x81, 0x0e, 0x41,
|
||||
0xc7, 0x4a, 0x27, 0x5c, 0x27, 0x47, 0x67, 0x8f, 0xce, 0x05, 0x9d, 0xe7,
|
||||
0x53, 0xd9, 0x53, 0xdd, 0xa7, 0x0a, 0xa7, 0x16, 0x4d, 0x3d, 0x3a, 0xf5,
|
||||
0xae, 0x2e, 0xaa, 0x6b, 0xa5, 0x1b, 0xa1, 0xbb, 0x44, 0x77, 0xbf, 0x6e,
|
||||
0xa7, 0xee, 0x98, 0x9e, 0xbe, 0x5e, 0x80, 0x9e, 0x4c, 0x6f, 0xa7, 0xde,
|
||||
0x79, 0xbd, 0xe7, 0xfa, 0x1c, 0x7d, 0x2f, 0xfd, 0x54, 0xfd, 0x6d, 0xfa,
|
||||
0xa7, 0xf5, 0x47, 0x0c, 0x58, 0x06, 0xb3, 0x0c, 0x24, 0x06, 0xdb, 0x0c,
|
||||
0xce, 0x18, 0x3c, 0xc5, 0x35, 0x71, 0x6f, 0x3c, 0x1d, 0x2f, 0xc7, 0xdb,
|
||||
0xf1, 0x51, 0x43, 0x5d, 0xc3, 0x40, 0x43, 0xa5, 0x61, 0x95, 0x61, 0x97,
|
||||
0xe1, 0x84, 0x91, 0xb9, 0xd1, 0x3c, 0xa3, 0xd5, 0x46, 0x8d, 0x46, 0x0f,
|
||||
0x8c, 0x69, 0xc6, 0x5c, 0xe3, 0x24, 0xe3, 0x6d, 0xc6, 0x6d, 0xc6, 0xa3,
|
||||
0x26, 0x06, 0x26, 0x21, 0x26, 0x4b, 0x4d, 0xea, 0x4d, 0xee, 0x9a, 0x52,
|
||||
0x4d, 0xb9, 0xa6, 0x29, 0xa6, 0x3b, 0x4c, 0x3b, 0x4c, 0xc7, 0xcd, 0xcc,
|
||||
0xcd, 0xa2, 0xcd, 0xd6, 0x99, 0x35, 0x9b, 0x3d, 0x31, 0xd7, 0x32, 0xe7,
|
||||
0x9b, 0xe7, 0x9b, 0xd7, 0x9b, 0xdf, 0xb7, 0x60, 0x5a, 0x78, 0x5a, 0x2c,
|
||||
0xb6, 0xa8, 0xb6, 0xb8, 0x65, 0x49, 0xb2, 0xe4, 0x5a, 0xa6, 0x59, 0xee,
|
||||
0xb6, 0xbc, 0x6e, 0x85, 0x5a, 0x39, 0x59, 0xa5, 0x58, 0x55, 0x5a, 0x5d,
|
||||
0xb3, 0x46, 0xad, 0x9d, 0xad, 0x25, 0xd6, 0xbb, 0xad, 0xbb, 0xa7, 0x11,
|
||||
0xa7, 0xb9, 0x4e, 0x93, 0x4e, 0xab, 0x9e, 0xd6, 0x67, 0xc3, 0xb0, 0xf1,
|
||||
0xb6, 0xc9, 0xb6, 0xa9, 0xb7, 0x19, 0xb0, 0xe5, 0xd8, 0x06, 0xdb, 0xae,
|
||||
0xb6, 0x6d, 0xb6, 0x7d, 0x61, 0x67, 0x62, 0x17, 0x67, 0xb7, 0xc5, 0xae,
|
||||
0xc3, 0xee, 0x93, 0xbd, 0x93, 0x7d, 0xba, 0x7d, 0x8d, 0xfd, 0x3d, 0x07,
|
||||
0x0d, 0x87, 0xd9, 0x0e, 0xab, 0x1d, 0x5a, 0x1d, 0x7e, 0x73, 0xb4, 0x72,
|
||||
0x14, 0x3a, 0x56, 0x3a, 0xde, 0x9a, 0xce, 0x9c, 0xee, 0x3f, 0x7d, 0xc5,
|
||||
0xf4, 0x96, 0xe9, 0x2f, 0x67, 0x58, 0xcf, 0x10, 0xcf, 0xd8, 0x33, 0xe3,
|
||||
0xb6, 0x13, 0xcb, 0x29, 0xc4, 0x69, 0x9d, 0x53, 0x9b, 0xd3, 0x47, 0x67,
|
||||
0x17, 0x67, 0xb9, 0x73, 0x83, 0xf3, 0x88, 0x8b, 0x89, 0x4b, 0x82, 0xcb,
|
||||
0x2e, 0x97, 0x3e, 0x2e, 0x9b, 0x1b, 0xc6, 0xdd, 0xc8, 0xbd, 0xe4, 0x4a,
|
||||
0x74, 0xf5, 0x71, 0x5d, 0xe1, 0x7a, 0xd2, 0xf5, 0x9d, 0x9b, 0xb3, 0x9b,
|
||||
0xc2, 0xed, 0xa8, 0xdb, 0xaf, 0xee, 0x36, 0xee, 0x69, 0xee, 0x87, 0xdc,
|
||||
0x9f, 0xcc, 0x34, 0x9f, 0x29, 0x9e, 0x59, 0x33, 0x73, 0xd0, 0xc3, 0xc8,
|
||||
0x43, 0xe0, 0x51, 0xe5, 0xd1, 0x3f, 0x0b, 0x9f, 0x95, 0x30, 0x6b, 0xdf,
|
||||
0xac, 0x7e, 0x4f, 0x43, 0x4f, 0x81, 0x67, 0xb5, 0xe7, 0x23, 0x2f, 0x63,
|
||||
0x2f, 0x91, 0x57, 0xad, 0xd7, 0xb0, 0xb7, 0xa5, 0x77, 0xaa, 0xf7, 0x61,
|
||||
0xef, 0x17, 0x3e, 0xf6, 0x3e, 0x72, 0x9f, 0xe3, 0x3e, 0xe3, 0x3c, 0x37,
|
||||
0xde, 0x32, 0xde, 0x59, 0x5f, 0xcc, 0x37, 0xc0, 0xb7, 0xc8, 0xb7, 0xcb,
|
||||
0x4f, 0xc3, 0x6f, 0x9e, 0x5f, 0x85, 0xdf, 0x43, 0x7f, 0x23, 0xff, 0x64,
|
||||
0xff, 0x7a, 0xff, 0xd1, 0x00, 0xa7, 0x80, 0x25, 0x01, 0x67, 0x03, 0x89,
|
||||
0x81, 0x41, 0x81, 0x5b, 0x02, 0xfb, 0xf8, 0x7a, 0x7c, 0x21, 0xbf, 0x8e,
|
||||
0x3f, 0x3a, 0xdb, 0x65, 0xf6, 0xb2, 0xd9, 0xed, 0x41, 0x8c, 0xa0, 0xb9,
|
||||
0x41, 0x15, 0x41, 0x8f, 0x82, 0xad, 0x82, 0xe5, 0xc1, 0xad, 0x21, 0x68,
|
||||
0xc8, 0xec, 0x90, 0xad, 0x21, 0xf7, 0xe7, 0x98, 0xce, 0x91, 0xce, 0x69,
|
||||
0x0e, 0x85, 0x50, 0x7e, 0xe8, 0xd6, 0xd0, 0x07, 0x61, 0xe6, 0x61, 0x8b,
|
||||
0xc3, 0x7e, 0x0c, 0x27, 0x85, 0x87, 0x85, 0x57, 0x86, 0x3f, 0x8e, 0x70,
|
||||
0x88, 0x58, 0x1a, 0xd1, 0x31, 0x97, 0x35, 0x77, 0xd1, 0xdc, 0x43, 0x73,
|
||||
0xdf, 0x44, 0xfa, 0x44, 0x96, 0x44, 0xde, 0x9b, 0x67, 0x31, 0x4f, 0x39,
|
||||
0xaf, 0x2d, 0x4a, 0x35, 0x2a, 0x3e, 0xaa, 0x2e, 0x6a, 0x3c, 0xda, 0x37,
|
||||
0xba, 0x34, 0xba, 0x3f, 0xc6, 0x2e, 0x66, 0x59, 0xcc, 0xd5, 0x58, 0x9d,
|
||||
0x58, 0x49, 0x6c, 0x4b, 0x1c, 0x39, 0x2e, 0x2a, 0xae, 0x36, 0x6e, 0x6c,
|
||||
0xbe, 0xdf, 0xfc, 0xed, 0xf3, 0x87, 0xe2, 0x9d, 0xe2, 0x0b, 0xe3, 0x7b,
|
||||
0x17, 0x98, 0x2f, 0xc8, 0x5d, 0x70, 0x79, 0xa1, 0xce, 0xc2, 0xf4, 0x85,
|
||||
0xa7, 0x16, 0xa9, 0x2e, 0x12, 0x2c, 0x3a, 0x96, 0x40, 0x4c, 0x88, 0x4e,
|
||||
0x38, 0x94, 0xf0, 0x41, 0x10, 0x2a, 0xa8, 0x16, 0x8c, 0x25, 0xf2, 0x13,
|
||||
0x77, 0x25, 0x8e, 0x0a, 0x79, 0xc2, 0x1d, 0xc2, 0x67, 0x22, 0x2f, 0xd1,
|
||||
0x36, 0xd1, 0x88, 0xd8, 0x43, 0x5c, 0x2a, 0x1e, 0x4e, 0xf2, 0x48, 0x2a,
|
||||
0x4d, 0x7a, 0x92, 0xec, 0x91, 0xbc, 0x35, 0x79, 0x24, 0xc5, 0x33, 0xa5,
|
||||
0x2c, 0xe5, 0xb9, 0x84, 0x27, 0xa9, 0x90, 0xbc, 0x4c, 0x0d, 0x4c, 0xdd,
|
||||
0x9b, 0x3a, 0x9e, 0x16, 0x9a, 0x76, 0x20, 0x6d, 0x32, 0x3d, 0x3a, 0xbd,
|
||||
0x31, 0x83, 0x92, 0x91, 0x90, 0x71, 0x42, 0xaa, 0x21, 0x4d, 0x93, 0xb6,
|
||||
0x67, 0xea, 0x67, 0xe6, 0x66, 0x76, 0xcb, 0xac, 0x65, 0x85, 0xb2, 0xfe,
|
||||
0xc5, 0x6e, 0x8b, 0xb7, 0x2f, 0x1e, 0x95, 0x07, 0xc9, 0x6b, 0xb3, 0x90,
|
||||
0xac, 0x05, 0x59, 0x2d, 0x0a, 0xb6, 0x42, 0xa6, 0xe8, 0x54, 0x5a, 0x28,
|
||||
0xd7, 0x2a, 0x07, 0xb2, 0x67, 0x65, 0x57, 0x66, 0xbf, 0xcd, 0x89, 0xca,
|
||||
0x39, 0x96, 0xab, 0x9e, 0x2b, 0xcd, 0xed, 0xcc, 0xb3, 0xca, 0xdb, 0x90,
|
||||
0x37, 0x9c, 0xef, 0x9f, 0xff, 0xed, 0x12, 0xc2, 0x12, 0xe1, 0x92, 0xb6,
|
||||
0xa5, 0x86, 0x4b, 0x57, 0x2d, 0x1d, 0x58, 0xe6, 0xbd, 0xac, 0x6a, 0x39,
|
||||
0xb2, 0x3c, 0x71, 0x79, 0xdb, 0x0a, 0xe3, 0x15, 0x05, 0x2b, 0x86, 0x56,
|
||||
0x06, 0xac, 0x3c, 0xb8, 0x8a, 0xb6, 0x2a, 0x6d, 0xd5, 0x4f, 0xab, 0xed,
|
||||
0x57, 0x97, 0xae, 0x7e, 0xbd, 0x26, 0x7a, 0x4d, 0x6b, 0x81, 0x5e, 0xc1,
|
||||
0xca, 0x82, 0xc1, 0xb5, 0x01, 0x6b, 0xeb, 0x0b, 0x55, 0x0a, 0xe5, 0x85,
|
||||
0x7d, 0xeb, 0xdc, 0xd7, 0xed, 0x5d, 0x4f, 0x58, 0x2f, 0x59, 0xdf, 0xb5,
|
||||
0x61, 0xfa, 0x86, 0x9d, 0x1b, 0x3e, 0x15, 0x89, 0x8a, 0xae, 0x14, 0xdb,
|
||||
0x17, 0x97, 0x15, 0x7f, 0xd8, 0x28, 0xdc, 0x78, 0xe5, 0x1b, 0x87, 0x6f,
|
||||
0xca, 0xbf, 0x99, 0xdc, 0x94, 0xb4, 0xa9, 0xab, 0xc4, 0xb9, 0x64, 0xcf,
|
||||
0x66, 0xd2, 0x66, 0xe9, 0xe6, 0xde, 0x2d, 0x9e, 0x5b, 0x0e, 0x96, 0xaa,
|
||||
0x97, 0xe6, 0x97, 0x0e, 0x6e, 0x0d, 0xd9, 0xda, 0xb4, 0x0d, 0xdf, 0x56,
|
||||
0xb4, 0xed, 0xf5, 0xf6, 0x45, 0xdb, 0x2f, 0x97, 0xcd, 0x28, 0xdb, 0xbb,
|
||||
0x83, 0xb6, 0x43, 0xb9, 0xa3, 0xbf, 0x3c, 0xb8, 0xbc, 0x65, 0xa7, 0xc9,
|
||||
0xce, 0xcd, 0x3b, 0x3f, 0x54, 0xa4, 0x54, 0xf4, 0x54, 0xfa, 0x54, 0x36,
|
||||
0xee, 0xd2, 0xdd, 0xb5, 0x61, 0xd7, 0xf8, 0x6e, 0xd1, 0xee, 0x1b, 0x7b,
|
||||
0xbc, 0xf6, 0x34, 0xec, 0xd5, 0xdb, 0x5b, 0xbc, 0xf7, 0xfd, 0x3e, 0xc9,
|
||||
0xbe, 0xdb, 0x55, 0x01, 0x55, 0x4d, 0xd5, 0x66, 0xd5, 0x65, 0xfb, 0x49,
|
||||
0xfb, 0xb3, 0xf7, 0x3f, 0xae, 0x89, 0xaa, 0xe9, 0xf8, 0x96, 0xfb, 0x6d,
|
||||
0x5d, 0xad, 0x4e, 0x6d, 0x71, 0xed, 0xc7, 0x03, 0xd2, 0x03, 0xfd, 0x07,
|
||||
0x23, 0x0e, 0xb6, 0xd7, 0xb9, 0xd4, 0xd5, 0x1d, 0xd2, 0x3d, 0x54, 0x52,
|
||||
0x8f, 0xd6, 0x2b, 0xeb, 0x47, 0x0e, 0xc7, 0x1f, 0xbe, 0xfe, 0x9d, 0xef,
|
||||
0x77, 0x2d, 0x0d, 0x36, 0x0d, 0x55, 0x8d, 0x9c, 0xc6, 0xe2, 0x23, 0x70,
|
||||
0x44, 0x79, 0xe4, 0xe9, 0xf7, 0x09, 0xdf, 0xf7, 0x1e, 0x0d, 0x3a, 0xda,
|
||||
0x76, 0x8c, 0x7b, 0xac, 0xe1, 0x07, 0xd3, 0x1f, 0x76, 0x1d, 0x67, 0x1d,
|
||||
0x2f, 0x6a, 0x42, 0x9a, 0xf2, 0x9a, 0x46, 0x9b, 0x53, 0x9a, 0xfb, 0x5b,
|
||||
0x62, 0x5b, 0xba, 0x4f, 0xcc, 0x3e, 0xd1, 0xd6, 0xea, 0xde, 0x7a, 0xfc,
|
||||
0x47, 0xdb, 0x1f, 0x0f, 0x9c, 0x34, 0x3c, 0x59, 0x79, 0x4a, 0xf3, 0x54,
|
||||
0xc9, 0x69, 0xda, 0xe9, 0x82, 0xd3, 0x93, 0x67, 0xf2, 0xcf, 0x8c, 0x9d,
|
||||
0x95, 0x9d, 0x7d, 0x7e, 0x2e, 0xf9, 0xdc, 0x60, 0xdb, 0xa2, 0xb6, 0x7b,
|
||||
0xe7, 0x63, 0xce, 0xdf, 0x6a, 0x0f, 0x6f, 0xef, 0xba, 0x10, 0x74, 0xe1,
|
||||
0xd2, 0x45, 0xff, 0x8b, 0xe7, 0x3b, 0xbc, 0x3b, 0xce, 0x5c, 0xf2, 0xb8,
|
||||
0x74, 0xf2, 0xb2, 0xdb, 0xe5, 0x13, 0x57, 0xb8, 0x57, 0x9a, 0xaf, 0x3a,
|
||||
0x5f, 0x6d, 0xea, 0x74, 0xea, 0x3c, 0xfe, 0x93, 0xd3, 0x4f, 0xc7, 0xbb,
|
||||
0x9c, 0xbb, 0x9a, 0xae, 0xb9, 0x5c, 0x6b, 0xb9, 0xee, 0x7a, 0xbd, 0xb5,
|
||||
0x7b, 0x66, 0xf7, 0xe9, 0x1b, 0x9e, 0x37, 0xce, 0xdd, 0xf4, 0xbd, 0x79,
|
||||
0xf1, 0x16, 0xff, 0xd6, 0xd5, 0x9e, 0x39, 0x3d, 0xdd, 0xbd, 0xf3, 0x7a,
|
||||
0x6f, 0xf7, 0xc5, 0xf7, 0xf5, 0xdf, 0x16, 0xdd, 0x7e, 0x72, 0x27, 0xfd,
|
||||
0xce, 0xcb, 0xbb, 0xd9, 0x77, 0x27, 0xee, 0xad, 0xbc, 0x4f, 0xbc, 0x5f,
|
||||
0xf4, 0x40, 0xed, 0x41, 0xd9, 0x43, 0xdd, 0x87, 0xd5, 0x3f, 0x5b, 0xfe,
|
||||
0xdc, 0xd8, 0xef, 0xdc, 0x7f, 0x6a, 0xc0, 0x77, 0xa0, 0xf3, 0xd1, 0xdc,
|
||||
0x47, 0xf7, 0x06, 0x85, 0x83, 0xcf, 0xfe, 0x91, 0xf5, 0x8f, 0x0f, 0x43,
|
||||
0x05, 0x8f, 0x99, 0x8f, 0xcb, 0x86, 0x0d, 0x86, 0xeb, 0x9e, 0x38, 0x3e,
|
||||
0x39, 0x39, 0xe2, 0x3f, 0x72, 0xfd, 0xe9, 0xfc, 0xa7, 0x43, 0xcf, 0x64,
|
||||
0xcf, 0x26, 0x9e, 0x17, 0xfe, 0xa2, 0xfe, 0xcb, 0xae, 0x17, 0x16, 0x2f,
|
||||
0x7e, 0xf8, 0xd5, 0xeb, 0xd7, 0xce, 0xd1, 0x98, 0xd1, 0xa1, 0x97, 0xf2,
|
||||
0x97, 0x93, 0xbf, 0x6d, 0x7c, 0xa5, 0xfd, 0xea, 0xc0, 0xeb, 0x19, 0xaf,
|
||||
0xdb, 0xc6, 0xc2, 0xc6, 0x1e, 0xbe, 0xc9, 0x78, 0x33, 0x31, 0x5e, 0xf4,
|
||||
0x56, 0xfb, 0xed, 0xc1, 0x77, 0xdc, 0x77, 0x1d, 0xef, 0xa3, 0xdf, 0x0f,
|
||||
0x4f, 0xe4, 0x7c, 0x20, 0x7f, 0x28, 0xff, 0x68, 0xf9, 0xb1, 0xf5, 0x53,
|
||||
0xd0, 0xa7, 0xfb, 0x93, 0x19, 0x93, 0x93, 0xff, 0x04, 0x03, 0x98, 0xf3,
|
||||
0xfc, 0x63, 0x33, 0x2d, 0xdb, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52,
|
||||
0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9,
|
||||
0xff, 0x00, 0x00, 0x80, 0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea,
|
||||
0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5,
|
||||
0x46, 0x00, 0x00, 0x02, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec,
|
||||
0x98, 0x4d, 0x4e, 0x02, 0x41, 0x10, 0x85, 0x3f, 0x8d, 0xdb, 0xb9, 0x80,
|
||||
0x73, 0x01, 0x70, 0x2f, 0xee, 0x41, 0xf7, 0x72, 0x00, 0x0d, 0x7b, 0xc2,
|
||||
0xde, 0xc4, 0xb5, 0x09, 0x7b, 0xc2, 0xde, 0xe0, 0x01, 0xd0, 0xbd, 0x5c,
|
||||
0x00, 0x2e, 0xc0, 0x05, 0xe4, 0x00, 0xce, 0x01, 0x74, 0x53, 0x9d, 0x54,
|
||||
0xda, 0xea, 0x99, 0x46, 0x51, 0x8c, 0xd6, 0x4b, 0x3a, 0x0c, 0xdd, 0x3d,
|
||||
0x5d, 0x5d, 0xf5, 0xea, 0x2f, 0x73, 0x00, 0xbc, 0xe1, 0xd8, 0x1b, 0x0e,
|
||||
0xdd, 0x04, 0x4e, 0x80, 0x13, 0xe0, 0x70, 0x02, 0x9c, 0x00, 0x87, 0x13,
|
||||
0xe0, 0x04, 0x38, 0x9c, 0x00, 0x27, 0xc0, 0xe1, 0x04, 0x38, 0x01, 0x0e,
|
||||
0x27, 0xe0, 0xdf, 0xe0, 0xc8, 0x9a, 0x6c, 0x01, 0x13, 0xa0, 0x34, 0xd6,
|
||||
0x66, 0xc0, 0x58, 0x9e, 0xfb, 0xc0, 0x0d, 0x50, 0x18, 0xfb, 0x5e, 0x80,
|
||||
0x11, 0xb0, 0xce, 0xb8, 0x44, 0x07, 0xb8, 0x4f, 0xac, 0x55, 0x22, 0x73,
|
||||
0x9a, 0x71, 0xce, 0x50, 0x86, 0x96, 0x9d, 0xba, 0x63, 0x25, 0x7a, 0xcc,
|
||||
0xe5, 0xff, 0x0d, 0x70, 0xdd, 0xa0, 0x47, 0x21, 0x76, 0xe9, 0x18, 0xfb,
|
||||
0x96, 0xc0, 0x4a, 0xe4, 0x93, 0x38, 0x67, 0x0c, 0x2c, 0xa2, 0xf9, 0x03,
|
||||
0xa2, 0xaf, 0xa1, 0x05, 0xf0, 0x9c, 0x30, 0x6a, 0xc0, 0x54, 0x84, 0xdd,
|
||||
0x37, 0x18, 0xa4, 0x02, 0xce, 0xe5, 0xf7, 0xb3, 0x04, 0x04, 0xdc, 0x2a,
|
||||
0x63, 0x59, 0xb8, 0x13, 0x63, 0x07, 0x2c, 0x80, 0x87, 0x8c, 0x73, 0x07,
|
||||
0xc0, 0x69, 0x8d, 0xe1, 0xb4, 0x1e, 0x29, 0xe3, 0xe7, 0x10, 0x10, 0x70,
|
||||
0x21, 0x64, 0x24, 0x53, 0x50, 0x5b, 0x8c, 0xbf, 0x06, 0x4e, 0xa2, 0x31,
|
||||
0x92, 0x3d, 0xa7, 0x32, 0x42, 0x44, 0x9c, 0x18, 0x23, 0x78, 0x4c, 0x7b,
|
||||
0x8b, 0x70, 0x5c, 0xd6, 0xc8, 0x3c, 0xce, 0x34, 0xfe, 0x42, 0x39, 0x52,
|
||||
0xdd, 0x1d, 0x67, 0x86, 0x2e, 0xa3, 0x06, 0x3d, 0x82, 0xf1, 0xcf, 0x8c,
|
||||
0x7d, 0x83, 0xc8, 0x41, 0x53, 0xf2, 0xca, 0x9c, 0x14, 0x04, 0xf0, 0x9a,
|
||||
0xf0, 0x84, 0x9c, 0xb9, 0xd4, 0xfb, 0x4d, 0x68, 0x1b, 0x1e, 0x5b, 0x36,
|
||||
0xc8, 0xd1, 0xc6, 0xaf, 0x12, 0x69, 0xb3, 0xfa, 0xc2, 0x9c, 0xa5, 0xc7,
|
||||
0xc4, 0x98, 0x7b, 0x52, 0xcf, 0x97, 0x8a, 0x54, 0xad, 0x9b, 0x75, 0xde,
|
||||
0xd1, 0x6f, 0x2a, 0x48, 0x45, 0x4d, 0x88, 0x57, 0x89, 0x9c, 0xdf, 0x8f,
|
||||
0xde, 0x6f, 0xfd, 0xc0, 0x3d, 0xad, 0x3b, 0xae, 0x22, 0xa7, 0x29, 0x33,
|
||||
0xf5, 0xf8, 0x55, 0x04, 0xac, 0x55, 0x81, 0x47, 0xa5, 0x88, 0x21, 0xd0,
|
||||
0x8d, 0x6a, 0x40, 0x5f, 0xe5, 0xdb, 0xb1, 0x2a, 0xf6, 0x2d, 0x29, 0xa8,
|
||||
0xdf, 0x89, 0x41, 0xa2, 0xc8, 0x5e, 0xca, 0xf3, 0x3c, 0x8a, 0x08, 0x80,
|
||||
0x2b, 0xa0, 0x27, 0x7b, 0xa6, 0xbb, 0x20, 0x20, 0x30, 0xd9, 0xab, 0x49,
|
||||
0x27, 0xdb, 0xa6, 0xa2, 0xc2, 0x08, 0x5d, 0xcb, 0xa3, 0xfb, 0x92, 0x7a,
|
||||
0x72, 0x8a, 0xf3, 0x2e, 0x51, 0xc9, 0x1d, 0xbb, 0x86, 0x27, 0x6b, 0x8f,
|
||||
0xdf, 0x48, 0x3d, 0x8b, 0x1d, 0xa9, 0x97, 0xdb, 0x86, 0xe6, 0x60, 0x2e,
|
||||
0x6c, 0xb6, 0x6a, 0xc2, 0x7e, 0x9e, 0xd9, 0x86, 0x6a, 0x25, 0x86, 0x09,
|
||||
0xc5, 0xa7, 0x7b, 0x36, 0x7e, 0x88, 0xb4, 0xbb, 0x44, 0xbb, 0xba, 0x8c,
|
||||
0xd2, 0x50, 0x2e, 0x3e, 0xb4, 0xa1, 0xa5, 0x18, 0x76, 0x63, 0x28, 0x17,
|
||||
0xaf, 0x15, 0x62, 0x10, 0xab, 0x65, 0xdd, 0x6c, 0x61, 0x9c, 0x52, 0x85,
|
||||
0xaf, 0x85, 0x47, 0x09, 0x71, 0xbd, 0x6f, 0x6d, 0xf4, 0xd4, 0xf1, 0x1d,
|
||||
0x5f, 0xc4, 0xf3, 0x56, 0x86, 0x47, 0x76, 0xd4, 0x5a, 0x29, 0x5d, 0xd6,
|
||||
0x63, 0xd4, 0x22, 0x06, 0xc2, 0xf5, 0x5a, 0xc7, 0x88, 0x52, 0xb6, 0x94,
|
||||
0xb7, 0xac, 0x23, 0xc0, 0xe1, 0x9f, 0x22, 0x9c, 0x00, 0x87, 0x13, 0xe0,
|
||||
0x04, 0x38, 0x9c, 0x00, 0x27, 0xc0, 0xe1, 0x04, 0x38, 0x01, 0x0e, 0x27,
|
||||
0xe0, 0x4f, 0xe3, 0x7d, 0x00, 0x51, 0xbe, 0x83, 0xcd, 0x57, 0x34, 0x65,
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60,
|
||||
0x82,
|
||||
};
|
|
@ -84,35 +84,34 @@ TextureCache::~TextureCache()
|
|||
|
||||
void TextureCache::OnConfigChanged(VideoConfig& config)
|
||||
{
|
||||
if (!g_texture_cache)
|
||||
goto skip_checks;
|
||||
|
||||
// TODO: Invalidating texcache is really stupid in some of these cases
|
||||
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
|
||||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
|
||||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
|
||||
config.bHiresTextures != backup_config.s_hires_textures)
|
||||
if (g_texture_cache)
|
||||
{
|
||||
g_texture_cache->Invalidate();
|
||||
// TODO: Invalidating texcache is really stupid in some of these cases
|
||||
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
|
||||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
|
||||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
|
||||
config.bHiresTextures != backup_config.s_hires_textures)
|
||||
{
|
||||
g_texture_cache->Invalidate();
|
||||
|
||||
if(g_ActiveConfig.bHiresTextures)
|
||||
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
if(g_ActiveConfig.bHiresTextures)
|
||||
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
|
||||
|
||||
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
|
||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
|
||||
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
|
||||
}
|
||||
|
||||
// TODO: Probably shouldn't clear all render targets here, just mark them dirty or something.
|
||||
if (config.bEFBCopyCacheEnable != backup_config.s_copy_cache_enable || // TODO: not sure if this is needed?
|
||||
config.bCopyEFBToTexture != backup_config.s_copy_efb_to_texture ||
|
||||
config.bCopyEFBScaled != backup_config.s_copy_efb_scaled ||
|
||||
config.bEFBCopyEnable != backup_config.s_copy_efb ||
|
||||
config.iEFBScale != backup_config.s_efb_scale)
|
||||
{
|
||||
g_texture_cache->ClearRenderTargets();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Probably shouldn't clear all render targets here, just mark them dirty or something.
|
||||
if (config.bEFBCopyCacheEnable != backup_config.s_copy_cache_enable || // TODO: not sure if this is needed?
|
||||
config.bCopyEFBToTexture != backup_config.s_copy_efb_to_texture ||
|
||||
config.bCopyEFBScaled != backup_config.s_copy_efb_scaled ||
|
||||
config.bEFBCopyEnable != backup_config.s_copy_efb ||
|
||||
config.iEFBScale != backup_config.s_efb_scale)
|
||||
{
|
||||
g_texture_cache->ClearRenderTargets();
|
||||
}
|
||||
|
||||
skip_checks:
|
||||
|
||||
backup_config.s_colorsamples = config.iSafeTextureCache_ColorSamples;
|
||||
backup_config.s_copy_efb_to_texture = config.bCopyEFBToTexture;
|
||||
backup_config.s_copy_efb_scaled = config.bCopyEFBScaled;
|
||||
|
@ -301,14 +300,30 @@ void TextureCache::DumpTexture(TCacheEntryBase* entry, unsigned int level)
|
|||
entry->Save(szTemp, level);
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
||||
u32 address, unsigned int width, unsigned int height, int texformat,
|
||||
unsigned int tlutaddr, int tlutfmt, bool use_mipmaps, unsigned int maxlevel, bool from_tmem)
|
||||
static u32 CalculateLevelSize(u32 level_0_size, u32 level)
|
||||
{
|
||||
return (level_0_size + ((1 << level) - 1)) >> level;
|
||||
}
|
||||
|
||||
// Used by TextureCache::Load
|
||||
static TextureCache::TCacheEntryBase* ReturnEntry(unsigned int stage, TextureCache::TCacheEntryBase* entry)
|
||||
{
|
||||
entry->frameCount = frameCount;
|
||||
entry->Bind(stage);
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE, true);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage,
|
||||
u32 const address, unsigned int width, unsigned int height, int const texformat,
|
||||
unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int maxlevel, bool const from_tmem)
|
||||
{
|
||||
if (0 == address)
|
||||
return NULL;
|
||||
|
||||
// TexelSizeInNibbles(format)*width*height/16;
|
||||
// TexelSizeInNibbles(format) * width * height / 16;
|
||||
const unsigned int bsw = TexDecoder_GetBlockWidthInTexels(texformat) - 1;
|
||||
const unsigned int bsh = TexDecoder_GetBlockHeightInTexels(texformat) - 1;
|
||||
|
||||
|
@ -317,11 +332,9 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
const unsigned int nativeW = width;
|
||||
const unsigned int nativeH = height;
|
||||
|
||||
bool using_custom_texture = false;
|
||||
bool using_custom_lods = false;
|
||||
|
||||
u32 texID = address;
|
||||
u64 tex_hash = TEXHASH_INVALID; // Hash assigned to texcache entry (also used to generate filenames used for texture dumping and custom texture lookup)
|
||||
// Hash assigned to texcache entry (also used to generate filenames used for texture dumping and custom texture lookup)
|
||||
u64 tex_hash = TEXHASH_INVALID;
|
||||
u64 tlut_hash = TEXHASH_INVALID;
|
||||
|
||||
u32 full_format = texformat;
|
||||
|
@ -332,9 +345,12 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
full_format = texformat | (tlutfmt << 16);
|
||||
|
||||
const u32 texture_size = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, texformat);
|
||||
u8* src_data;
|
||||
if (from_tmem) src_data = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE];
|
||||
else src_data = Memory::GetPointer(address);
|
||||
|
||||
const u8* src_data;
|
||||
if (from_tmem)
|
||||
src_data = &texMem[bpmem.tex[stage / 4].texImage1[stage % 4].tmem_even * TMEM_LINE_SIZE];
|
||||
else
|
||||
src_data = Memory::GetPointer(address);
|
||||
|
||||
// TODO: This doesn't hash GB tiles for preloaded RGBA8 textures (instead, it's hashing more data from the low tmem bank than it should)
|
||||
tex_hash = GetHash64(src_data, texture_size, g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
|
@ -356,6 +372,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
tex_hash ^= tlut_hash;
|
||||
}
|
||||
|
||||
// D3D doesn't like when the specified mipmap count would require more than one 1x1-sized LOD in the mipmap chain
|
||||
// e.g. 64x64 with 7 LODs would have the mipmap chain 64x64,32x32,16x16,8x8,4x4,2x2,1x1,1x1, so we limit the mipmap count to 6 there
|
||||
while (g_ActiveConfig.backend_info.bUseMinimalMipCount && max(expandedWidth, expandedHeight) >> maxlevel == 0)
|
||||
--maxlevel;
|
||||
|
||||
TCacheEntryBase *entry = textures[texID];
|
||||
if (entry)
|
||||
{
|
||||
|
@ -369,15 +390,17 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
{
|
||||
entry->type = TCET_EC_VRAM;
|
||||
|
||||
// TODO: Print a warning if the format changes! In this case, we could reinterpret the internal texture object data to the new pixel format (similiar to what is already being done in Renderer::ReinterpretPixelFormat())
|
||||
goto return_entry;
|
||||
// TODO: Print a warning if the format changes! In this case,
|
||||
// we could reinterpret the internal texture object data to the new pixel format
|
||||
// (similiar to what is already being done in Renderer::ReinterpretPixelFormat())
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
// 2. b) For normal textures, all texture parameters need to match
|
||||
if (address == entry->addr && tex_hash == entry->hash && full_format == entry->format &&
|
||||
entry->num_mipmaps > maxlevel && entry->native_width == nativeW && entry->native_height == nativeH)
|
||||
{
|
||||
goto return_entry;
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
// 3. If we reach this line, we'll have to upload the new texture data to VRAM.
|
||||
|
@ -385,7 +408,8 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
//
|
||||
// TODO: Don't we need to force texture decoding to RGBA8 for dynamic EFB copies?
|
||||
// TODO: Actually, it should be enough if the internal texture format matches...
|
||||
if ((entry->type == TCET_NORMAL && width == entry->virtual_width && height == entry->virtual_height && full_format == entry->format && entry->num_mipmaps > maxlevel)
|
||||
if ((entry->type == TCET_NORMAL && width == entry->virtual_width && height == entry->virtual_height
|
||||
&& full_format == entry->format && entry->num_mipmaps > maxlevel)
|
||||
|| (entry->type == TCET_EC_DYNAMIC && entry->native_width == width && entry->native_height == height))
|
||||
{
|
||||
// reuse the texture
|
||||
|
@ -398,9 +422,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
}
|
||||
}
|
||||
|
||||
bool using_custom_texture = false;
|
||||
|
||||
if (g_ActiveConfig.bHiresTextures)
|
||||
{
|
||||
// This function may modify width/height.
|
||||
pcfmt = LoadCustomTexture(tex_hash, texformat, 0, width, height);
|
||||
if (pcfmt != PC_TEX_FMT_NONE)
|
||||
{
|
||||
|
@ -431,111 +457,100 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int stage,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int texLevels;
|
||||
bool use_native_mips;
|
||||
texLevels = use_mipmaps ? (maxlevel + 1) : 1;
|
||||
using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels);
|
||||
use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH); // Only load native mips if their dimensions fit to our virtual texture dimensions
|
||||
texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1;
|
||||
u32 texLevels = use_mipmaps ? (maxlevel + 1) : 1;
|
||||
const bool using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels);
|
||||
// Only load native mips if their dimensions fit to our virtual texture dimensions
|
||||
const bool use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH);
|
||||
texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; // TODO: Should be forced to 1 for non-pow2 textures (e.g. efb copies with automatically adjusted IR)
|
||||
|
||||
// create the entry/texture
|
||||
if (NULL == entry) {
|
||||
if (NULL == entry)
|
||||
{
|
||||
textures[texID] = entry = g_texture_cache->CreateTexture(width, height, expandedWidth, texLevels, pcfmt);
|
||||
|
||||
// Sometimes, we can get around recreating a texture if only the number of mip levels changes
|
||||
// e.g. if our texture cache entry got too many mipmap levels we can limit the number of used levels by setting the appropriate render states
|
||||
// Thus, we don't update this member for every Load, but just whenever the texture gets recreated
|
||||
// TODO: D3D9 doesn't support min_lod. We should add a workaround for that here!
|
||||
|
||||
// TODO: This is the wrong value. We should be storing the number of levels our actual texture has.
|
||||
// But that will currently make the above "existing entry" tests fail as "texLevels" is not calculated until after.
|
||||
// Currently, we might try to reuse a texture which appears to have more levels than actual, maybe..
|
||||
entry->num_mipmaps = maxlevel + 1;
|
||||
entry->type = TCET_NORMAL;
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load texture (CreateTexture also loads level 0)
|
||||
entry->Load(width, height, expandedWidth, 0);
|
||||
}
|
||||
|
||||
entry->SetGeneralParameters(address, texture_size, full_format, entry->num_mipmaps);
|
||||
entry->SetDimensions(nativeW, nativeH, width, height);
|
||||
entry->hash = tex_hash;
|
||||
if (entry->IsEfbCopy() && !g_ActiveConfig.bCopyEFBToTexture) entry->type = TCET_EC_DYNAMIC;
|
||||
else entry->type = TCET_NORMAL;
|
||||
|
||||
// load texture
|
||||
entry->Load(width, height, expandedWidth, 0);
|
||||
|
||||
if (entry->IsEfbCopy() && !g_ActiveConfig.bCopyEFBToTexture)
|
||||
entry->type = TCET_EC_DYNAMIC;
|
||||
else
|
||||
entry->type = TCET_NORMAL;
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures && !using_custom_texture)
|
||||
DumpTexture(entry, 0);
|
||||
|
||||
u32 level = 1;
|
||||
// load mips - TODO: Loading mipmaps from tmem is untested!
|
||||
if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && use_native_mips)
|
||||
if (pcfmt != PC_TEX_FMT_NONE)
|
||||
{
|
||||
const unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(texformat);
|
||||
|
||||
unsigned int level = 1;
|
||||
unsigned int mipWidth = (width + 1) >> 1;
|
||||
unsigned int mipHeight = (height + 1) >> 1;
|
||||
|
||||
u8* ptr_even = NULL, *ptr_odd = NULL;
|
||||
if (from_tmem)
|
||||
if (use_native_mips)
|
||||
{
|
||||
ptr_even = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE + texture_size];
|
||||
ptr_odd = &texMem[bpmem.tex[stage/4].texImage2[stage%4].tmem_odd * TMEM_LINE_SIZE];
|
||||
src_data += texture_size;
|
||||
|
||||
const u8* ptr_even = NULL;
|
||||
const u8* ptr_odd = NULL;
|
||||
if (from_tmem)
|
||||
{
|
||||
ptr_even = &texMem[bpmem.tex[stage/4].texImage1[stage%4].tmem_even * TMEM_LINE_SIZE + texture_size];
|
||||
ptr_odd = &texMem[bpmem.tex[stage/4].texImage2[stage%4].tmem_odd * TMEM_LINE_SIZE];
|
||||
}
|
||||
|
||||
for (; level != texLevels; ++level)
|
||||
{
|
||||
const u32 mip_width = CalculateLevelSize(width, level);
|
||||
const u32 mip_height = CalculateLevelSize(height, level);
|
||||
const u32 expanded_mip_width = (mip_width + bsw) & (~bsw);
|
||||
const u32 expanded_mip_height = (mip_height + bsh) & (~bsh);
|
||||
|
||||
const u8*& mip_src_data = from_tmem
|
||||
? ((level % 2) ? ptr_odd : ptr_even)
|
||||
: src_data;
|
||||
TexDecoder_Decode(temp, mip_src_data, expanded_mip_width, expanded_mip_height, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures);
|
||||
mip_src_data += TexDecoder_GetTextureSizeInBytes(expanded_mip_width, expanded_mip_height, texformat);
|
||||
|
||||
entry->Load(mip_width, mip_height, expanded_mip_width, level);
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures)
|
||||
DumpTexture(entry, level);
|
||||
}
|
||||
}
|
||||
src_data += texture_size;
|
||||
|
||||
while ((mipHeight || mipWidth) && (level < texLevels))
|
||||
else if (using_custom_lods)
|
||||
{
|
||||
u8** ptr;
|
||||
if (from_tmem) ptr = (level % 2) ? &ptr_odd : &ptr_even;
|
||||
else ptr = &src_data;
|
||||
for (; level != texLevels; ++level)
|
||||
{
|
||||
unsigned int mip_width = CalculateLevelSize(width, level);
|
||||
unsigned int mip_height = CalculateLevelSize(height, level);
|
||||
|
||||
const unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1;
|
||||
const unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1;
|
||||
|
||||
expandedWidth = (currentWidth + bsw) & (~bsw);
|
||||
expandedHeight = (currentHeight + bsh) & (~bsh);
|
||||
|
||||
TexDecoder_Decode(temp, *ptr, expandedWidth, expandedHeight, texformat, tlutaddr, tlutfmt, g_ActiveConfig.backend_info.bUseRGBATextures);
|
||||
entry->Load(currentWidth, currentHeight, expandedWidth, level);
|
||||
|
||||
if (g_ActiveConfig.bDumpTextures)
|
||||
DumpTexture(entry, level);
|
||||
|
||||
*ptr += ((std::max(mipWidth, bsw) * std::max(mipHeight, bsh) * bsdepth) >> 1);
|
||||
mipWidth >>= 1;
|
||||
mipHeight >>= 1;
|
||||
++level;
|
||||
}
|
||||
}
|
||||
else if (texLevels > 1 && pcfmt != PC_TEX_FMT_NONE && using_custom_lods)
|
||||
{
|
||||
unsigned int level = 1;
|
||||
unsigned int mipWidth = (width + 1) >> 1;
|
||||
unsigned int mipHeight = (height + 1) >> 1;
|
||||
|
||||
while ((mipHeight || mipWidth) && (level < texLevels))
|
||||
{
|
||||
unsigned int currentWidth = (mipWidth > 0) ? mipWidth : 1;
|
||||
unsigned int currentHeight = (mipHeight > 0) ? mipHeight : 1;
|
||||
|
||||
LoadCustomTexture(tex_hash, texformat, level, currentWidth, currentHeight);
|
||||
entry->Load(currentWidth, currentHeight, currentWidth, level);
|
||||
|
||||
mipWidth >>= 1;
|
||||
mipHeight >>= 1;
|
||||
++level;
|
||||
LoadCustomTexture(tex_hash, texformat, level, mip_width, mip_height);
|
||||
entry->Load(mip_width, mip_height, mip_width, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INCSTAT(stats.numTexturesCreated);
|
||||
SETSTAT(stats.numTexturesAlive, textures.size());
|
||||
|
||||
return_entry:
|
||||
|
||||
entry->frameCount = frameCount;
|
||||
entry->Bind(stage);
|
||||
|
||||
GFX_DEBUGGER_PAUSE_AT(NEXT_TEXTURE_CHANGE, true);
|
||||
|
||||
return entry;
|
||||
return ReturnEntry(stage, entry);
|
||||
}
|
||||
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
|
||||
|
|
|
@ -692,7 +692,7 @@ inline void SetOpenMPThreadCount(int width, int height)
|
|||
if (g_ActiveConfig.bOMPDecoder && width > 127 && height > 127)
|
||||
{
|
||||
// don't span to many threads they will kill the rest of the emu :)
|
||||
omp_set_num_threads((cpu_info.num_cores + 2) / 3);
|
||||
omp_set_num_threads((omp_get_num_procs() + 2) / 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@ VideoConfig::VideoConfig()
|
|||
// disable all features by default
|
||||
backend_info.APIType = API_NONE;
|
||||
backend_info.bUseRGBATextures = false;
|
||||
backend_info.bUseMinimalMipCount = false;
|
||||
backend_info.bSupports3DVision = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ struct VideoConfig
|
|||
std::vector<std::string> PPShaders; // post-processing shaders
|
||||
|
||||
bool bUseRGBATextures; // used for D3D11 in TextureCache
|
||||
bool bUseMinimalMipCount;
|
||||
bool bSupports3DVision;
|
||||
bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL
|
||||
bool bSupportsFormatReinterpretation;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue