From 231f0fc2e5e22b2d4907341cc191cfc9215556fb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 Apr 2020 23:38:48 +0200 Subject: welp --- src/frontend/qt_sdl/main.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/frontend/qt_sdl/main.cpp (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp new file mode 100644 index 0000000..3f61ec6 --- /dev/null +++ b/src/frontend/qt_sdl/main.cpp @@ -0,0 +1,45 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include +#include + +// Qt includes and shit here, I guess + +#include "main.h" + +#include "../version.h" + + +// + + +int main(int argc, char** argv) +{ + srand(time(NULL)); + + printf("melonDS " MELONDS_VERSION "\n"); + printf(MELONDS_URL "\n"); + + printf("Arisotura hereby admits defeat\n"); + printf("NI DIEU NI MAITRE\n"); + + return 0; +} -- cgit v1.2.3 From 439ca1b2b557040f6d5a2fe1e70dd0f5e4d74484 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 Apr 2020 20:43:09 +0200 Subject: get a Qt window showing up. 'tis a start, I guess. --- src/frontend/qt_sdl/CMakeLists.txt | 7 +++++-- src/frontend/qt_sdl/main.cpp | 27 ++++++++++++++++++++------- src/frontend/qt_sdl/main.h | 14 +++++++++++++- 3 files changed, 38 insertions(+), 10 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index ff2ed09..1ee7629 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -9,8 +9,11 @@ if (WIN32) endif() find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(Qt5 COMPONENTS Gui REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED) +set(CMAKE_AUTOMOC ON) + find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2) @@ -41,14 +44,14 @@ if (UNIX) --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(melonDS dl Qt5::Core Qt5::Widgets) + target_link_libraries(melonDS dl Qt5::Core Qt5::Gui Qt5::Widgets) endif () target_sources(melonDS PUBLIC melon_grc.c) elseif (WIN32) target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") - target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Widgets) + target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Gui Qt5::Widgets) endif () install(FILES ../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0b9d15e..0eb84a5 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -21,15 +21,26 @@ #include #include -// Qt includes and shit here, I guess -#include +#include +#include #include "main.h" #include "../../version.h" -// +MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) +{ + setWindowTitle("melonDS - assfucking Qt version"); + + // burp + QWidget *centralWidget = new QWidget(this); + setCentralWidget(centralWidget); +} + +MainWindow::~MainWindow() +{ +} int main(int argc, char** argv) @@ -39,10 +50,12 @@ int main(int argc, char** argv) printf("melonDS " MELONDS_VERSION "\n"); printf(MELONDS_URL "\n"); - printf("Arisotura hereby admits defeat\n"); - printf("NI DIEU NI MAITRE\n"); + QApplication melon(argc, argv); + + MainWindow win; + win.show(); - return 0; + return melon.exec(); } #ifdef __WIN32__ @@ -59,7 +72,7 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho for (int i = 0; i < argc; i++) { int len = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, NULL, 0, NULL, NULL); - if (len < 1) return NULL; + if (len < 1) { argv[i] = nullarg; continue; } argv[i] = new char[len]; int res = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, argv[i], len, NULL, NULL); if (res != len) { delete[] argv[i]; argv[i] = nullarg; } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 65d6518..ad795ef 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -19,6 +19,18 @@ #ifndef MAIN_H #define MAIN_H -// put the class shit here +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget* parent = nullptr); + ~MainWindow(); + +private: + // private shit goes here +}; #endif // MAIN_H -- cgit v1.2.3 From 690f9f38744ddda7fd65c299288227767e4b03f0 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 12:06:44 +0200 Subject: get some of the shit going, I guess atleast the emuthread is going and we have its control system down and other fun shit, too --- src/CMakeLists.txt | 1 + src/frontend/qt_sdl/CMakeLists.txt | 2 + src/frontend/qt_sdl/Platform.cpp | 558 ++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/PlatformConfig.cpp | 151 +++++++++ src/frontend/qt_sdl/PlatformConfig.h | 82 +++++ src/frontend/qt_sdl/main.cpp | 570 ++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/main.h | 42 ++- 7 files changed, 1397 insertions(+), 9 deletions(-) create mode 100644 src/frontend/qt_sdl/Platform.cpp create mode 100644 src/frontend/qt_sdl/PlatformConfig.cpp create mode 100644 src/frontend/qt_sdl/PlatformConfig.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5537e6d..64d922c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(core STATIC NDS.cpp NDSCart.cpp OpenGLSupport.cpp + Platform.h RTC.cpp Savestate.cpp SPI.cpp diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 1ee7629..f24464d 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -2,6 +2,8 @@ project(qt_sdl) SET(SOURCES_QT_SDL main.cpp + Platform.cpp + PlatformConfig.cpp ) if (WIN32) diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp new file mode 100644 index 0000000..31b5277 --- /dev/null +++ b/src/frontend/qt_sdl/Platform.cpp @@ -0,0 +1,558 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include +#include +#include "Platform.h" +#include "PlatformConfig.h" +//#include "LAN_Socket.h" +//#include "LAN_PCap.h" +#include + +#ifdef __WIN32__ + #define NTDDI_VERSION 0x06000000 // GROSS FUCKING HACK + #include + //#include // FUCK THAT SHIT + extern "C" const GUID DECLSPEC_SELECTANY FOLDERID_RoamingAppData = {0x3eb685db, 0x65f9, 0x4cf6, {0xa0, 0x3a, 0xe3, 0xef, 0x65, 0x72, 0x9f, 0x3d}}; + #include + #include + #include + #define socket_t SOCKET + #define sockaddr_t SOCKADDR +#else + #include + #include + #include + #include + #include + #include + #define socket_t int + #define sockaddr_t struct sockaddr + #define closesocket close +#endif + +#ifndef INVALID_SOCKET +#define INVALID_SOCKET (socket_t)-1 +#endif + + +extern char* EmuDirectory; + +void Stop(bool internal); + + +namespace Platform +{ + + +typedef struct +{ + SDL_Thread* ID; + void (*Func)(); + +} ThreadData; + +int ThreadEntry(void* data) +{ + ThreadData* thread = (ThreadData*)data; + thread->Func(); + return 0; +} + + +socket_t MPSocket; +sockaddr_t MPSendAddr; +u8 PacketBuffer[2048]; + +#define NIFI_VER 1 + + +void StopEmu() +{ + //Stop(true); +} + + +FILE* OpenFile(const char* path, const char* mode, bool mustexist) +{ + FILE* ret; + +#ifdef __WIN32__ + + int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + if (len < 1) return NULL; + WCHAR* fatpath = new WCHAR[len]; + int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, fatpath, len); + if (res != len) { delete[] fatpath; return NULL; } // checkme? + + // this will be more than enough + WCHAR fatmode[4]; + fatmode[0] = mode[0]; + fatmode[1] = mode[1]; + fatmode[2] = mode[2]; + fatmode[3] = 0; + + if (mustexist) + { + ret = _wfopen(fatpath, L"rb"); + if (ret) ret = _wfreopen(fatpath, fatmode, ret); + } + else + ret = _wfopen(fatpath, fatmode); + + delete[] fatpath; + +#else + + if (mustexist) + { + ret = fopen(path, "rb"); + if (ret) ret = freopen(path, mode, ret); + } + else + ret = fopen(path, mode); + +#endif + + return ret; +} + +#if !defined(UNIX_PORTABLE) && !defined(__WIN32__) + +FILE* OpenLocalFile(const char* path, const char* mode) +{ + std::string fullpath; + if (path[0] == '/') + { + // If it's an absolute path, just open that. + fullpath = std::string(path); + } + else + { + // Check user configuration directory + std::string confpath = std::string(g_get_user_config_dir()) + "/melonDS/"; + g_mkdir_with_parents(confpath.c_str(), 0755); + fullpath = confpath + path; + } + + return OpenFile(fullpath.c_str(), mode, mode[0] != 'w'); +} + +FILE* OpenDataFile(const char* path) +{ + const char* melondir = "melonDS"; + const char* const* sys_dirs = g_get_system_data_dirs(); + const char* user_dir = g_get_user_data_dir(); + + // First check the user's data directory + char* fullpath = g_build_path("/", user_dir, melondir, path, NULL); + if (access(fullpath, R_OK) == 0) + { + FILE* f = fopen(fullpath, "r"); + g_free(fullpath); + return f; + } + free(fullpath); + + // Then check the system data directories + for (size_t i = 0; sys_dirs[i] != NULL; i++) + { + const char* dir = sys_dirs[i]; + char* fullpath = g_build_path("/", dir, melondir, path, NULL); + + if (access(fullpath, R_OK) == 0) + { + FILE* f = fopen(fullpath, "r"); + g_free(fullpath); + return f; + } + free(fullpath); + } + + FILE* f = fopen(path, "rb"); + if (f) return f; + + return NULL; +} + +#else + +FILE* OpenLocalFile(const char* path, const char* mode) +{ + bool relpath = false; + int pathlen = strlen(path); + +#ifdef __WIN32__ + if (pathlen > 3) + { + if (path[1] == ':' && path[2] == '\\') + return OpenFile(path, mode); + } +#else + if (pathlen > 1) + { + if (path[0] == '/') + return OpenFile(path, mode); + } +#endif + + if (pathlen >= 3) + { + if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\')) + relpath = true; + } + + int emudirlen = strlen(EmuDirectory); + char* emudirpath; + if (emudirlen) + { + int len = emudirlen + 1 + pathlen + 1; + emudirpath = new char[len]; + strncpy(&emudirpath[0], EmuDirectory, emudirlen); + emudirpath[emudirlen] = '/'; + strncpy(&emudirpath[emudirlen+1], path, pathlen); + emudirpath[emudirlen+1+pathlen] = '\0'; + } + else + { + emudirpath = new char[pathlen+1]; + strncpy(&emudirpath[0], path, pathlen); + emudirpath[pathlen] = '\0'; + } + + // Locations are application directory, and AppData/melonDS on Windows or XDG_CONFIG_HOME/melonDS on Linux + + FILE* f; + + // First check current working directory + f = OpenFile(path, mode, true); + if (f) { delete[] emudirpath; return f; } + + // then emu directory + f = OpenFile(emudirpath, mode, true); + if (f) { delete[] emudirpath; return f; } + +#ifdef __WIN32__ + + // a path relative to AppData wouldn't make much sense + if (!relpath) + { + // Now check AppData + PWSTR appDataPath = NULL; + SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &appDataPath); + if (!appDataPath) + { + delete[] emudirpath; + return NULL; + } + + // this will be more than enough + WCHAR fatperm[4]; + fatperm[0] = mode[0]; + fatperm[1] = mode[1]; + fatperm[2] = mode[2]; + fatperm[3] = 0; + + int fnlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + if (fnlen < 1) { delete[] emudirpath; return NULL; } + WCHAR* wfileName = new WCHAR[fnlen]; + int res = MultiByteToWideChar(CP_UTF8, 0, path, -1, wfileName, fnlen); + if (res != fnlen) { delete[] wfileName; delete[] emudirpath; return NULL; } // checkme? + + const WCHAR* appdir = L"\\melonDS\\"; + + int pos = wcslen(appDataPath); + void* ptr = CoTaskMemRealloc(appDataPath, (pos+wcslen(appdir)+fnlen+1)*sizeof(WCHAR)); + if (!ptr) { delete[] wfileName; delete[] emudirpath; return NULL; } // oh well + appDataPath = (PWSTR)ptr; + + wcscpy(&appDataPath[pos], appdir); pos += wcslen(appdir); + wcscpy(&appDataPath[pos], wfileName); + + f = _wfopen(appDataPath, L"rb"); + if (f) f = _wfreopen(appDataPath, fatperm, f); + CoTaskMemFree(appDataPath); + delete[] wfileName; + if (f) { delete[] emudirpath; return f; } + } + +#else + + if (!relpath) + { + // Now check XDG_CONFIG_HOME + // TODO: check for memory leak there + std::string fullpath = std::string(g_get_user_config_dir()) + "/melonDS/" + path; + f = OpenFile(fullpath.c_str(), mode, true); + if (f) { delete[] emudirpath; return f; } + } + +#endif + + if (mode[0] != 'r') + { + f = OpenFile(emudirpath, mode); + if (f) { delete[] emudirpath; return f; } + } + + delete[] emudirpath; + return NULL; +} + +FILE* OpenDataFile(const char* path) +{ + return OpenLocalFile(path, "rb"); +} + +#endif + + +void* Thread_Create(void (*func)()) +{ + ThreadData* data = new ThreadData; + data->Func = func; + data->ID = SDL_CreateThread(ThreadEntry, "melonDS core thread", data); + return data; +} + +void Thread_Free(void* thread) +{ + delete (ThreadData*)thread; +} + +void Thread_Wait(void* thread) +{ + SDL_WaitThread((SDL_Thread*)((ThreadData*)thread)->ID, NULL); +} + + +void* Semaphore_Create() +{ + return SDL_CreateSemaphore(0); +} + +void Semaphore_Free(void* sema) +{ + SDL_DestroySemaphore((SDL_sem*)sema); +} + +void Semaphore_Reset(void* sema) +{ + while (SDL_SemTryWait((SDL_sem*)sema) == 0); +} + +void Semaphore_Wait(void* sema) +{ + SDL_SemWait((SDL_sem*)sema); +} + +void Semaphore_Post(void* sema) +{ + SDL_SemPost((SDL_sem*)sema); +} + + +void* GL_GetProcAddress(const char* proc) +{ + return NULL;//uiGLGetProcAddress(proc); +} + + +bool MP_Init() +{ + int opt_true = 1; + int res; + +#ifdef __WIN32__ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) + { + return false; + } +#endif // __WIN32__ + + MPSocket = socket(AF_INET, SOCK_DGRAM, 0); + if (MPSocket < 0) + { + return false; + } + + res = setsockopt(MPSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(int)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + sockaddr_t saddr; + saddr.sa_family = AF_INET; + *(u32*)&saddr.sa_data[2] = htonl(Config::SocketBindAnyAddr ? INADDR_ANY : INADDR_LOOPBACK); + *(u16*)&saddr.sa_data[0] = htons(7064); + res = bind(MPSocket, &saddr, sizeof(sockaddr_t)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + res = setsockopt(MPSocket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(int)); + if (res < 0) + { + closesocket(MPSocket); + MPSocket = INVALID_SOCKET; + return false; + } + + MPSendAddr.sa_family = AF_INET; + *(u32*)&MPSendAddr.sa_data[2] = htonl(INADDR_BROADCAST); + *(u16*)&MPSendAddr.sa_data[0] = htons(7064); + + return true; +} + +void MP_DeInit() +{ + if (MPSocket >= 0) + closesocket(MPSocket); + +#ifdef __WIN32__ + WSACleanup(); +#endif // __WIN32__ +} + +int MP_SendPacket(u8* data, int len) +{ + if (MPSocket < 0) + return 0; + + if (len > 2048-8) + { + printf("MP_SendPacket: error: packet too long (%d)\n", len); + return 0; + } + + *(u32*)&PacketBuffer[0] = htonl(0x4946494E); // NIFI + PacketBuffer[4] = NIFI_VER; + PacketBuffer[5] = 0; + *(u16*)&PacketBuffer[6] = htons(len); + memcpy(&PacketBuffer[8], data, len); + + int slen = sendto(MPSocket, (const char*)PacketBuffer, len+8, 0, &MPSendAddr, sizeof(sockaddr_t)); + if (slen < 8) return 0; + return slen - 8; +} + +int MP_RecvPacket(u8* data, bool block) +{ + if (MPSocket < 0) + return 0; + + fd_set fd; + struct timeval tv; + + FD_ZERO(&fd); + FD_SET(MPSocket, &fd); + tv.tv_sec = 0; + tv.tv_usec = block ? 5000 : 0; + + if (!select(MPSocket+1, &fd, 0, 0, &tv)) + { + return 0; + } + + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int rlen = recvfrom(MPSocket, (char*)PacketBuffer, 2048, 0, &fromAddr, &fromLen); + if (rlen < 8+24) + { + return 0; + } + rlen -= 8; + + if (ntohl(*(u32*)&PacketBuffer[0]) != 0x4946494E) + { + return 0; + } + + if (PacketBuffer[4] != NIFI_VER) + { + return 0; + } + + if (ntohs(*(u16*)&PacketBuffer[6]) != rlen) + { + return 0; + } + + memcpy(data, &PacketBuffer[8], rlen); + return rlen; +} + + + +bool LAN_Init() +{ + /*if (Config::DirectLAN) + { + if (!LAN_PCap::Init(true)) + return false; + } + else + { + if (!LAN_Socket::Init()) + return false; + }*/ + + return true; +} + +void LAN_DeInit() +{ + // checkme. blarg + //if (Config::DirectLAN) + // LAN_PCap::DeInit(); + //else + // LAN_Socket::DeInit(); + /*LAN_PCap::DeInit(); + LAN_Socket::DeInit();*/ +} + +int LAN_SendPacket(u8* data, int len) +{ + /*if (Config::DirectLAN) + return LAN_PCap::SendPacket(data, len); + else + return LAN_Socket::SendPacket(data, len);*/ + return 0; +} + +int LAN_RecvPacket(u8* data) +{ + /*if (Config::DirectLAN) + return LAN_PCap::RecvPacket(data); + else + return LAN_Socket::RecvPacket(data);*/ + return 0; +} + + +} diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp new file mode 100644 index 0000000..f78b195 --- /dev/null +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -0,0 +1,151 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include +#include "PlatformConfig.h" + +namespace Config +{ + +int KeyMapping[12]; +int JoyMapping[12]; + +int HKKeyMapping[HK_MAX]; +int HKJoyMapping[HK_MAX]; + +int JoystickID; + +int WindowWidth; +int WindowHeight; +int WindowMaximized; + +int ScreenRotation; +int ScreenGap; +int ScreenLayout; +int ScreenSizing; +int ScreenFilter; + +int ScreenUseGL; +int ScreenVSync; +int ScreenRatio; + +int LimitFPS; +int AudioSync; +int ShowOSD; + +int DirectBoot; + +int SocketBindAnyAddr; +char LANDevice[128]; +int DirectLAN; + +int SavestateRelocSRAM; + +int AudioVolume; +int MicInputType; +char MicWavPath[512]; + +char LastROMFolder[512]; + + +ConfigEntry PlatformConfigFile[] = +{ + {"Key_A", 0, &KeyMapping[0], 32, NULL, 0}, + {"Key_B", 0, &KeyMapping[1], 31, NULL, 0}, + {"Key_Select", 0, &KeyMapping[2], 57, NULL, 0}, + {"Key_Start", 0, &KeyMapping[3], 28, NULL, 0}, + {"Key_Right", 0, &KeyMapping[4], 333, NULL, 0}, + {"Key_Left", 0, &KeyMapping[5], 331, NULL, 0}, + {"Key_Up", 0, &KeyMapping[6], 328, NULL, 0}, + {"Key_Down", 0, &KeyMapping[7], 336, NULL, 0}, + {"Key_R", 0, &KeyMapping[8], 54, NULL, 0}, + {"Key_L", 0, &KeyMapping[9], 86, NULL, 0}, + {"Key_X", 0, &KeyMapping[10], 17, NULL, 0}, + {"Key_Y", 0, &KeyMapping[11], 30, NULL, 0}, + + {"Joy_A", 0, &JoyMapping[0], -1, NULL, 0}, + {"Joy_B", 0, &JoyMapping[1], -1, NULL, 0}, + {"Joy_Select", 0, &JoyMapping[2], -1, NULL, 0}, + {"Joy_Start", 0, &JoyMapping[3], -1, NULL, 0}, + {"Joy_Right", 0, &JoyMapping[4], -1, NULL, 0}, + {"Joy_Left", 0, &JoyMapping[5], -1, NULL, 0}, + {"Joy_Up", 0, &JoyMapping[6], -1, NULL, 0}, + {"Joy_Down", 0, &JoyMapping[7], -1, NULL, 0}, + {"Joy_R", 0, &JoyMapping[8], -1, NULL, 0}, + {"Joy_L", 0, &JoyMapping[9], -1, NULL, 0}, + {"Joy_X", 0, &JoyMapping[10], -1, NULL, 0}, + {"Joy_Y", 0, &JoyMapping[11], -1, NULL, 0}, + + {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], 0x0D, NULL, 0}, + {"HKKey_Mic", 0, &HKKeyMapping[HK_Mic], 0x35, NULL, 0}, + {"HKKey_Pause", 0, &HKKeyMapping[HK_Pause], -1, NULL, 0}, + {"HKKey_Reset", 0, &HKKeyMapping[HK_Reset], -1, NULL, 0}, + {"HKKey_FastForward", 0, &HKKeyMapping[HK_FastForward], 0x0F, NULL, 0}, + {"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], 0x4B, NULL, 0}, + {"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], 0x4D, NULL, 0}, + + {"HKJoy_Lid", 0, &HKJoyMapping[HK_Lid], -1, NULL, 0}, + {"HKJoy_Mic", 0, &HKJoyMapping[HK_Mic], -1, NULL, 0}, + {"HKJoy_Pause", 0, &HKJoyMapping[HK_Pause], -1, NULL, 0}, + {"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0}, + {"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0}, + {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, + {"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, + + {"JoystickID", 0, &JoystickID, 0, NULL, 0}, + + {"WindowWidth", 0, &WindowWidth, 256, NULL, 0}, + {"WindowHeight", 0, &WindowHeight, 384, NULL, 0}, + {"WindowMax", 0, &WindowMaximized, 0, NULL, 0}, + + {"ScreenRotation", 0, &ScreenRotation, 0, NULL, 0}, + {"ScreenGap", 0, &ScreenGap, 0, NULL, 0}, + {"ScreenLayout", 0, &ScreenLayout, 0, NULL, 0}, + {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, + {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, + + {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, + {"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0}, + {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, + + {"LimitFPS", 0, &LimitFPS, 0, NULL, 0}, + {"AudioSync", 0, &AudioSync, 1, NULL, 0}, + {"ShowOSD", 0, &ShowOSD, 1, NULL, 0}, + + {"DirectBoot", 0, &DirectBoot, 1, NULL, 0}, + + {"SockBindAnyAddr", 0, &SocketBindAnyAddr, 0, NULL, 0}, + {"LANDevice", 1, LANDevice, 0, "", 127}, + {"DirectLAN", 0, &DirectLAN, 0, NULL, 0}, + + {"SavStaRelocSRAM", 0, &SavestateRelocSRAM, 0, NULL, 0}, + + {"AudioVolume", 0, &AudioVolume, 256, NULL, 0}, + {"MicInputType", 0, &MicInputType, 1, NULL, 0}, + {"MicWavPath", 1, MicWavPath, 0, "", 511}, + + {"LastROMFolder", 1, LastROMFolder, 0, "", 511}, + + {"", -1, NULL, 0, NULL, 0} +}; + +} diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h new file mode 100644 index 0000000..d0f765b --- /dev/null +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -0,0 +1,82 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef PLATFORMCONFIG_H +#define PLATFORMCONFIG_H + +#include "Config.h" + +enum +{ + HK_Lid = 0, + HK_Mic, + HK_Pause, + HK_Reset, + HK_FastForward, + HK_FastForwardToggle, + HK_SolarSensorDecrease, + HK_SolarSensorIncrease, + HK_MAX +}; + +namespace Config +{ + +extern int KeyMapping[12]; +extern int JoyMapping[12]; + +extern int HKKeyMapping[HK_MAX]; +extern int HKJoyMapping[HK_MAX]; + +extern int JoystickID; + +extern int WindowWidth; +extern int WindowHeight; +extern int WindowMaximized; + +extern int ScreenRotation; +extern int ScreenGap; +extern int ScreenLayout; +extern int ScreenSizing; +extern int ScreenFilter; + +extern int ScreenUseGL; +extern int ScreenVSync; +extern int ScreenRatio; + +extern int LimitFPS; +extern int AudioSync; +extern int ShowOSD; + +extern int DirectBoot; + +extern int SocketBindAnyAddr; +extern char LANDevice[128]; +extern int DirectLAN; + +extern int SavestateRelocSRAM; + +extern int AudioVolume; +extern int MicInputType; +extern char MicWavPath[512]; + +extern char LastROMFolder[512]; + +} + +#endif // PLATFORMCONFIG_H diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0eb84a5..9192685 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -22,20 +22,364 @@ #include #include -#include +#include +#include +#include +#include +#include + +#include #include "main.h" -#include "../../version.h" +#include "types.h" +#include "version.h" + +#include "NDS.h" +#include "GBACart.h" +#include "GPU.h" +#include "SPU.h" +#include "Wifi.h" +#include "Platform.h" +#include "Config.h" + +#include "Savestate.h" + + +char* EmuDirectory; + +bool RunningSomething; +char ROMPath[2][1024]; +char SRAMPath[2][1024]; +char PrevSRAMPath[2][1024]; // for savestate 'undo load' + +bool SavestateLoaded; + +MainWindow* mainWindow; +EmuThread* emuThread; + + +EmuThread::EmuThread(QObject* parent) : QThread(parent) +{ + EmuStatus = 0; + EmuRunning = 2; +} + +void EmuThread::run() +{ + NDS::Init(); + + /*MainScreenPos[0] = 0; + MainScreenPos[1] = 0; + MainScreenPos[2] = 0; + AutoScreenSizing = 0;*/ + + /*if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GPU3D::InitRenderer(true); + uiGLMakeContextCurrent(NULL); + } + else*/ + { + GPU3D::InitRenderer(false); + } + + /*Touching = false; + KeyInputMask = 0xFFF; + JoyInputMask = 0xFFF; + KeyHotkeyMask = 0; + JoyHotkeyMask = 0; + HotkeyMask = 0; + LastHotkeyMask = 0; + LidStatus = false;*/ + + u32 nframes = 0; + u32 starttick = SDL_GetTicks(); + u32 lasttick = starttick; + u32 lastmeasuretick = lasttick; + u32 fpslimitcount = 0; + u64 perfcount = SDL_GetPerformanceCounter(); + u64 perffreq = SDL_GetPerformanceFrequency(); + float samplesleft = 0; + u32 nsamples = 0; + + char melontitle[100]; + SDL_mutex* titlemutex = SDL_CreateMutex(); + void* titledata[2] = {melontitle, titlemutex}; +printf("emu thread start: %d\n", EmuRunning); + while (EmuRunning != 0) + { + /*ProcessInput(); + + if (HotkeyPressed(HK_FastForwardToggle)) + { + Config::LimitFPS = !Config::LimitFPS; + uiQueueMain(UpdateFPSLimit, NULL); + } + // TODO: similar hotkeys for video/audio sync? + + if (HotkeyPressed(HK_Pause)) uiQueueMain(TogglePause, NULL); + if (HotkeyPressed(HK_Reset)) uiQueueMain(Reset, NULL); + + if (GBACart::CartInserted && GBACart::HasSolarSensor) + { + if (HotkeyPressed(HK_SolarSensorDecrease)) + { + if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); + } + if (HotkeyPressed(HK_SolarSensorIncrease)) + { + if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); + } + }*/ + + if (EmuRunning == 1) + { + EmuStatus = 1; + + // process input and hotkeys + NDS::SetKeyMask(0xFFF); + /*NDS::SetKeyMask(KeyInputMask & JoyInputMask); + + if (HotkeyPressed(HK_Lid)) + { + LidStatus = !LidStatus; + NDS::SetLidClosed(LidStatus); + OSD::AddMessage(0, LidStatus ? "Lid closed" : "Lid opened"); + }*/ + + // microphone input + /*FeedMicInput(); + + if (Screen_UseGL) + { + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + }*/ + + // auto screen layout + /*{ + MainScreenPos[2] = MainScreenPos[1]; + MainScreenPos[1] = MainScreenPos[0]; + MainScreenPos[0] = NDS::PowerControl9 >> 15; + + int guess; + if (MainScreenPos[0] == MainScreenPos[2] && + MainScreenPos[0] != MainScreenPos[1]) + { + // constant flickering, likely displaying 3D on both screens + // TODO: when both screens are used for 2D only...??? + guess = 0; + } + else + { + if (MainScreenPos[0] == 1) + guess = 1; + else + guess = 2; + } + + if (guess != AutoScreenSizing) + { + AutoScreenSizing = guess; + SetupScreenRects(WindowWidth, WindowHeight); + } + }*/ + + // emulate + u32 nlines = NDS::RunFrame(); + +#ifdef MELONCAP + MelonCap::Update(); +#endif // MELONCAP + + if (EmuRunning == 0) break; + + /*if (Screen_UseGL) + { + GLScreen_DrawScreen(); + uiGLEnd(GLContext); + } + uiAreaQueueRedrawAll(MainDrawArea);*/ + + /*bool fastforward = HotkeyDown(HK_FastForward); + + if (Config::AudioSync && !fastforward) + { + SDL_LockMutex(AudioSyncLock); + while (SPU::GetOutputSize() > 1024) + { + int ret = SDL_CondWaitTimeout(AudioSync, AudioSyncLock, 500); + if (ret == SDL_MUTEX_TIMEDOUT) break; + } + SDL_UnlockMutex(AudioSyncLock); + } + + float framerate = (1000.0f * nlines) / (60.0f * 263.0f); + + { + u32 curtick = SDL_GetTicks(); + u32 delay = curtick - lasttick; + + bool limitfps = Config::LimitFPS && !fastforward; + if (limitfps) + { + float wantedtickF = starttick + (framerate * (fpslimitcount+1)); + u32 wantedtick = (u32)ceil(wantedtickF); + if (curtick < wantedtick) SDL_Delay(wantedtick - curtick); + + lasttick = SDL_GetTicks(); + fpslimitcount++; + if ((abs(wantedtickF - (float)wantedtick) < 0.001312) || (fpslimitcount > 60)) + { + fpslimitcount = 0; + nsamples = 0; + starttick = lasttick; + } + } + else + { + if (delay < 1) SDL_Delay(1); + lasttick = SDL_GetTicks(); + } + } + + nframes++; + if (nframes >= 30) + { + u32 tick = SDL_GetTicks(); + u32 diff = tick - lastmeasuretick; + lastmeasuretick = tick; + + u32 fps; + if (diff < 1) fps = 77777; + else fps = (nframes * 1000) / diff; + nframes = 0; + + float fpstarget; + if (framerate < 1) fpstarget = 999; + else fpstarget = 1000.0f/framerate; + + SDL_LockMutex(titlemutex); + sprintf(melontitle, "[%d/%.0f] melonDS " MELONDS_VERSION, fps, fpstarget); + SDL_UnlockMutex(titlemutex); + uiQueueMain(UpdateWindowTitle, titledata); + }*/ + } + else + { + // paused + nframes = 0; + lasttick = SDL_GetTicks(); + starttick = lasttick; + lastmeasuretick = lasttick; + fpslimitcount = 0; + + if (EmuRunning == 2) + { + /*if (Screen_UseGL) + { + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + uiGLEnd(GLContext); + } + uiAreaQueueRedrawAll(MainDrawArea);*/ + } + + //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + + EmuStatus = EmuRunning; + + SDL_Delay(100); + } + printf("ran iteration: status=%d run=%d\n", EmuStatus, EmuRunning); + } + + EmuStatus = 0; + + SDL_DestroyMutex(titlemutex); + + //if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); + + NDS::DeInit(); + //Platform::LAN_DeInit(); + + /*if (Screen_UseGL) + { + OSD::DeInit(true); + GLScreen_DeInit(); + } + else + OSD::DeInit(false);*/ + + //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); +} + +void EmuThread::emuRun() +{ + EmuRunning = 1; +} + +void EmuThread::emuPause(bool refresh) +{ + int status = refresh ? 2:3; + PrevEmuStatus = EmuRunning; + EmuRunning = status;printf("emuPause %d -> %d %d\n", PrevEmuStatus, EmuRunning, EmuStatus); + while (EmuStatus != status);printf("wait done\n"); +} + +void EmuThread::emuUnpause() +{ + EmuRunning = PrevEmuStatus; +} + +void EmuThread::emuStop() +{ + EmuRunning = 0; +} + + +MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) +{ +} + +MainWindowPanel::~MainWindowPanel() +{ +} + +void MainWindowPanel::paintEvent(QPaintEvent* event) +{ + QPainter painter(this); + + //painter. +} MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS - assfucking Qt version"); - // burp - QWidget *centralWidget = new QWidget(this); - setCentralWidget(centralWidget); + QMenuBar* menubar = new QMenuBar(); + { + QMenu* menu = menubar->addMenu("File"); + QAction* act; + + act = menu->addAction("Open file..."); + connect(act, &QAction::triggered, this, &MainWindow::onOpenFile); + } + setMenuBar(menubar); + + panel = new MainWindowPanel(this); + setCentralWidget(panel); + panel->setMinimumSize(256, 384); } MainWindow::~MainWindow() @@ -43,6 +387,13 @@ MainWindow::~MainWindow() } +void MainWindow::onOpenFile() +{ + QString filename = QFileDialog::getOpenFileName(this, "Open ROM", "", "DS ROMs (*.nds *.srl);;Any file (*.*)"); + printf("fark: %p %d %s\n", filename, filename.isEmpty(), filename.toStdString().c_str()); +} + + int main(int argc, char** argv) { srand(time(NULL)); @@ -50,12 +401,212 @@ int main(int argc, char** argv) printf("melonDS " MELONDS_VERSION "\n"); printf(MELONDS_URL "\n"); +#if defined(__WIN32__) || defined(UNIX_PORTABLE) + if (argc > 0 && strlen(argv[0]) > 0) + { + int len = strlen(argv[0]); + while (len > 0) + { + if (argv[0][len] == '/') break; + if (argv[0][len] == '\\') break; + len--; + } + if (len > 0) + { + EmuDirectory = new char[len+1]; + strncpy(EmuDirectory, argv[0], len); + EmuDirectory[len] = '\0'; + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } +#else + const char* confdir = g_get_user_config_dir(); + const char* confname = "/melonDS"; + EmuDirectory = new char[strlen(confdir) + strlen(confname) + 1]; + strcat(EmuDirectory, confdir); + strcat(EmuDirectory, confname); +#endif + QApplication melon(argc, argv); - MainWindow win; - win.show(); + // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl + SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); + + if (SDL_Init(SDL_INIT_HAPTIC) < 0) + { + printf("SDL couldn't init rumble\n"); + } + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) + { + QMessageBox::critical(NULL, "melonDS", "SDL shat itself :("); + return 1; + } + + SDL_JoystickEventState(SDL_ENABLE); + + Config::Load(); + + //if (Config::AudioVolume < 0) Config::AudioVolume = 0; + //else if (Config::AudioVolume > 256) Config::AudioVolume = 256; - return melon.exec(); + // TODO: those should be checked before running anything + // (as to let the user specify their own BIOS/firmware path etc) +#if 0 + if (!Platform::LocalFileExists("bios7.bin") || + !Platform::LocalFileExists("bios9.bin") || + !Platform::LocalFileExists("firmware.bin")) + { +#if defined(__WIN32__) || defined(UNIX_PORTABLE) + const char* locationName = "the directory you run melonDS from"; +#else + char* locationName = EmuDirectory; +#endif + char msgboxtext[512]; + sprintf(msgboxtext, + "One or more of the following required files don't exist or couldn't be accessed:\n\n" + "bios7.bin -- ARM7 BIOS\n" + "bios9.bin -- ARM9 BIOS\n" + "firmware.bin -- firmware image\n\n" + "Dump the files from your DS and place them in %s.\n" + "Make sure that the files can be accessed.", + locationName + ); + + uiMsgBoxError(NULL, "BIOS/Firmware not found", msgboxtext); + + uiUninit(); + SDL_Quit(); + return 0; + } + if (!Platform::LocalFileExists("firmware.bin.bak")) + { + // verify the firmware + // + // there are dumps of an old hacked firmware floating around on the internet + // and those are problematic + // the hack predates WFC, and, due to this, any game that alters the WFC + // access point data will brick that firmware due to it having critical + // data in the same area. it has the same problem on hardware. + // + // but this should help stop users from reporting that issue over and over + // again, when the issue is not from melonDS but from their firmware dump. + // + // I don't know about all the firmware hacks in existence, but the one I + // looked at has 0x180 bytes from the header repeated at 0x3FC80, but + // bytes 0x0C-0x14 are different. + + FILE* f = Platform::OpenLocalFile("firmware.bin", "rb"); + u8 chk1[0x180], chk2[0x180]; + + fseek(f, 0, SEEK_SET); + fread(chk1, 1, 0x180, f); + fseek(f, -0x380, SEEK_END); + fread(chk2, 1, 0x180, f); + + memset(&chk1[0x0C], 0, 8); + memset(&chk2[0x0C], 0, 8); + + fclose(f); + + if (!memcmp(chk1, chk2, 0x180)) + { + uiMsgBoxError(NULL, + "Problematic firmware dump", + "You are using an old hacked firmware dump.\n" + "Firmware boot will stop working if you run any game that alters WFC settings.\n\n" + "Note that the issue is not from melonDS, it would also happen on an actual DS."); + } + } + { + const char* romlist_missing = "Save memory type detection will not work correctly.\n\n" + "You should use the latest version of romlist.bin (provided in melonDS release packages)."; +#if !defined(UNIX_PORTABLE) && !defined(__WIN32__) + std::string missingstr = std::string(romlist_missing) + + "\n\nThe ROM list should be placed in " + g_get_user_data_dir() + "/melonds/, otherwise " + "melonDS will search for it in the current working directory."; + const char* romlist_missing_text = missingstr.c_str(); +#else + const char* romlist_missing_text = romlist_missing; +#endif + + FILE* f = Platform::OpenDataFile("romlist.bin"); + if (f) + { + u32 data; + fread(&data, 4, 1, f); + fclose(f); + + if ((data >> 24) == 0) // old CRC-based list + { + uiMsgBoxError(NULL, "Your version of romlist.bin is outdated.", romlist_missing_text); + } + } + else + { + uiMsgBoxError(NULL, "romlist.bin not found.", romlist_missing_text); + } + } +#endif + + mainWindow = new MainWindow(); + mainWindow->show(); + + emuThread = new EmuThread(); + emuThread->start(); + emuThread->emuPause(true); + + if (argc > 1) + { + char* file = argv[1]; + char* ext = &file[strlen(file)-3]; + + if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl")) + { + strncpy(ROMPath[0], file, 1023); + ROMPath[0][1023] = '\0'; + + //SetupSRAMPath(0); + + //if (NDS::LoadROM(ROMPath[0], SRAMPath[0], Config::DirectBoot)) + // Run(); + } + + if (argc > 2) + { + file = argv[2]; + ext = &file[strlen(file)-3]; + + if (!strcasecmp(ext, "gba")) + { + strncpy(ROMPath[1], file, 1023); + ROMPath[1][1023] = '\0'; + + //SetupSRAMPath(1); + + //NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); + } + } + } + + int ret = melon.exec(); +printf("melon over\n"); + emuThread->emuStop();printf("STOP\n"); + emuThread->wait();printf("farked\n"); + + Config::Save(); + + SDL_Quit(); + delete[] EmuDirectory; + return ret; } #ifdef __WIN32__ @@ -71,6 +622,7 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho char** argv = new char*[argc]; for (int i = 0; i < argc; i++) { + if (!argv_w) { argv[i] = nullarg; continue; } int len = WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, NULL, 0, NULL, NULL); if (len < 1) { argv[i] = nullarg; continue; } argv[i] = new char[len]; @@ -78,6 +630,8 @@ int CALLBACK WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int cmdsho if (res != len) { delete[] argv[i]; argv[i] = nullarg; } } + if (argv_w) LocalFree(argv_w); + if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index ad795ef..92b1846 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -19,8 +19,45 @@ #ifndef MAIN_H #define MAIN_H +#include +#include #include + +class EmuThread : public QThread +{ + Q_OBJECT + void run() override; + +public: + explicit EmuThread(QObject* parent = nullptr); + + // to be called from the UI thread + void emuRun(); + void emuPause(bool refresh); + void emuUnpause(); + void emuStop(); + +private: + volatile int EmuStatus; + int PrevEmuStatus; + int EmuRunning; +}; + + +class MainWindowPanel : public QWidget +{ + Q_OBJECT + +public: + explicit MainWindowPanel(QWidget* parent); + ~MainWindowPanel(); + +protected: + void paintEvent(QPaintEvent* event) override; +}; + + class MainWindow : public QMainWindow { Q_OBJECT @@ -29,8 +66,11 @@ public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); +private slots: + void onOpenFile(); + private: - // private shit goes here + MainWindowPanel* panel; }; #endif // MAIN_H -- cgit v1.2.3 From d9c55a4f1f269de2fd17fe214403f13a9cf6f341 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 15:59:52 +0200 Subject: fix dumb include path shit. --- src/frontend/qt_sdl/CMakeLists.txt | 2 +- src/frontend/qt_sdl/main.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index f24464d..baa4be2 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -21,6 +21,7 @@ pkg_check_modules(SDL2 REQUIRED sdl2) add_executable(melonDS ${SOURCES_QT_SDL}) target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS}) +target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") target_link_libraries(melonDS core ${SDL2_LIBRARIES}) if (UNIX) @@ -52,7 +53,6 @@ if (UNIX) target_sources(melonDS PUBLIC melon_grc.c) elseif (WIN32) target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") - target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Gui Qt5::Widgets) endif () diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 9192685..4999d94 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -208,6 +208,7 @@ printf("emu thread start: %d\n", EmuRunning); uiGLEnd(GLContext); } uiAreaQueueRedrawAll(MainDrawArea);*/ + mainWindow->update(); /*bool fastforward = HotkeyDown(HK_FastForward); @@ -292,6 +293,7 @@ printf("emu thread start: %d\n", EmuRunning); uiGLEnd(GLContext); } uiAreaQueueRedrawAll(MainDrawArea);*/ + mainWindow->update(); } //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); @@ -359,7 +361,10 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) { QPainter painter(this); - //painter. + // fill background + painter.fillRect(event->rect(), QColor::fromRgb(0, 0, 0)); + + painter.fillRect(0, 0, 256, 192, QColor::fromRgb(0, 255, 255)); } -- cgit v1.2.3 From 931da1c66fb50138109f8bf4cb157db8f1e79c64 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 22:02:45 +0200 Subject: add a bunch of code --- src/CMakeLists.txt | 2 + src/Config.h | 2 + src/frontend/FrontendUtil.h | 38 ++++++- src/frontend/Util_ROM.cpp | 236 +++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 19 ++-- 5 files changed, 284 insertions(+), 13 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64d922c..dca0ca9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,8 @@ add_library(core STATIC Savestate.cpp SPI.cpp SPU.cpp + types.h + version.h Wifi.cpp WifiAP.cpp ) diff --git a/src/Config.h b/src/Config.h index 84fd57b..0aeab85 100644 --- a/src/Config.h +++ b/src/Config.h @@ -19,6 +19,8 @@ #ifndef CONFIG_H #define CONFIG_H +#include + #include "types.h" namespace Config diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 6a199b7..7e171ce 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -21,10 +21,44 @@ #include "types.h" -namespace FrontendUtil +namespace Frontend { -// +enum +{ + ROMSlot_NDS = 0, + ROMSlot_GBA, + + ROMSlot_MAX +}; + +extern char ROMPath [ROMSlot_MAX][1024]; +extern char SRAMPath[ROMSlot_MAX][1024]; +extern bool SavestateLoaded; + + +// initialize the ROM handling utility +void Init_ROM(); + +// load a ROM file to the specified cart slot +// note: loading a ROM to the NDS slot resets emulation +bool LoadROM(char* file, int slot); + +// get the filename associated with the given savestate slot +void GetSavestateName(int slot, char* filename, int len); + +// determine whether the given savestate slot does contain a savestate +bool SavestateExists(int slot); + +// load the given savestate file +// if successful, emulation will continue from the savestate's point +bool LoadState(const char* filename); + +// save the current emulator state to the given file +bool SaveState(const char* filename); + +// undo the latest savestate load +void UndoStateLoad(); } diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index b3077f7..574148b 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -15,3 +15,239 @@ You should have received a copy of the GNU General Public License along with melonDS. If not, see http://www.gnu.org/licenses/. */ + +#include +#include + +#include "FrontendUtil.h" +#include "Config.h" +#include "qt_sdl/PlatformConfig.h" // FIXME!!! +#include "Platform.h" + +#include "NDS.h" +#include "GBACart.h" + + +namespace Frontend +{ + +char ROMPath [ROMSlot_MAX][1024]; +char SRAMPath [ROMSlot_MAX][1024]; +char PrevSRAMPath[ROMSlot_MAX][1024]; // for savestate 'undo load' + +bool SavestateLoaded; + + +void Init_ROM() +{ + SavestateLoaded = false; + + memset(ROMPath[ROMSlot_NDS], 0, 1024); + memset(ROMPath[ROMSlot_GBA], 0, 1024); + memset(SRAMPath[ROMSlot_NDS], 0, 1024); + memset(SRAMPath[ROMSlot_GBA], 0, 1024); + memset(PrevSRAMPath[ROMSlot_NDS], 0, 1024); + memset(PrevSRAMPath[ROMSlot_GBA], 0, 1024); +} + +void SetupSRAMPath(int slot) +{ + strncpy(SRAMPath[slot], ROMPath[slot], 1023); + SRAMPath[slot][1023] = '\0'; + strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); +} + +bool LoadROM(char* file, int slot) +{ + char oldpath[1024]; + char oldsram[1024]; + strncpy(oldpath, ROMPath[slot], 1024); + strncpy(oldsram, SRAMPath[slot], 1024); + + strncpy(ROMPath[slot], file, 1023); + ROMPath[slot][1023] = '\0'; + + SetupSRAMPath(0); + SetupSRAMPath(1); + + if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot)) + { + SavestateLoaded = false; + + // Reload the inserted GBA cartridge (if any) + if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]); + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety + return true; + } + else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) + { + SavestateLoaded = false; + + strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety + return true; + } + else + { + strncpy(ROMPath[slot], oldpath, 1024); + strncpy(SRAMPath[slot], oldsram, 1024); + return false; + } +} + + +// SAVESTATE TODO +// * configurable paths. not everyone wants their ROM directory to be polluted, I guess. + +void GetSavestateName(int slot, char* filename, int len) +{ + int pos; + + if (ROMPath[ROMSlot_NDS][0] == '\0') // running firmware, no ROM + { + strcpy(filename, "firmware"); + pos = 8; + } + else + { + int l = strlen(ROMPath[ROMSlot_NDS]); + pos = l; + while (ROMPath[ROMSlot_NDS][pos] != '.' && pos > 0) pos--; + if (pos == 0) pos = l; + + // avoid buffer overflow. shoddy + if (pos > len-5) pos = len-5; + + strncpy(&filename[0], ROMPath[ROMSlot_NDS], pos); + } + strcpy(&filename[pos], ".ml"); + filename[pos+3] = '0'+slot; + filename[pos+4] = '\0'; +} + +bool SavestateExists(int slot) +{ + char ssfile[1024]; + GetSavestateName(slot, ssfile, 1024); + return Platform::FileExists(ssfile); +} + +bool LoadState(const char* filename) +{ + u32 oldGBACartCRC = GBACart::CartCRC; + + // backup + Savestate* backup = new Savestate("timewarp.mln", true); + NDS::DoSavestate(backup); + delete backup; + + bool failed = false; + + Savestate* state = new Savestate(filename, false); + if (state->Error) + { + delete state; + + //uiMsgBoxError(MainWindow, "Error", "Could not load savestate file."); + + // current state might be crapoed, so restore from sane backup + state = new Savestate("timewarp.mln", false); + failed = true; + } + + NDS::DoSavestate(state); + delete state; + + if (!failed) + { + if (Config::SavestateRelocSRAM && ROMPath[ROMSlot_NDS][0]!='\0') + { + strncpy(PrevSRAMPath[ROMSlot_NDS], SRAMPath[0], 1024); + + strncpy(SRAMPath[ROMSlot_NDS], filename, 1019); + int len = strlen(SRAMPath[ROMSlot_NDS]); + strcpy(&SRAMPath[ROMSlot_NDS][len], ".sav"); + SRAMPath[ROMSlot_NDS][len+4] = '\0'; + + NDS::RelocateSave(SRAMPath[ROMSlot_NDS], false); + } + + bool loadedPartialGBAROM = false; + + // in case we have a GBA cart inserted, and the GBA ROM changes + // due to having loaded a save state, we do not want to reload + // the previous cartridge on reset, or commit writes to any + // loaded save file. therefore, their paths are "nulled". + if (GBACart::CartInserted && GBACart::CartCRC != oldGBACartCRC) + { + ROMPath[ROMSlot_GBA][0] = '\0'; + SRAMPath[ROMSlot_GBA][0] = '\0'; + loadedPartialGBAROM = true; + } + + // TODO forward this to user in a meaningful way!! + /*char msg[64]; + if (slot > 0) sprintf(msg, "State loaded from slot %d%s", + slot, loadedPartialGBAROM ? " (GBA ROM header only)" : ""); + else sprintf(msg, "State loaded from file%s", + loadedPartialGBAROM ? " (GBA ROM header only)" : ""); + OSD::AddMessage(0, msg);*/ + + SavestateLoaded = true; + } + + return !failed; +} + +bool SaveState(const char* filename) +{ + Savestate* state = new Savestate(filename, true); + if (state->Error) + { + delete state; + return false; + } + else + { + NDS::DoSavestate(state); + delete state; + + if (Config::SavestateRelocSRAM && ROMPath[ROMSlot_NDS][0]!='\0') + { + strncpy(SRAMPath[ROMSlot_NDS], filename, 1019); + int len = strlen(SRAMPath[ROMSlot_NDS]); + strcpy(&SRAMPath[ROMSlot_NDS][len], ".sav"); + SRAMPath[ROMSlot_NDS][len+4] = '\0'; + + NDS::RelocateSave(SRAMPath[ROMSlot_NDS], true); + } + } + + /*char msg[64]; + if (slot > 0) sprintf(msg, "State saved to slot %d", slot); + else sprintf(msg, "State saved to file"); + OSD::AddMessage(0, msg);*/ + return true; +} + +void UndoStateLoad() +{ + if (!SavestateLoaded) return; + + // pray that this works + // what do we do if it doesn't??? + // but it should work. + Savestate* backup = new Savestate("timewarp.mln", false); + NDS::DoSavestate(backup); + delete backup; + + if (ROMPath[ROMSlot_NDS][0]!='\0') + { + strncpy(SRAMPath[ROMSlot_NDS], PrevSRAMPath[ROMSlot_NDS], 1024); + NDS::RelocateSave(SRAMPath[ROMSlot_NDS], false); + } + + //OSD::AddMessage(0, "State load undone"); +} + +} diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 4999d94..648cd99 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -49,11 +49,6 @@ char* EmuDirectory; bool RunningSomething; -char ROMPath[2][1024]; -char SRAMPath[2][1024]; -char PrevSRAMPath[2][1024]; // for savestate 'undo load' - -bool SavestateLoaded; MainWindow* mainWindow; EmuThread* emuThread; @@ -334,8 +329,8 @@ void EmuThread::emuPause(bool refresh) { int status = refresh ? 2:3; PrevEmuStatus = EmuRunning; - EmuRunning = status;printf("emuPause %d -> %d %d\n", PrevEmuStatus, EmuRunning, EmuStatus); - while (EmuStatus != status);printf("wait done\n"); + EmuRunning = status; + while (EmuStatus != status); } void EmuThread::emuUnpause() @@ -370,7 +365,7 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { - setWindowTitle("melonDS - assfucking Qt version"); + setWindowTitle("melonDS " MELONDS_VERSION); QMenuBar* menubar = new QMenuBar(); { @@ -569,6 +564,7 @@ int main(int argc, char** argv) emuThread->start(); emuThread->emuPause(true); + #if 0 if (argc > 1) { char* file = argv[1]; @@ -601,11 +597,12 @@ int main(int argc, char** argv) } } } + #endif int ret = melon.exec(); -printf("melon over\n"); - emuThread->emuStop();printf("STOP\n"); - emuThread->wait();printf("farked\n"); + + emuThread->emuStop(); + emuThread->wait(); Config::Save(); -- cgit v1.2.3 From 3c883a2152c699b432c951b3498a1adc3d4c21b1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 22:32:33 +0200 Subject: hey look, it runs shit now! --- src/frontend/FrontendUtil.h | 2 +- src/frontend/Util_ROM.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 60 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 6 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 7e171ce..91f3cdd 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -42,7 +42,7 @@ void Init_ROM(); // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation -bool LoadROM(char* file, int slot); +bool LoadROM(const char* file, int slot); // get the filename associated with the given savestate slot void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 574148b..ffee69a 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,7 +57,7 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } -bool LoadROM(char* file, int slot) +bool LoadROM(const char* file, int slot) { char oldpath[1024]; char oldsram[1024]; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 648cd99..6b4c873 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -35,13 +35,15 @@ #include "types.h" #include "version.h" +#include "FrontendUtil.h" + #include "NDS.h" -#include "GBACart.h" #include "GPU.h" #include "SPU.h" #include "Wifi.h" #include "Platform.h" #include "Config.h" +#include "PlatformConfig.h" #include "Savestate.h" @@ -102,7 +104,7 @@ void EmuThread::run() char melontitle[100]; SDL_mutex* titlemutex = SDL_CreateMutex(); void* titledata[2] = {melontitle, titlemutex}; -printf("emu thread start: %d\n", EmuRunning); + while (EmuRunning != 0) { /*ProcessInput(); @@ -389,8 +391,56 @@ MainWindow::~MainWindow() void MainWindow::onOpenFile() { - QString filename = QFileDialog::getOpenFileName(this, "Open ROM", "", "DS ROMs (*.nds *.srl);;Any file (*.*)"); - printf("fark: %p %d %s\n", filename, filename.isEmpty(), filename.toStdString().c_str()); + emuThread->emuPause(true); + + QString filename = QFileDialog::getOpenFileName(this, + "Open ROM", + Config::LastROMFolder, + "DS ROMs (*.nds *.srl);;GBA ROMs (*.gba);;Any file (*.*)"); + if (filename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + // this shit is stupid + char file[1024]; + strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0'; + + int pos = strlen(file)-1; + while (file[pos] != '/' && file[pos] != '\\' && pos > 0) pos--; + strncpy(Config::LastROMFolder, file, pos); + Config::LastROMFolder[pos] = '\0'; + char* ext = &file[strlen(file)-3]; + + int slot; bool res; + if (!strcasecmp(ext, "gba")) + { + slot = 1; + res = Frontend::LoadROM(file, Frontend::ROMSlot_GBA); + } + else + { + slot = 0; + res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); + } + + if (!res) + { + QMessageBox::critical(this, + "melonDS", + "Failed to load the ROM.\n\nMake sure the file is accessible and isn't used by another application."); + emuThread->emuUnpause(); + } + else if (slot == 1) + { + // checkme + emuThread->emuUnpause(); + } + else + { + emuThread->emuRun(); + } } @@ -557,6 +607,8 @@ int main(int argc, char** argv) } #endif + RunningSomething = false; + mainWindow = new MainWindow(); mainWindow->show(); -- cgit v1.2.3 From a8aa834c16d5044c25f6d313f88a470cb79ffbfa Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 22:42:07 +0200 Subject: now with display! --- src/frontend/qt_sdl/main.cpp | 20 ++++++++++++++++++-- src/frontend/qt_sdl/main.h | 4 ++++ 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 6b4c873..33dad2b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -299,7 +299,6 @@ void EmuThread::run() SDL_Delay(100); } - printf("ran iteration: status=%d run=%d\n", EmuStatus, EmuRunning); } EmuStatus = 0; @@ -325,6 +324,7 @@ void EmuThread::run() void EmuThread::emuRun() { EmuRunning = 1; + RunningSomething = true; } void EmuThread::emuPause(bool refresh) @@ -348,10 +348,14 @@ void EmuThread::emuStop() MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) { + screen[0] = new QImage(256, 192, QImage::Format_RGB32); + screen[1] = new QImage(256, 192, QImage::Format_RGB32); } MainWindowPanel::~MainWindowPanel() { + delete screen[0]; + delete screen[1]; } void MainWindowPanel::paintEvent(QPaintEvent* event) @@ -361,7 +365,19 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) // fill background painter.fillRect(event->rect(), QColor::fromRgb(0, 0, 0)); - painter.fillRect(0, 0, 256, 192, QColor::fromRgb(0, 255, 255)); + int frontbuf = GPU::FrontBuffer; + if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) return; + + memcpy(screen[0]->scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); + memcpy(screen[1]->scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); + + QRect src = QRect(0, 0, 256, 192); + + QRect dstTop = QRect(0, 0, 256, 192); // TODO + QRect dstBot = QRect(0, 192, 256, 192); // TODO + + painter.drawImage(dstTop, *screen[0]); + painter.drawImage(dstBot, *screen[1]); } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 92b1846..fb35fa5 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -22,6 +22,7 @@ #include #include #include +#include class EmuThread : public QThread @@ -55,6 +56,9 @@ public: protected: void paintEvent(QPaintEvent* event) override; + +private: + QImage* screen[2]; }; -- cgit v1.2.3 From 0913576ef598bee4d2ea3c4268a6a6f163cd90ef Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 23:58:29 +0200 Subject: FPS counter is back --- src/frontend/qt_sdl/main.cpp | 32 +++++++++++++++++++++----------- src/frontend/qt_sdl/main.h | 7 +++++++ 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 33dad2b..e9b9122 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -60,6 +60,9 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) { EmuStatus = 0; EmuRunning = 2; + RunningSomething = false; + + connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); } void EmuThread::run() @@ -102,8 +105,6 @@ void EmuThread::run() u32 nsamples = 0; char melontitle[100]; - SDL_mutex* titlemutex = SDL_CreateMutex(); - void* titledata[2] = {melontitle, titlemutex}; while (EmuRunning != 0) { @@ -207,6 +208,7 @@ void EmuThread::run() uiAreaQueueRedrawAll(MainDrawArea);*/ mainWindow->update(); + bool fastforward = false; /*bool fastforward = HotkeyDown(HK_FastForward); if (Config::AudioSync && !fastforward) @@ -218,7 +220,7 @@ void EmuThread::run() if (ret == SDL_MUTEX_TIMEDOUT) break; } SDL_UnlockMutex(AudioSyncLock); - } + }*/ float framerate = (1000.0f * nlines) / (60.0f * 263.0f); @@ -265,11 +267,9 @@ void EmuThread::run() if (framerate < 1) fpstarget = 999; else fpstarget = 1000.0f/framerate; - SDL_LockMutex(titlemutex); sprintf(melontitle, "[%d/%.0f] melonDS " MELONDS_VERSION, fps, fpstarget); - SDL_UnlockMutex(titlemutex); - uiQueueMain(UpdateWindowTitle, titledata); - }*/ + changeWindowTitle(melontitle); + } } else { @@ -297,14 +297,15 @@ void EmuThread::run() EmuStatus = EmuRunning; + sprintf(melontitle, "melonDS " MELONDS_VERSION); + changeWindowTitle(melontitle); + SDL_Delay(100); } } EmuStatus = 0; - SDL_DestroyMutex(titlemutex); - //if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); NDS::DeInit(); @@ -321,6 +322,11 @@ void EmuThread::run() //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); } +void EmuThread::changeWindowTitle(char* title) +{ + emit windowTitleChange(QString(title)); +} + void EmuThread::emuRun() { EmuRunning = 1; @@ -460,6 +466,12 @@ void MainWindow::onOpenFile() } +void MainWindow::onTitleUpdate(QString title) +{ + setWindowTitle(title); +} + + int main(int argc, char** argv) { srand(time(NULL)); @@ -623,8 +635,6 @@ int main(int argc, char** argv) } #endif - RunningSomething = false; - mainWindow = new MainWindow(); mainWindow->show(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index fb35fa5..a1093fe 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -33,12 +33,17 @@ class EmuThread : public QThread public: explicit EmuThread(QObject* parent = nullptr); + void changeWindowTitle(char* title); + // to be called from the UI thread void emuRun(); void emuPause(bool refresh); void emuUnpause(); void emuStop(); +signals: + void windowTitleChange(QString title); + private: volatile int EmuStatus; int PrevEmuStatus; @@ -73,6 +78,8 @@ public: private slots: void onOpenFile(); + void onTitleUpdate(QString title); + private: MainWindowPanel* panel; }; -- cgit v1.2.3 From 63efc2e02aa51c44c9cb5abc621624aa1d7bf1e5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 28 Apr 2020 22:45:11 +0200 Subject: add menu items for running the firmware and for quitting. --- src/frontend/FrontendUtil.h | 3 +++ src/frontend/Util_ROM.cpp | 16 ++++++++++++++++ src/frontend/qt_sdl/main.cpp | 44 +++++++++++++++++++++++++++++++++++++++++--- src/frontend/qt_sdl/main.h | 9 +++++++++ 4 files changed, 69 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 91f3cdd..eb4cb38 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -40,6 +40,9 @@ extern bool SavestateLoaded; // initialize the ROM handling utility void Init_ROM(); +// load the BIOS/firmware and boot from it +bool LoadBIOS(); + // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation bool LoadROM(const char* file, int slot); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index ffee69a..cf40a78 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,6 +57,22 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } +bool LoadBIOS() +{ + // TODO: + // original code in the libui frontend called NDS::LoadGBAROM() if needed + // should this be carried over here? + // is that behavior consistent with that of LoadROM() below? + + ROMPath[ROMSlot_NDS][0] = '\0'; + SRAMPath[ROMSlot_NDS][0] = '\0'; + + NDS::LoadBIOS(); + + // TODO: error reporting? + return true; +} + bool LoadROM(const char* file, int slot) { char oldpath[1024]; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index e9b9122..cadcec9 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -394,10 +394,17 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) QMenuBar* menubar = new QMenuBar(); { QMenu* menu = menubar->addMenu("File"); - QAction* act; - act = menu->addAction("Open file..."); - connect(act, &QAction::triggered, this, &MainWindow::onOpenFile); + actOpenROM = menu->addAction("Open file..."); + connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); + + actBootFirmware = menu->addAction("Launch DS menu"); + connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware); + + menu->addSeparator(); + + actQuit = menu->addAction("Quit"); + connect(actQuit, &QAction::triggered, this, &MainWindow::onQuit); } setMenuBar(menubar); @@ -411,6 +418,12 @@ MainWindow::~MainWindow() } +void MainWindow::keyPressEvent(QKeyEvent* event) +{ + printf("key press. %d %d %08X %08X\n", event->key(), event->nativeScanCode(), event->modifiers(), event->nativeModifiers()); +} + + void MainWindow::onOpenFile() { emuThread->emuPause(true); @@ -465,6 +478,31 @@ void MainWindow::onOpenFile() } } +void MainWindow::onBootFirmware() +{ + // TODO: ensure the firmware is actually bootable!! + // TODO: check the whole GBA cart shito + + emuThread->emuPause(true); + + bool res = Frontend::LoadBIOS(); + if (!res) + { + // TODO! + + emuThread->emuUnpause(); + } + else + { + emuThread->emuRun(); + } +} + +void MainWindow::onQuit() +{ + QApplication::quit(); +} + void MainWindow::onTitleUpdate(QString title) { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index a1093fe..9ccbddd 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -75,13 +75,22 @@ public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); +protected: + void keyPressEvent(QKeyEvent* event) override; + private slots: void onOpenFile(); + void onBootFirmware(); + void onQuit(); void onTitleUpdate(QString title); private: MainWindowPanel* panel; + + QAction* actOpenROM; + QAction* actBootFirmware; + QAction* actQuit; }; #endif // MAIN_H -- cgit v1.2.3 From 47ff012f5ed743d30d994a10de48e07b650f706b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 28 Apr 2020 22:46:31 +0200 Subject: blarg --- src/frontend/qt_sdl/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index cadcec9..af4fd4b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -398,7 +398,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actOpenROM = menu->addAction("Open file..."); connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); - actBootFirmware = menu->addAction("Launch DS menu"); + //actBootFirmware = menu->addAction("Launch DS menu"); + actBootFirmware = menu->addAction("Boot firmware"); connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware); menu->addSeparator(); -- cgit v1.2.3 From 5fbad464c27fd5290c837d78a72378215ee8e77f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 29 Apr 2020 00:50:23 +0200 Subject: hook up savestate shito --- src/frontend/FrontendUtil.h | 2 +- src/frontend/Util_ROM.cpp | 2 + src/frontend/qt_sdl/main.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/main.h | 6 ++ 4 files changed, 149 insertions(+), 2 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index eb4cb38..d9f5c58 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -47,7 +47,7 @@ bool LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation bool LoadROM(const char* file, int slot); -// get the filename associated with the given savestate slot +// get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); // determine whether the given savestate slot does contain a savestate diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index cf40a78..19c8eb9 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -69,6 +69,8 @@ bool LoadBIOS() NDS::LoadBIOS(); + SavestateLoaded = false; + // TODO: error reporting? return true; } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index af4fd4b..a6a1423 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -395,7 +395,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { QMenu* menu = menubar->addMenu("File"); - actOpenROM = menu->addAction("Open file..."); + actOpenROM = menu->addAction("Open ROM..."); connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); //actBootFirmware = menu->addAction("Launch DS menu"); @@ -404,6 +404,49 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) menu->addSeparator(); + { + QMenu* submenu = menu->addMenu("Save state"); + + for (int i = 1; i < 9; i++) + { + char title[16]; + sprintf(title, "%d", i); + actSaveState[i] = submenu->addAction(title); + actSaveState[i]->setShortcut(QKeySequence(Qt::ShiftModifier | (Qt::Key_F1+i-1))); + actSaveState[i]->setData(QVariant(i)); + connect(actSaveState[i], &QAction::triggered, this, &MainWindow::onSaveState); + } + + actSaveState[0] = submenu->addAction("File..."); + actSaveState[0]->setShortcut(QKeySequence(Qt::ShiftModifier | Qt::Key_F9)); + actSaveState[0]->setData(QVariant(0)); + connect(actSaveState[0], &QAction::triggered, this, &MainWindow::onSaveState); + } + { + QMenu* submenu = menu->addMenu("Load state"); + + for (int i = 1; i < 9; i++) + { + char title[16]; + sprintf(title, "%d", i); + actLoadState[i] = submenu->addAction(title); + actLoadState[i]->setShortcut(QKeySequence(Qt::Key_F1+i-1)); + actLoadState[i]->setData(QVariant(i)); + connect(actLoadState[i], &QAction::triggered, this, &MainWindow::onLoadState); + } + + actLoadState[0] = submenu->addAction("File..."); + actLoadState[0]->setShortcut(QKeySequence(Qt::Key_F9)); + actLoadState[0]->setData(QVariant(0)); + connect(actLoadState[0], &QAction::triggered, this, &MainWindow::onLoadState); + } + + actUndoStateLoad = menu->addAction("Undo state load"); + actUndoStateLoad->setShortcut(QKeySequence(Qt::Key_F12)); + connect(actUndoStateLoad, &QAction::triggered, this, &MainWindow::onUndoStateLoad); + + menu->addSeparator(); + actQuit = menu->addAction("Quit"); connect(actQuit, &QAction::triggered, this, &MainWindow::onQuit); } @@ -499,6 +542,102 @@ void MainWindow::onBootFirmware() } } +void MainWindow::onSaveState() +{ + int slot = ((QAction*)sender())->data().toInt(); + + emuThread->emuPause(true); + + char filename[1024]; + if (slot > 0) + { + Frontend::GetSavestateName(slot, filename, 1024); + } + else + { + // TODO: specific 'last directory' for savestate files? + QString qfilename = QFileDialog::getSaveFileName(this, + "Save state", + Config::LastROMFolder, + "melonDS savestates (*.mln);;Any file (*.*)"); + if (qfilename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0'; + } + + if (Frontend::SaveState(filename)) + { + // TODO: OSD message + } + else + { + // TODO: OSD error message? + } + + emuThread->emuUnpause(); +} + +void MainWindow::onLoadState() +{ + int slot = ((QAction*)sender())->data().toInt(); + + emuThread->emuPause(true); + + char filename[1024]; + if (slot > 0) + { + Frontend::GetSavestateName(slot, filename, 1024); + } + else + { + // TODO: specific 'last directory' for savestate files? + QString qfilename = QFileDialog::getOpenFileName(this, + "Load state", + Config::LastROMFolder, + "melonDS savestates (*.ml*);;Any file (*.*)"); + if (qfilename.isEmpty()) + { + emuThread->emuUnpause(); + return; + } + + strncpy(filename, qfilename.toStdString().c_str(), 1023); filename[1023] = '\0'; + } + + if (!Platform::FileExists(filename)) + { + /*char msg[64]; + if (slot > 0) sprintf(msg, "State slot %d is empty", slot); + else sprintf(msg, "State file does not exist"); + OSD::AddMessage(0xFFA0A0, msg);*/ + + emuThread->emuUnpause(); + return; + } + + if (Frontend::LoadState(filename)) + { + // TODO: OSD message + } + else + { + // TODO: OSD error message? + } + + emuThread->emuUnpause(); +} + +void MainWindow::onUndoStateLoad() +{ + emuThread->emuPause(true); + Frontend::UndoStateLoad(); + emuThread->emuUnpause(); +} + void MainWindow::onQuit() { QApplication::quit(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 9ccbddd..8694838 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -81,6 +81,9 @@ protected: private slots: void onOpenFile(); void onBootFirmware(); + void onSaveState(); + void onLoadState(); + void onUndoStateLoad(); void onQuit(); void onTitleUpdate(QString title); @@ -90,6 +93,9 @@ private: QAction* actOpenROM; QAction* actBootFirmware; + QAction* actSaveState[9]; + QAction* actLoadState[9]; + QAction* actUndoStateLoad; QAction* actQuit; }; -- cgit v1.2.3 From 7f3e67c12a6b7687467c4b56d79e4770cc32ae43 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 30 Apr 2020 01:02:17 +0200 Subject: some more UI work --- src/frontend/qt_sdl/main.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.h | 19 +++++++++ 2 files changed, 112 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index a6a1423..5cc4826 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -63,6 +63,10 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) RunningSomething = false; connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); + connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); + connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); + + emit windowEmuStop(); } void EmuThread::run() @@ -331,6 +335,9 @@ void EmuThread::emuRun() { EmuRunning = 1; RunningSomething = true; + + // checkme + emit windowEmuStart(); } void EmuThread::emuPause(bool refresh) @@ -339,11 +346,15 @@ void EmuThread::emuPause(bool refresh) PrevEmuStatus = EmuRunning; EmuRunning = status; while (EmuStatus != status); + + //emit windowEmuPause(); } void EmuThread::emuUnpause() { EmuRunning = PrevEmuStatus; + + //emit windowEmuUnpause(); } void EmuThread::emuStop() @@ -351,6 +362,11 @@ void EmuThread::emuStop() EmuRunning = 0; } +bool EmuThread::emuIsRunning() +{ + return (EmuRunning == 1); +} + MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) { @@ -450,6 +466,19 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actQuit = menu->addAction("Quit"); connect(actQuit, &QAction::triggered, this, &MainWindow::onQuit); } + { + QMenu* menu = menubar->addMenu("System"); + + actPause = menu->addAction("Pause"); + actPause->setCheckable(true); + connect(actPause, &QAction::triggered, this, &MainWindow::onPause); + + actReset = menu->addAction("Reset"); + connect(actReset, &QAction::triggered, this, &MainWindow::onReset); + + actStop = menu->addAction("Stop"); + connect(actStop, &QAction::triggered, this, &MainWindow::onStop); + } setMenuBar(menubar); panel = new MainWindowPanel(this); @@ -644,11 +673,75 @@ void MainWindow::onQuit() } +void MainWindow::onPause(bool checked) +{ + if (emuThread->emuIsRunning()) + { + emuThread->emuPause(true); + } + else + { + emuThread->emuUnpause(); + } +} + +void MainWindow::onReset() +{ + // +} + +void MainWindow::onStop() +{ + // +} + + void MainWindow::onTitleUpdate(QString title) { setWindowTitle(title); } +void MainWindow::onEmuStart() +{ + for (int i = 1; i < 9; i++) + { + actSaveState[i]->setEnabled(true); + actLoadState[i]->setEnabled(Frontend::SavestateExists(i)); + } + actSaveState[0]->setEnabled(true); + actLoadState[0]->setEnabled(true); + actUndoStateLoad->setEnabled(true); + + actPause->setEnabled(true); + actPause->setChecked(false); + actReset->setEnabled(true); + actStop->setEnabled(true); +} + +void MainWindow::onEmuStop() +{ + for (int i = 0; i < 9; i++) + { + actSaveState[i]->setEnabled(false); + actLoadState[i]->setEnabled(false); + } + actUndoStateLoad->setEnabled(false); + + actPause->setEnabled(false); + actReset->setEnabled(false); + actStop->setEnabled(false); +} + +void MainWindow::onEmuPause() +{ + // +} + +void MainWindow::onEmuUnpause() +{ + // +} + int main(int argc, char** argv) { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 8694838..30cef1f 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -41,9 +41,15 @@ public: void emuUnpause(); void emuStop(); + bool emuIsRunning(); + signals: void windowTitleChange(QString title); + void windowEmuStart(); + void windowEmuStop(); + void windowPauseToggle(); + private: volatile int EmuStatus; int PrevEmuStatus; @@ -86,8 +92,17 @@ private slots: void onUndoStateLoad(); void onQuit(); + void onPause(bool checked); + void onReset(); + void onStop(); + void onTitleUpdate(QString title); + void onEmuStart(); + void onEmuStop(); + void onEmuPause(); + void onEmuUnpause(); + private: MainWindowPanel* panel; @@ -97,6 +112,10 @@ private: QAction* actLoadState[9]; QAction* actUndoStateLoad; QAction* actQuit; + + QAction* actPause; + QAction* actReset; + QAction* actStop; }; #endif // MAIN_H -- cgit v1.2.3 From 690f39ca3382f1e82a27c8a16dde1a4379f978f8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 2 May 2020 19:41:03 +0200 Subject: enable savestate slots when saving a new savestate --- src/frontend/qt_sdl/main.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 5cc4826..bdf68bd 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -601,6 +601,8 @@ void MainWindow::onSaveState() if (Frontend::SaveState(filename)) { // TODO: OSD message + + actLoadState[slot]->setEnabled(true); } else { -- cgit v1.2.3 From aa4344e249d855bfc2ddd52af61d3213d9e99db3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 2 May 2020 20:25:39 +0200 Subject: add audio output. HARK HARK HARK --- src/CMakeLists.txt | 3 ++ src/frontend/FrontendUtil.h | 13 ++++++ src/frontend/Util_Audio.cpp | 77 ++++++++++++++++++++++++++++++ src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/main.cpp | 96 +++++++++++++++++++++++++++++++++++--- 5 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 src/frontend/Util_Audio.cpp (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dca0ca9..245e6a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,7 @@ add_library(core STATIC ARCodeList.cpp AREngine.cpp ARM.cpp + ARM_InstrTable.h ARMInterpreter.cpp ARMInterpreter_ALU.cpp ARMInterpreter_Branch.cpp @@ -12,11 +13,13 @@ add_library(core STATIC CP15.cpp CRC32.cpp DMA.cpp + FIFO.h GBACart.cpp GPU.cpp GPU2D.cpp GPU3D.cpp GPU3D_OpenGL.cpp + GPU3D_OpenGL_shaders.h GPU3D_Soft.cpp NDS.cpp NDSCart.cpp diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index d9f5c58..32f28d1 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -63,6 +63,19 @@ bool SaveState(const char* filename); // undo the latest savestate load void UndoStateLoad(); + +// initialize the audio utility +void Init_Audio(int outputfreq); + +// get how many samples to read from the core audio output +// based on how many are needed by the frontend (outlen in samples) +int AudioOut_GetNumSamples(int outlen); + +// resample audio from the core audio output to match the frontend's +// output frequency, and apply user-specified volume +// note: this assumes the output buffer is interleaved stereo +void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen); + } #endif // FRONTENDUTIL_H diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp new file mode 100644 index 0000000..fe0ecab --- /dev/null +++ b/src/frontend/Util_Audio.cpp @@ -0,0 +1,77 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include + +#include "FrontendUtil.h" +#include "Config.h" +#include "qt_sdl/PlatformConfig.h" // FIXME!!! +#include "Platform.h" + +#include "NDS.h" +#include "GBACart.h" + + +namespace Frontend +{ + +int AudioOut_Freq; +float AudioOut_SampleFrac; + + +void Init_Audio(int outputfreq) +{ + AudioOut_Freq = outputfreq; + AudioOut_SampleFrac = 0; +} + +int AudioOut_GetNumSamples(int outlen) +{ + float f_len_in = (outlen * 32823.6328125) / (float)AudioOut_Freq; + f_len_in += AudioOut_SampleFrac; + int len_in = (int)floor(f_len_in); + AudioOut_SampleFrac = f_len_in - len_in; + + return len_in; +} + +void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen) +{ + float res_incr = inlen / (float)outlen; + float res_timer = 0; + int res_pos = 0; + + int volume = Config::AudioVolume; + + for (int i = 0; i < outlen; i++) + { + outbuf[i*2 ] = (inbuf[res_pos*2 ] * volume) >> 8; + outbuf[i*2+1] = (inbuf[res_pos*2+1] * volume) >> 8; + + res_timer += res_incr; + while (res_timer >= 1.0) + { + res_timer -= 1.0; + res_pos++; + } + } +} + +} diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index fb9f547..05a4029 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -6,6 +6,7 @@ SET(SOURCES_QT_SDL PlatformConfig.cpp ../Util_ROM.cpp + ../Util_Audio.cpp ../FrontendUtil.h ) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index bdf68bd..80c25b5 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -48,6 +48,8 @@ #include "Savestate.h" +// TODO: uniform variable spelling + char* EmuDirectory; bool RunningSomething; @@ -55,6 +57,48 @@ bool RunningSomething; MainWindow* mainWindow; EmuThread* emuThread; +SDL_AudioDeviceID audioDevice; +int audioFreq; +SDL_cond* audioSync; +SDL_mutex* audioSyncLock; + + +void audioCallback(void* data, Uint8* stream, int len) +{ + len /= (sizeof(s16) * 2); + + // resample incoming audio to match the output sample rate + + int len_in = Frontend::AudioOut_GetNumSamples(len); + s16 buf_in[1024*2]; + int num_in; + + SDL_LockMutex(audioSyncLock); + num_in = SPU::ReadOutput(buf_in, len_in); + SDL_CondSignal(audioSync); + SDL_UnlockMutex(audioSyncLock); + + if (num_in < 1) + { + memset(stream, 0, len*sizeof(s16)*2); + return; + } + + int margin = 6; + if (num_in < len_in-margin) + { + int last = num_in-1; + if (last < 0) last = 0; + + for (int i = num_in; i < len_in-margin; i++) + ((u32*)buf_in)[i] = ((u32*)buf_in)[last]; + + num_in = len_in-margin; + } + + Frontend::AudioOut_Resample(buf_in, num_in, (s16*)stream, len); +} + EmuThread::EmuThread(QObject* parent) : QThread(parent) { @@ -213,18 +257,18 @@ void EmuThread::run() mainWindow->update(); bool fastforward = false; - /*bool fastforward = HotkeyDown(HK_FastForward); + //bool fastforward = HotkeyDown(HK_FastForward); - if (Config::AudioSync && !fastforward) + if (Config::AudioSync && (!fastforward) && audioDevice) { - SDL_LockMutex(AudioSyncLock); + SDL_LockMutex(audioSyncLock); while (SPU::GetOutputSize() > 1024) { - int ret = SDL_CondWaitTimeout(AudioSync, AudioSyncLock, 500); + int ret = SDL_CondWaitTimeout(audioSync, audioSyncLock, 500); if (ret == SDL_MUTEX_TIMEDOUT) break; } - SDL_UnlockMutex(AudioSyncLock); - }*/ + SDL_UnlockMutex(audioSyncLock); + } float framerate = (1000.0f * nlines) / (60.0f * 263.0f); @@ -338,6 +382,7 @@ void EmuThread::emuRun() // checkme emit windowEmuStart(); + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } void EmuThread::emuPause(bool refresh) @@ -348,6 +393,7 @@ void EmuThread::emuPause(bool refresh) while (EmuStatus != status); //emit windowEmuPause(); + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); } void EmuThread::emuUnpause() @@ -355,11 +401,14 @@ void EmuThread::emuUnpause() EmuRunning = PrevEmuStatus; //emit windowEmuUnpause(); + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } void EmuThread::emuStop() { EmuRunning = 0; + + if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); } bool EmuThread::emuIsRunning() @@ -908,6 +957,32 @@ int main(int argc, char** argv) } #endif + audioSync = SDL_CreateCond(); + audioSyncLock = SDL_CreateMutex(); + + audioFreq = 48000; // TODO: make configurable? + SDL_AudioSpec whatIwant, whatIget; + memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); + whatIwant.freq = audioFreq; + whatIwant.format = AUDIO_S16LSB; + whatIwant.channels = 2; + whatIwant.samples = 1024; + whatIwant.callback = audioCallback; + audioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); + if (!audioDevice) + { + printf("Audio init failed: %s\n", SDL_GetError()); + } + else + { + audioFreq = whatIget.freq; + printf("Audio output frequency: %d Hz\n", audioFreq); + SDL_PauseAudioDevice(audioDevice, 1); + } + + Frontend::Init_ROM(); + Frontend::Init_Audio(audioFreq); + mainWindow = new MainWindow(); mainWindow->show(); @@ -955,6 +1030,15 @@ int main(int argc, char** argv) emuThread->emuStop(); emuThread->wait(); + //if (Joystick) SDL_JoystickClose(Joystick); + if (audioDevice) SDL_CloseAudioDevice(audioDevice); + //if (MicDevice) SDL_CloseAudioDevice(MicDevice); + + SDL_DestroyCond(audioSync); + SDL_DestroyMutex(audioSyncLock); + + //if (MicWavBuffer) delete[] MicWavBuffer; + Config::Save(); SDL_Quit(); -- cgit v1.2.3 From 9432a9f3822f024e97185ac4b0a9df5c07987dd1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 3 May 2020 15:05:52 +0200 Subject: remove useless variables --- src/frontend/qt_sdl/main.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 80c25b5..643cf90 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -147,10 +147,6 @@ void EmuThread::run() u32 lasttick = starttick; u32 lastmeasuretick = lasttick; u32 fpslimitcount = 0; - u64 perfcount = SDL_GetPerformanceCounter(); - u64 perffreq = SDL_GetPerformanceFrequency(); - float samplesleft = 0; - u32 nsamples = 0; char melontitle[100]; @@ -288,7 +284,6 @@ void EmuThread::run() if ((abs(wantedtickF - (float)wantedtick) < 0.001312) || (fpslimitcount > 60)) { fpslimitcount = 0; - nsamples = 0; starttick = lasttick; } } -- cgit v1.2.3 From 978212e3e0b2d910ff3ca95464ad855f5872e500 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 16 May 2020 17:43:35 +0200 Subject: accept mouse events --- src/frontend/qt_sdl/main.cpp | 22 ++++++++++++++++++++++ src/frontend/qt_sdl/main.h | 4 ++++ 2 files changed, 26 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 643cf90..11602a6 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -447,6 +447,28 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) } +void MainWindowPanel::mousePressEvent(QMouseEvent* event) +{ + event->accept(); + + printf("mouse press %d,%d\n", event->pos().x(), event->pos().y()); +} + +void MainWindowPanel::mouseReleaseEvent(QMouseEvent* event) +{ + event->accept(); + + printf("mouse release %d,%d\n", event->pos().x(), event->pos().y()); +} + +void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) +{ + event->accept(); + + printf("mouse move %d,%d %08X\n", event->pos().x(), event->pos().y(), event->buttons()); +} + + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS " MELONDS_VERSION); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 30cef1f..f8ad9a3 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -68,6 +68,10 @@ public: protected: void paintEvent(QPaintEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + private: QImage* screen[2]; }; -- cgit v1.2.3 From 2afa70b8172339266feabbb9a93f2f165521f7d8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 02:37:23 +0200 Subject: miserable little attempt at adding a dialog --- src/frontend/qt_sdl/CMakeLists.txt | 3 + src/frontend/qt_sdl/EmuSettingsDialog.cpp | 31 +++++ src/frontend/qt_sdl/EmuSettingsDialog.h | 38 ++++++ src/frontend/qt_sdl/EmuSettingsDialog.ui | 201 ++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 15 +++ src/frontend/qt_sdl/main.h | 4 + 6 files changed, 292 insertions(+) create mode 100644 src/frontend/qt_sdl/EmuSettingsDialog.cpp create mode 100644 src/frontend/qt_sdl/EmuSettingsDialog.h create mode 100644 src/frontend/qt_sdl/EmuSettingsDialog.ui (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 05a4029..a6aeb0e 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -2,6 +2,7 @@ project(qt_sdl) SET(SOURCES_QT_SDL main.cpp + EmuSettingsDialog.cpp Platform.cpp PlatformConfig.cpp @@ -19,6 +20,8 @@ find_package(Qt5 COMPONENTS Gui REQUIRED) find_package(Qt5 COMPONENTS Widgets REQUIRED) set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2) diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp new file mode 100644 index 0000000..c64f192 --- /dev/null +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -0,0 +1,31 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include "EmuSettingsDialog.h" +#include "ui_EmuSettingsDialog.h" + + +EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::EmuSettingsDialog) +{ + ui->setupUi(this); +} + +EmuSettingsDialog::~EmuSettingsDialog() +{ + delete ui; +} diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h new file mode 100644 index 0000000..eb21aaa --- /dev/null +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -0,0 +1,38 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef EMUSETTINGSDIALOG_H +#define EMUSETTINGSDIALOG_H + +#include + +namespace Ui { class EmuSettingsDialog; } + +class EmuSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EmuSettingsDialog(QWidget* parent); + ~EmuSettingsDialog(); + +private: + Ui::EmuSettingsDialog* ui; +}; + +#endif // EMUSETTINGSDIALOG_H diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui new file mode 100644 index 0000000..e4deaba --- /dev/null +++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui @@ -0,0 +1,201 @@ + + + EmuSettingsDialog + + + + 0 + 0 + 490 + 243 + + + + + 0 + 0 + + + + Emu settings - melonDS + + + + QLayout::SetFixedSize + + + + + DS mode + + + + + + + 0 + 0 + + + + + 290 + 0 + + + + + + + <html><head/><body><p>DS-mode ARM9 BIOS</p><p>Size should be 4 KB</p></body></html> + + + + + + + DS firmware: + + + + + + + DS ARM7 BIOS: + + + + + + + DS ARM9 BIOS: + + + + + + + + 0 + 0 + + + + Browse... + + + true + + + + + + + <html><head/><body><p>DS-mode ARM7 BIOS</p><p>Size should be 16 KB</p></body></html> + + + + + + + Browse... + + + + + + + <html><head/><body><p>DS-mode firmware</p><p><br/></p><p>Possible firmwares:</p><p>* 128 KB: DS-mode firmware from a DSi or 3DS. Not bootable.</p><p>* 256 KB: regular DS firmware.</p><p>* 512 KB: iQue DS firmware.</p></body></html> + + + + + + + Browse... + + + + + + + + + + Startup + + + + + + <html><head/><body><p>When loading a ROM, completely skip the regular boot process (&quot;Nintendo DS&quot; screen) to boot the ROM directly.</p><p><br/></p><p>Note: if your firmware dump isn't bootable, the ROM will be booted directly regardless of this setting.</p></body></html> + + + Boot game directly + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EmuSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EmuSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 11602a6..3986876 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -31,6 +31,7 @@ #include #include "main.h" +#include "EmuSettingsDialog.h" #include "types.h" #include "version.h" @@ -545,6 +546,12 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actStop = menu->addAction("Stop"); connect(actStop, &QAction::triggered, this, &MainWindow::onStop); } + { + QMenu* menu = menubar->addMenu("Config"); + + actEmuSettings = menu->addAction("Emu settings"); + connect(actEmuSettings, &QAction::triggered, this, &MainWindow::onOpenEmuSettings); + } setMenuBar(menubar); panel = new MainWindowPanel(this); @@ -811,6 +818,14 @@ void MainWindow::onEmuUnpause() } +void MainWindow::onOpenEmuSettings() +{ + // TODO keep track of this pointer!! + EmuSettingsDialog* dlg = new EmuSettingsDialog(this); + dlg->show(); +} + + int main(int argc, char** argv) { srand(time(NULL)); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index f8ad9a3..bb5e903 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -107,6 +107,8 @@ private slots: void onEmuPause(); void onEmuUnpause(); + void onOpenEmuSettings(); + private: MainWindowPanel* panel; @@ -120,6 +122,8 @@ private: QAction* actPause; QAction* actReset; QAction* actStop; + + QAction* actEmuSettings; }; #endif // MAIN_H -- cgit v1.2.3 From 60ba163f08e0af4272c8de6141583238eb283fe8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 04:02:16 +0200 Subject: take this somewhere --- src/frontend/qt_sdl/EmuSettingsDialog.cpp | 70 +++++++++++++++++++++++++++++++ src/frontend/qt_sdl/EmuSettingsDialog.h | 26 ++++++++++++ src/frontend/qt_sdl/main.cpp | 4 +- 3 files changed, 97 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index c64f192..34cafb5 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -16,16 +16,86 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ +#include + +#include "types.h" +#include "Config.h" +#include "PlatformConfig.h" + #include "EmuSettingsDialog.h" #include "ui_EmuSettingsDialog.h" +EmuSettingsDialog* EmuSettingsDialog::currentDlg = nullptr; + +extern char* EmuDirectory; + + EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::EmuSettingsDialog) { ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + ui->txtBIOS9Path->setText(Config::BIOS9Path); + ui->txtBIOS7Path->setText(Config::BIOS7Path); + ui->txtFirmwarePath->setText(Config::FirmwarePath); + ui->chkDirectBoot->setChecked(Config::DirectBoot != 0); } EmuSettingsDialog::~EmuSettingsDialog() { delete ui; } + +void EmuSettingsDialog::on_EmuSettingsDialog_accepted() +{ + strncpy(Config::BIOS9Path, ui->txtBIOS9Path->text().toStdString().c_str(), 1023); Config::BIOS9Path[1023] = '\0'; + strncpy(Config::BIOS7Path, ui->txtBIOS7Path->text().toStdString().c_str(), 1023); Config::BIOS7Path[1023] = '\0'; + strncpy(Config::FirmwarePath, ui->txtFirmwarePath->text().toStdString().c_str(), 1023); Config::FirmwarePath[1023] = '\0'; + Config::DirectBoot = ui->chkDirectBoot->isChecked() ? 1:0; + + closeDlg(); +} + +void EmuSettingsDialog::on_EmuSettingsDialog_rejected() +{ + closeDlg(); +} + +void EmuSettingsDialog::on_btnBIOS9Browse_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, + "Select DS-mode ARM9 BIOS...", + EmuDirectory, + "BIOS files (*.bin *.rom);;Any file (*.*)"); + + if (file.isEmpty()) return; + + ui->txtBIOS9Path->setText(file); +} + +void EmuSettingsDialog::on_btnBIOS7Browse_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, + "Select DS-mode ARM7 BIOS...", + EmuDirectory, + "BIOS files (*.bin *.rom);;Any file (*.*)"); + + if (file.isEmpty()) return; + + ui->txtBIOS7Path->setText(file); +} + +void EmuSettingsDialog::on_btnFirmwareBrowse_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, + "Select DS-mode firmware...", + EmuDirectory, + "Firmware files (*.bin *.rom);;Any file (*.*)"); + + if (file.isEmpty()) return; + + // TODO: check for shitty hacked firmware here? + + ui->txtFirmwarePath->setText(file); +} diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h index eb21aaa..471e0fb 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -22,6 +22,7 @@ #include namespace Ui { class EmuSettingsDialog; } +class EmuSettingsDialog; class EmuSettingsDialog : public QDialog { @@ -31,6 +32,31 @@ public: explicit EmuSettingsDialog(QWidget* parent); ~EmuSettingsDialog(); + static EmuSettingsDialog* currentDlg; + static void openDlg(QWidget* parent) + { + if (currentDlg) + { + currentDlg->activateWindow(); + return; + } + + currentDlg = new EmuSettingsDialog(parent); + currentDlg->show(); + } + static void closeDlg() + { + currentDlg = nullptr; + } + +private slots: + void on_EmuSettingsDialog_accepted(); + void on_EmuSettingsDialog_rejected(); + + void on_btnBIOS9Browse_clicked(); + void on_btnBIOS7Browse_clicked(); + void on_btnFirmwareBrowse_clicked(); + private: Ui::EmuSettingsDialog* ui; }; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 3986876..8b97320 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -820,9 +820,7 @@ void MainWindow::onEmuUnpause() void MainWindow::onOpenEmuSettings() { - // TODO keep track of this pointer!! - EmuSettingsDialog* dlg = new EmuSettingsDialog(this); - dlg->show(); + EmuSettingsDialog::openDlg(this); } -- cgit v1.2.3 From c5c9434ac9abaa0ae9c3125ee6e8bc4653846ebd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 05:42:09 +0200 Subject: verify BIOS and firmware before booting games/firmware --- src/NDS.cpp | 2 +- src/frontend/FrontendUtil.h | 22 +++++++++- src/frontend/Util_ROM.cpp | 100 +++++++++++++++++++++++++++++++++++++++---- src/frontend/qt_sdl/main.cpp | 41 +++++++++++++++--- src/frontend/qt_sdl/main.h | 2 + 5 files changed, 149 insertions(+), 18 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/NDS.cpp b/src/NDS.cpp index 1d425a8..745ed28 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -587,7 +587,7 @@ bool DoSavestate_Scheduler(Savestate* file) } if (funcid == -1) { - printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK STAPLEBUTTER.\n", i); + printf("savestate: VERY BAD!!!!! FUNCTION POINTER FOR EVENT %d NOT IN HACKY LIST. CANNOT SAVE. SMACK ARISOTURA.\n", i); return false; } } diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 32f28d1..f4f6850 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -32,6 +32,24 @@ enum ROMSlot_MAX }; +enum +{ + Load_OK = 0, + + Load_BIOS9Missing, + Load_BIOS9Bad, + + Load_BIOS7Missing, + Load_BIOS7Bad, + + Load_FirmwareMissing, + Load_FirmwareBad, + Load_FirmwareNotBootable, + + // TODO: more precise errors for ROM loading + Load_ROMLoadError, +}; + extern char ROMPath [ROMSlot_MAX][1024]; extern char SRAMPath[ROMSlot_MAX][1024]; extern bool SavestateLoaded; @@ -41,11 +59,11 @@ extern bool SavestateLoaded; void Init_ROM(); // load the BIOS/firmware and boot from it -bool LoadBIOS(); +int LoadBIOS(); // load a ROM file to the specified cart slot // note: loading a ROM to the NDS slot resets emulation -bool LoadROM(const char* file, int slot); +int LoadROM(const char* file, int slot); // get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 19c8eb9..3200de4 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -57,8 +57,77 @@ void SetupSRAMPath(int slot) strncpy(SRAMPath[slot] + strlen(ROMPath[slot]) - 3, "sav", 3); } -bool LoadBIOS() +int VerifyDSBIOS() { + FILE* f; + long len; + + f = Platform::OpenLocalFile(Config::BIOS9Path, "rb"); + if (!f) return Load_BIOS9Missing; + + fseek(f, 0, SEEK_END); + len = ftell(f); + if (len != 0x1000) + { + fclose(f); + return Load_BIOS9Bad; + } + + fclose(f); + + f = Platform::OpenLocalFile(Config::BIOS7Path, "rb"); + if (!f) return Load_BIOS7Missing; + + fseek(f, 0, SEEK_END); + len = ftell(f); + if (len != 0x4000) + { + fclose(f); + return Load_BIOS7Bad; + } + + fclose(f); + + return Load_OK; +} + +int VerifyDSFirmware() +{ + FILE* f; + long len; + + f = Platform::OpenLocalFile(Config::FirmwarePath, "rb"); + if (!f) return Load_FirmwareMissing; + + fseek(f, 0, SEEK_END); + len = ftell(f); + if (len == 0x20000) + { + // 128KB firmware, not bootable + fclose(f); + return Load_FirmwareNotBootable; + } + else if (len != 0x40000 && len != 0x80000) + { + fclose(f); + return Load_FirmwareBad; + } + + fclose(f); + + return Load_OK; +} + +int LoadBIOS() +{ + int res; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + res = VerifyDSFirmware(); + if (res != Load_OK) return res; + // TODO: // original code in the libui frontend called NDS::LoadGBAROM() if needed // should this be carried over here? @@ -71,12 +140,26 @@ bool LoadBIOS() SavestateLoaded = false; - // TODO: error reporting? - return true; + return Load_OK; } -bool LoadROM(const char* file, int slot) +int LoadROM(const char* file, int slot) { + int res; + bool directboot = Config::DirectBoot != 0; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + res = VerifyDSFirmware(); + if (res != Load_OK) + { + if (res == Load_FirmwareNotBootable) + directboot = true; + else + return res; + } + char oldpath[1024]; char oldsram[1024]; strncpy(oldpath, ROMPath[slot], 1024); @@ -88,28 +171,29 @@ bool LoadROM(const char* file, int slot) SetupSRAMPath(0); SetupSRAMPath(1); - if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], Config::DirectBoot)) + if (slot == ROMSlot_NDS && NDS::LoadROM(ROMPath[slot], SRAMPath[slot], directboot)) { SavestateLoaded = false; // Reload the inserted GBA cartridge (if any) + // TODO: report failure there?? if (ROMPath[ROMSlot_GBA][0] != '\0') NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA]); strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety - return true; + return Load_OK; } else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) { SavestateLoaded = false; strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety - return true; + return Load_OK; } else { strncpy(ROMPath[slot], oldpath, 1024); strncpy(SRAMPath[slot], oldsram, 1024); - return false; + return Load_ROMLoadError; } } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8b97320..ec4b04b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -570,6 +570,27 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } +QString MainWindow::loadErrorStr(int error) +{ + switch (error) + { + case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed."; + case Frontend::Load_BIOS9Bad: return "DS ARM9 BIOS is not a valid BIOS dump."; + + case Frontend::Load_BIOS7Missing: return "DS ARM7 BIOS was not found or could not be accessed."; + case Frontend::Load_BIOS7Bad: return "DS ARM7 BIOS is not a valid BIOS dump."; + + case Frontend::Load_FirmwareMissing: return "DS firmware was not found or could not be accessed."; + case Frontend::Load_FirmwareBad: return "DS firmware is not a valid firmware dump."; + case Frontend::Load_FirmwareNotBootable: return "DS firmware is not bootable."; + + case Frontend::Load_ROMLoadError: return "Failed to load the ROM. Make sure the file is accessible and isn't used by another application."; + + default: return "Unknown error during launch; smack Arisotura."; + } +} + + void MainWindow::onOpenFile() { emuThread->emuPause(true); @@ -584,6 +605,11 @@ void MainWindow::onOpenFile() return; } + // TODO: validate the input file!! + // * check that it is a proper ROM + // * ensure the binary offsets are sane + // * etc + // this shit is stupid char file[1024]; strncpy(file, filename.toStdString().c_str(), 1023); file[1023] = '\0'; @@ -594,7 +620,7 @@ void MainWindow::onOpenFile() Config::LastROMFolder[pos] = '\0'; char* ext = &file[strlen(file)-3]; - int slot; bool res; + int slot; int res; if (!strcasecmp(ext, "gba")) { slot = 1; @@ -606,11 +632,11 @@ void MainWindow::onOpenFile() res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); } - if (!res) + if (res != Frontend::Load_OK) { QMessageBox::critical(this, "melonDS", - "Failed to load the ROM.\n\nMake sure the file is accessible and isn't used by another application."); + loadErrorStr(res)); emuThread->emuUnpause(); } else if (slot == 1) @@ -631,11 +657,12 @@ void MainWindow::onBootFirmware() emuThread->emuPause(true); - bool res = Frontend::LoadBIOS(); - if (!res) + int res = Frontend::LoadBIOS(); + if (res != Frontend::Load_OK) { - // TODO! - + QMessageBox::critical(this, + "melonDS", + loadErrorStr(res)); emuThread->emuUnpause(); } else diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index bb5e903..ee0094f 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -110,6 +110,8 @@ private slots: void onOpenEmuSettings(); private: + QString loadErrorStr(int error); + MainWindowPanel* panel; QAction* actOpenROM; -- cgit v1.2.3 From 0566c9e34c36f7f1841765b02147fd4c890e8550 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 13:04:02 +0200 Subject: minor fix --- src/NDSCart.cpp | 5 +++ src/frontend/qt_sdl/Platform.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 68 +--------------------------------------- 3 files changed, 7 insertions(+), 68 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 5a2a0d0..585eadf 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -867,6 +867,11 @@ bool ReadROMParams(u32 gamecode, u32* params) void DecryptSecureArea(u8* out) { + // TODO: source decryption data from different possible sources + // * original DS-mode ARM7 BIOS has the key data at 0x30 + // * .srl ROMs (VC dumps) have encrypted secure areas but have precomputed + // decryption data at 0x1000 (and at the beginning of the DSi region if any) + u32 gamecode = *(u32*)&CartROM[0x0C]; u32 arm9base = *(u32*)&CartROM[0x20]; diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 31b5277..fea9166 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -202,7 +202,7 @@ FILE* OpenLocalFile(const char* path, const char* mode) #ifdef __WIN32__ if (pathlen > 3) { - if (path[1] == ':' && path[2] == '\\') + if (path[1] == ':' && (path[2] == '\\' || path[2] == '/')) return OpenFile(path, mode); } #else diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index ec4b04b..67eb3d8 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -915,74 +915,8 @@ int main(int argc, char** argv) //if (Config::AudioVolume < 0) Config::AudioVolume = 0; //else if (Config::AudioVolume > 256) Config::AudioVolume = 256; - // TODO: those should be checked before running anything - // (as to let the user specify their own BIOS/firmware path etc) + // TODO: this should be checked before running anything #if 0 - if (!Platform::LocalFileExists("bios7.bin") || - !Platform::LocalFileExists("bios9.bin") || - !Platform::LocalFileExists("firmware.bin")) - { -#if defined(__WIN32__) || defined(UNIX_PORTABLE) - const char* locationName = "the directory you run melonDS from"; -#else - char* locationName = EmuDirectory; -#endif - char msgboxtext[512]; - sprintf(msgboxtext, - "One or more of the following required files don't exist or couldn't be accessed:\n\n" - "bios7.bin -- ARM7 BIOS\n" - "bios9.bin -- ARM9 BIOS\n" - "firmware.bin -- firmware image\n\n" - "Dump the files from your DS and place them in %s.\n" - "Make sure that the files can be accessed.", - locationName - ); - - uiMsgBoxError(NULL, "BIOS/Firmware not found", msgboxtext); - - uiUninit(); - SDL_Quit(); - return 0; - } - if (!Platform::LocalFileExists("firmware.bin.bak")) - { - // verify the firmware - // - // there are dumps of an old hacked firmware floating around on the internet - // and those are problematic - // the hack predates WFC, and, due to this, any game that alters the WFC - // access point data will brick that firmware due to it having critical - // data in the same area. it has the same problem on hardware. - // - // but this should help stop users from reporting that issue over and over - // again, when the issue is not from melonDS but from their firmware dump. - // - // I don't know about all the firmware hacks in existence, but the one I - // looked at has 0x180 bytes from the header repeated at 0x3FC80, but - // bytes 0x0C-0x14 are different. - - FILE* f = Platform::OpenLocalFile("firmware.bin", "rb"); - u8 chk1[0x180], chk2[0x180]; - - fseek(f, 0, SEEK_SET); - fread(chk1, 1, 0x180, f); - fseek(f, -0x380, SEEK_END); - fread(chk2, 1, 0x180, f); - - memset(&chk1[0x0C], 0, 8); - memset(&chk2[0x0C], 0, 8); - - fclose(f); - - if (!memcmp(chk1, chk2, 0x180)) - { - uiMsgBoxError(NULL, - "Problematic firmware dump", - "You are using an old hacked firmware dump.\n" - "Firmware boot will stop working if you run any game that alters WFC settings.\n\n" - "Note that the issue is not from melonDS, it would also happen on an actual DS."); - } - } { const char* romlist_missing = "Save memory type detection will not work correctly.\n\n" "You should use the latest version of romlist.bin (provided in melonDS release packages)."; -- cgit v1.2.3 From c9a76edf210410dbf95d100690bad9c86aa5bd84 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 14:23:06 +0200 Subject: probably fix some pretty bad issue good one, Generic --- src/frontend/qt_sdl/main.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 67eb3d8..a7388a0 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -888,9 +888,12 @@ int main(int argc, char** argv) #else const char* confdir = g_get_user_config_dir(); const char* confname = "/melonDS"; - EmuDirectory = new char[strlen(confdir) + strlen(confname) + 1]; - strcat(EmuDirectory, confdir); - strcat(EmuDirectory, confname); + int cdlen = strlen(confdir); + int cnlen = strlen(confname); + EmuDirectory = new char[cdlen + cnlen + 1]; + strncpy(&EmuDirectory[0], confdir, cdlen); + strncpy(&EmuDirectory[cdlen], confname, cnlen); + EmuDirectory[cdlen+cnlen] = '\0'; #endif QApplication melon(argc, argv); -- cgit v1.2.3 From 19566178ba7ee1fcd4207139286707cc3896493a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 18:33:03 +0200 Subject: begin adding input dialog --- src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/EmuSettingsDialog.h | 5 +- src/frontend/qt_sdl/InputConfigDialog.cpp | 53 +++++++++++++ src/frontend/qt_sdl/InputConfigDialog.h | 63 +++++++++++++++ src/frontend/qt_sdl/InputConfigDialog.ui | 126 ++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 21 ++++- src/frontend/qt_sdl/main.h | 3 + 7 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 src/frontend/qt_sdl/InputConfigDialog.cpp create mode 100644 src/frontend/qt_sdl/InputConfigDialog.h create mode 100644 src/frontend/qt_sdl/InputConfigDialog.ui (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index a6aeb0e..da3bb1d 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -3,6 +3,7 @@ project(qt_sdl) SET(SOURCES_QT_SDL main.cpp EmuSettingsDialog.cpp + InputConfigDialog.cpp Platform.cpp PlatformConfig.cpp diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.h b/src/frontend/qt_sdl/EmuSettingsDialog.h index ce64145..7378641 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -33,16 +33,17 @@ public: ~EmuSettingsDialog(); static EmuSettingsDialog* currentDlg; - static void openDlg(QWidget* parent) + static EmuSettingsDialog* openDlg(QWidget* parent) { if (currentDlg) { currentDlg->activateWindow(); - return; + return currentDlg; } currentDlg = new EmuSettingsDialog(parent); currentDlg->show(); + return currentDlg; } static void closeDlg() { diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp new file mode 100644 index 0000000..f7c0ab2 --- /dev/null +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -0,0 +1,53 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +// + +#include "types.h" +#include "Config.h" +#include "PlatformConfig.h" + +#include "InputConfigDialog.h" +#include "ui_InputConfigDialog.h" + + +InputConfigDialog* InputConfigDialog::currentDlg = nullptr; + + +InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new Ui::InputConfigDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + // +} + +InputConfigDialog::~InputConfigDialog() +{ + delete ui; +} + +void InputConfigDialog::on_InputConfigDialog_accepted() +{ + closeDlg(); +} + +void InputConfigDialog::on_InputConfigDialog_rejected() +{ + closeDlg(); +} diff --git a/src/frontend/qt_sdl/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfigDialog.h new file mode 100644 index 0000000..2af73db --- /dev/null +++ b/src/frontend/qt_sdl/InputConfigDialog.h @@ -0,0 +1,63 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef INPUTCONFIGDIALOG_H +#define INPUTCONFIGDIALOG_H + +#include + +namespace Ui { class InputConfigDialog; } +class InputConfigDialog; + +class InputConfigDialog : public QDialog +{ + Q_OBJECT + +public: + explicit InputConfigDialog(QWidget* parent); + ~InputConfigDialog(); + + static InputConfigDialog* currentDlg; + static InputConfigDialog* openDlg(QWidget* parent) + { + if (currentDlg) + { + currentDlg->activateWindow(); + return currentDlg; + } + + currentDlg = new InputConfigDialog(parent); + currentDlg->open(); + return currentDlg; + } + static void closeDlg() + { + currentDlg = nullptr; + } + +private slots: + void on_InputConfigDialog_accepted(); + void on_InputConfigDialog_rejected(); + + // + +private: + Ui::InputConfigDialog* ui; +}; + +#endif // INPUTCONFIGDIALOG_H diff --git a/src/frontend/qt_sdl/InputConfigDialog.ui b/src/frontend/qt_sdl/InputConfigDialog.ui new file mode 100644 index 0000000..c1422e9 --- /dev/null +++ b/src/frontend/qt_sdl/InputConfigDialog.ui @@ -0,0 +1,126 @@ + + + InputConfigDialog + + + + 0 + 0 + 488 + 365 + + + + TDAH + + + + QLayout::SetFixedSize + + + + + 1 + + + + DS input + + + + + General hotkeys + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Joystick: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Selects which joystick will be used for joystick input, if any is present.</p></body></html> + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + InputConfigDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + InputConfigDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index a7388a0..cd7849d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -32,6 +32,7 @@ #include "main.h" #include "EmuSettingsDialog.h" +#include "InputConfigDialog.h" #include "types.h" #include "version.h" @@ -551,6 +552,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actEmuSettings = menu->addAction("Emu settings"); connect(actEmuSettings, &QAction::triggered, this, &MainWindow::onOpenEmuSettings); + + actInputConfig = menu->addAction("Input and hotkeys"); + connect(actInputConfig, &QAction::triggered, this, &MainWindow::onOpenInputConfig); } setMenuBar(menubar); @@ -850,6 +854,19 @@ void MainWindow::onOpenEmuSettings() EmuSettingsDialog::openDlg(this); } +void MainWindow::onOpenInputConfig() +{ + emuThread->emuPause(true); + + InputConfigDialog* dlg = InputConfigDialog::openDlg(this); + connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); +} + +void MainWindow::onInputConfigFinished() +{printf("FARTO\n"); + emuThread->emuUnpause(); +} + int main(int argc, char** argv) { @@ -915,8 +932,8 @@ int main(int argc, char** argv) Config::Load(); - //if (Config::AudioVolume < 0) Config::AudioVolume = 0; - //else if (Config::AudioVolume > 256) Config::AudioVolume = 256; + if (Config::AudioVolume < 0) Config::AudioVolume = 0; + else if (Config::AudioVolume > 256) Config::AudioVolume = 256; // TODO: this should be checked before running anything #if 0 diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index ee0094f..0324ecf 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -108,6 +108,8 @@ private slots: void onEmuUnpause(); void onOpenEmuSettings(); + void onOpenInputConfig(); + void onInputConfigFinished(); private: QString loadErrorStr(int error); @@ -126,6 +128,7 @@ private: QAction* actStop; QAction* actEmuSettings; + QAction* actInputConfig; }; #endif // MAIN_H -- cgit v1.2.3 From 7026bb15f6688d4148932a7624baf2f3d5d22d8f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 12:06:25 +0200 Subject: input dialog progress. --- src/frontend/qt_sdl/InputConfigDialog.cpp | 245 +++++++++++++++++++++++++++++- src/frontend/qt_sdl/InputConfigDialog.h | 32 ++++ src/frontend/qt_sdl/InputConfigDialog.ui | 11 +- src/frontend/qt_sdl/main.cpp | 4 +- src/frontend/qt_sdl/main.h | 2 +- 5 files changed, 286 insertions(+), 8 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index f7c0ab2..3b006fd 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -16,7 +16,9 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ -// +#include +#include +#include #include "types.h" #include "Config.h" @@ -28,13 +30,68 @@ InputConfigDialog* InputConfigDialog::currentDlg = nullptr; +const int dskeyorder[12] = {0, 1, 10, 11, 5, 4, 6, 7, 9, 8, 2, 3}; +const char* dskeylabels[12] = {"A", "B", "X", "Y", "Left", "Right", "Up", "Down", "L", "R", "Select", "Start"}; + +const int hk_addons[] = +{ + HK_SolarSensorIncrease, + HK_SolarSensorDecrease, +}; + +const char* hk_addons_labels[] = +{ + "[Boktai] Sunlight + ", + "[Boktai] Sunlight - ", +}; + +const int hk_general[] = +{ + HK_Pause, + HK_Reset, + HK_FastForward, + HK_FastForwardToggle, + HK_Lid, + HK_Mic, +}; + +const char* hk_general_labels[] = +{ + "Pause/resume", + "Reset", + "Fast forward", + "Toggle FPS limit", + "Close/open lid", + "Microphone", +}; + InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new Ui::InputConfigDialog) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); - // + for (int i = 0; i < 12; i++) + { + keypadKeyMap[i] = Config::KeyMapping[dskeyorder[i]]; + keypadJoyMap[i] = Config::JoyMapping[dskeyorder[i]]; + } + + for (int i = 0; i < 2; i++) + { + addonsKeyMap[i] = Config::HKKeyMapping[hk_addons[i]]; + addonsJoyMap[i] = Config::HKJoyMapping[hk_addons[i]]; + } + + for (int i = 0; i < 6; i++) + { + hkGeneralKeyMap[i] = Config::HKKeyMapping[hk_general[i]]; + hkGeneralJoyMap[i] = Config::HKJoyMapping[hk_general[i]]; + } + + populatePage(ui->tabInput, 12, dskeylabels, keypadKeyMap, keypadJoyMap); + populatePage(ui->tabAddons, 2, hk_addons_labels, addonsKeyMap, addonsJoyMap); + populatePage(ui->tabHotkeysGeneral, 6, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap); } InputConfigDialog::~InputConfigDialog() @@ -42,6 +99,109 @@ InputConfigDialog::~InputConfigDialog() delete ui; } +void InputConfigDialog::populatePage(QWidget* page, int num, const char** labels, int* keymap, int* joymap) +{ + // kind of a hack + bool ishotkey = (page != ui->tabInput); + + QHBoxLayout* main_layout = new QHBoxLayout(); + + QGroupBox* group; + QGridLayout* group_layout; + + group = new QGroupBox("Keyboard mappings:"); + main_layout->addWidget(group); + group_layout = new QGridLayout(); + group_layout->setSpacing(1); + for (int i = 0; i < num; i++) + { + QLabel* label = new QLabel(QString(labels[i])+":"); + KeyMapButton* btn = new KeyMapButton(nullptr, &keymap[i], ishotkey); + + group_layout->addWidget(label, i, 0); + group_layout->addWidget(btn, i, 1); + } + group_layout->setRowStretch(num, 1); + group->setLayout(group_layout); + group->setMinimumWidth(275); + + group = new QGroupBox("Joystick mappings:"); + main_layout->addWidget(group); + group_layout = new QGridLayout(); + group_layout->setSpacing(1); + for (int i = 0; i < num; i++) + { + QLabel* label = new QLabel(QString(labels[i])+":"); + QPushButton* btn = new QPushButton(); + + group_layout->addWidget(label, i, 0); + group_layout->addWidget(btn, i, 1); + + btn->setText(joyMappingName(joymap[i])); + + //btn->setProperty("mapping", QVariant(&joymap[i])); + //btn->setProperty("isHotkey", QVariant(ishotkey)); + } + group_layout->setRowStretch(num, 1); + group->setLayout(group_layout); + group->setMinimumWidth(275); + + page->setLayout(main_layout); +} + +QString InputConfigDialog::joyMappingName(int id) +{ + if (id < 0) + { + return "None"; + } + + bool hasbtn = ((id & 0xFFFF) != 0xFFFF); + QString str; + + if (hasbtn) + { + if (id & 0x100) + { + int hatnum = ((id >> 4) & 0xF) + 1; + + switch (id & 0xF) + { + case 0x1: str = "Hat %1 up"; break; + case 0x2: str = "Hat %1 right"; break; + case 0x4: str = "Hat %1 down"; break; + case 0x8: str = "Hat %1 left"; break; + } + + str = str.arg(hatnum); + } + else + { + str = QString("Button %1").arg((id & 0xFFFF) + 1); + } + } + else + { + str = ""; + } + + if (id & 0x10000) + { + int axisnum = ((id >> 24) & 0xF) + 1; + + if (hasbtn) str += " / "; + + switch ((id >> 20) & 0xF) + { + case 0: str += QString("Axis %1 +").arg(axisnum); break; + case 1: str += QString("Axis %1 -").arg(axisnum); break; + case 2: str += QString("Trigger %1").arg(axisnum); break; + } + } + + return str; +} + void InputConfigDialog::on_InputConfigDialog_accepted() { closeDlg(); @@ -51,3 +211,84 @@ void InputConfigDialog::on_InputConfigDialog_rejected() { closeDlg(); } + + +KeyMapButton::KeyMapButton(QWidget* parent, int* mapping, bool hotkey) : QPushButton(parent) +{ + this->mapping = mapping; + this->isHotkey = hotkey; + + setCheckable(true); + setText(mappingText()); + + connect(this, &KeyMapButton::clicked, this, &KeyMapButton::onClick); +} + +KeyMapButton::~KeyMapButton() +{ +} + +void KeyMapButton::keyPressEvent(QKeyEvent* event) +{ + if (!isChecked()) return QPushButton::keyPressEvent(event); +printf("KEY PRESSED = %08X %08X | %08X %08X %08X | %08X\n", event->key(), event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode(), Qt::SHIFT); + int key = event->key(); + bool ismod = (key == Qt::Key_Control || + key == Qt::Key_Alt || + key == Qt::Key_Shift || + key == Qt::Key_Meta); + + if (isHotkey) + { + if (ismod) + return; + } + + if (!ismod) + key |= event->modifiers(); + + *mapping = key; + click(); +} + +void KeyMapButton::focusOutEvent(QFocusEvent* event) +{ + if (isChecked()) + { + // if we lost the focus while mapping, consider it 'done' + click(); + } + + QPushButton::focusOutEvent(event); +} + +void KeyMapButton::onClick() +{ + if (isChecked()) + { + setText("[press key]"); + } + else + { + setText(mappingText()); + } +} + +QString KeyMapButton::mappingText() +{ + int key = *mapping; + + switch (key) + { + case -1: return "None"; + + case Qt::Key_Control: return "Ctrl"; + case Qt::Key_Alt: return "Alt"; + case Qt::Key_Shift: return "Shift"; + case Qt::Key_Meta: return "Meta"; + } + + QKeySequence seq(key); + QString ret = seq.toString(); + return ret.replace("&", "&&"); +} diff --git a/src/frontend/qt_sdl/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfigDialog.h index 2af73db..b2ca3f2 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.h +++ b/src/frontend/qt_sdl/InputConfigDialog.h @@ -20,6 +20,7 @@ #define INPUTCONFIGDIALOG_H #include +#include namespace Ui { class InputConfigDialog; } class InputConfigDialog; @@ -57,7 +58,38 @@ private slots: // private: + void populatePage(QWidget* page, int num, const char** labels, int* keymap, int* joymap); + + QString joyMappingName(int id); + Ui::InputConfigDialog* ui; + + int keypadKeyMap[12], keypadJoyMap[12]; + int addonsKeyMap[2], addonsJoyMap[2]; + int hkGeneralKeyMap[6], hkGeneralJoyMap[6]; +}; + + +class KeyMapButton : public QPushButton +{ + Q_OBJECT + +public: + explicit KeyMapButton(QWidget* parent, int* mapping, bool hotkey); + ~KeyMapButton(); + +protected: + void keyPressEvent(QKeyEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + +private slots: + void onClick(); + +private: + QString mappingText(); + + int* mapping; + bool isHotkey; }; #endif // INPUTCONFIGDIALOG_H diff --git a/src/frontend/qt_sdl/InputConfigDialog.ui b/src/frontend/qt_sdl/InputConfigDialog.ui index c1422e9..655da16 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.ui +++ b/src/frontend/qt_sdl/InputConfigDialog.ui @@ -11,7 +11,7 @@ - TDAH + Input and hotkeys - melonDS @@ -20,11 +20,16 @@ - 1 + 0 - DS input + DS keypad + + + + + Add-ons diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index cd7849d..d664172 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -862,8 +862,8 @@ void MainWindow::onOpenInputConfig() connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); } -void MainWindow::onInputConfigFinished() -{printf("FARTO\n"); +void MainWindow::onInputConfigFinished(int res) +{ emuThread->emuUnpause(); } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 0324ecf..4553875 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -109,7 +109,7 @@ private slots: void onOpenEmuSettings(); void onOpenInputConfig(); - void onInputConfigFinished(); + void onInputConfigFinished(int res); private: QString loadErrorStr(int error); -- cgit v1.2.3 From 7d69699d648b93d76f14024705c4a86f5929ba3d Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 19 May 2020 14:37:54 +0200 Subject: fix Linux build error --- src/frontend/qt_sdl/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index d664172..9d4c274 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -868,6 +868,11 @@ void MainWindow::onInputConfigFinished(int res) } +// FIXME!!!! +#if (!defined(__WIN32__) && !defined(UNIX_PORTABLE)) +#include +#endif + int main(int argc, char** argv) { srand(time(NULL)); -- cgit v1.2.3 From 9fbf9b997bb950a667d0af4583fd68098a7ed717 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 19 May 2020 13:28:46 +0200 Subject: this might be a good idea --- src/frontend/qt_sdl/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 9d4c274..7b50af4 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1045,6 +1045,7 @@ int main(int argc, char** argv) emuThread->emuStop(); emuThread->wait(); + delete emuThread; //if (Joystick) SDL_JoystickClose(Joystick); if (audioDevice) SDL_CloseAudioDevice(audioDevice); -- cgit v1.2.3 From 34506ff2bb1be880cf260e0c1b09efede14ac0d8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 20:48:52 +0200 Subject: actually complete the input config dialog --- src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/Input.cpp | 119 +++++++++++++ src/frontend/qt_sdl/Input.h | 40 +++++ src/frontend/qt_sdl/InputConfigDialog.cpp | 283 ++++++++++++++++++++++++------ src/frontend/qt_sdl/InputConfigDialog.h | 32 +++- src/frontend/qt_sdl/main.cpp | 15 +- src/frontend/qt_sdl/main.h | 21 --- 7 files changed, 425 insertions(+), 86 deletions(-) create mode 100644 src/frontend/qt_sdl/Input.cpp create mode 100644 src/frontend/qt_sdl/Input.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index da3bb1d..42cf912 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -4,6 +4,7 @@ SET(SOURCES_QT_SDL main.cpp EmuSettingsDialog.cpp InputConfigDialog.cpp + Input.cpp Platform.cpp PlatformConfig.cpp diff --git a/src/frontend/qt_sdl/Input.cpp b/src/frontend/qt_sdl/Input.cpp new file mode 100644 index 0000000..7caf24a --- /dev/null +++ b/src/frontend/qt_sdl/Input.cpp @@ -0,0 +1,119 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include + +#include "Input.h" +#include "PlatformConfig.h" + + +namespace Input +{ + +int JoystickID; +SDL_Joystick* Joystick = nullptr; + +u32 KeyInputMask, JoyInputMask; +u32 KeyHotkeyMask, JoyHotkeyMask; +u32 HotkeyMask, LastHotkeyMask; +u32 HotkeyPress, HotkeyRelease; + + +void OpenJoystick() +{ + if (Joystick) SDL_JoystickClose(Joystick); + + int num = SDL_NumJoysticks(); + if (num < 1) + { + Joystick = nullptr; + return; + } + + if (JoystickID >= num) + JoystickID = 0; + + Joystick = SDL_JoystickOpen(JoystickID); +} + +void CloseJoystick() +{ + if (Joystick) + { + SDL_JoystickClose(Joystick); + Joystick = nullptr; + } +} + + +void Process() +{ + SDL_JoystickUpdate(); + + if (Joystick) + { + if (!SDL_JoystickGetAttached(Joystick)) + { + SDL_JoystickClose(Joystick); + Joystick = NULL; + } + } + if (!Joystick && (SDL_NumJoysticks() > 0)) + { + JoystickID = Config::JoystickID; + OpenJoystick(); + } + + /*JoyInputMask = 0xFFF; + for (int i = 0; i < 12; i++) + if (JoystickButtonDown(Config::JoyMapping[i])) + JoyInputMask &= ~(1<nativeScanCode(); + return (scan == 0x11D || scan == 0x138 || scan == 0x36); +} +#else +bool IsRightModKey(QKeyEvent* event) +{ + quint32 scan = event->nativeScanCode(); + return (scan == 0x69 || scan == 0x6C || scan == 0x3E); +} +#endif + +} diff --git a/src/frontend/qt_sdl/Input.h b/src/frontend/qt_sdl/Input.h new file mode 100644 index 0000000..24ec3a7 --- /dev/null +++ b/src/frontend/qt_sdl/Input.h @@ -0,0 +1,40 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef INPUT_H +#define INPUT_H + +#include "types.h" + +namespace Input +{ + +extern int JoystickID; +extern SDL_Joystick* Joystick; + +// set joystickID before calling openJoystick() +void OpenJoystick(); +void CloseJoystick(); + +void Process(); + +bool IsRightModKey(QKeyEvent* event); + +} + +#endif // INPUT_H diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 93204aa..2c0afc4 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -20,11 +20,13 @@ #include #include +#include + #include "types.h" #include "Config.h" #include "PlatformConfig.h" -#include "main.h" +#include "Input.h" #include "InputConfigDialog.h" #include "ui_InputConfigDialog.h" @@ -93,6 +95,22 @@ InputConfigDialog::InputConfigDialog(QWidget* parent) : QDialog(parent), ui(new populatePage(ui->tabInput, 12, dskeylabels, keypadKeyMap, keypadJoyMap); populatePage(ui->tabAddons, 2, hk_addons_labels, addonsKeyMap, addonsJoyMap); populatePage(ui->tabHotkeysGeneral, 6, hk_general_labels, hkGeneralKeyMap, hkGeneralJoyMap); + + int njoy = SDL_NumJoysticks(); + if (njoy > 0) + { + for (int i = 0; i < njoy; i++) + { + const char* name = SDL_JoystickNameForIndex(i); + ui->cbxJoystick->addItem(QString(name)); + } + ui->cbxJoystick->setCurrentIndex(Input::JoystickID); + } + else + { + ui->cbxJoystick->addItem("(no joysticks available)"); + ui->cbxJoystick->setEnabled(false); + } } InputConfigDialog::~InputConfigDialog() @@ -117,7 +135,7 @@ void InputConfigDialog::populatePage(QWidget* page, int num, const char** labels for (int i = 0; i < num; i++) { QLabel* label = new QLabel(QString(labels[i])+":"); - KeyMapButton* btn = new KeyMapButton(nullptr, &keymap[i], ishotkey); + KeyMapButton* btn = new KeyMapButton(&keymap[i], ishotkey); group_layout->addWidget(label, i, 0); group_layout->addWidget(btn, i, 1); @@ -133,15 +151,10 @@ void InputConfigDialog::populatePage(QWidget* page, int num, const char** labels for (int i = 0; i < num; i++) { QLabel* label = new QLabel(QString(labels[i])+":"); - QPushButton* btn = new QPushButton(); + JoyMapButton* btn = new JoyMapButton(&joymap[i], ishotkey); group_layout->addWidget(label, i, 0); group_layout->addWidget(btn, i, 1); - - btn->setText(joyMappingName(joymap[i])); - - //btn->setProperty("mapping", QVariant(&joymap[i])); - //btn->setProperty("isHotkey", QVariant(ishotkey)); } group_layout->setRowStretch(num, 1); group->setLayout(group_layout); @@ -150,71 +163,48 @@ void InputConfigDialog::populatePage(QWidget* page, int num, const char** labels page->setLayout(main_layout); } -QString InputConfigDialog::joyMappingName(int id) +void InputConfigDialog::on_InputConfigDialog_accepted() { - if (id < 0) + for (int i = 0; i < 12; i++) { - return "None"; + Config::KeyMapping[dskeyorder[i]] = keypadKeyMap[i]; + Config::JoyMapping[dskeyorder[i]] = keypadJoyMap[i]; } - bool hasbtn = ((id & 0xFFFF) != 0xFFFF); - QString str; - - if (hasbtn) - { - if (id & 0x100) - { - int hatnum = ((id >> 4) & 0xF) + 1; - - switch (id & 0xF) - { - case 0x1: str = "Hat %1 up"; break; - case 0x2: str = "Hat %1 right"; break; - case 0x4: str = "Hat %1 down"; break; - case 0x8: str = "Hat %1 left"; break; - } - - str = str.arg(hatnum); - } - else - { - str = QString("Button %1").arg((id & 0xFFFF) + 1); - } - } - else + for (int i = 0; i < 2; i++) { - str = ""; + Config::HKKeyMapping[hk_addons[i]] = addonsKeyMap[i]; + Config::HKJoyMapping[hk_addons[i]] = addonsJoyMap[i]; } - if (id & 0x10000) + for (int i = 0; i < 6; i++) { - int axisnum = ((id >> 24) & 0xF) + 1; - - if (hasbtn) str += " / "; - - switch ((id >> 20) & 0xF) - { - case 0: str += QString("Axis %1 +").arg(axisnum); break; - case 1: str += QString("Axis %1 -").arg(axisnum); break; - case 2: str += QString("Trigger %1").arg(axisnum); break; - } + Config::HKKeyMapping[hk_general[i]] = hkGeneralKeyMap[i]; + Config::HKJoyMapping[hk_general[i]] = hkGeneralJoyMap[i]; } - return str; -} + Config::JoystickID = Input::JoystickID; + Config::Save(); -void InputConfigDialog::on_InputConfigDialog_accepted() -{ closeDlg(); } void InputConfigDialog::on_InputConfigDialog_rejected() { + Input::JoystickID = Config::JoystickID; + Input::OpenJoystick(); + closeDlg(); } +void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id) +{ + Input::JoystickID = id; + Input::OpenJoystick(); +} + -KeyMapButton::KeyMapButton(QWidget* parent, int* mapping, bool hotkey) : QPushButton(parent) +KeyMapButton::KeyMapButton(int* mapping, bool hotkey) : QPushButton() { this->mapping = mapping; this->isHotkey = hotkey; @@ -257,7 +247,7 @@ void KeyMapButton::keyPressEvent(QKeyEvent* event) if (!ismod) key |= mod; - else if (IsRightModKey(event)) + else if (Input::IsRightModKey(event)) key |= (1<<31); *mapping = key; @@ -314,3 +304,188 @@ QString KeyMapButton::mappingText() return ret.replace("&", "&&"); } + + +JoyMapButton::JoyMapButton(int* mapping, bool hotkey) : QPushButton() +{ + this->mapping = mapping; + this->isHotkey = hotkey; + + setCheckable(true); + setText(mappingText()); + + connect(this, &JoyMapButton::clicked, this, &JoyMapButton::onClick); + + timerID = 0; +} + +JoyMapButton::~JoyMapButton() +{ +} + +void JoyMapButton::keyPressEvent(QKeyEvent* event) +{ + if (!isChecked()) return QPushButton::keyPressEvent(event); + + int key = event->key(); + int mod = event->modifiers(); + + if (!mod) + { + if (key == Qt::Key_Escape) { click(); return; } + if (key == Qt::Key_Backspace) { *mapping = -1; click(); return; } + } +} + +void JoyMapButton::focusOutEvent(QFocusEvent* event) +{ + if (isChecked()) + { + // if we lost the focus while mapping, consider it 'done' + click(); + } + + QPushButton::focusOutEvent(event); +} + +void JoyMapButton::timerEvent(QTimerEvent* event) +{ + SDL_Joystick* joy = Input::Joystick; + if (!joy) { click(); return; } + if (!SDL_JoystickGetAttached(joy)) { click(); return; } + + int oldmap; + if (*mapping == -1) oldmap = 0xFFFF; + else oldmap = *mapping; + + int nbuttons = SDL_JoystickNumButtons(joy); + for (int i = 0; i < nbuttons; i++) + { + if (SDL_JoystickGetButton(joy, i)) + { + *mapping = (oldmap & 0xFFFF0000) | i; + click(); + return; + } + } + + int nhats = SDL_JoystickNumHats(joy); + if (nhats > 16) nhats = 16; + for (int i = 0; i < nhats; i++) + { + Uint8 blackhat = SDL_JoystickGetHat(joy, i); + if (blackhat) + { + if (blackhat & 0x1) blackhat = 0x1; + else if (blackhat & 0x2) blackhat = 0x2; + else if (blackhat & 0x4) blackhat = 0x4; + else blackhat = 0x8; + + *mapping = (oldmap & 0xFFFF0000) | 0x100 | blackhat | (i << 4); + click(); + return; + } + } + + int naxes = SDL_JoystickNumAxes(joy); + if (naxes > 16) naxes = 16; + for (int i = 0; i < naxes; i++) + { + Sint16 axisval = SDL_JoystickGetAxis(joy, i); + int diff = abs(axisval - axesRest[i]); + + if (axesRest[i] < -16384 && axisval >= 0) + { + *mapping = (oldmap & 0xFFFF) | 0x10000 | (2 << 20) | (i << 24); + click(); + return; + } + else if (diff > 16384) + { + int axistype; + if (axisval > 0) axistype = 0; + else axistype = 1; + + *mapping = (oldmap & 0xFFFF) | 0x10000 | (axistype << 20) | (i << 24); + click(); + return; + } + } +} + +void JoyMapButton::onClick() +{ + if (isChecked()) + { + setText("[press button/axis]"); + timerID = startTimer(50); + + memset(axesRest, 0, sizeof(axesRest)); + if (Input::Joystick && SDL_JoystickGetAttached(Input::Joystick)) + { + int naxes = SDL_JoystickNumAxes(Input::Joystick); + if (naxes > 16) naxes = 16; + for (int a = 0; a < naxes; a++) + { + axesRest[a] = SDL_JoystickGetAxis(Input::Joystick, a); + } + } + } + else + { + setText(mappingText()); + if (timerID) { killTimer(timerID); timerID = 0; } + } +} + +QString JoyMapButton::mappingText() +{ + int id = *mapping; + + if (id == -1) return "None"; + + bool hasbtn = ((id & 0xFFFF) != 0xFFFF); + QString str; + + if (hasbtn) + { + if (id & 0x100) + { + int hatnum = ((id >> 4) & 0xF) + 1; + + switch (id & 0xF) + { + case 0x1: str = "Hat %1 up"; break; + case 0x2: str = "Hat %1 right"; break; + case 0x4: str = "Hat %1 down"; break; + case 0x8: str = "Hat %1 left"; break; + } + + str = str.arg(hatnum); + } + else + { + str = QString("Button %1").arg((id & 0xFFFF) + 1); + } + } + else + { + str = ""; + } + + if (id & 0x10000) + { + int axisnum = ((id >> 24) & 0xF) + 1; + + if (hasbtn) str += " / "; + + switch ((id >> 20) & 0xF) + { + case 0: str += QString("Axis %1 +").arg(axisnum); break; + case 1: str += QString("Axis %1 -").arg(axisnum); break; + case 2: str += QString("Trigger %1").arg(axisnum); break; + } + } + + return str; +} diff --git a/src/frontend/qt_sdl/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfigDialog.h index b2ca3f2..82e37bc 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.h +++ b/src/frontend/qt_sdl/InputConfigDialog.h @@ -55,13 +55,11 @@ private slots: void on_InputConfigDialog_accepted(); void on_InputConfigDialog_rejected(); - // + void on_cbxJoystick_currentIndexChanged(int id); private: void populatePage(QWidget* page, int num, const char** labels, int* keymap, int* joymap); - QString joyMappingName(int id); - Ui::InputConfigDialog* ui; int keypadKeyMap[12], keypadJoyMap[12]; @@ -75,7 +73,7 @@ class KeyMapButton : public QPushButton Q_OBJECT public: - explicit KeyMapButton(QWidget* parent, int* mapping, bool hotkey); + explicit KeyMapButton(int* mapping, bool hotkey); ~KeyMapButton(); protected: @@ -92,4 +90,30 @@ private: bool isHotkey; }; +class JoyMapButton : public QPushButton +{ + Q_OBJECT + +public: + explicit JoyMapButton(int* mapping, bool hotkey); + ~JoyMapButton(); + +protected: + void keyPressEvent(QKeyEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + void timerEvent(QTimerEvent* event) override; + +private slots: + void onClick(); + +private: + QString mappingText(); + + int* mapping; + bool isHotkey; + + int timerID; + int axesRest[16]; +}; + #endif // INPUTCONFIGDIALOG_H diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 7b50af4..8fe776e 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -27,10 +27,12 @@ #include #include #include +#include #include #include "main.h" +#include "Input.h" #include "EmuSettingsDialog.h" #include "InputConfigDialog.h" @@ -136,12 +138,6 @@ void EmuThread::run() } /*Touching = false; - KeyInputMask = 0xFFF; - JoyInputMask = 0xFFF; - KeyHotkeyMask = 0; - JoyHotkeyMask = 0; - HotkeyMask = 0; - LastHotkeyMask = 0; LidStatus = false;*/ u32 nframes = 0; @@ -154,6 +150,7 @@ void EmuThread::run() while (EmuRunning != 0) { + Input::Process(); /*ProcessInput(); if (HotkeyPressed(HK_FastForwardToggle)) @@ -999,6 +996,9 @@ int main(int argc, char** argv) Frontend::Init_ROM(); Frontend::Init_Audio(audioFreq); + Input::JoystickID = Config::JoystickID; + Input::OpenJoystick(); + mainWindow = new MainWindow(); mainWindow->show(); @@ -1047,7 +1047,8 @@ int main(int argc, char** argv) emuThread->wait(); delete emuThread; - //if (Joystick) SDL_JoystickClose(Joystick); + Input::CloseJoystick(); + if (audioDevice) SDL_CloseAudioDevice(audioDevice); //if (MicDevice) SDL_CloseAudioDevice(MicDevice); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 5d6638c..4553875 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -23,7 +23,6 @@ #include #include #include -#include class EmuThread : public QThread @@ -132,24 +131,4 @@ private: QAction* actInputConfig; }; - -// TODO: MacOS version of this! -// distinguish between left and right modifier keys (Ctrl, Alt, Shift) -// Qt provides no real cross-platform way to do this, so here we go -// for Windows and Linux we can distinguish via scancodes (but both -// provide different scancodes) -#ifdef __WIN32__ -inline bool IsRightModKey(QKeyEvent* event) -{ - quint32 scan = event->nativeScanCode(); - return (scan == 0x11D || scan == 0x138 || scan == 0x36); -} -#else -inline bool IsRightModKey(QKeyEvent* event) -{ - quint32 scan = event->nativeScanCode(); - return (scan == 0x69 || scan == 0x6C || scan == 0x3E); -} -#endif - #endif // MAIN_H -- cgit v1.2.3 From 9df8d91bdc12ab2e65569e26dc7c57246e384a8f Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 21:34:24 +0200 Subject: keep the ugliness confined in Platform.cpp --- src/Platform.h | 3 +++ src/frontend/qt_sdl/Platform.cpp | 49 +++++++++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/main.cpp | 47 ++------------------------------------ 3 files changed, 53 insertions(+), 46 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/Platform.h b/src/Platform.h index b6effdc..fea98dd 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -24,6 +24,9 @@ namespace Platform { +void Init(int argc, char** argv); +void DeInit(); + void StopEmu(); // fopen() wrappers diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index fea9166..6a5b466 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -53,7 +53,7 @@ #endif -extern char* EmuDirectory; +char* EmuDirectory; void Stop(bool internal); @@ -84,6 +84,53 @@ u8 PacketBuffer[2048]; #define NIFI_VER 1 +void Init(int argc, char** argv) +{ +#if defined(__WIN32__) || defined(UNIX_PORTABLE) + if (argc > 0 && strlen(argv[0]) > 0) + { + int len = strlen(argv[0]); + while (len > 0) + { + if (argv[0][len] == '/') break; + if (argv[0][len] == '\\') break; + len--; + } + if (len > 0) + { + EmuDirectory = new char[len+1]; + strncpy(EmuDirectory, argv[0], len); + EmuDirectory[len] = '\0'; + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } + } + else + { + EmuDirectory = new char[2]; + strcpy(EmuDirectory, "."); + } +#else + const char* confdir = g_get_user_config_dir(); + const char* confname = "/melonDS"; + int cdlen = strlen(confdir); + int cnlen = strlen(confname); + EmuDirectory = new char[cdlen + cnlen + 1]; + strncpy(&EmuDirectory[0], confdir, cdlen); + strncpy(&EmuDirectory[cdlen], confname, cnlen); + EmuDirectory[cdlen+cnlen] = '\0'; +#endif +} + +void DeInit() +{ + delete[] EmuDirectory; +} + + void StopEmu() { //Stop(true); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8fe776e..a68f933 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -54,8 +54,6 @@ // TODO: uniform variable spelling -char* EmuDirectory; - bool RunningSomething; MainWindow* mainWindow; @@ -865,11 +863,6 @@ void MainWindow::onInputConfigFinished(int res) } -// FIXME!!!! -#if (!defined(__WIN32__) && !defined(UNIX_PORTABLE)) -#include -#endif - int main(int argc, char** argv) { srand(time(NULL)); @@ -877,43 +870,7 @@ int main(int argc, char** argv) printf("melonDS " MELONDS_VERSION "\n"); printf(MELONDS_URL "\n"); -#if defined(__WIN32__) || defined(UNIX_PORTABLE) - if (argc > 0 && strlen(argv[0]) > 0) - { - int len = strlen(argv[0]); - while (len > 0) - { - if (argv[0][len] == '/') break; - if (argv[0][len] == '\\') break; - len--; - } - if (len > 0) - { - EmuDirectory = new char[len+1]; - strncpy(EmuDirectory, argv[0], len); - EmuDirectory[len] = '\0'; - } - else - { - EmuDirectory = new char[2]; - strcpy(EmuDirectory, "."); - } - } - else - { - EmuDirectory = new char[2]; - strcpy(EmuDirectory, "."); - } -#else - const char* confdir = g_get_user_config_dir(); - const char* confname = "/melonDS"; - int cdlen = strlen(confdir); - int cnlen = strlen(confname); - EmuDirectory = new char[cdlen + cnlen + 1]; - strncpy(&EmuDirectory[0], confdir, cdlen); - strncpy(&EmuDirectory[cdlen], confname, cnlen); - EmuDirectory[cdlen+cnlen] = '\0'; -#endif + Platform::Init(argc, argv); QApplication melon(argc, argv); @@ -1060,7 +1017,7 @@ int main(int argc, char** argv) Config::Save(); SDL_Quit(); - delete[] EmuDirectory; + Platform::DeInit(); return ret; } -- cgit v1.2.3 From b262313816b9fac581353f74dd71e1dde1f23013 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 22:22:21 +0200 Subject: actually hook up input to the core also unbotch CMakeLists.txt --- CMakeLists.txt | 8 +++ src/frontend/qt_sdl/Input.cpp | 124 +++++++++++++++++++++++++++++++++++++++++- src/frontend/qt_sdl/Input.h | 7 +++ src/frontend/qt_sdl/main.cpp | 14 ++++- src/frontend/qt_sdl/main.h | 1 + 5 files changed, 150 insertions(+), 4 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index ee021d9..e640a48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,14 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() +if (CMAKE_BUILD_TYPE STREQUAL Debug) + add_compile_options(-Og) +endif() + +if (CMAKE_BUILD_TYPE STREQUAL Release) + add_compile_options(-O3) +endif() + add_compile_options(-fno-pic) add_link_options(-no-pie) diff --git a/src/frontend/qt_sdl/Input.cpp b/src/frontend/qt_sdl/Input.cpp index 7caf24a..d60271c 100644 --- a/src/frontend/qt_sdl/Input.cpp +++ b/src/frontend/qt_sdl/Input.cpp @@ -34,6 +34,21 @@ u32 KeyHotkeyMask, JoyHotkeyMask; u32 HotkeyMask, LastHotkeyMask; u32 HotkeyPress, HotkeyRelease; +u32 InputMask; + + +void Init() +{ + KeyInputMask = 0xFFF; + JoyInputMask = 0xFFF; + InputMask = 0xFFF; + + KeyHotkeyMask = 0; + JoyHotkeyMask = 0; + HotkeyMask = 0; + LastHotkeyMask = 0; +} + void OpenJoystick() { @@ -62,6 +77,109 @@ void CloseJoystick() } +int GetEventKeyVal(QKeyEvent* event) +{ + int key = event->key(); + int mod = event->modifiers(); + bool ismod = (key == Qt::Key_Control || + key == Qt::Key_Alt || + key == Qt::Key_AltGr || + key == Qt::Key_Shift || + key == Qt::Key_Meta); + + if (!ismod) + key |= mod; + else if (Input::IsRightModKey(event)) + key |= (1<<31); + + return key; +} + +void KeyPress(QKeyEvent* event) +{ + int keyHK = GetEventKeyVal(event); + int keyKP = keyHK & ~event->modifiers(); + + for (int i = 0; i < 12; i++) + if (keyKP == Config::KeyMapping[i]) + KeyInputMask &= ~(1<modifiers(); + + for (int i = 0; i < 12; i++) + if (keyKP == Config::KeyMapping[i]) + KeyInputMask |= (1<> 4) & 0xF; + int hatdir = val & 0xF; + Uint8 hatval = SDL_JoystickGetHat(Joystick, hatnum); + + bool pressed = false; + if (hatdir == 0x1) pressed = (hatval & SDL_HAT_UP); + else if (hatdir == 0x4) pressed = (hatval & SDL_HAT_DOWN); + else if (hatdir == 0x2) pressed = (hatval & SDL_HAT_RIGHT); + else if (hatdir == 0x8) pressed = (hatval & SDL_HAT_LEFT); + + if (pressed) return true; + } + else + { + int btnnum = val & 0xFFFF; + Uint8 btnval = SDL_JoystickGetButton(Joystick, btnnum); + + if (btnval) return true; + } + } + + if (val & 0x10000) + { + int axisnum = (val >> 24) & 0xF; + int axisdir = (val >> 20) & 0xF; + Sint16 axisval = SDL_JoystickGetAxis(Joystick, axisnum); + + switch (axisdir) + { + case 0: // positive + if (axisval > 16384) return true; + break; + + case 1: // negative + if (axisval < -16384) return true; + break; + + case 2: // trigger + if (axisval > 0) return true; + break; + } + } + + return false; +} + void Process() { SDL_JoystickUpdate(); @@ -80,11 +198,13 @@ void Process() OpenJoystick(); } - /*JoyInputMask = 0xFFF; + JoyInputMask = 0xFFF; for (int i = 0; i < 12; i++) if (JoystickButtonDown(Config::JoyMapping[i])) JoyInputMask &= ~(1<key(), event->nativeScanCode(), event->modifiers(), event->nativeModifiers()); + if (event->isAutoRepeat()) return; + + Input::KeyPress(event); +} + +void MainWindow::keyReleaseEvent(QKeyEvent* event) +{ + if (event->isAutoRepeat()) return; + + Input::KeyRelease(event); } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 4553875..a3125cc 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -87,6 +87,7 @@ public: protected: void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; private slots: void onOpenFile(); -- cgit v1.2.3 From 95f9698077fe50d2567aacd8728ff2625f88f228 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 22:37:48 +0200 Subject: add back some hotkeys. remove some legacy cruft from NDS.cpp. --- src/NDS.cpp | 18 ++++++++-------- src/NDS.h | 3 +-- src/frontend/qt_sdl/Input.cpp | 5 +++++ src/frontend/qt_sdl/Input.h | 4 ++++ src/frontend/qt_sdl/main.cpp | 48 ++++++++++++++++++++----------------------- 5 files changed, 40 insertions(+), 38 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/NDS.cpp b/src/NDS.cpp index 745ed28..e89aa66 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -951,23 +951,15 @@ void CancelEvent(u32 id) } -void PressKey(u32 key) -{ - KeyInput &= ~(1 << key); -} - -void ReleaseKey(u32 key) -{ - KeyInput |= (1 << key); -} - void TouchScreen(u16 x, u16 y) { + KeyInput &= ~(1<<22); SPI_TSC::SetTouchCoords(x, y); } void ReleaseScreen() { + KeyInput |= (1<<22); SPI_TSC::SetTouchCoords(0x000, 0xFFF); } @@ -981,6 +973,12 @@ void SetKeyMask(u32 mask) KeyInput |= key_lo | (key_hi << 16); } +bool IsLidClosed() +{ + if (KeyInput & (1<<23)) return true; + return false; +} + void SetLidClosed(bool closed) { if (closed) diff --git a/src/NDS.h b/src/NDS.h index c7b455e..daeadc4 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -142,13 +142,12 @@ void RelocateSave(const char* path, bool write); u32 RunFrame(); -void PressKey(u32 key); -void ReleaseKey(u32 key); void TouchScreen(u16 x, u16 y); void ReleaseScreen(); void SetKeyMask(u32 mask); +bool IsLidClosed(); void SetLidClosed(bool closed); void MicInputFrame(s16* data, int samples); diff --git a/src/frontend/qt_sdl/Input.cpp b/src/frontend/qt_sdl/Input.cpp index d60271c..84d20ad 100644 --- a/src/frontend/qt_sdl/Input.cpp +++ b/src/frontend/qt_sdl/Input.cpp @@ -217,6 +217,11 @@ void Process() } +bool HotkeyDown(int id) { return HotkeyMask & (1< 0) GBACart_SolarSensor::LightLevel--; - char msg[64]; - sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - OSD::AddMessage(0, msg); + //char msg[64]; + //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + //OSD::AddMessage(0, msg); } - if (HotkeyPressed(HK_SolarSensorIncrease)) + if (Input::HotkeyPressed(HK_SolarSensorIncrease)) { if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; - char msg[64]; - sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - OSD::AddMessage(0, msg); + //char msg[64]; + //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + //OSD::AddMessage(0, msg); } - }*/ + } if (EmuRunning == 1) { @@ -186,14 +184,13 @@ void EmuThread::run() // process input and hotkeys NDS::SetKeyMask(Input::InputMask); - /*NDS::SetKeyMask(KeyInputMask & JoyInputMask); - if (HotkeyPressed(HK_Lid)) + if (Input::HotkeyPressed(HK_Lid)) { - LidStatus = !LidStatus; - NDS::SetLidClosed(LidStatus); - OSD::AddMessage(0, LidStatus ? "Lid closed" : "Lid opened"); - }*/ + bool lid = !NDS::IsLidClosed(); + NDS::SetLidClosed(lid); + //OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened"); + } // microphone input /*FeedMicInput(); @@ -250,8 +247,7 @@ void EmuThread::run() uiAreaQueueRedrawAll(MainDrawArea);*/ mainWindow->update(); - bool fastforward = false; - //bool fastforward = HotkeyDown(HK_FastForward); + bool fastforward = Input::HotkeyDown(HK_FastForward); if (Config::AudioSync && (!fastforward) && audioDevice) { -- cgit v1.2.3 From 68a7865096a17b7a10a9dc521c99c7eb042582ec Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 22:57:15 +0200 Subject: basic touchscreen support --- src/frontend/qt_sdl/main.cpp | 42 +++++++++++++++++++++++++++++++++++++++--- src/frontend/qt_sdl/main.h | 3 +++ 2 files changed, 42 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 67ac92c..3b0b35d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -410,6 +410,8 @@ MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) { screen[0] = new QImage(256, 192, QImage::Format_RGB32); screen[1] = new QImage(256, 192, QImage::Format_RGB32); + + touching = false; } MainWindowPanel::~MainWindowPanel() @@ -441,25 +443,59 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) } +void MainWindowPanel::transformTSCoords(int& x, int& y) +{ + // TODO: actual screen de-transform taking screen layout/rotation/etc into account + + y -= 192; + + // clamp to screen range + if (x < 0) x = 0; + else if (x > 255) x = 255; + if (y < 0) y = 0; + else if (y > 191) y = 191; +} + void MainWindowPanel::mousePressEvent(QMouseEvent* event) { event->accept(); + if (event->button() != Qt::LeftButton) return; + + int x = event->pos().x(); + int y = event->pos().y(); - printf("mouse press %d,%d\n", event->pos().x(), event->pos().y()); + if (x >= 0 && x < 256 && y >= 192 && y < 384) + { + touching = true; + + transformTSCoords(x, y); + NDS::TouchScreen(x, y); + } } void MainWindowPanel::mouseReleaseEvent(QMouseEvent* event) { event->accept(); + if (event->button() != Qt::LeftButton) return; - printf("mouse release %d,%d\n", event->pos().x(), event->pos().y()); + if (touching) + { + touching = false; + NDS::ReleaseScreen(); + } } void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) { event->accept(); + if (!(event->buttons() & Qt::LeftButton)) return; + if (!touching) return; + + int x = event->pos().x(); + int y = event->pos().y(); - printf("mouse move %d,%d %08X\n", event->pos().x(), event->pos().y(), event->buttons()); + transformTSCoords(x, y); + NDS::TouchScreen(x, y); } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index a3125cc..5443780 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -74,6 +74,9 @@ protected: private: QImage* screen[2]; + bool touching; + + void transformTSCoords(int& x, int& y); }; -- cgit v1.2.3 From a2f9472e5dff77039d66783ffda9ee0fc2de77f8 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 01:11:57 +0200 Subject: might help fix crashes on exit? --- src/frontend/qt_sdl/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 3b0b35d..70a6ec1 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -502,6 +502,7 @@ void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS " MELONDS_VERSION); + setAttribute(Qt::WA_DeleteOnClose); QMenuBar* menubar = new QMenuBar(); { -- cgit v1.2.3 From 4dae6d8928b57792c4ba746a7078c9f7dcac44af Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 01:49:40 +0200 Subject: load shit from command line --- src/frontend/qt_sdl/main.cpp | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 70a6ec1..0cd9f70 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1006,7 +1006,6 @@ int main(int argc, char** argv) emuThread->start(); emuThread->emuPause(true); - #if 0 if (argc > 1) { char* file = argv[1]; @@ -1014,32 +1013,25 @@ int main(int argc, char** argv) if (!strcasecmp(ext, "nds") || !strcasecmp(ext, "srl")) { - strncpy(ROMPath[0], file, 1023); - ROMPath[0][1023] = '\0'; + int res = Frontend::LoadROM(file, Frontend::ROMSlot_NDS); - //SetupSRAMPath(0); - - //if (NDS::LoadROM(ROMPath[0], SRAMPath[0], Config::DirectBoot)) - // Run(); - } - - if (argc > 2) - { - file = argv[2]; - ext = &file[strlen(file)-3]; - - if (!strcasecmp(ext, "gba")) + if (res == Frontend::Load_OK) { - strncpy(ROMPath[1], file, 1023); - ROMPath[1][1023] = '\0'; + if (argc > 2) + { + file = argv[2]; + ext = &file[strlen(file)-3]; - //SetupSRAMPath(1); + if (!strcasecmp(ext, "gba")) + { + Frontend::LoadROM(file, Frontend::ROMSlot_GBA); + } + } - //NDS::LoadGBAROM(ROMPath[1], SRAMPath[1]); + emuThread->emuRun(); } } } - #endif int ret = melon.exec(); -- cgit v1.2.3 From 5ed87a634afcff941aad2769496784249a568723 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 02:36:48 +0200 Subject: add drag-drop support --- src/frontend/qt_sdl/main.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.h | 3 +++ 2 files changed, 65 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0cd9f70..d38a73e 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -503,6 +504,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS " MELONDS_VERSION); setAttribute(Qt::WA_DeleteOnClose); + setAcceptDrops(true); QMenuBar* menubar = new QMenuBar(); { @@ -612,6 +614,66 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) } +void MainWindow::dragEnterEvent(QDragEnterEvent* event) +{ + if (!event->mimeData()->hasUrls()) return; + + QList urls = event->mimeData()->urls(); + if (urls.count() > 1) return; // not handling more than one file at once + + QString filename = urls.at(0).toLocalFile(); + QString ext = filename.right(3); + + if (ext == "nds" || ext == "srl" || (ext == "gba" && RunningSomething)) + event->acceptProposedAction(); +} + +void MainWindow::dropEvent(QDropEvent* event) +{ + if (!event->mimeData()->hasUrls()) return; + + QList urls = event->mimeData()->urls(); + if (urls.count() > 1) return; // not handling more than one file at once + + emuThread->emuPause(true); + + QString filename = urls.at(0).toLocalFile(); + QString ext = filename.right(3); + + char _filename[1024]; + strncpy(_filename, filename.toStdString().c_str(), 1023); _filename[1023] = '\0'; + + int slot; int res; + if (ext == "gba") + { + slot = 1; + res = Frontend::LoadROM(_filename, Frontend::ROMSlot_GBA); + } + else + { + slot = 0; + res = Frontend::LoadROM(_filename, Frontend::ROMSlot_NDS); + } + + if (res != Frontend::Load_OK) + { + QMessageBox::critical(this, + "melonDS", + loadErrorStr(res)); + emuThread->emuUnpause(); + } + else if (slot == 1) + { + // checkme + emuThread->emuUnpause(); + } + else + { + emuThread->emuRun(); + } +} + + QString MainWindow::loadErrorStr(int error) { switch (error) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 5443780..83777bd 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -92,6 +92,9 @@ protected: void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; + void dragEnterEvent(QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; + private slots: void onOpenFile(); void onBootFirmware(); -- cgit v1.2.3 From 700b1a8b9dfb3cb7502a2f0941cea0090ddbdf44 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 03:01:09 +0200 Subject: add window icon --- melon.qrc | 6 ++++++ src/frontend/qt_sdl/CMakeLists.txt | 18 ++++++++++-------- src/frontend/qt_sdl/main.cpp | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 melon.qrc (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/melon.qrc b/melon.qrc new file mode 100644 index 0000000..b1ea364 --- /dev/null +++ b/melon.qrc @@ -0,0 +1,6 @@ + + + + icon/melon_32x32.png + + \ No newline at end of file diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 42cf912..c3d0959 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -11,6 +11,8 @@ SET(SOURCES_QT_SDL ../Util_ROM.cpp ../Util_Audio.cpp ../FrontendUtil.h + + ../../../melon.qrc ) if (WIN32) @@ -66,12 +68,12 @@ elseif (WIN32) target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Gui Qt5::Widgets) endif () -install(FILES ../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) -install(FILES ../../icon/melon_16x16.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/16x16/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../icon/melon_32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../icon/melon_48x48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../icon/melon_64x64.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../icon/melon_128x128.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../icon/melon_256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps RENAME net.kuribo64.melonDS.png) -install(FILES ../../romlist.bin DESTINATION ${CMAKE_INSTALL_PREFIX}/share/melonDS) +install(FILES ../../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) +install(FILES ../../../icon/melon_16x16.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/16x16/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../icon/melon_32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../icon/melon_48x48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../icon/melon_64x64.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../icon/melon_128x128.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../icon/melon_256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps RENAME net.kuribo64.melonDS.png) +install(FILES ../../../romlist.bin DESTINATION ${CMAKE_INSTALL_PREFIX}/share/melonDS) install(TARGETS melonDS RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index d38a73e..b81fc86 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -978,6 +978,7 @@ int main(int argc, char** argv) Platform::Init(argc, argv); QApplication melon(argc, argv); + melon.setWindowIcon(QIcon(":/melon-icon")); // http://stackoverflow.com/questions/14543333/joystick-wont-work-using-sdl SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); -- cgit v1.2.3 From 7be662b2dd1e7f99cf5a31c18c115c1106300964 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 20:57:12 +0200 Subject: finish fleshing out the menus --- src/frontend/qt_sdl/main.cpp | 256 +++++++++++++++++++++++++++++++++++++------ src/frontend/qt_sdl/main.h | 41 ++++++- 2 files changed, 258 insertions(+), 39 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index b81fc86..7ab7f0e 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -524,9 +524,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) for (int i = 1; i < 9; i++) { - char title[16]; - sprintf(title, "%d", i); - actSaveState[i] = submenu->addAction(title); + actSaveState[i] = submenu->addAction(QString("%1").arg(i)); actSaveState[i]->setShortcut(QKeySequence(Qt::ShiftModifier | (Qt::Key_F1+i-1))); actSaveState[i]->setData(QVariant(i)); connect(actSaveState[i], &QAction::triggered, this, &MainWindow::onSaveState); @@ -542,9 +540,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) for (int i = 1; i < 9; i++) { - char title[16]; - sprintf(title, "%d", i); - actLoadState[i] = submenu->addAction(title); + actLoadState[i] = submenu->addAction(QString("%1").arg(i)); actLoadState[i]->setShortcut(QKeySequence(Qt::Key_F1+i-1)); actLoadState[i]->setData(QVariant(i)); connect(actLoadState[i], &QAction::triggered, this, &MainWindow::onLoadState); @@ -586,6 +582,125 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actInputConfig = menu->addAction("Input and hotkeys"); connect(actInputConfig, &QAction::triggered, this, &MainWindow::onOpenInputConfig); + + actVideoSettings = menu->addAction("Video settings"); + connect(actVideoSettings, &QAction::triggered, this, &MainWindow::onOpenVideoSettings); + + actAudioSettings = menu->addAction("Audio settings"); + connect(actAudioSettings, &QAction::triggered, this, &MainWindow::onOpenAudioSettings); + + actWifiSettings = menu->addAction("Wifi settings"); + connect(actWifiSettings, &QAction::triggered, this, &MainWindow::onOpenWifiSettings); + + { + QMenu* submenu = menu->addMenu("Savestate settings"); + + actSavestateSRAMReloc = submenu->addAction("Separate savefiles"); + actSavestateSRAMReloc->setCheckable(true); + connect(actSavestateSRAMReloc, &QAction::triggered, this, &MainWindow::onChangeSavestateSRAMReloc); + } + + menu->addSeparator(); + + { + QMenu* submenu = menu->addMenu("Screen size"); + + for (int i = 0; i < 4; i++) + { + int data = i+1; + actScreenSize[i] = submenu->addAction(QString("%1x").arg(data)); + actScreenSize[i]->setData(QVariant(data)); + connect(actScreenSize[i], &QAction::triggered, this, &MainWindow::onChangeScreenSize); + } + } + { + QMenu* submenu = menu->addMenu("Screen rotation"); + grpScreenRotation = new QActionGroup(submenu); + + for (int i = 0; i < 4; i++) + { + int data = i*90; + actScreenRotation[i] = submenu->addAction(QString("%1°").arg(data)); + actScreenRotation[i]->setActionGroup(grpScreenRotation); + actScreenRotation[i]->setData(QVariant(data)); + actScreenRotation[i]->setCheckable(true); + } + + connect(grpScreenRotation, &QActionGroup::triggered, this, &MainWindow::onChangeScreenRotation); + } + { + QMenu* submenu = menu->addMenu("Screen gap"); + grpScreenGap = new QActionGroup(submenu); + + const int screengap[] = {0, 1, 8, 64, 90, 128}; + + for (int i = 0; i < 6; i++) + { + int data = screengap[i]; + actScreenGap[i] = submenu->addAction(QString("%1 px").arg(data)); + actScreenGap[i]->setActionGroup(grpScreenGap); + actScreenGap[i]->setData(QVariant(data)); + actScreenGap[i]->setCheckable(true); + } + + connect(grpScreenGap, &QActionGroup::triggered, this, &MainWindow::onChangeScreenGap); + } + { + QMenu* submenu = menu->addMenu("Screen layout"); + grpScreenLayout = new QActionGroup(submenu); + + const char* screenlayout[] = {"Natural", "Vertical", "Horizontal"}; + + for (int i = 0; i < 3; i++) + { + actScreenLayout[i] = submenu->addAction(QString(screenlayout[i])); + actScreenLayout[i]->setActionGroup(grpScreenLayout); + actScreenLayout[i]->setData(QVariant(i)); + actScreenLayout[i]->setCheckable(true); + } + + connect(grpScreenLayout, &QActionGroup::triggered, this, &MainWindow::onChangeScreenLayout); + } + { + QMenu* submenu = menu->addMenu("Screen sizing"); + grpScreenSizing = new QActionGroup(submenu); + + const char* screensizing[] = {"Even", "Emphasize top", "Emphasize bottom", "Auto"}; + + for (int i = 0; i < 4; i++) + { + actScreenSizing[i] = submenu->addAction(QString(screensizing[i])); + actScreenSizing[i]->setActionGroup(grpScreenSizing); + actScreenSizing[i]->setData(QVariant(i)); + actScreenSizing[i]->setCheckable(true); + } + + connect(grpScreenSizing, &QActionGroup::triggered, this, &MainWindow::onChangeScreenSizing); + + submenu->addSeparator(); + + actIntegerScaling = submenu->addAction("Force integer scaling"); + actIntegerScaling->setCheckable(true); + connect(actIntegerScaling, &QAction::triggered, this, &MainWindow::onChangeIntegerScaling); + } + + actScreenFiltering = menu->addAction("Screen filtering"); + actScreenFiltering->setCheckable(true); + connect(actScreenFiltering, &QAction::triggered, this, &MainWindow::onChangeScreenFiltering); + + actShowOSD = menu->addAction("Show OSD"); + actShowOSD->setCheckable(true); + connect(actShowOSD, &QAction::triggered, this, &MainWindow::onChangeShowOSD); + + menu->addSeparator(); + + actLimitFramerate = menu->addAction("Limit framerate"); + actLimitFramerate->setCheckable(true); + connect(actLimitFramerate, &QAction::triggered, this, &MainWindow::onChangeLimitFramerate); + + actAudioSync = menu->addAction("Audio sync"); + actAudioSync->setCheckable(true); + connect(actAudioSync, &QAction::triggered, this, &MainWindow::onChangeAudioSync); } setMenuBar(menubar); @@ -756,7 +871,6 @@ void MainWindow::onOpenFile() void MainWindow::onBootFirmware() { - // TODO: ensure the firmware is actually bootable!! // TODO: check the whole GBA cart shito emuThread->emuPause(true); @@ -902,6 +1016,106 @@ void MainWindow::onStop() } +void MainWindow::onEmuPause() +{ + // +} + +void MainWindow::onEmuUnpause() +{ + // +} + + +void MainWindow::onOpenEmuSettings() +{ + EmuSettingsDialog::openDlg(this); +} + +void MainWindow::onOpenInputConfig() +{ + emuThread->emuPause(true); + + InputConfigDialog* dlg = InputConfigDialog::openDlg(this); + connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); +} + +void MainWindow::onInputConfigFinished(int res) +{ + emuThread->emuUnpause(); +} + +void MainWindow::onOpenVideoSettings() +{ + // +} + +void MainWindow::onOpenAudioSettings() +{ + // +} + +void MainWindow::onOpenWifiSettings() +{ + // +} + +void MainWindow::onChangeSavestateSRAMReloc(bool checked) +{ + // +} + +void MainWindow::onChangeScreenSize() +{ + // +} + +void MainWindow::onChangeScreenRotation(QAction* act) +{ + printf("DATABOTTE %p\n", act); +} + +void MainWindow::onChangeScreenGap(QAction* act) +{ + // +} + +void MainWindow::onChangeScreenLayout(QAction* act) +{ + // +} + +void MainWindow::onChangeScreenSizing(QAction* act) +{ + // +} + +void MainWindow::onChangeIntegerScaling(bool checked) +{ + // +} + +void MainWindow::onChangeScreenFiltering(bool checked) +{ + // +} + +void MainWindow::onChangeShowOSD(bool checked) +{ + // +} + +void MainWindow::onChangeLimitFramerate(bool checked) +{ + // +} + +void MainWindow::onChangeAudioSync(bool checked) +{ + // +} + + void MainWindow::onTitleUpdate(QString title) { setWindowTitle(title); @@ -938,34 +1152,6 @@ void MainWindow::onEmuStop() actStop->setEnabled(false); } -void MainWindow::onEmuPause() -{ - // -} - -void MainWindow::onEmuUnpause() -{ - // -} - - -void MainWindow::onOpenEmuSettings() -{ - EmuSettingsDialog::openDlg(this); -} - -void MainWindow::onOpenInputConfig() -{ - emuThread->emuPause(true); - - InputConfigDialog* dlg = InputConfigDialog::openDlg(this); - connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); -} - -void MainWindow::onInputConfigFinished(int res) -{ - emuThread->emuUnpause(); -} int main(int argc, char** argv) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 83777bd..b478f4e 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -23,6 +23,7 @@ #include #include #include +#include class EmuThread : public QThread @@ -107,6 +108,24 @@ private slots: void onReset(); void onStop(); + void onOpenEmuSettings(); + void onOpenInputConfig(); + void onInputConfigFinished(int res); + void onOpenVideoSettings(); + void onOpenAudioSettings(); + void onOpenWifiSettings(); + void onChangeSavestateSRAMReloc(bool checked); + void onChangeScreenSize(); + void onChangeScreenRotation(QAction* act); + void onChangeScreenGap(QAction* act); + void onChangeScreenLayout(QAction* act); + void onChangeScreenSizing(QAction* act); + void onChangeIntegerScaling(bool checked); + void onChangeScreenFiltering(bool checked); + void onChangeShowOSD(bool checked); + void onChangeLimitFramerate(bool checked); + void onChangeAudioSync(bool checked); + void onTitleUpdate(QString title); void onEmuStart(); @@ -114,10 +133,6 @@ private slots: void onEmuPause(); void onEmuUnpause(); - void onOpenEmuSettings(); - void onOpenInputConfig(); - void onInputConfigFinished(int res); - private: QString loadErrorStr(int error); @@ -136,6 +151,24 @@ private: QAction* actEmuSettings; QAction* actInputConfig; + QAction* actVideoSettings; + QAction* actAudioSettings; + QAction* actWifiSettings; + QAction* actSavestateSRAMReloc; + QAction* actScreenSize[4]; + QActionGroup* grpScreenRotation; + QAction* actScreenRotation[4]; + QActionGroup* grpScreenGap; + QAction* actScreenGap[6]; + QActionGroup* grpScreenLayout; + QAction* actScreenLayout[3]; + QActionGroup* grpScreenSizing; + QAction* actScreenSizing[4]; + QAction* actIntegerScaling; + QAction* actScreenFiltering; + QAction* actShowOSD; + QAction* actLimitFramerate; + QAction* actAudioSync; }; #endif // MAIN_H -- cgit v1.2.3 From d761db005694899342beee101b12aaa6d6cbf711 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 21:19:04 +0200 Subject: populate the menus with the config data --- src/frontend/qt_sdl/PlatformConfig.cpp | 4 ++-- src/frontend/qt_sdl/PlatformConfig.h | 2 +- src/frontend/qt_sdl/main.cpp | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 3b4b4aa..28c224d 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -40,11 +40,11 @@ int ScreenRotation; int ScreenGap; int ScreenLayout; int ScreenSizing; +int IntegerScaling; int ScreenFilter; int ScreenUseGL; int ScreenVSync; -int ScreenRatio; int LimitFPS; int AudioSync; @@ -121,11 +121,11 @@ ConfigEntry PlatformConfigFile[] = {"ScreenGap", 0, &ScreenGap, 0, NULL, 0}, {"ScreenLayout", 0, &ScreenLayout, 0, NULL, 0}, {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, + {"IntegerScaling", 0, &IntegerScaling, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, {"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0}, - {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, {"LimitFPS", 0, &LimitFPS, 0, NULL, 0}, {"AudioSync", 0, &AudioSync, 1, NULL, 0}, diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h index 3704d14..539f9a4 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -53,11 +53,11 @@ extern int ScreenRotation; extern int ScreenGap; extern int ScreenLayout; extern int ScreenSizing; +extern int IntegerScaling; extern int ScreenFilter; extern int ScreenUseGL; extern int ScreenVSync; -extern int ScreenRatio; extern int LimitFPS; extern int AudioSync; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 7ab7f0e..af95c49 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -707,6 +707,30 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) panel = new MainWindowPanel(this); setCentralWidget(panel); panel->setMinimumSize(256, 384); + + + actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0); + + actScreenRotation[Config::ScreenRotation]->setChecked(true); + + for (int i = 0; i < 6; i++) + { + if (actScreenGap[i]->data().toInt() == Config::ScreenGap) + { + actScreenGap[i]->setChecked(true); + break; + } + } + + actScreenLayout[Config::ScreenLayout]->setChecked(true); + actScreenSizing[Config::ScreenSizing]->setChecked(true); + actIntegerScaling->setChecked(Config::IntegerScaling != 0); + + actScreenFiltering->setChecked(Config::ScreenFilter != 0); + actShowOSD->setChecked(Config::ShowOSD != 0); + + actLimitFramerate->setChecked(Config::LimitFPS != 0); + actAudioSync->setChecked(Config::AudioSync != 0); } MainWindow::~MainWindow() @@ -1183,8 +1207,13 @@ int main(int argc, char** argv) Config::Load(); - if (Config::AudioVolume < 0) Config::AudioVolume = 0; - else if (Config::AudioVolume > 256) Config::AudioVolume = 256; +#define SANITIZE(var, min, max) { if (var < min) var = min; else if (var > max) var = max; } + SANITIZE(Config::AudioVolume, 0, 256); + SANITIZE(Config::ScreenRotation, 0, 3); + SANITIZE(Config::ScreenGap, 0, 500); + SANITIZE(Config::ScreenLayout, 0, 2); + SANITIZE(Config::ScreenSizing, 0, 3); +#undef SANITIZE // TODO: this should be checked before running anything #if 0 -- cgit v1.2.3 From 26dcc95c20b13eac0c2c55529507cf0ab881cb0a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 21:23:15 +0200 Subject: do the easy menus --- src/frontend/qt_sdl/main.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index af95c49..35eac70 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1040,17 +1040,6 @@ void MainWindow::onStop() } -void MainWindow::onEmuPause() -{ - // -} - -void MainWindow::onEmuUnpause() -{ - // -} - - void MainWindow::onOpenEmuSettings() { EmuSettingsDialog::openDlg(this); @@ -1086,7 +1075,7 @@ void MainWindow::onOpenWifiSettings() void MainWindow::onChangeSavestateSRAMReloc(bool checked) { - // + Config::SavestateRelocSRAM = checked?1:0; } void MainWindow::onChangeScreenSize() @@ -1096,7 +1085,7 @@ void MainWindow::onChangeScreenSize() void MainWindow::onChangeScreenRotation(QAction* act) { - printf("DATABOTTE %p\n", act); + // } void MainWindow::onChangeScreenGap(QAction* act) @@ -1121,22 +1110,22 @@ void MainWindow::onChangeIntegerScaling(bool checked) void MainWindow::onChangeScreenFiltering(bool checked) { - // + Config::ScreenFilter = checked?1:0; } void MainWindow::onChangeShowOSD(bool checked) { - // + Config::ShowOSD = checked?1:0; } void MainWindow::onChangeLimitFramerate(bool checked) { - // + Config::LimitFPS = checked?1:0; } void MainWindow::onChangeAudioSync(bool checked) { - // + Config::AudioSync = checked?1:0; } @@ -1176,6 +1165,16 @@ void MainWindow::onEmuStop() actStop->setEnabled(false); } +void MainWindow::onEmuPause() +{ + // +} + +void MainWindow::onEmuUnpause() +{ + // +} + int main(int argc, char** argv) -- cgit v1.2.3 From 2ebb21ce3bcf1a445dce7b13f64e44d6098a3acd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 22:22:22 +0200 Subject: hook up pause and reset, w/ relevant hotkeys --- src/frontend/FrontendUtil.h | 3 ++ src/frontend/Util_ROM.cpp | 47 +++++++++++++++++++++- src/frontend/qt_sdl/main.cpp | 93 +++++++++++++++++++++++--------------------- src/frontend/qt_sdl/main.h | 10 +++-- 4 files changed, 104 insertions(+), 49 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index f4f6850..d838b63 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -65,6 +65,9 @@ int LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation int LoadROM(const char* file, int slot); +// reset execution of the current ROM +int Reset(); + // get the filename associated with the given savestate slot (1-8) void GetSavestateName(int slot, char* filename, int len); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 3200de4..e13eb2c 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -50,6 +50,11 @@ void Init_ROM() memset(PrevSRAMPath[ROMSlot_GBA], 0, 1024); } +// TODO: currently, when failing to load a ROM for whatever reason, we attempt +// to revert to the previous state and resume execution; this may not be a very +// good thing, depending on what state the core was left in. +// should we do a better state revert (via the savestate system)? completely stop? + void SetupSRAMPath(int slot) { strncpy(SRAMPath[slot], ROMPath[slot], 1023); @@ -184,7 +189,7 @@ int LoadROM(const char* file, int slot) } else if (slot == ROMSlot_GBA && NDS::LoadGBAROM(ROMPath[slot], SRAMPath[slot])) { - SavestateLoaded = false; + SavestateLoaded = false; // checkme?? strncpy(PrevSRAMPath[slot], SRAMPath[slot], 1024); // safety return Load_OK; @@ -197,6 +202,46 @@ int LoadROM(const char* file, int slot) } } +int Reset() +{ + int res; + bool directboot = Config::DirectBoot != 0; + + res = VerifyDSBIOS(); + if (res != Load_OK) return res; + + res = VerifyDSFirmware(); + if (res != Load_OK) + { + if (res == Load_FirmwareNotBootable) + directboot = true; + else + return res; + } + + SavestateLoaded = false; + + if (ROMPath[ROMSlot_NDS][0] == '\0') + { + NDS::LoadBIOS(); + } + else + { + SetupSRAMPath(0); + if (!NDS::LoadROM(ROMPath[ROMSlot_NDS], SRAMPath[ROMSlot_NDS], directboot)) + return Load_ROMLoadError; + } + + if (ROMPath[ROMSlot_GBA][0] != '\0') + { + SetupSRAMPath(1); + if (!NDS::LoadGBAROM(ROMPath[ROMSlot_GBA], SRAMPath[ROMSlot_GBA])) + return Load_ROMLoadError; + } + + return Load_OK; +} + // SAVESTATE TODO // * configurable paths. not everyone wants their ROM directory to be polluted, I guess. diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 35eac70..a73362d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -113,6 +113,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); + connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); + connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); emit windowEmuStop(); } @@ -152,14 +154,10 @@ void EmuThread::run() { Input::Process(); - /*if (Input::HotkeyPressed(HK_FastForwardToggle)) - { - Config::LimitFPS = !Config::LimitFPS; - // TODO: reflect in UI! - }*/ + if (Input::HotkeyPressed(HK_FastForwardToggle)) emit windowLimitFPSChange(); - //if (Input::HotkeyPressed(HK_Pause)) uiQueueMain(TogglePause, NULL); - //if (Input::HotkeyPressed(HK_Reset)) uiQueueMain(Reset, NULL); + if (Input::HotkeyPressed(HK_Pause)) emit windowEmuPause(); + if (Input::HotkeyPressed(HK_Reset)) emit windowEmuReset(); if (GBACart::CartInserted && GBACart::HasSolarSensor) { @@ -318,18 +316,15 @@ void EmuThread::run() lastmeasuretick = lasttick; fpslimitcount = 0; - if (EmuRunning == 2) + /*if (Screen_UseGL) { - /*if (Screen_UseGL) - { - uiGLBegin(GLContext); - uiGLMakeContextCurrent(GLContext); - GLScreen_DrawScreen(); - uiGLEnd(GLContext); - } - uiAreaQueueRedrawAll(MainDrawArea);*/ - mainWindow->update(); + uiGLBegin(GLContext); + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + uiGLEnd(GLContext); } + uiAreaQueueRedrawAll(MainDrawArea);*/ + mainWindow->update(); //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); @@ -338,7 +333,7 @@ void EmuThread::run() sprintf(melontitle, "melonDS " MELONDS_VERSION); changeWindowTitle(melontitle); - SDL_Delay(100); + SDL_Delay(75); } } @@ -375,12 +370,11 @@ void EmuThread::emuRun() if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } -void EmuThread::emuPause(bool refresh) +void EmuThread::emuPause() { - int status = refresh ? 2:3; PrevEmuStatus = EmuRunning; - EmuRunning = status; - while (EmuStatus != status); + EmuRunning = 2; + while (EmuStatus != 2); //emit windowEmuPause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); @@ -774,7 +768,7 @@ void MainWindow::dropEvent(QDropEvent* event) QList urls = event->mimeData()->urls(); if (urls.count() > 1) return; // not handling more than one file at once - emuThread->emuPause(true); + emuThread->emuPause(); QString filename = urls.at(0).toLocalFile(); QString ext = filename.right(3); @@ -836,7 +830,7 @@ QString MainWindow::loadErrorStr(int error) void MainWindow::onOpenFile() { - emuThread->emuPause(true); + emuThread->emuPause(); QString filename = QFileDialog::getOpenFileName(this, "Open ROM", @@ -897,7 +891,7 @@ void MainWindow::onBootFirmware() { // TODO: check the whole GBA cart shito - emuThread->emuPause(true); + emuThread->emuPause(); int res = Frontend::LoadBIOS(); if (res != Frontend::Load_OK) @@ -917,7 +911,7 @@ void MainWindow::onSaveState() { int slot = ((QAction*)sender())->data().toInt(); - emuThread->emuPause(true); + emuThread->emuPause(); char filename[1024]; if (slot > 0) @@ -958,7 +952,7 @@ void MainWindow::onLoadState() { int slot = ((QAction*)sender())->data().toInt(); - emuThread->emuPause(true); + emuThread->emuPause(); char filename[1024]; if (slot > 0) @@ -1006,7 +1000,7 @@ void MainWindow::onLoadState() void MainWindow::onUndoStateLoad() { - emuThread->emuPause(true); + emuThread->emuPause(); Frontend::UndoStateLoad(); emuThread->emuUnpause(); } @@ -1019,9 +1013,11 @@ void MainWindow::onQuit() void MainWindow::onPause(bool checked) { - if (emuThread->emuIsRunning()) + if (!RunningSomething) return; + + if (checked) { - emuThread->emuPause(true); + emuThread->emuPause(); } else { @@ -1031,7 +1027,26 @@ void MainWindow::onPause(bool checked) void MainWindow::onReset() { - // + if (!RunningSomething) return; + + emuThread->emuPause(); + + actUndoStateLoad->setEnabled(false); + + int res = Frontend::Reset(); + if (res != Frontend::Load_OK) + { + QMessageBox::critical(this, + "melonDS", + loadErrorStr(res)); + emuThread->emuUnpause(); + } + else + { + // OSD::AddMessage(0, "Reset"); + + emuThread->emuRun(); + } } void MainWindow::onStop() @@ -1047,7 +1062,7 @@ void MainWindow::onOpenEmuSettings() void MainWindow::onOpenInputConfig() { - emuThread->emuPause(true); + emuThread->emuPause(); InputConfigDialog* dlg = InputConfigDialog::openDlg(this); connect(dlg, &InputConfigDialog::finished, this, &MainWindow::onInputConfigFinished); @@ -1143,7 +1158,7 @@ void MainWindow::onEmuStart() } actSaveState[0]->setEnabled(true); actLoadState[0]->setEnabled(true); - actUndoStateLoad->setEnabled(true); + actUndoStateLoad->setEnabled(false); actPause->setEnabled(true); actPause->setChecked(false); @@ -1165,16 +1180,6 @@ void MainWindow::onEmuStop() actStop->setEnabled(false); } -void MainWindow::onEmuPause() -{ - // -} - -void MainWindow::onEmuUnpause() -{ - // -} - int main(int argc, char** argv) @@ -1281,7 +1286,7 @@ int main(int argc, char** argv) emuThread = new EmuThread(); emuThread->start(); - emuThread->emuPause(true); + emuThread->emuPause(); if (argc > 1) { diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index b478f4e..22f045f 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -38,7 +38,7 @@ public: // to be called from the UI thread void emuRun(); - void emuPause(bool refresh); + void emuPause(); void emuUnpause(); void emuStop(); @@ -49,7 +49,10 @@ signals: void windowEmuStart(); void windowEmuStop(); - void windowPauseToggle(); + void windowEmuPause(); + void windowEmuReset(); + + void windowLimitFPSChange(); private: volatile int EmuStatus; @@ -130,14 +133,13 @@ private slots: void onEmuStart(); void onEmuStop(); - void onEmuPause(); - void onEmuUnpause(); private: QString loadErrorStr(int error); MainWindowPanel* panel; +public: QAction* actOpenROM; QAction* actBootFirmware; QAction* actSaveState[9]; -- cgit v1.2.3 From a9b275bc253510d77b8b6fcd80e6d24b56bc8680 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 22:58:04 +0200 Subject: reimplement Stop --- src/SPU.cpp | 3 +++ src/frontend/FrontendUtil.h | 4 ++++ src/frontend/Util_ROM.cpp | 14 ++++++++++++++ src/frontend/qt_sdl/Platform.cpp | 4 ++-- src/frontend/qt_sdl/main.cpp | 37 +++++++++++++++++++++++++++++++------ 5 files changed, 54 insertions(+), 8 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/SPU.cpp b/src/SPU.cpp index 710533e..1ebfd4c 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -116,6 +116,9 @@ void Reset() void Stop() { memset(OutputBuffer, 0, 2*OutputBufferSize*2); + + OutputReadOffset = 0; + OutputWriteOffset = 0; } void DoSavestate(Savestate* file) diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index d838b63..faa29de 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -65,6 +65,10 @@ int LoadBIOS(); // note: loading a ROM to the NDS slot resets emulation int LoadROM(const char* file, int slot); +// unload the ROM loaded in the specified cart slot +// simulating ejection of the cartridge +void UnloadROM(int slot); + // reset execution of the current ROM int Reset(); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index e13eb2c..ec3186a 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -202,6 +202,20 @@ int LoadROM(const char* file, int slot) } } +void UnloadROM(int slot) +{ + if (slot == ROMSlot_NDS) + { + // TODO! + } + else if (slot == ROMSlot_GBA) + { + GBACart::Eject(); + } + + ROMPath[slot][0] = '\0'; +} + int Reset() { int res; diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 6a5b466..dd838d7 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -55,7 +55,7 @@ char* EmuDirectory; -void Stop(bool internal); +void emuStop(); namespace Platform @@ -133,7 +133,7 @@ void DeInit() void StopEmu() { - //Stop(true); + emuStop(); } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index a73362d..67272af 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -115,8 +115,6 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); - - emit windowEmuStop(); } void EmuThread::run() @@ -140,7 +138,6 @@ void EmuThread::run() } Input::Init(); - /*Touching = false;*/ u32 nframes = 0; u32 starttick = SDL_GetTicks(); @@ -376,7 +373,6 @@ void EmuThread::emuPause() EmuRunning = 2; while (EmuStatus != 2); - //emit windowEmuPause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); } @@ -384,7 +380,6 @@ void EmuThread::emuUnpause() { EmuRunning = PrevEmuStatus; - //emit windowEmuUnpause(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); } @@ -703,6 +698,18 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) panel->setMinimumSize(256, 384); + for (int i = 0; i < 9; i++) + { + actSaveState[i]->setEnabled(false); + actLoadState[i]->setEnabled(false); + } + actUndoStateLoad->setEnabled(false); + + actPause->setEnabled(false); + actReset->setEnabled(false); + actStop->setEnabled(false); + + actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0); actScreenRotation[Config::ScreenRotation]->setChecked(true); @@ -1051,7 +1058,10 @@ void MainWindow::onReset() void MainWindow::onStop() { - // + if (!RunningSomething) return; + + emuThread->emuPause(); + NDS::Stop(); } @@ -1168,6 +1178,8 @@ void MainWindow::onEmuStart() void MainWindow::onEmuStop() { + emuThread->emuPause(); + for (int i = 0; i < 9; i++) { actSaveState[i]->setEnabled(false); @@ -1181,6 +1193,19 @@ void MainWindow::onEmuStop() } +void emuStop() +{ + RunningSomething = false; + + Frontend::UnloadROM(Frontend::ROMSlot_NDS); + Frontend::UnloadROM(Frontend::ROMSlot_GBA); + + emit emuThread->windowEmuStop(); + + //OSD::AddMessage(0xFFC040, "Shutdown"); +} + + int main(int argc, char** argv) { -- cgit v1.2.3 From 9e43c85b4d86cdb79242045c5fcf3929e3568322 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 23:55:18 +0200 Subject: hook up microphone shit. I did my best. --- src/frontend/FrontendUtil.h | 11 +++ src/frontend/Util_Audio.cpp | 64 +++++++++++++++- src/frontend/qt_sdl/main.cpp | 177 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 247 insertions(+), 5 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index faa29de..6a6f8ea 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -101,6 +101,17 @@ int AudioOut_GetNumSamples(int outlen); // note: this assumes the output buffer is interleaved stereo void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen); +// feed silence to the microphone input +void Mic_FeedSilence(); + +// feed random noise to the microphone input +void Mic_FeedNoise(); + +// feed an external buffer to the microphone input +// buffer should be mono +void Mic_FeedExternalBuffer(); +void Mic_SetExternalBuffer(s16* buffer, u32 len); + } #endif // FRONTENDUTIL_H diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp index fe0ecab..2088efe 100644 --- a/src/frontend/Util_Audio.cpp +++ b/src/frontend/Util_Audio.cpp @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -26,7 +27,6 @@ #include "Platform.h" #include "NDS.h" -#include "GBACart.h" namespace Frontend @@ -35,13 +35,22 @@ namespace Frontend int AudioOut_Freq; float AudioOut_SampleFrac; +s16* MicBuffer; +u32 MicBufferLength; +u32 MicBufferReadPos; + void Init_Audio(int outputfreq) { AudioOut_Freq = outputfreq; AudioOut_SampleFrac = 0; + + MicBuffer = nullptr; + MicBufferLength = 0; + MicBufferReadPos = 0; } + int AudioOut_GetNumSamples(int outlen) { float f_len_in = (outlen * 32823.6328125) / (float)AudioOut_Freq; @@ -74,4 +83,57 @@ void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen) } } + +void Mic_FeedSilence() +{ + MicBufferReadPos = 0; + NDS::MicInputFrame(NULL, 0); +} + +void Mic_FeedNoise() +{ + // note: DS games seem to expect very saturated 'blowing into mic' noise + + s16 tmp[735]; + + for (int i = 0; i < 735; i++) + { + int val = rand() >> 8; + if (val < -0x8000) val = -0x8000; + else if (val > 0x7FFF) val = 0x7FFF; + + tmp[i] = val; + } + + NDS::MicInputFrame(tmp, 735); +} + +void Mic_FeedExternalBuffer() +{ + if (!MicBuffer) return Mic_FeedSilence(); + + if ((MicBufferReadPos + 735) > MicBufferLength) + { + s16 tmp[735]; + u32 len1 = MicBufferLength - MicBufferReadPos; + memcpy(&tmp[0], &MicBuffer[MicBufferReadPos], len1*sizeof(s16)); + memcpy(&tmp[len1], &MicBuffer[0], (735 - len1)*sizeof(s16)); + + NDS::MicInputFrame(tmp, 735); + MicBufferReadPos = 735 - len1; + } + else + { + NDS::MicInputFrame(&MicBuffer[MicBufferReadPos], 735); + MicBufferReadPos += 735; + } +} + +void Mic_SetExternalBuffer(s16* buffer, u32 len) +{ + MicBuffer = buffer; + MicBufferLength = len; + MicBufferReadPos = 0; +} + } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 67272af..1615fa3 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -66,6 +66,13 @@ int audioFreq; SDL_cond* audioSync; SDL_mutex* audioSyncLock; +SDL_AudioDeviceID micDevice; +s16 micExtBuffer[2048]; +u32 micExtBufferWritePos; + +u32 micWavLength; +s16* micWavBuffer; + void audioCallback(void* data, Uint8* stream, int len) { @@ -104,6 +111,133 @@ void audioCallback(void* data, Uint8* stream, int len) } +void micLoadWav(const char* name) +{ + SDL_AudioSpec format; + memset(&format, 0, sizeof(SDL_AudioSpec)); + + if (micWavBuffer) delete[] micWavBuffer; + micWavBuffer = nullptr; + micWavLength = 0; + + u8* buf; + u32 len; + if (!SDL_LoadWAV(name, &format, &buf, &len)) + return; + + const u64 dstfreq = 44100; + + if (format.format == AUDIO_S16 || format.format == AUDIO_U16) + { + int srcinc = format.channels; + len /= (2 * srcinc); + + micWavLength = (len * dstfreq) / format.freq; + if (micWavLength < 735) micWavLength = 735; + micWavBuffer = new s16[micWavLength]; + + float res_incr = len / (float)micWavLength; + float res_timer = 0; + int res_pos = 0; + + for (int i = 0; i < micWavLength; i++) + { + u16 val = ((u16*)buf)[res_pos]; + if (SDL_AUDIO_ISUNSIGNED(format.format)) val ^= 0x8000; + + micWavBuffer[i] = val; + + res_timer += res_incr; + while (res_timer >= 1.0) + { + res_timer -= 1.0; + res_pos += srcinc; + } + } + } + else if (format.format == AUDIO_S8 || format.format == AUDIO_U8) + { + int srcinc = format.channels; + len /= srcinc; + + micWavLength = (len * dstfreq) / format.freq; + if (micWavLength < 735) micWavLength = 735; + micWavBuffer = new s16[micWavLength]; + + float res_incr = len / (float)micWavLength; + float res_timer = 0; + int res_pos = 0; + + for (int i = 0; i < micWavLength; i++) + { + u16 val = buf[res_pos] << 8; + if (SDL_AUDIO_ISUNSIGNED(format.format)) val ^= 0x8000; + + micWavBuffer[i] = val; + + res_timer += res_incr; + while (res_timer >= 1.0) + { + res_timer -= 1.0; + res_pos += srcinc; + } + } + } + else + printf("bad WAV format %08X\n", format.format); + + SDL_FreeWAV(buf); +} + +void micCallback(void* data, Uint8* stream, int len) +{ + s16* input = (s16*)stream; + len /= sizeof(s16); + + int maxlen = sizeof(micExtBuffer) / sizeof(s16); + + if ((micExtBufferWritePos + len) > maxlen) + { + u32 len1 = maxlen - micExtBufferWritePos; + memcpy(&micExtBuffer[micExtBufferWritePos], &input[0], len1*sizeof(s16)); + memcpy(&micExtBuffer[0], &input[len1], (len - len1)*sizeof(s16)); + micExtBufferWritePos = len - len1; + } + else + { + memcpy(&micExtBuffer[micExtBufferWritePos], input, len*sizeof(s16)); + micExtBufferWritePos += len; + } +} + +void micProcess() +{ + int type = Config::MicInputType; + bool cmd = Input::HotkeyDown(HK_Mic); + + if (type != 1 && !cmd) + { + type = 0; + } + + switch (type) + { + case 0: // no mic + Frontend::Mic_FeedSilence(); + break; + + case 1: // host mic + case 3: // WAV + Frontend::Mic_FeedExternalBuffer(); + break; + + case 2: // white noise + Frontend::Mic_FeedNoise(); + break; + } +} + + EmuThread::EmuThread(QObject* parent) : QThread(parent) { EmuStatus = 0; @@ -189,9 +323,9 @@ void EmuThread::run() } // microphone input - /*FeedMicInput(); + micProcess(); - if (Screen_UseGL) + /*if (Screen_UseGL) { uiGLBegin(GLContext); uiGLMakeContextCurrent(GLContext); @@ -365,6 +499,7 @@ void EmuThread::emuRun() // checkme emit windowEmuStart(); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); + if (micDevice) SDL_PauseAudioDevice(micDevice, 0); } void EmuThread::emuPause() @@ -374,6 +509,7 @@ void EmuThread::emuPause() while (EmuStatus != 2); if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); + if (micDevice) SDL_PauseAudioDevice(micDevice, 1); } void EmuThread::emuUnpause() @@ -381,6 +517,7 @@ void EmuThread::emuUnpause() EmuRunning = PrevEmuStatus; if (audioDevice) SDL_PauseAudioDevice(audioDevice, 0); + if (micDevice) SDL_PauseAudioDevice(micDevice, 0); } void EmuThread::emuStop() @@ -388,6 +525,7 @@ void EmuThread::emuStop() EmuRunning = 0; if (audioDevice) SDL_PauseAudioDevice(audioDevice, 1); + if (micDevice) SDL_PauseAudioDevice(micDevice, 1); } bool EmuThread::emuIsRunning() @@ -1300,9 +1438,40 @@ int main(int argc, char** argv) SDL_PauseAudioDevice(audioDevice, 1); } + memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); + whatIwant.freq = 44100; + whatIwant.format = AUDIO_S16LSB; + whatIwant.channels = 1; + whatIwant.samples = 1024; + whatIwant.callback = micCallback; + micDevice = SDL_OpenAudioDevice(NULL, 1, &whatIwant, &whatIget, 0); + if (!micDevice) + { + printf("Mic init failed: %s\n", SDL_GetError()); + } + else + { + SDL_PauseAudioDevice(micDevice, 1); + } + + + memset(micExtBuffer, 0, sizeof(micExtBuffer)); + micExtBufferWritePos = 0; + micWavBuffer = nullptr; + Frontend::Init_ROM(); Frontend::Init_Audio(audioFreq); + if (Config::MicInputType == 1) + { + Frontend::Mic_SetExternalBuffer(micExtBuffer, sizeof(micExtBuffer)/sizeof(s16)); + } + else if (Config::MicInputType == 3) + { + micLoadWav(Config::MicWavPath); + Frontend::Mic_SetExternalBuffer(micWavBuffer, micWavLength); + } + Input::JoystickID = Config::JoystickID; Input::OpenJoystick(); @@ -1349,12 +1518,12 @@ int main(int argc, char** argv) Input::CloseJoystick(); if (audioDevice) SDL_CloseAudioDevice(audioDevice); - //if (MicDevice) SDL_CloseAudioDevice(MicDevice); + if (micDevice) SDL_CloseAudioDevice(micDevice); SDL_DestroyCond(audioSync); SDL_DestroyMutex(audioSyncLock); - //if (MicWavBuffer) delete[] MicWavBuffer; + if (micWavBuffer) delete[] micWavBuffer; Config::Save(); -- cgit v1.2.3 From 108647e03320788729bcfa229d81c0f7678fe1fb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 21 May 2020 01:39:41 +0200 Subject: * add audio settings dialog * attempt at betterer mic noise that doesn't work worth a damn --- src/frontend/Util_Audio.cpp | 8 +- src/frontend/qt_sdl/AudioSettingsDialog.cpp | 103 ++++++++++++++++++ src/frontend/qt_sdl/AudioSettingsDialog.h | 69 ++++++++++++ src/frontend/qt_sdl/AudioSettingsDialog.ui | 162 ++++++++++++++++++++++++++++ src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/EmuSettingsDialog.cpp | 1 + src/frontend/qt_sdl/EmuSettingsDialog.ui | 15 +-- src/frontend/qt_sdl/main.cpp | 24 ++++- src/frontend/qt_sdl/main.h | 1 + 9 files changed, 366 insertions(+), 18 deletions(-) create mode 100644 src/frontend/qt_sdl/AudioSettingsDialog.cpp create mode 100644 src/frontend/qt_sdl/AudioSettingsDialog.h create mode 100644 src/frontend/qt_sdl/AudioSettingsDialog.ui (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp index 2088efe..3f03810 100644 --- a/src/frontend/Util_Audio.cpp +++ b/src/frontend/Util_Audio.cpp @@ -93,14 +93,16 @@ void Mic_FeedSilence() void Mic_FeedNoise() { // note: DS games seem to expect very saturated 'blowing into mic' noise + s16 noisesample[8] = {-0x8000, -0x8000, 0x7FFF, -0x8000, 0x7FFF, 0x7FFF, -0x8000, 0x7FFF}; + int j = 0; s16 tmp[735]; for (int i = 0; i < 735; i++) { - int val = rand() >> 8; - if (val < -0x8000) val = -0x8000; - else if (val > 0x7FFF) val = 0x7FFF; + int val = noisesample[j]; + j++; + if (j >= 8) j = rand() & 7; tmp[i] = val; } diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.cpp b/src/frontend/qt_sdl/AudioSettingsDialog.cpp new file mode 100644 index 0000000..2ff5307 --- /dev/null +++ b/src/frontend/qt_sdl/AudioSettingsDialog.cpp @@ -0,0 +1,103 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include + +#include "types.h" +#include "Platform.h" +#include "Config.h" +#include "PlatformConfig.h" + +#include "AudioSettingsDialog.h" +#include "ui_AudioSettingsDialog.h" + + +AudioSettingsDialog* AudioSettingsDialog::currentDlg = nullptr; + +extern char* EmuDirectory; + + +AudioSettingsDialog::AudioSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AudioSettingsDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + oldVolume = Config::AudioVolume; + + ui->slVolume->setValue(Config::AudioVolume); + + grpMicMode = new QButtonGroup(this); + grpMicMode->addButton(ui->rbMicNone, 0); + grpMicMode->addButton(ui->rbMicExternal, 1); + grpMicMode->addButton(ui->rbMicNoise, 2); + grpMicMode->addButton(ui->rbMicWav, 3); + connect(grpMicMode, SIGNAL(buttonClicked(int)), this, SLOT(onChangeMicMode(int))); + grpMicMode->button(Config::MicInputType)->setChecked(true); + + ui->txtMicWavPath->setText(Config::MicWavPath); + + bool iswav = (Config::MicInputType == 3); + ui->txtMicWavPath->setEnabled(iswav); + ui->btnMicWavBrowse->setEnabled(iswav); +} + +AudioSettingsDialog::~AudioSettingsDialog() +{ + delete ui; +} + +void AudioSettingsDialog::on_AudioSettingsDialog_accepted() +{ + Config::MicInputType = grpMicMode->checkedId(); + strncpy(Config::MicWavPath, ui->txtMicWavPath->text().toStdString().c_str(), 1023); Config::MicWavPath[1023] = '\0'; + Config::Save(); + + closeDlg(); +} + +void AudioSettingsDialog::on_AudioSettingsDialog_rejected() +{ + Config::AudioVolume = oldVolume; + + closeDlg(); +} + +void AudioSettingsDialog::on_slVolume_valueChanged(int val) +{ + Config::AudioVolume = val; +} + +void AudioSettingsDialog::onChangeMicMode(int mode) +{ + bool iswav = (mode == 3); + ui->txtMicWavPath->setEnabled(iswav); + ui->btnMicWavBrowse->setEnabled(iswav); +} + +void AudioSettingsDialog::on_btnMicWavBrowse_clicked() +{ + QString file = QFileDialog::getOpenFileName(this, + "Select WAV file...", + EmuDirectory, + "WAV files (*.wav);;Any file (*.*)"); + + if (file.isEmpty()) return; + + ui->txtMicWavPath->setText(file); +} diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.h b/src/frontend/qt_sdl/AudioSettingsDialog.h new file mode 100644 index 0000000..3bafa30 --- /dev/null +++ b/src/frontend/qt_sdl/AudioSettingsDialog.h @@ -0,0 +1,69 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef AUDIOSETTINGSDIALOG_H +#define AUDIOSETTINGSDIALOG_H + +#include +#include + +namespace Ui { class AudioSettingsDialog; } +class AudioSettingsDialog; + +class AudioSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AudioSettingsDialog(QWidget* parent); + ~AudioSettingsDialog(); + + static AudioSettingsDialog* currentDlg; + static AudioSettingsDialog* openDlg(QWidget* parent) + { + if (currentDlg) + { + currentDlg->activateWindow(); + return currentDlg; + } + + currentDlg = new AudioSettingsDialog(parent); + currentDlg->show(); + return currentDlg; + } + static void closeDlg() + { + currentDlg = nullptr; + } + +private slots: + void on_AudioSettingsDialog_accepted(); + void on_AudioSettingsDialog_rejected(); + + void on_slVolume_valueChanged(int val); + void onChangeMicMode(int mode); + void on_btnMicWavBrowse_clicked(); + +private: + Ui::AudioSettingsDialog* ui; + + int oldVolume; + QButtonGroup* grpMicMode; +}; + +#endif // AUDIOSETTINGSDIALOG_H diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.ui b/src/frontend/qt_sdl/AudioSettingsDialog.ui new file mode 100644 index 0000000..b6c215e --- /dev/null +++ b/src/frontend/qt_sdl/AudioSettingsDialog.ui @@ -0,0 +1,162 @@ + + + AudioSettingsDialog + + + + 0 + 0 + 482 + 230 + + + + Audio settings - melonDS + + + + + + Audio output + + + + + + Volume: + + + + + + + <html><head/><body><p>Controls the volume of the audio output.</p></body></html> + + + 256 + + + 16 + + + Qt::Horizontal + + + + + + + + + + Microphone input + + + + + + + 290 + 0 + + + + + + + + <html><head/><body><p>Forward a WAV file to the emulated microphone.</p></body></html> + + + WAV file: + + + + + + + Browse... + + + + + + + <html><head/><body><p>Input from an external microphone, if available, will be forwarded to the emulated microphone.</p></body></html> + + + External microphone + + + + + + + <html><head/><body><p>Noise will be forwarded to the emulated microphone, simulating blowing into the microphone.</p></body></html> + + + White noise + + + + + + + <html><head/><body><p>No microphone input.</p></body></html> + + + None + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AudioSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AudioSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index c3d0959..caa78e9 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -4,6 +4,7 @@ SET(SOURCES_QT_SDL main.cpp EmuSettingsDialog.cpp InputConfigDialog.cpp + AudioSettingsDialog.cpp Input.cpp Platform.cpp PlatformConfig.cpp diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 6264d91..5c2efc0 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -100,6 +100,7 @@ void EmuSettingsDialog::on_EmuSettingsDialog_accepted() strncpy(Config::BIOS7Path, ui->txtBIOS7Path->text().toStdString().c_str(), 1023); Config::BIOS7Path[1023] = '\0'; strncpy(Config::FirmwarePath, ui->txtFirmwarePath->text().toStdString().c_str(), 1023); Config::FirmwarePath[1023] = '\0'; Config::DirectBoot = ui->chkDirectBoot->isChecked() ? 1:0; + Config::Save(); closeDlg(); } diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.ui b/src/frontend/qt_sdl/EmuSettingsDialog.ui index e4deaba..c70c3a2 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.ui +++ b/src/frontend/qt_sdl/EmuSettingsDialog.ui @@ -7,7 +7,7 @@ 0 0 490 - 243 + 217 @@ -138,19 +138,6 @@ - - - - Qt::Vertical - - - - 20 - 20 - - - - diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 1615fa3..245324f 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -36,6 +36,7 @@ #include "Input.h" #include "EmuSettingsDialog.h" #include "InputConfigDialog.h" +#include "AudioSettingsDialog.h" #include "types.h" #include "version.h" @@ -1228,7 +1229,27 @@ void MainWindow::onOpenVideoSettings() void MainWindow::onOpenAudioSettings() { - // + AudioSettingsDialog* dlg = AudioSettingsDialog::openDlg(this); + connect(dlg, &AudioSettingsDialog::finished, this, &MainWindow::onAudioSettingsFinished); +} + +void MainWindow::onAudioSettingsFinished(int res) +{ + if (Config::MicInputType == 3) + { + micLoadWav(Config::MicWavPath); + Frontend::Mic_SetExternalBuffer(micWavBuffer, micWavLength); + } + else + { + delete[] micWavBuffer; + micWavBuffer = nullptr; + + if (Config::MicInputType == 1) + Frontend::Mic_SetExternalBuffer(micExtBuffer, sizeof(micExtBuffer)/sizeof(s16)); + else + Frontend::Mic_SetExternalBuffer(NULL, 0); + } } void MainWindow::onOpenWifiSettings() @@ -1376,6 +1397,7 @@ int main(int argc, char** argv) #define SANITIZE(var, min, max) { if (var < min) var = min; else if (var > max) var = max; } SANITIZE(Config::AudioVolume, 0, 256); + SANITIZE(Config::MicInputType, 0, 3); SANITIZE(Config::ScreenRotation, 0, 3); SANITIZE(Config::ScreenGap, 0, 500); SANITIZE(Config::ScreenLayout, 0, 2); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 22f045f..7051a08 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -116,6 +116,7 @@ private slots: void onInputConfigFinished(int res); void onOpenVideoSettings(); void onOpenAudioSettings(); + void onAudioSettingsFinished(int res); void onOpenWifiSettings(); void onChangeSavestateSRAMReloc(bool checked); void onChangeScreenSize(); -- cgit v1.2.3 From 8f9369beebf60f3b10d75f50507b194f2ccdaceb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 21 May 2020 18:43:07 +0200 Subject: add screen layout system --- src/frontend/FrontendUtil.h | 26 +++ src/frontend/Util_Video.cpp | 334 +++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/main.cpp | 213 ++++++++++++++++++----- src/frontend/qt_sdl/main.h | 17 +- 5 files changed, 545 insertions(+), 46 deletions(-) create mode 100644 src/frontend/Util_Video.cpp (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 6a6f8ea..1fd7329 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -89,6 +89,32 @@ bool SaveState(const char* filename); void UndoStateLoad(); +// setup the display layout based on the provided display size and parameters +// * screenWidth/screenHeight: size of the host display +// * screenLayout: how the DS screens are laid out +// 0 = natural (top screen above bottom screen always) +// 1 = vertical +// 2 = horizontal +// * rotation: angle at which the DS screens are presented: 0/1/2/3 = 0/90/180/270 +// * sizing: how the display size is shared between the two screens +// 0 = even (both screens get same size) +// 1 = emphasize top screen (make top screen as big as possible, fit bottom screen in remaining space) +// 2 = emphasize bottom screen +// * screenGap: size of the gap between the two screens +// * integerScale: force screens to be scaled up at integer scaling factors +void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale); + +// get a 2x3 transform matrix for the given screen (0=top, 1=bottom) +// note: the transform assumes an origin point at the top left of the display, +// X going left and Y going down +// for each screen the source coordinates should be (0,0) and (256,192) +float* GetScreenTransform(int screen); + +// de-transform the provided host display coordinates to get coordinates +// on the bottom screen +void GetTouchCoords(int& x, int& y); + + // initialize the audio utility void Init_Audio(int outputfreq); diff --git a/src/frontend/Util_Video.cpp b/src/frontend/Util_Video.cpp new file mode 100644 index 0000000..cd4e21c --- /dev/null +++ b/src/frontend/Util_Video.cpp @@ -0,0 +1,334 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include +#include +#include + +#include "FrontendUtil.h" + + +namespace Frontend +{ + +float TopScreenMtx[6]; +float BotScreenMtx[6]; +float TouchMtx[6]; + + +void M23_Identity(float* m) +{ + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + m[4] = 0; m[5] = 0; +} + +void M23_Scale(float* m, float s) +{ + m[0] *= s; m[1] *= s; + m[2] *= s; m[3] *= s; + m[4] *= s; m[5] *= s; +} + +void M23_RotateFast(float* m, int angle) +{ + if (angle == 0) return; + + float temp[4]; memcpy(temp, m, sizeof(float)*4); + + switch (angle) + { + case 1: // 90 + m[0] = temp[2]; + m[1] = temp[3]; + m[2] = -temp[0]; + m[3] = -temp[1]; + break; + + case 2: // 180 + m[0] = -temp[0]; + m[1] = -temp[1]; + m[2] = -temp[2]; + m[3] = -temp[3]; + break; + + case 3: // 270 + m[0] = -temp[2]; + m[1] = -temp[3]; + m[2] = temp[0]; + m[3] = temp[1]; + break; + } +} + +void M23_Translate(float* m, float tx, float ty) +{ + m[4] += tx; + m[5] += ty; +} + +void M23_Multiply(float* m, float* _a, float* _b) +{ + float a[6]; memcpy(a, _a, 6*sizeof(float)); + float b[6]; memcpy(b, _b, 6*sizeof(float)); + + m[0] = (a[0] * b[0]) + (a[2] * b[1]); + m[1] = (a[1] * b[0]) + (a[3] * b[1]); + + m[2] = (a[0] * b[2]) + (a[2] * b[3]); + m[3] = (a[1] * b[2]) + (a[3] * b[3]); + + m[4] = (a[0] * b[4]) + (a[2] * b[5]) + a[4]; + m[5] = (a[1] * b[4]) + (a[3] * b[5]) + a[5]; +} + +void M23_Transform(float* m, float& x, float& y) +{ + float vx = x; + float vy = y; + + x = (vx * m[0]) + (vy * m[2]) + m[4]; + y = (vx * m[1]) + (vy * m[3]) + m[5]; +} + + +void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale) +{ + float refpoints[4][2] = + { + {0, 0}, {256, 192}, + {0, 0}, {256, 192} + }; + + int layout = screenLayout == 0 + ? ((rotation % 2 == 0) ? 0 : 1) + : screenLayout - 1; + + float botScale = 1; + float botTrans[4] = {0}; + + M23_Identity(TopScreenMtx); + M23_Identity(BotScreenMtx); + + M23_Translate(TopScreenMtx, -256/2, -192/2); + M23_Translate(BotScreenMtx, -256/2, -192/2); + + // rotation + { + float rotmtx[6]; + M23_Identity(rotmtx); + + M23_RotateFast(rotmtx, rotation); + M23_Multiply(TopScreenMtx, rotmtx, TopScreenMtx); + M23_Multiply(BotScreenMtx, rotmtx, BotScreenMtx); + + M23_Transform(TopScreenMtx, refpoints[0][0], refpoints[0][1]); + M23_Transform(TopScreenMtx, refpoints[1][0], refpoints[1][1]); + M23_Transform(BotScreenMtx, refpoints[2][0], refpoints[2][1]); + M23_Transform(BotScreenMtx, refpoints[3][0], refpoints[3][1]); + } + + // move screens apart + { + int idx = layout == 0 ? 1 : 0; + float offset = + (((layout == 0 && (rotation % 2 == 0)) || (layout == 1 && (rotation % 2 == 1)) + ? 192.f : 256.f) + + screenGap) / 2.f; + if (rotation == 1 || rotation == 2) + offset *= -1.f; + + M23_Translate(TopScreenMtx, (idx==0)?-offset:0, (idx==1)?-offset:0); + M23_Translate(BotScreenMtx, (idx==0)?offset:0, (idx==1)?offset:0); + + refpoints[0][idx] -= offset; + refpoints[1][idx] -= offset; + refpoints[2][idx] += offset; + refpoints[3][idx] += offset; + + botTrans[idx] = offset; + } + + // scale + { + if (sizing == 0) + { + float minX = refpoints[0][0], maxX = minX; + float minY = refpoints[0][1], maxY = minY; + + for (int i = 1; i < 4; i++) + { + minX = std::min(minX, refpoints[i][0]); + minY = std::min(minY, refpoints[i][1]); + maxX = std::max(maxX, refpoints[i][0]); + maxY = std::max(maxY, refpoints[i][1]); + } + + float hSize = maxX - minX; + float vSize = maxY - minY; + + // scale evenly + float scale = std::min(screenWidth / hSize, screenHeight / vSize); + + if (integerScale) + scale = floor(scale); + + M23_Scale(TopScreenMtx, scale); + M23_Scale(BotScreenMtx, scale); + + for (int i = 0; i < 4; i++) + { + refpoints[i][0] *= scale; + refpoints[i][1] *= scale; + } + + botScale = scale; + } + else + { + int primOffset = (sizing == 1) ? 0 : 2; + int secOffset = (sizing == 1) ? 2 : 0; + float* primMtx = (sizing == 1) ? TopScreenMtx : BotScreenMtx; + float* secMtx = (sizing == 1) ? BotScreenMtx : TopScreenMtx; + + float primMinX = refpoints[primOffset][0], primMaxX = primMinX; + float primMinY = refpoints[primOffset][1], primMaxY = primMinY; + float secMinX = refpoints[secOffset][0], secMaxX = secMinX; + float secMinY = refpoints[secOffset][1], secMaxY = secMinY; + + primMinX = std::min(primMinX, refpoints[primOffset+1][0]); + primMinY = std::min(primMinY, refpoints[primOffset+1][1]); + primMaxX = std::max(primMaxX, refpoints[primOffset+1][0]); + primMaxY = std::max(primMaxY, refpoints[primOffset+1][1]); + + secMinX = std::min(secMinX, refpoints[secOffset+1][0]); + secMinY = std::min(secMinY, refpoints[secOffset+1][1]); + secMaxX = std::max(secMaxX, refpoints[secOffset+1][0]); + secMaxY = std::max(secMaxY, refpoints[secOffset+1][1]); + + float primHSize = layout == 1 ? std::max(primMaxX, -primMinX) : primMaxX - primMinX; + float primVSize = layout == 0 ? std::max(primMaxY, -primMinY) : primMaxY - primMinY; + + float secHSize = layout == 1 ? std::max(secMaxX, -secMinX) : secMaxX - secMinX; + float secVSize = layout == 0 ? std::max(secMaxY, -secMinY) : secMaxY - secMinY; + + float primScale = std::min(screenWidth / primHSize, screenHeight / primVSize); + float secScale = 1.f; + + if (layout == 0) + { + if (screenHeight - primVSize * primScale < secVSize) + primScale = std::min((screenWidth - secHSize) / primHSize, (screenHeight - secVSize) / primVSize); + else + secScale = std::min((screenHeight - primVSize * primScale) / secVSize, screenWidth / secHSize); + } + else + { + if (screenWidth - primHSize * primScale < secHSize) + primScale = std::min((screenWidth - secHSize) / primHSize, (screenHeight - secVSize) / primVSize); + else + secScale = std::min((screenWidth - primHSize * primScale) / secHSize, screenHeight / secVSize); + } + + if (integerScale) + { + primScale = floor(primScale); + secScale = floor(secScale); + } + + M23_Scale(primMtx, primScale); + M23_Scale(secMtx, secScale); + + refpoints[primOffset+0][0] *= primScale; + refpoints[primOffset+0][1] *= primScale; + refpoints[primOffset+1][0] *= primScale; + refpoints[primOffset+1][1] *= primScale; + refpoints[secOffset+0][0] *= secScale; + refpoints[secOffset+0][1] *= secScale; + refpoints[secOffset+1][0] *= secScale; + refpoints[secOffset+1][1] *= secScale; + + botScale = (sizing == 1) ? secScale : primScale; + } + } + + // position + { + float minX = refpoints[0][0], maxX = minX; + float minY = refpoints[0][1], maxY = minY; + + for (int i = 1; i < 4; i++) + { + minX = std::min(minX, refpoints[i][0]); + minY = std::min(minY, refpoints[i][1]); + maxX = std::max(maxX, refpoints[i][0]); + maxY = std::max(maxY, refpoints[i][1]); + } + + float width = maxX - minX; + float height = maxY - minY; + + float tx = (screenWidth/2) - (width/2) - minX; + float ty = (screenHeight/2) - (height/2) - minY; + + M23_Translate(TopScreenMtx, tx, ty); + M23_Translate(BotScreenMtx, tx, ty); + + botTrans[2] = tx; botTrans[3] = ty; + } + + // prepare a 'reverse' matrix for the touchscreen + // this matrix undoes the transforms applied to the bottom screen + // and can be used to calculate touchscreen coords from host screen coords + { + M23_Identity(TouchMtx); + + M23_Translate(TouchMtx, -botTrans[2], -botTrans[3]); + M23_Scale(TouchMtx, 1.f / botScale); + M23_Translate(TouchMtx, -botTrans[0], -botTrans[1]); + + float rotmtx[6]; + M23_Identity(rotmtx); + M23_RotateFast(rotmtx, (4-rotation) & 3); + M23_Multiply(TouchMtx, rotmtx, TouchMtx); + + M23_Translate(TouchMtx, 256/2, 192/2); + } +} + +float* GetScreenTransform(int screen) +{ + if (screen == 0) return TopScreenMtx; + else return BotScreenMtx; +} + +void GetTouchCoords(int& x, int& y) +{ + float vx = x; + float vy = y; + + M23_Transform(TouchMtx, vx, vy); + + x = (int)vx; + y = (int)vy; +} + +} + diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index ffd7d17..7bc81f0 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -10,6 +10,7 @@ SET(SOURCES_QT_SDL PlatformConfig.cpp ../Util_ROM.cpp + ../Util_Video.cpp ../Util_Audio.cpp ../FrontendUtil.h ../mic_blow.h diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 245324f..0d10378 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -62,6 +62,8 @@ bool RunningSomething; MainWindow* mainWindow; EmuThread* emuThread; +int autoScreenSizing = 0; + SDL_AudioDeviceID audioDevice; int audioFreq; SDL_cond* audioSync; @@ -250,16 +252,19 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); + connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged())); } void EmuThread::run() { + u32 mainScreenPos[3]; + NDS::Init(); - /*MainScreenPos[0] = 0; - MainScreenPos[1] = 0; - MainScreenPos[2] = 0; - AutoScreenSizing = 0;*/ + mainScreenPos[0] = 0; + mainScreenPos[1] = 0; + mainScreenPos[2] = 0; + autoScreenSizing = 0; /*if (Screen_UseGL) { @@ -333,14 +338,14 @@ void EmuThread::run() }*/ // auto screen layout - /*{ - MainScreenPos[2] = MainScreenPos[1]; - MainScreenPos[1] = MainScreenPos[0]; - MainScreenPos[0] = NDS::PowerControl9 >> 15; + { + mainScreenPos[2] = mainScreenPos[1]; + mainScreenPos[1] = mainScreenPos[0]; + mainScreenPos[0] = NDS::PowerControl9 >> 15; int guess; - if (MainScreenPos[0] == MainScreenPos[2] && - MainScreenPos[0] != MainScreenPos[1]) + if (mainScreenPos[0] == mainScreenPos[2] && + mainScreenPos[0] != mainScreenPos[1]) { // constant flickering, likely displaying 3D on both screens // TODO: when both screens are used for 2D only...??? @@ -348,18 +353,18 @@ void EmuThread::run() } else { - if (MainScreenPos[0] == 1) + if (mainScreenPos[0] == 1) guess = 1; else guess = 2; } - if (guess != AutoScreenSizing) + if (guess != autoScreenSizing) { - AutoScreenSizing = guess; - SetupScreenRects(WindowWidth, WindowHeight); + autoScreenSizing = guess; + emit screenLayoutChange(); } - }*/ + } // emulate u32 nlines = NDS::RunFrame(); @@ -540,6 +545,9 @@ MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) screen[0] = new QImage(256, 192, QImage::Format_RGB32); screen[1] = new QImage(256, 192, QImage::Format_RGB32); + screenTrans[0].reset(); + screenTrans[1].reset(); + touching = false; } @@ -549,6 +557,64 @@ MainWindowPanel::~MainWindowPanel() delete screen[1]; } +void MainWindowPanel::ensureProperMinSize() +{ + bool isHori = (Config::ScreenRotation == 1 || Config::ScreenRotation == 3); + int gap = Config::ScreenGap; + + int w = 256; + int h = 192; + + if (Config::ScreenLayout == 0) // natural + { + if (isHori) + setMinimumSize(h+gap+h, w); + else + setMinimumSize(w, h+gap+h); + } + else if (Config::ScreenLayout == 1) // vertical + { + if (isHori) + setMinimumSize(h, w+gap+w); + else + setMinimumSize(w, h+gap+h); + } + else // horizontal + { + if (isHori) + setMinimumSize(h+gap+h, w); + else + setMinimumSize(w+gap+w, h); + } +} + +void MainWindowPanel::setupScreenLayout() +{ + int w = width(); + int h = height(); + float* mtx; + + int sizing = Config::ScreenSizing; + if (sizing == 3) sizing = autoScreenSizing; + + Frontend::SetupScreenLayout(w, h, + Config::ScreenLayout, + Config::ScreenRotation, + sizing, + Config::ScreenGap, + Config::IntegerScaling != 0); + + mtx = Frontend::GetScreenTransform(0); + screenTrans[0].setMatrix(mtx[0], mtx[1], 0.f, + mtx[2], mtx[3], 0.f, + mtx[4], mtx[5], 1.f); + + mtx = Frontend::GetScreenTransform(1); + screenTrans[1].setMatrix(mtx[0], mtx[1], 0.f, + mtx[2], mtx[3], 0.f, + mtx[4], mtx[5], 1.f); +} + void MainWindowPanel::paintEvent(QPaintEvent* event) { QPainter painter(this); @@ -562,27 +628,18 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) memcpy(screen[0]->scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); memcpy(screen[1]->scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); - QRect src = QRect(0, 0, 256, 192); + QRect screenrc = QRect(0, 0, 256, 192); - QRect dstTop = QRect(0, 0, 256, 192); // TODO - QRect dstBot = QRect(0, 192, 256, 192); // TODO + painter.setTransform(screenTrans[0]); + painter.drawImage(screenrc, *screen[0]); - painter.drawImage(dstTop, *screen[0]); - painter.drawImage(dstBot, *screen[1]); + painter.setTransform(screenTrans[1]); + painter.drawImage(screenrc, *screen[1]); } - -void MainWindowPanel::transformTSCoords(int& x, int& y) +void MainWindowPanel::resizeEvent(QResizeEvent* event) { - // TODO: actual screen de-transform taking screen layout/rotation/etc into account - - y -= 192; - - // clamp to screen range - if (x < 0) x = 0; - else if (x > 255) x = 255; - if (y < 0) y = 0; - else if (y > 191) y = 191; + setupScreenLayout(); } void MainWindowPanel::mousePressEvent(QMouseEvent* event) @@ -593,11 +650,11 @@ void MainWindowPanel::mousePressEvent(QMouseEvent* event) int x = event->pos().x(); int y = event->pos().y(); - if (x >= 0 && x < 256 && y >= 192 && y < 384) + Frontend::GetTouchCoords(x, y); + + if (x >= 0 && x < 256 && y >= 0 && y < 192) { touching = true; - - transformTSCoords(x, y); NDS::TouchScreen(x, y); } } @@ -623,10 +680,22 @@ void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) int x = event->pos().x(); int y = event->pos().y(); - transformTSCoords(x, y); + Frontend::GetTouchCoords(x, y); + + // clamp to screen range + if (x < 0) x = 0; + else if (x > 255) x = 255; + if (y < 0) y = 0; + else if (y > 191) y = 191; + NDS::TouchScreen(x, y); } +void MainWindowPanel::onScreenLayoutChanged() +{ + setupScreenLayout(); +} + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { @@ -750,7 +819,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) int data = i*90; actScreenRotation[i] = submenu->addAction(QString("%1°").arg(data)); actScreenRotation[i]->setActionGroup(grpScreenRotation); - actScreenRotation[i]->setData(QVariant(data)); + actScreenRotation[i]->setData(QVariant(i)); actScreenRotation[i]->setCheckable(true); } @@ -834,8 +903,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) panel = new MainWindowPanel(this); setCentralWidget(panel); - panel->setMinimumSize(256, 384); + panel->ensureProperMinSize(); + resize(Config::WindowWidth, Config::WindowHeight); for (int i = 0; i < 9; i++) { @@ -877,6 +947,16 @@ MainWindow::~MainWindow() { } +void MainWindow::resizeEvent(QResizeEvent* event) +{ + int w = event->size().width(); + int h = event->size().height(); + + Config::WindowWidth = w; + Config::WindowHeight = h; + + // TODO: detect when the window gets maximized! +} void MainWindow::keyPressEvent(QKeyEvent* event) { @@ -1264,32 +1344,79 @@ void MainWindow::onChangeSavestateSRAMReloc(bool checked) void MainWindow::onChangeScreenSize() { - // + int factor = ((QAction*)sender())->data().toInt(); + + bool isHori = (Config::ScreenRotation == 1 || Config::ScreenRotation == 3); + int gap = Config::ScreenGap; + + int w = 256*factor; + int h = 192*factor; + + QSize diff = size() - panel->size(); + + if (Config::ScreenLayout == 0) // natural + { + if (isHori) + resize(QSize(h+gap+h, w) + diff); + else + resize(QSize(w, h+gap+h) + diff); + } + else if (Config::ScreenLayout == 1) // vertical + { + if (isHori) + resize(QSize(h, w+gap+w) + diff); + else + resize(QSize(w, h+gap+h) + diff); + } + else // horizontal + { + if (isHori) + resize(QSize(h+gap+h, w) + diff); + else + resize(QSize(w+gap+w, h) + diff); + } } void MainWindow::onChangeScreenRotation(QAction* act) { - // + int rot = act->data().toInt(); + Config::ScreenRotation = rot; + + panel->ensureProperMinSize(); + panel->setupScreenLayout(); } void MainWindow::onChangeScreenGap(QAction* act) { - // + int gap = act->data().toInt(); + Config::ScreenGap = gap; + + panel->ensureProperMinSize(); + panel->setupScreenLayout(); } void MainWindow::onChangeScreenLayout(QAction* act) { - // + int layout = act->data().toInt(); + Config::ScreenLayout = layout; + + panel->ensureProperMinSize(); + panel->setupScreenLayout(); } void MainWindow::onChangeScreenSizing(QAction* act) { - // + int sizing = act->data().toInt(); + Config::ScreenSizing = sizing; + + panel->setupScreenLayout(); } void MainWindow::onChangeIntegerScaling(bool checked) { - // + Config::IntegerScaling = checked?1:0; + + panel->setupScreenLayout(); } void MainWindow::onChangeScreenFiltering(bool checked) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 7051a08..2d14eea 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -54,6 +54,8 @@ signals: void windowLimitFPSChange(); + void screenLayoutChange(); + private: volatile int EmuStatus; int PrevEmuStatus; @@ -69,18 +71,25 @@ public: explicit MainWindowPanel(QWidget* parent); ~MainWindowPanel(); + void ensureProperMinSize(); + void setupScreenLayout(); + protected: void paintEvent(QPaintEvent* event) override; + void resizeEvent(QResizeEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; +private slots: + void onScreenLayoutChanged(); + private: QImage* screen[2]; + QTransform screenTrans[2]; bool touching; - - void transformTSCoords(int& x, int& y); }; @@ -93,6 +102,8 @@ public: ~MainWindow(); protected: + void resizeEvent(QResizeEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; @@ -138,9 +149,9 @@ private slots: private: QString loadErrorStr(int error); +public: MainWindowPanel* panel; -public: QAction* actOpenROM; QAction* actBootFirmware; QAction* actSaveState[9]; -- cgit v1.2.3 From 5dcf57e86dc8e768d33406fb446f25bf186eef4d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 21 May 2020 18:49:34 +0200 Subject: add screen filtering --- src/frontend/qt_sdl/main.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0d10378..36a3b8e 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -628,6 +628,8 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) memcpy(screen[0]->scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); memcpy(screen[1]->scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); + painter.setRenderHint(QPainter::SmoothPixmapTransform, Config::ScreenFilter!=0); + QRect screenrc = QRect(0, 0, 256, 192); painter.setTransform(screenTrans[0]); -- cgit v1.2.3 From f69f3fcb7a6f5eabe07de3db58409aee036348ea Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 22 May 2020 13:54:29 +0200 Subject: * safer window update * only do auto screen sizing if needed --- src/frontend/qt_sdl/main.cpp | 9 ++++++--- src/frontend/qt_sdl/main.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 36a3b8e..922206f 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -247,6 +247,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) EmuRunning = 2; RunningSomething = false; + connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update())); + //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(repaint())); connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); @@ -338,6 +340,7 @@ void EmuThread::run() }*/ // auto screen layout + if (Config::ScreenSizing == 3) { mainScreenPos[2] = mainScreenPos[1]; mainScreenPos[1] = mainScreenPos[0]; @@ -381,7 +384,7 @@ void EmuThread::run() uiGLEnd(GLContext); } uiAreaQueueRedrawAll(MainDrawArea);*/ - mainWindow->update(); + emit windowUpdate(); bool fastforward = Input::HotkeyDown(HK_FastForward); @@ -461,7 +464,7 @@ void EmuThread::run() uiGLEnd(GLContext); } uiAreaQueueRedrawAll(MainDrawArea);*/ - mainWindow->update(); + emit windowUpdate(); //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); @@ -630,7 +633,7 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) painter.setRenderHint(QPainter::SmoothPixmapTransform, Config::ScreenFilter!=0); - QRect screenrc = QRect(0, 0, 256, 192); + QRect screenrc(0, 0, 256, 192); painter.setTransform(screenTrans[0]); painter.drawImage(screenrc, *screen[0]); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 2d14eea..c0dc465 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -45,6 +45,7 @@ public: bool emuIsRunning(); signals: + void windowUpdate(); void windowTitleChange(QString title); void windowEmuStart(); -- cgit v1.2.3 From 16252a85e70feaa1bd10312a357ac74bd677ade3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 24 May 2020 23:16:56 +0200 Subject: separate screen handling shit to a specialized class --- src/frontend/FrontendUtil.h | 5 +- src/frontend/Util_Video.cpp | 6 +- src/frontend/qt_sdl/main.cpp | 168 +++++++++++++++++++++++++------------------ src/frontend/qt_sdl/main.h | 22 +++++- 4 files changed, 122 insertions(+), 79 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 1fd7329..359018f 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -104,11 +104,12 @@ void UndoStateLoad(); // * integerScale: force screens to be scaled up at integer scaling factors void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int rotation, int sizing, int screenGap, bool integerScale); -// get a 2x3 transform matrix for the given screen (0=top, 1=bottom) +// get a 2x3 transform matrix for each screen // note: the transform assumes an origin point at the top left of the display, // X going left and Y going down // for each screen the source coordinates should be (0,0) and (256,192) -float* GetScreenTransform(int screen); +// 'top' and 'bot' should point each to an array of 6 floats +void GetScreenTransforms(float* top, float* bot); // de-transform the provided host display coordinates to get coordinates // on the bottom screen diff --git a/src/frontend/Util_Video.cpp b/src/frontend/Util_Video.cpp index 0f5ff66..87cb9b5 100644 --- a/src/frontend/Util_Video.cpp +++ b/src/frontend/Util_Video.cpp @@ -313,10 +313,10 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int } } -float* GetScreenTransform(int screen) +void GetScreenTransforms(float* top, float* bot) { - if (screen == 0) return TopScreenMtx; - else return BotScreenMtx; + memcpy(top, TopScreenMtx, 6*sizeof(float)); + memcpy(bot, BotScreenMtx, 6*sizeof(float)); } void GetTouchCoords(int& x, int& y) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 922206f..0e0a21b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -543,24 +543,22 @@ bool EmuThread::emuIsRunning() } -MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) +void ScreenHandler::screenSetupLayout(int w, int h) { - screen[0] = new QImage(256, 192, QImage::Format_RGB32); - screen[1] = new QImage(256, 192, QImage::Format_RGB32); - - screenTrans[0].reset(); - screenTrans[1].reset(); + int sizing = Config::ScreenSizing; + if (sizing == 3) sizing = autoScreenSizing; - touching = false; -} + Frontend::SetupScreenLayout(w, h, + Config::ScreenLayout, + Config::ScreenRotation, + sizing, + Config::ScreenGap, + Config::IntegerScaling != 0); -MainWindowPanel::~MainWindowPanel() -{ - delete screen[0]; - delete screen[1]; + Frontend::GetScreenTransforms(screenMatrix[0], screenMatrix[1]); } -void MainWindowPanel::ensureProperMinSize() +QSize ScreenHandler::screenGetMinSize() { bool isHori = (Config::ScreenRotation == 1 || Config::ScreenRotation == 3); int gap = Config::ScreenGap; @@ -571,48 +569,110 @@ void MainWindowPanel::ensureProperMinSize() if (Config::ScreenLayout == 0) // natural { if (isHori) - setMinimumSize(h+gap+h, w); + return QSize(h+gap+h, w); else - setMinimumSize(w, h+gap+h); + return QSize(w, h+gap+h); } else if (Config::ScreenLayout == 1) // vertical { if (isHori) - setMinimumSize(h, w+gap+w); + return QSize(h, w+gap+w); else - setMinimumSize(w, h+gap+h); + return QSize(w, h+gap+h); } else // horizontal { if (isHori) - setMinimumSize(h+gap+h, w); + return QSize(h+gap+h, w); else - setMinimumSize(w+gap+w, h); + return QSize(w+gap+w, h); + } +} + +void ScreenHandler::screenOnMousePress(QMouseEvent* event) +{ + event->accept(); + if (event->button() != Qt::LeftButton) return; + + int x = event->pos().x(); + int y = event->pos().y(); + + Frontend::GetTouchCoords(x, y); + + if (x >= 0 && x < 256 && y >= 0 && y < 192) + { + touching = true; + NDS::TouchScreen(x, y); + } +} + +void ScreenHandler::screenOnMouseRelease(QMouseEvent* event) +{ + event->accept(); + if (event->button() != Qt::LeftButton) return; + + if (touching) + { + touching = false; + NDS::ReleaseScreen(); } } +void ScreenHandler::screenOnMouseMove(QMouseEvent* event) +{ + event->accept(); + if (!(event->buttons() & Qt::LeftButton)) return; + if (!touching) return; + + int x = event->pos().x(); + int y = event->pos().y(); + + Frontend::GetTouchCoords(x, y); + + // clamp to screen range + if (x < 0) x = 0; + else if (x > 255) x = 255; + if (y < 0) y = 0; + else if (y > 191) y = 191; + + NDS::TouchScreen(x, y); +} + + +MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) +{ + screen[0] = QImage(256, 192, QImage::Format_RGB32); + screen[1] = QImage(256, 192, QImage::Format_RGB32); + + screenTrans[0].reset(); + screenTrans[1].reset(); + + touching = false; +} + +MainWindowPanel::~MainWindowPanel() +{ +} + +void MainWindowPanel::ensureProperMinSize() +{ + setMinimumSize(screenGetMinSize()); +} + void MainWindowPanel::setupScreenLayout() { int w = width(); int h = height(); float* mtx; - int sizing = Config::ScreenSizing; - if (sizing == 3) sizing = autoScreenSizing; - - Frontend::SetupScreenLayout(w, h, - Config::ScreenLayout, - Config::ScreenRotation, - sizing, - Config::ScreenGap, - Config::IntegerScaling != 0); + screenSetupLayout(w, h); - mtx = Frontend::GetScreenTransform(0); + mtx = screenMatrix[0]; screenTrans[0].setMatrix(mtx[0], mtx[1], 0.f, mtx[2], mtx[3], 0.f, mtx[4], mtx[5], 1.f); - mtx = Frontend::GetScreenTransform(1); + mtx = screenMatrix[1]; screenTrans[1].setMatrix(mtx[0], mtx[1], 0.f, mtx[2], mtx[3], 0.f, mtx[4], mtx[5], 1.f); @@ -628,18 +688,18 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) int frontbuf = GPU::FrontBuffer; if (!GPU::Framebuffer[frontbuf][0] || !GPU::Framebuffer[frontbuf][1]) return; - memcpy(screen[0]->scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); - memcpy(screen[1]->scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); + memcpy(screen[0].scanLine(0), GPU::Framebuffer[frontbuf][0], 256*192*4); + memcpy(screen[1].scanLine(0), GPU::Framebuffer[frontbuf][1], 256*192*4); painter.setRenderHint(QPainter::SmoothPixmapTransform, Config::ScreenFilter!=0); QRect screenrc(0, 0, 256, 192); painter.setTransform(screenTrans[0]); - painter.drawImage(screenrc, *screen[0]); + painter.drawImage(screenrc, screen[0]); painter.setTransform(screenTrans[1]); - painter.drawImage(screenrc, *screen[1]); + painter.drawImage(screenrc, screen[1]); } void MainWindowPanel::resizeEvent(QResizeEvent* event) @@ -649,51 +709,17 @@ void MainWindowPanel::resizeEvent(QResizeEvent* event) void MainWindowPanel::mousePressEvent(QMouseEvent* event) { - event->accept(); - if (event->button() != Qt::LeftButton) return; - - int x = event->pos().x(); - int y = event->pos().y(); - - Frontend::GetTouchCoords(x, y); - - if (x >= 0 && x < 256 && y >= 0 && y < 192) - { - touching = true; - NDS::TouchScreen(x, y); - } + screenOnMousePress(event); } void MainWindowPanel::mouseReleaseEvent(QMouseEvent* event) { - event->accept(); - if (event->button() != Qt::LeftButton) return; - - if (touching) - { - touching = false; - NDS::ReleaseScreen(); - } + screenOnMouseRelease(event); } void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) { - event->accept(); - if (!(event->buttons() & Qt::LeftButton)) return; - if (!touching) return; - - int x = event->pos().x(); - int y = event->pos().y(); - - Frontend::GetTouchCoords(x, y); - - // clamp to screen range - if (x < 0) x = 0; - else if (x > 255) x = 255; - if (y < 0) y = 0; - else if (y > 191) y = 191; - - NDS::TouchScreen(x, y); + screenOnMouseMove(event); } void MainWindowPanel::onScreenLayoutChanged() diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index c0dc465..1121da1 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -64,7 +64,24 @@ private: }; -class MainWindowPanel : public QWidget +class ScreenHandler +{ +protected: + void screenSetupLayout(int w, int h); + + QSize screenGetMinSize(); + + void screenOnMousePress(QMouseEvent* event); + void screenOnMouseRelease(QMouseEvent* event); + void screenOnMouseMove(QMouseEvent* event); + + float screenMatrix[2][6]; + + bool touching; +}; + + +class MainWindowPanel : public QWidget, public ScreenHandler { Q_OBJECT @@ -88,9 +105,8 @@ private slots: void onScreenLayoutChanged(); private: - QImage* screen[2]; + QImage screen[2]; QTransform screenTrans[2]; - bool touching; }; -- cgit v1.2.3 From bc4a83abca991effe082f76f81cd6b4eef6ef0ba Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 24 May 2020 23:47:11 +0200 Subject: make frontend-util audio module config-agnostic --- src/frontend/FrontendUtil.h | 4 ++-- src/frontend/Util_Audio.cpp | 7 +------ src/frontend/qt_sdl/main.cpp | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index 359018f..6b83cbc 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -124,9 +124,9 @@ void Init_Audio(int outputfreq); int AudioOut_GetNumSamples(int outlen); // resample audio from the core audio output to match the frontend's -// output frequency, and apply user-specified volume +// output frequency, and apply specified volume // note: this assumes the output buffer is interleaved stereo -void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen); +void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volume); // feed silence to the microphone input void Mic_FeedSilence(); diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp index d4c3333..fc80c90 100644 --- a/src/frontend/Util_Audio.cpp +++ b/src/frontend/Util_Audio.cpp @@ -22,9 +22,6 @@ #include #include "FrontendUtil.h" -#include "Config.h" -#include "qt_sdl/PlatformConfig.h" // FIXME!!! -#include "Platform.h" #include "NDS.h" @@ -63,14 +60,12 @@ int AudioOut_GetNumSamples(int outlen) return len_in; } -void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen) +void AudioOut_Resample(s16* inbuf, int inlen, s16* outbuf, int outlen, int volume) { float res_incr = inlen / (float)outlen; float res_timer = 0; int res_pos = 0; - int volume = Config::AudioVolume; - for (int i = 0; i < outlen; i++) { outbuf[i*2 ] = (inbuf[res_pos*2 ] * volume) >> 8; diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 0e0a21b..fac4709 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -110,7 +110,7 @@ void audioCallback(void* data, Uint8* stream, int len) num_in = len_in-margin; } - Frontend::AudioOut_Resample(buf_in, num_in, (s16*)stream, len); + Frontend::AudioOut_Resample(buf_in, num_in, (s16*)stream, len, Config::AudioVolume); } -- cgit v1.2.3 From 4e34359a80833c21ef6a8fabd35c4d26babcaaab Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 25 May 2020 03:12:09 +0200 Subject: get the GL shit going --- src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/main.cpp | 91 ++++++++++++++++++++------- src/frontend/qt_sdl/main.h | 49 ++++++++++++--- src/frontend/qt_sdl/main_shaders.h | 124 +++++++++++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+), 31 deletions(-) create mode 100644 src/frontend/qt_sdl/main_shaders.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 7bc81f0..5778b40 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -2,6 +2,7 @@ project(qt_sdl) SET(SOURCES_QT_SDL main.cpp + main_shaders.h EmuSettingsDialog.cpp InputConfigDialog.cpp AudioSettingsDialog.cpp diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index fac4709..b11dd10 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -639,7 +639,7 @@ void ScreenHandler::screenOnMouseMove(QMouseEvent* event) } -MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) +ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent) { screen[0] = QImage(256, 192, QImage::Format_RGB32); screen[1] = QImage(256, 192, QImage::Format_RGB32); @@ -650,16 +650,11 @@ MainWindowPanel::MainWindowPanel(QWidget* parent) : QWidget(parent) touching = false; } -MainWindowPanel::~MainWindowPanel() +ScreenPanelNative::~ScreenPanelNative() { } -void MainWindowPanel::ensureProperMinSize() -{ - setMinimumSize(screenGetMinSize()); -} - -void MainWindowPanel::setupScreenLayout() +void ScreenPanelNative::setupScreenLayout() { int w = width(); int h = height(); @@ -678,7 +673,7 @@ void MainWindowPanel::setupScreenLayout() mtx[4], mtx[5], 1.f); } -void MainWindowPanel::paintEvent(QPaintEvent* event) +void ScreenPanelNative::paintEvent(QPaintEvent* event) { QPainter painter(this); @@ -702,28 +697,78 @@ void MainWindowPanel::paintEvent(QPaintEvent* event) painter.drawImage(screenrc, screen[1]); } -void MainWindowPanel::resizeEvent(QResizeEvent* event) +void ScreenPanelNative::resizeEvent(QResizeEvent* event) +{ + setupScreenLayout(); +} + +void ScreenPanelNative::mousePressEvent(QMouseEvent* event) +{ + screenOnMousePress(event); +} + +void ScreenPanelNative::mouseReleaseEvent(QMouseEvent* event) +{ + screenOnMouseRelease(event); +} + +void ScreenPanelNative::mouseMoveEvent(QMouseEvent* event) +{ + screenOnMouseMove(event); +} + +void ScreenPanelNative::onScreenLayoutChanged() +{ + setMinimumSize(screenGetMinSize()); + setupScreenLayout(); +} + + +ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) +{ + // +} + +ScreenPanelGL::~ScreenPanelGL() +{ +} + +void ScreenPanelGL::setupScreenLayout() +{ + int w = width(); + int h = height(); + + screenSetupLayout(w, h); +} + +void ScreenPanelGL::paintEvent(QPaintEvent* event) +{ + // TODO? +} + +void ScreenPanelGL::resizeEvent(QResizeEvent* event) { setupScreenLayout(); } -void MainWindowPanel::mousePressEvent(QMouseEvent* event) +void ScreenPanelGL::mousePressEvent(QMouseEvent* event) { screenOnMousePress(event); } -void MainWindowPanel::mouseReleaseEvent(QMouseEvent* event) +void ScreenPanelGL::mouseReleaseEvent(QMouseEvent* event) { screenOnMouseRelease(event); } -void MainWindowPanel::mouseMoveEvent(QMouseEvent* event) +void ScreenPanelGL::mouseMoveEvent(QMouseEvent* event) { screenOnMouseMove(event); } -void MainWindowPanel::onScreenLayoutChanged() +void ScreenPanelGL::onScreenLayoutChanged() { + setMinimumSize(screenGetMinSize()); setupScreenLayout(); } @@ -932,9 +977,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) } setMenuBar(menubar); - panel = new MainWindowPanel(this); + panel = new ScreenPanelNative(this); setCentralWidget(panel); - panel->ensureProperMinSize(); + connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged())); + emit screenLayoutChange(); resize(Config::WindowWidth, Config::WindowHeight); @@ -1413,8 +1459,7 @@ void MainWindow::onChangeScreenRotation(QAction* act) int rot = act->data().toInt(); Config::ScreenRotation = rot; - panel->ensureProperMinSize(); - panel->setupScreenLayout(); + emit screenLayoutChange(); } void MainWindow::onChangeScreenGap(QAction* act) @@ -1422,8 +1467,7 @@ void MainWindow::onChangeScreenGap(QAction* act) int gap = act->data().toInt(); Config::ScreenGap = gap; - panel->ensureProperMinSize(); - panel->setupScreenLayout(); + emit screenLayoutChange(); } void MainWindow::onChangeScreenLayout(QAction* act) @@ -1431,8 +1475,7 @@ void MainWindow::onChangeScreenLayout(QAction* act) int layout = act->data().toInt(); Config::ScreenLayout = layout; - panel->ensureProperMinSize(); - panel->setupScreenLayout(); + emit screenLayoutChange(); } void MainWindow::onChangeScreenSizing(QAction* act) @@ -1440,14 +1483,14 @@ void MainWindow::onChangeScreenSizing(QAction* act) int sizing = act->data().toInt(); Config::ScreenSizing = sizing; - panel->setupScreenLayout(); + emit screenLayoutChange(); } void MainWindow::onChangeIntegerScaling(bool checked) { Config::IntegerScaling = checked?1:0; - panel->setupScreenLayout(); + emit screenLayoutChange(); } void MainWindow::onChangeScreenFiltering(bool checked) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 1121da1..a244907 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -24,6 +24,7 @@ #include #include #include +#include class EmuThread : public QThread @@ -66,6 +67,11 @@ private: class ScreenHandler { + Q_GADGET + +public: + virtual ~ScreenHandler() {} + protected: void screenSetupLayout(int w, int h); @@ -81,16 +87,13 @@ protected: }; -class MainWindowPanel : public QWidget, public ScreenHandler +class ScreenPanelNative : public QWidget, public ScreenHandler { Q_OBJECT public: - explicit MainWindowPanel(QWidget* parent); - ~MainWindowPanel(); - - void ensureProperMinSize(); - void setupScreenLayout(); + explicit ScreenPanelNative(QWidget* parent); + ~ScreenPanelNative(); protected: void paintEvent(QPaintEvent* event) override; @@ -105,11 +108,40 @@ private slots: void onScreenLayoutChanged(); private: + void setupScreenLayout(); + QImage screen[2]; QTransform screenTrans[2]; }; +class ScreenPanelGL : public QOpenGLWidget, public ScreenHandler +{ + Q_OBJECT + +public: + explicit ScreenPanelGL(QWidget* parent); + ~ScreenPanelGL(); + +protected: + void paintEvent(QPaintEvent* event) override; + + void resizeEvent(QResizeEvent* event) override; + + void mousePressEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + +private slots: + void onScreenLayoutChanged(); + +private: + void setupScreenLayout(); + + // +}; + + class MainWindow : public QMainWindow { Q_OBJECT @@ -127,6 +159,9 @@ protected: void dragEnterEvent(QDragEnterEvent* event) override; void dropEvent(QDropEvent* event) override; +signals: + void screenLayoutChange(); + private slots: void onOpenFile(); void onBootFirmware(); @@ -167,7 +202,7 @@ private: QString loadErrorStr(int error); public: - MainWindowPanel* panel; + QWidget* panel; QAction* actOpenROM; QAction* actBootFirmware; diff --git a/src/frontend/qt_sdl/main_shaders.h b/src/frontend/qt_sdl/main_shaders.h new file mode 100644 index 0000000..7c4feec --- /dev/null +++ b/src/frontend/qt_sdl/main_shaders.h @@ -0,0 +1,124 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MAIN_SHADERS_H +#define MAIN_SHADERS_H + +const char* kScreenVS = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + +in vec2 vPosition; +in vec2 vTexcoord; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; + fTexcoord = vTexcoord; +} +)"; + +const char* kScreenFS = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + +uniform usampler2D ScreenTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + // TODO: filters + + oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); +} +)"; + + + +const char* kScreenVS_OSD = R"(#version 140 + +layout(std140) uniform uConfig +{ + vec2 uScreenSize; + uint u3DScale; + uint uFilterMode; +}; + +uniform ivec2 uOSDPos; +uniform ivec2 uOSDSize; + +in vec2 vPosition; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + + vec2 osdpos = (vPosition * vec2(uOSDSize)); + fTexcoord = osdpos; + osdpos += uOSDPos; + + fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; +} +)"; + +const char* kScreenFS_OSD = R"(#version 140 + +uniform sampler2D OSDTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0); + oColor = pixel.bgra; +} +)"; + +#endif // MAIN_SHADERS_H -- cgit v1.2.3 From 10f9eda58a7bbc9becb186ea2bdf1c9b7d2c1bc1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 25 May 2020 14:59:26 +0200 Subject: get the whole OpenGL shit going --- src/frontend/qt_sdl/main.cpp | 127 +++++++++++++++++++++++++++++++++++-- src/frontend/qt_sdl/main.h | 17 ++++- src/frontend/qt_sdl/main_shaders.h | 28 +++----- 3 files changed, 145 insertions(+), 27 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index b11dd10..bb08a87 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -54,6 +54,8 @@ #include "Savestate.h" +#include "main_shaders.h" + // TODO: uniform variable spelling @@ -247,7 +249,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) EmuRunning = 2; RunningSomething = false; - connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update())); + //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update())); + connect(this, SIGNAL(windowUpdate()), mainWindow->panel, SLOT(update())); //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(repaint())); connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); @@ -726,11 +729,18 @@ void ScreenPanelNative::onScreenLayoutChanged() ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) { - // + QSurfaceFormat format; + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setVersion(3, 2); + format.setProfile(QSurfaceFormat::CoreProfile); + setFormat(format); } ScreenPanelGL::~ScreenPanelGL() { + // CHECKME!!!! + delete screenShader; } void ScreenPanelGL::setupScreenLayout() @@ -741,14 +751,120 @@ void ScreenPanelGL::setupScreenLayout() screenSetupLayout(w, h); } -void ScreenPanelGL::paintEvent(QPaintEvent* event) +void ScreenPanelGL::initializeGL() { - // TODO? + initializeOpenGLFunctions(); + + glClearColor(0, 0, 0, 1); + + screenShader = new QOpenGLShaderProgram(this); + screenShader->addShaderFromSourceCode(QOpenGLShader::Vertex, kScreenVS); + screenShader->addShaderFromSourceCode(QOpenGLShader::Fragment, kScreenFS); + + GLuint pid = screenShader->programId(); + printf("program: %d\n", pid); + glBindAttribLocation(pid, 0, "vPosition"); + glBindAttribLocation(pid, 1, "vTexcoord"); + glBindFragDataLocation(pid, 0, "oColor"); + + screenShader->link(); + + screenShader->bind(); + screenShader->setUniformValue("ScreenTex", (GLint)0); + screenShader->release(); + + + float vertices[] = + { + 0, 0, 0, 0, + 0, 192, 0, 0.5, + 256, 192, 1, 0.5, + 0, 0, 0, 0, + 256, 192, 1, 0.5, + 256, 0, 1, 0, + + 0, 0, 0, 0.5, + 0, 192, 0, 1, + 256, 192, 1, 1, + 0, 0, 0, 0.5, + 256, 192, 1, 1, + 256, 0, 1, 0.5 + }; + + glGenBuffers(1, &screenVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &screenVertexArray); + glBindVertexArray(screenVertexArray); + glEnableVertexAttribArray(0); // position + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(0)); + glEnableVertexAttribArray(1); // texcoord + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4*4, (void*)(2*4)); + + glGenTextures(1, &screenTexture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, screenTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); +} + +void ScreenPanelGL::paintGL() +{ + int w = width(); + int h = height(); + + glClear(GL_COLOR_BUFFER_BIT); + + // TODO: check hiDPI compliance of this + glViewport(0, 0, w, h); + + screenShader->bind(); + + screenShader->setUniformValue("uScreenSize", (float)w, (float)h); + + int frontbuf = GPU::FrontBuffer; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, screenTexture); + + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } + + GLint filter = Config::ScreenFilter ? GL_LINEAR : GL_NEAREST; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + + glBindBuffer(GL_ARRAY_BUFFER, screenVertexBuffer); + glBindVertexArray(screenVertexArray); + + GLint transloc = screenShader->uniformLocation("uTransform"); + + glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[0]); + glDrawArrays(GL_TRIANGLES, 0, 2*3); + + glUniformMatrix2x3fv(transloc, 1, GL_TRUE, screenMatrix[1]); + glDrawArrays(GL_TRIANGLES, 2*3, 2*3); + + screenShader->release(); } void ScreenPanelGL::resizeEvent(QResizeEvent* event) { setupScreenLayout(); + + QOpenGLWidget::resizeEvent(event); +} + +void ScreenPanelGL::resizeGL(int w, int h) +{ } void ScreenPanelGL::mousePressEvent(QMouseEvent* event) @@ -977,7 +1093,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) } setMenuBar(menubar); - panel = new ScreenPanelNative(this); + //panel = new ScreenPanelNative(this); + panel = new ScreenPanelGL(this); setCentralWidget(panel); connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged())); emit screenLayoutChange(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index a244907..8a8c041 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -24,7 +24,12 @@ #include #include #include + #include +#include +#include +#include +#include class EmuThread : public QThread @@ -115,7 +120,7 @@ private: }; -class ScreenPanelGL : public QOpenGLWidget, public ScreenHandler +class ScreenPanelGL : public QOpenGLWidget, public ScreenHandler, protected QOpenGLFunctions_3_2_Core { Q_OBJECT @@ -124,9 +129,12 @@ public: ~ScreenPanelGL(); protected: - void paintEvent(QPaintEvent* event) override; + void initializeGL() override; + + void paintGL() override; void resizeEvent(QResizeEvent* event) override; + void resizeGL(int w, int h) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; @@ -138,7 +146,10 @@ private slots: private: void setupScreenLayout(); - // + QOpenGLShaderProgram* screenShader; + GLuint screenVertexBuffer; + GLuint screenVertexArray; + GLuint screenTexture; }; diff --git a/src/frontend/qt_sdl/main_shaders.h b/src/frontend/qt_sdl/main_shaders.h index 7c4feec..2e57e59 100644 --- a/src/frontend/qt_sdl/main_shaders.h +++ b/src/frontend/qt_sdl/main_shaders.h @@ -21,12 +21,8 @@ const char* kScreenVS = R"(#version 140 -layout(std140) uniform uConfig -{ - vec2 uScreenSize; - uint u3DScale; - uint uFilterMode; -}; +uniform vec2 uScreenSize; +uniform mat2x3 uTransform; in vec2 vPosition; in vec2 vTexcoord; @@ -36,7 +32,10 @@ smooth out vec2 fTexcoord; void main() { vec4 fpos; - fpos.xy = ((vPosition * 2.0) / uScreenSize) - 1.0; + + fpos.xy = vec3(vPosition, 1.0) * uTransform; + + fpos.xy = ((fpos.xy * 2.0) / uScreenSize) - 1.0; fpos.y *= -1; fpos.z = 0.0; fpos.w = 1.0; @@ -48,14 +47,7 @@ void main() const char* kScreenFS = R"(#version 140 -layout(std140) uniform uConfig -{ - vec2 uScreenSize; - uint u3DScale; - uint uFilterMode; -}; - -uniform usampler2D ScreenTex; +uniform sampler2D ScreenTex; smooth in vec2 fTexcoord; @@ -63,11 +55,9 @@ out vec4 oColor; void main() { - ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); - - // TODO: filters + vec4 pixel = texture2D(ScreenTex, fTexcoord); - oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); + oColor = vec4(pixel.bgr, 1.0); } )"; -- cgit v1.2.3 From 36f4cdbbbf1904c1a0455bf45d9720f03872e1bd Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 25 May 2020 18:25:50 +0200 Subject: get the OpenGL renderer going. sorta. (also make the blackmagic_II branch obsolete in the process) --- src/CMakeLists.txt | 2 + src/GPU.cpp | 2 + src/GPU.h | 14 + src/GPU2D.cpp | 2 + src/GPU3D.cpp | 2 +- src/GPU3D_OpenGL.cpp | 31 +- src/GPU_OpenGL.cpp | 207 ++++++++++ src/GPU_OpenGL_shaders.h | 867 +++++++++++++++++++++++++++++++++++++++ src/OpenGLSupport.cpp | 14 +- src/OpenGLSupport.h | 30 +- src/frontend/qt_sdl/Platform.cpp | 3 +- src/frontend/qt_sdl/main.cpp | 96 ++++- src/frontend/qt_sdl/main.h | 11 + 13 files changed, 1240 insertions(+), 41 deletions(-) create mode 100644 src/GPU_OpenGL.cpp create mode 100644 src/GPU_OpenGL_shaders.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 245e6a2..56bb3cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,8 @@ add_library(core STATIC FIFO.h GBACart.cpp GPU.cpp + GPU_OpenGL.cpp + GPU_OpenGL_shaders.h GPU2D.cpp GPU3D.cpp GPU3D_OpenGL.cpp diff --git a/src/GPU.cpp b/src/GPU.cpp index 42bfc56..993086e 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -985,6 +985,8 @@ void StartScanline(u32 line) GPU2D_A->VBlank(); GPU2D_B->VBlank(); GPU3D::VBlank(); + + if (Accelerated) GLCompositor::RenderFrame(); } else if (VCount == 144) { diff --git a/src/GPU.h b/src/GPU.h index 661a7d9..e85a5b4 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -422,6 +422,20 @@ void SetDispStat(u32 cpu, u16 val); void SetVCount(u16 val); +namespace GLCompositor +{ + +bool Init(); +void DeInit(); +void Reset(); + +void UpdateDisplaySettings(); + +void RenderFrame(); +void BindOutputTexture(); + +} + } #endif diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 1c6cf0c..6f950b7 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -728,6 +728,8 @@ u32 GPU2D::ColorComposite(int i, u32 val1, u32 val2) case 3: return ColorBrightnessDown(val1, EVY); case 4: return ColorBlend5(val1, val2); } + + return val1; } diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 4f146ae..e687e37 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -616,7 +616,7 @@ int InitRenderer(bool hasGL) if (!GLRenderer::Init()) renderer = 0; } - +printf("renderer: %d\n", renderer); if (renderer == 0) SoftRenderer::Init(); Renderer = renderer; diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index b1bcaa1..dcc4b6b 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -29,6 +29,8 @@ namespace GPU3D namespace GLRenderer { +using namespace OpenGL; + // GL version requirements // * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS) // * UBO: 3.1 @@ -142,7 +144,7 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) strcpy(&fsbuf[headerlen], kRenderFSCommon); strcpy(&fsbuf[headerlen + fsclen], fs); - bool ret = OpenGL_BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); + bool ret = OpenGL::BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername); delete[] vsbuf; delete[] fsbuf; @@ -158,7 +160,7 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs) glBindFragDataLocation(prog, 0, "oColor"); glBindFragDataLocation(prog, 1, "oAttr"); - if (!OpenGL_LinkShaderProgram(RenderShader[flags])) + if (!OpenGL::LinkShaderProgram(RenderShader[flags])) return false; GLint uni_id = glGetUniformBlockIndex(prog, "uConfig"); @@ -202,14 +204,14 @@ bool Init() glClearDepth(1.0); - if (!OpenGL_BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) + if (!OpenGL::BuildShaderProgram(kClearVS, kClearFS, ClearShaderPlain, "ClearShader")) return false; glBindAttribLocation(ClearShaderPlain[2], 0, "vPosition"); glBindFragDataLocation(ClearShaderPlain[2], 0, "oColor"); glBindFragDataLocation(ClearShaderPlain[2], 1, "oAttr"); - if (!OpenGL_LinkShaderProgram(ClearShaderPlain)) + if (!OpenGL::LinkShaderProgram(ClearShaderPlain)) return false; ClearUniformLoc[0] = glGetUniformLocation(ClearShaderPlain[2], "uColor"); @@ -237,15 +239,15 @@ bool Init() kRenderVS_W, kRenderFS_WSM)) return false; - if (!OpenGL_BuildShaderProgram(kFinalPassVS, kFinalPassEdgeFS, FinalPassEdgeShader, "FinalPassEdgeShader")) + if (!OpenGL::BuildShaderProgram(kFinalPassVS, kFinalPassEdgeFS, FinalPassEdgeShader, "FinalPassEdgeShader")) return false; - if (!OpenGL_BuildShaderProgram(kFinalPassVS, kFinalPassFogFS, FinalPassFogShader, "FinalPassFogShader")) + if (!OpenGL::BuildShaderProgram(kFinalPassVS, kFinalPassFogFS, FinalPassFogShader, "FinalPassFogShader")) return false; glBindAttribLocation(FinalPassEdgeShader[2], 0, "vPosition"); glBindFragDataLocation(FinalPassEdgeShader[2], 0, "oColor"); - if (!OpenGL_LinkShaderProgram(FinalPassEdgeShader)) + if (!OpenGL::LinkShaderProgram(FinalPassEdgeShader)) return false; uni_id = glGetUniformBlockIndex(FinalPassEdgeShader[2], "uConfig"); @@ -261,7 +263,7 @@ bool Init() glBindAttribLocation(FinalPassFogShader[2], 0, "vPosition"); glBindFragDataLocation(FinalPassFogShader[2], 0, "oColor"); - if (!OpenGL_LinkShaderProgram(FinalPassFogShader)) + if (!OpenGL::LinkShaderProgram(FinalPassFogShader)) return false; uni_id = glGetUniformBlockIndex(FinalPassFogShader[2], "uConfig"); @@ -371,11 +373,19 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); + if (!GPU::GLCompositor::Init()) + { + // TODO: clean up things? fail more gracefully?? + return false; + } + return true; } void DeInit() { + GPU::GLCompositor::DeInit(); + glDeleteTextures(1, &TexMemID); glDeleteTextures(1, &TexPalMemID); @@ -392,12 +402,13 @@ void DeInit() for (int i = 0; i < 16; i++) { if (!RenderShader[i][2]) continue; - OpenGL_DeleteShaderProgram(RenderShader[i]); + OpenGL::DeleteShaderProgram(RenderShader[i]); } } void Reset() { + GPU::GLCompositor::Reset(); } void UpdateDisplaySettings() @@ -480,6 +491,8 @@ void UpdateDisplaySettings() //glLineWidth(scale); //glLineWidth(1.5); + + GPU::GLCompositor::UpdateDisplaySettings(); } diff --git a/src/GPU_OpenGL.cpp b/src/GPU_OpenGL.cpp new file mode 100644 index 0000000..c9d31f1 --- /dev/null +++ b/src/GPU_OpenGL.cpp @@ -0,0 +1,207 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "NDS.h" +#include "GPU.h" +#include "Config.h" +#include "OpenGLSupport.h" +#include "GPU_OpenGL_shaders.h" + +namespace GPU +{ +namespace GLCompositor +{ + +using namespace OpenGL; + +int Scale; +int ScreenH, ScreenW; + +GLuint CompShader[1][3]; +GLuint CompScaleLoc[1]; + +GLuint CompVertexBufferID; +GLuint CompVertexArrayID; +float CompVertices[2 * 3*2 * 2]; // position + +GLuint CompScreenInputTex; +GLuint CompScreenOutputTex; +GLuint CompScreenOutputFB; + + +bool Init() +{ + if (!OpenGL::BuildShaderProgram(kCompositorVS, kCompositorFS_Nearest, CompShader[0], "CompositorShader")) + //if (!OpenGL::BuildShaderProgram(kCompositorVS, kCompositorFS_Linear, CompShader[0], "CompositorShader")) + //if (!OpenGL::BuildShaderProgram(kCompositorVS_xBRZ, kCompositorFS_xBRZ, CompShader[0], "CompositorShader")) + return false; + + for (int i = 0; i < 1; i++) + { + GLint uni_id; + + glBindAttribLocation(CompShader[i][2], 0, "vPosition"); + glBindFragDataLocation(CompShader[i][2], 0, "oColor"); + + if (!OpenGL::LinkShaderProgram(CompShader[i])) + return false; + + CompScaleLoc[i] = glGetUniformLocation(CompShader[i][2], "u3DScale"); + + glUseProgram(CompShader[i][2]); + uni_id = glGetUniformLocation(CompShader[i][2], "ScreenTex"); + glUniform1i(uni_id, 0); + uni_id = glGetUniformLocation(CompShader[i][2], "_3DTex"); + glUniform1i(uni_id, 1); + } + +#define SETVERTEX(i, x, y) \ + CompVertices[2*(i) + 0] = x; \ + CompVertices[2*(i) + 1] = y; + + // top screen + SETVERTEX(0, -1, 1); + SETVERTEX(1, 1, 0); + SETVERTEX(2, 1, 1); + SETVERTEX(3, -1, 1); + SETVERTEX(4, -1, 0); + SETVERTEX(5, 1, 0); + + // bottom screen + SETVERTEX(6, -1, 0); + SETVERTEX(7, 1, -1); + SETVERTEX(8, 1, 0); + SETVERTEX(9, -1, 0); + SETVERTEX(10, -1, -1); + SETVERTEX(11, 1, -1); + +#undef SETVERTEX + + glGenBuffers(1, &CompVertexBufferID); + glBindBuffer(GL_ARRAY_BUFFER, CompVertexBufferID); + glBufferData(GL_ARRAY_BUFFER, sizeof(CompVertices), CompVertices, GL_STATIC_DRAW); + + glGenVertexArrays(1, &CompVertexArrayID); + glBindVertexArray(CompVertexArrayID); + glEnableVertexAttribArray(0); // position + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*4, (void*)(0)); + + glGenFramebuffers(1, &CompScreenOutputFB); + + glGenTextures(1, &CompScreenInputTex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, CompScreenInputTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + + glGenTextures(1, &CompScreenOutputTex); + glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return true; +} + +void DeInit() +{ + glDeleteFramebuffers(1, &CompScreenOutputFB); + glDeleteTextures(1, &CompScreenInputTex); + glDeleteTextures(1, &CompScreenOutputTex); + + glDeleteVertexArrays(1, &CompVertexArrayID); + glDeleteBuffers(1, &CompVertexBufferID); + + for (int i = 0; i < 1; i++) + OpenGL::DeleteShaderProgram(CompShader[i]); +} + +void Reset() +{ +} + + +void UpdateDisplaySettings() +{ + int scale = Config::GL_ScaleFactor; + + Scale = scale; + ScreenW = 256 * scale; + ScreenH = 384 * scale; + + glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + GLenum fbassign[] = {GL_COLOR_ATTACHMENT0}; + glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, CompScreenOutputTex, 0); + glDrawBuffers(1, fbassign); +} + + +void RenderFrame() +{ + glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_BLEND); + glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glViewport(0, 0, ScreenW, ScreenH); + + // TODO: select more shaders (filtering, etc) + OpenGL::UseShaderProgram(CompShader[0]); + glUniform1ui(CompScaleLoc[0], Scale); + + //if (RunningSomething) + { + int frontbuf = GPU::FrontBuffer; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, CompScreenInputTex); + + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } + + glActiveTexture(GL_TEXTURE1); + GPU3D::GLRenderer::SetupAccelFrame(); + + glBindBuffer(GL_ARRAY_BUFFER, CompVertexBufferID); + glBindVertexArray(CompVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 4*3); + } +} + +void BindOutputTexture() +{ + glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex); +} + +} +} diff --git a/src/GPU_OpenGL_shaders.h b/src/GPU_OpenGL_shaders.h new file mode 100644 index 0000000..ec975ed --- /dev/null +++ b/src/GPU_OpenGL_shaders.h @@ -0,0 +1,867 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GPU_OPENGL_SHADERS_H +#define GPU_OPENGL_SHADERS_H + +const char* kCompositorVS = R"(#version 140 + +in vec2 vPosition; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + fpos.xy = vPosition; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; + fTexcoord = (vPosition + vec2(1.0, 1.0)) * (vec2(256.0, 384.0) / 2.0); +} +)"; + +const char* kCompositorFS_Nearest = R"(#version 140 + +uniform uint u3DScale; + +uniform usampler2D ScreenTex; +uniform sampler2D _3DTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; + + if (dispmode == 1) + { + ivec4 val1 = pixel; + ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + + int compmode = val3.a & 0xF; + int eva, evb, evy; + + if (compmode == 4) + { + // 3D on top, blending + + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + evb = 32 - eva; + + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode == 1) + { + // 3D on bottom, blending + + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) + { + eva = val3.g; + evb = val3.b; + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode <= 3) + { + // 3D on top, normal/fade + + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) + { + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; + } + else + val1 = val2; + } + + pixel = val1; + } + + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + + // TODO: filters + + oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); +} +)"; + + + +const char* kCompositorFS_Linear = R"(#version 140 + +uniform uint u3DScale; + +uniform usampler2D ScreenTex; +uniform sampler2D _3DTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +ivec4 Get3DPixel(vec2 pos) +{ + return ivec4(texelFetch(_3DTex, ivec2(pos*u3DScale), 0).bgra + * vec4(63,63,63,31)); +} + +ivec4 GetFullPixel(ivec4 val1, ivec4 val2, ivec4 val3, ivec4 _3dpix) +{ + int compmode = val3.a & 0xF; + int eva, evb, evy; + + if (compmode == 4) + { + // 3D on top, blending + + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + evb = 32 - eva; + + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode == 1) + { + // 3D on bottom, blending + + if (_3dpix.a > 0) + { + eva = val3.g; + evb = val3.b; + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode <= 3) + { + // 3D on top, normal/fade + + if (_3dpix.a > 0) + { + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; + } + else + val1 = val2; + } + + return val1; +} + +ivec4 imix(ivec4 a, ivec4 b, float x) +{ + return ivec4(vec4(a)*(1-x) + vec4(b)*x); +} + +void main() +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; + + if (dispmode == 1) + { + ivec4 val1 = pixel; + ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + + float xfract = fract(fTexcoord.x); + float yfract = fract(fTexcoord.y); + + float xpos = val3.r + xfract; + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = Get3DPixel(vec2(xpos,ypos)); + + ivec4 p00 = GetFullPixel(val1, val2, val3, _3dpix); + + int xdisp = 1 - int(step(255, fTexcoord.x)); + int ydisp = 1 - int(step(191, ypos)); + + ivec4 p01 = GetFullPixel(ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+0 ,0), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+256,0), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+512,0), 0)), + _3dpix); + + ivec4 p10 = GetFullPixel(ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(0+0 ,ydisp), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(0+256,ydisp), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(0+512,ydisp), 0)), + _3dpix); + + ivec4 p11 = GetFullPixel(ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+0 ,ydisp), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+256,ydisp), 0)), + ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(xdisp+512,ydisp), 0)), + _3dpix); + + ivec4 pa = imix(p00, p01, xfract); + ivec4 pb = imix(p10, p11, xfract); + + pixel = imix(pa, pb, yfract); + } + + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + + // TODO: filters + + oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); +} +)"; + + + + + + +// HUGE TEST ZONE ARRLGD + +const char* kCompositorVS_xBRZ = R"(#version 140 + +#define BLEND_NONE 0 +#define BLEND_NORMAL 1 +#define BLEND_DOMINANT 2 +#define LUMINANCE_WEIGHT 1.0 +#define EQUAL_COLOR_TOLERANCE 30.0/255.0 +#define STEEP_DIRECTION_THRESHOLD 2.2 +#define DOMINANT_DIRECTION_THRESHOLD 3.6 + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec2 vPosition; +COMPAT_VARYING vec4 TEX0; +COMPAT_VARYING vec4 t1; +COMPAT_VARYING vec4 t2; +COMPAT_VARYING vec4 t3; +COMPAT_VARYING vec4 t4; +COMPAT_VARYING vec4 t5; +COMPAT_VARYING vec4 t6; +COMPAT_VARYING vec4 t7; + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +// vertex compatibility #defines +#define vTexCoord TEX0.xy +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + +void main() +{ + vec4 fpos; + fpos.xy = vPosition; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; + vec2 TexCoord = (vPosition + vec2(1.0, 1.0)) * (vec2(256.0, 384.0) / 2.0); + + + //gl_Position = MVPMatrix * VertexCoord; + //COL0 = COLOR; + TEX0.xy = TexCoord.xy; + vec2 ps = vec2(1,1);//vec2(SourceSize.z, SourceSize.w); + float dx = ps.x; + float dy = ps.y; + + // A1 B1 C1 + // A0 A B C C4 + // D0 D E F F4 + // G0 G H I I4 + // G5 H5 I5 + + t1 = vTexCoord.xxxy + vec4( -dx, 0.0, dx,-2.0*dy); // A1 B1 C1 + t2 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, -dy); // A B C + t3 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, 0.0); // D E F + t4 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, dy); // G H I + t5 = vTexCoord.xxxy + vec4( -dx, 0.0, dx, 2.0*dy); // G5 H5 I5 + t6 = vTexCoord.xyyy + vec4(-2.0*dx,-dy, 0.0, dy); // A0 D0 G0 + t7 = vTexCoord.xyyy + vec4( 2.0*dx,-dy, 0.0, dy); // C4 F4 I4 +} +)"; + +const char* kCompositorFS_xBRZ = R"(#version 140 + +#define BLEND_NONE 0 +#define BLEND_NORMAL 1 +#define BLEND_DOMINANT 2 +#define LUMINANCE_WEIGHT 1.0 +#define EQUAL_COLOR_TOLERANCE 30.0/255.0 +#define STEEP_DIRECTION_THRESHOLD 2.2 +#define DOMINANT_DIRECTION_THRESHOLD 3.6 + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +//#define COMPAT_TEXTURE texture +#define FragColor oColor +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +//#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform uint u3DScale; + +uniform usampler2D ScreenTex; +uniform sampler2D _3DTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +//uniform COMPAT_PRECISION vec2 OutputSize; +//uniform COMPAT_PRECISION vec2 TextureSize; +#define TextureSize vec2(256,384) +//uniform COMPAT_PRECISION vec2 InputSize; +//uniform sampler2D Texture; +#define Texture 1312 +COMPAT_VARYING vec4 TEX0; +COMPAT_VARYING vec4 t1; +COMPAT_VARYING vec4 t2; +COMPAT_VARYING vec4 t3; +COMPAT_VARYING vec4 t4; +COMPAT_VARYING vec4 t5; +COMPAT_VARYING vec4 t6; +COMPAT_VARYING vec4 t7; + +// fragment compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + + const float one_sixth = 1.0 / 6.0; + const float two_sixth = 2.0 / 6.0; + const float four_sixth = 4.0 / 6.0; + const float five_sixth = 5.0 / 6.0; + +vec4 Get2DPixel(vec2 texcoord, int level) +{ + ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(texcoord) + ivec2(level*256,0), 0)); + + return vec4(pixel) / vec4(63.0, 63.0, 63.0, 31.0); +} + +ivec4 Get3DPixel(vec2 pos) +{ + return ivec4(texelFetch(_3DTex, ivec2(pos*u3DScale), 0).bgra + * vec4(63,63,63,31)); +} + +float reduce(const vec3 color) +{ + return dot(color, vec3(65536.0, 256.0, 1.0)); +} + +float DistYCbCr(const vec3 pixA, const vec3 pixB) +{ + const vec3 w = vec3(0.2627, 0.6780, 0.0593); + const float scaleB = 0.5 / (1.0 - w.b); + const float scaleR = 0.5 / (1.0 - w.r); + vec3 diff = pixA - pixB; + float Y = dot(diff, w); + float Cb = scaleB * (diff.b - Y); + float Cr = scaleR * (diff.r - Y); + + return sqrt( ((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr) ); +} + +bool IsPixEqual(const vec3 pixA, const vec3 pixB) +{ + return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE); +} + +bool IsBlendingNeeded(const ivec4 blend) +{ + return any(notEqual(blend, ivec4(BLEND_NONE))); +} + +//--------------------------------------- +// Input Pixel Mapping: --|21|22|23|-- +// 19|06|07|08|09 +// 18|05|00|01|10 +// 17|04|03|02|11 +// --|15|14|13|-- +// +// Output Pixel Mapping: 20|21|22|23|24|25 +// 19|06|07|08|09|26 +// 18|05|00|01|10|27 +// 17|04|03|02|11|28 +// 16|15|14|13|12|29 +// 35|34|33|32|31|30 + +ivec4 GetFiltered2DPixel(int level) +{ + vec2 f = fract(vTexCoord.xy);// * SourceSize.xy); + + //--------------------------------------- + // Input Pixel Mapping: 20|21|22|23|24 + // 19|06|07|08|09 + // 18|05|00|01|10 + // 17|04|03|02|11 + // 16|15|14|13|12 + + vec3 src[25]; + + src[21] = Get2DPixel(t1.xw, level).rgb; + src[22] = Get2DPixel(t1.yw, level).rgb; + src[23] = Get2DPixel(t1.zw, level).rgb; + src[ 6] = Get2DPixel(t2.xw, level).rgb; + src[ 7] = Get2DPixel(t2.yw, level).rgb; + src[ 8] = Get2DPixel(t2.zw, level).rgb; + src[ 5] = Get2DPixel(t3.xw, level).rgb; + src[ 0] = Get2DPixel(t3.yw, level).rgb; + src[ 1] = Get2DPixel(t3.zw, level).rgb; + src[ 4] = Get2DPixel(t4.xw, level).rgb; + src[ 3] = Get2DPixel(t4.yw, level).rgb; + src[ 2] = Get2DPixel(t4.zw, level).rgb; + src[15] = Get2DPixel(t5.xw, level).rgb; + src[14] = Get2DPixel(t5.yw, level).rgb; + src[13] = Get2DPixel(t5.zw, level).rgb; + src[19] = Get2DPixel(t6.xy, level).rgb; + src[18] = Get2DPixel(t6.xz, level).rgb; + src[17] = Get2DPixel(t6.xw, level).rgb; + src[ 9] = Get2DPixel(t7.xy, level).rgb; + src[10] = Get2DPixel(t7.xz, level).rgb; + src[11] = Get2DPixel(t7.xw, level).rgb; + + float v[9]; + v[0] = reduce(src[0]); + v[1] = reduce(src[1]); + v[2] = reduce(src[2]); + v[3] = reduce(src[3]); + v[4] = reduce(src[4]); + v[5] = reduce(src[5]); + v[6] = reduce(src[6]); + v[7] = reduce(src[7]); + v[8] = reduce(src[8]); + + ivec4 blendResult = ivec4(BLEND_NONE); + + // Preprocess corners + // Pixel Tap Mapping: --|--|--|--|-- + // --|--|07|08|-- + // --|05|00|01|10 + // --|04|03|02|11 + // --|--|14|13|-- + // Corner (1, 1) + if ( ((v[0] == v[1] && v[3] == v[2]) || (v[0] == v[3] && v[1] == v[2])) == false) + { + float dist_03_01 = DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + DistYCbCr(src[14], src[ 2]) + DistYCbCr(src[ 2], src[10]) + (4.0 * DistYCbCr(src[ 3], src[ 1])); + float dist_00_02 = DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[ 3], src[13]) + DistYCbCr(src[ 7], src[ 1]) + DistYCbCr(src[ 1], src[11]) + (4.0 * DistYCbCr(src[ 0], src[ 2])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_03_01) < dist_00_02; + blendResult[2] = ((dist_03_01 < dist_00_02) && (v[0] != v[1]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|--|--|--|-- + // --|06|07|--|-- + // 18|05|00|01|-- + // 17|04|03|02|-- + // --|15|14|--|-- + // Corner (0, 1) + if ( ((v[5] == v[0] && v[4] == v[3]) || (v[5] == v[4] && v[0] == v[3])) == false) + { + float dist_04_00 = DistYCbCr(src[17], src[ 5]) + DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[15], src[ 3]) + DistYCbCr(src[ 3], src[ 1]) + (4.0 * DistYCbCr(src[ 4], src[ 0])); + float dist_05_03 = DistYCbCr(src[18], src[ 4]) + DistYCbCr(src[ 4], src[14]) + DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + (4.0 * DistYCbCr(src[ 5], src[ 3])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_03) < dist_04_00; + blendResult[3] = ((dist_04_00 > dist_05_03) && (v[0] != v[5]) && (v[0] != v[3])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|--|22|23|-- + // --|06|07|08|09 + // --|05|00|01|10 + // --|--|03|02|-- + // --|--|--|--|-- + // Corner (1, 0) + if ( ((v[7] == v[8] && v[0] == v[1]) || (v[7] == v[0] && v[8] == v[1])) == false) + { + float dist_00_08 = DistYCbCr(src[ 5], src[ 7]) + DistYCbCr(src[ 7], src[23]) + DistYCbCr(src[ 3], src[ 1]) + DistYCbCr(src[ 1], src[ 9]) + (4.0 * DistYCbCr(src[ 0], src[ 8])); + float dist_07_01 = DistYCbCr(src[ 6], src[ 0]) + DistYCbCr(src[ 0], src[ 2]) + DistYCbCr(src[22], src[ 8]) + DistYCbCr(src[ 8], src[10]) + (4.0 * DistYCbCr(src[ 7], src[ 1])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_07_01) < dist_00_08; + blendResult[1] = ((dist_00_08 > dist_07_01) && (v[0] != v[7]) && (v[0] != v[1])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: --|21|22|--|-- + // 19|06|07|08|-- + // 18|05|00|01|-- + // --|04|03|--|-- + // --|--|--|--|-- + // Corner (0, 0) + if ( ((v[6] == v[7] && v[5] == v[0]) || (v[6] == v[5] && v[7] == v[0])) == false) + { + float dist_05_07 = DistYCbCr(src[18], src[ 6]) + DistYCbCr(src[ 6], src[22]) + DistYCbCr(src[ 4], src[ 0]) + DistYCbCr(src[ 0], src[ 8]) + (4.0 * DistYCbCr(src[ 5], src[ 7])); + float dist_06_00 = DistYCbCr(src[19], src[ 5]) + DistYCbCr(src[ 5], src[ 3]) + DistYCbCr(src[21], src[ 7]) + DistYCbCr(src[ 7], src[ 1]) + (4.0 * DistYCbCr(src[ 6], src[ 0])); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_05_07) < dist_06_00; + blendResult[0] = ((dist_05_07 < dist_06_00) && (v[0] != v[5]) && (v[0] != v[7])) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + vec3 dst[16]; + dst[ 0] = src[0]; + dst[ 1] = src[0]; + dst[ 2] = src[0]; + dst[ 3] = src[0]; + dst[ 4] = src[0]; + dst[ 5] = src[0]; + dst[ 6] = src[0]; + dst[ 7] = src[0]; + dst[ 8] = src[0]; + dst[ 9] = src[0]; + dst[10] = src[0]; + dst[11] = src[0]; + dst[12] = src[0]; + dst[13] = src[0]; + dst[14] = src[0]; + dst[15] = src[0]; + + // Scale pixel + if (IsBlendingNeeded(blendResult) == true) + { + float dist_01_04 = DistYCbCr(src[1], src[4]); + float dist_03_08 = DistYCbCr(src[3], src[8]); + bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[4]) && (v[5] != v[4]); + bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[8]) && (v[7] != v[8]); + bool needBlend = (blendResult[2] != BLEND_NONE); + bool doLineBlend = ( blendResult[2] >= BLEND_DOMINANT || + ((blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || + (blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || + (IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[0], src[2]) == false) ) == false ); + + vec3 blendPix = ( DistYCbCr(src[0], src[1]) <= DistYCbCr(src[0], src[3]) ) ? src[1] : src[3]; + dst[ 2] = mix(dst[ 2], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[10] = mix(dst[10], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[11] = mix(dst[11], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[13] = mix(dst[13], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[14] = mix(dst[14], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + dist_01_04 = DistYCbCr(src[7], src[2]); + dist_03_08 = DistYCbCr(src[1], src[6]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[2]) && (v[3] != v[2]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[6]) && (v[5] != v[6]); + needBlend = (blendResult[1] != BLEND_NONE); + doLineBlend = ( blendResult[1] >= BLEND_DOMINANT || + !((blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || + (blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || + (IsPixEqual(src[2], src[1]) && IsPixEqual(src[1], src[8]) && IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && !IsPixEqual(src[0], src[8])) ) ); + + blendPix = ( DistYCbCr(src[0], src[7]) <= DistYCbCr(src[0], src[1]) ) ? src[7] : src[1]; + dst[ 1] = mix(dst[ 1], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[ 7] = mix(dst[ 7], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[ 8] = mix(dst[ 8], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[10] = mix(dst[10], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[11] = mix(dst[11], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + dist_01_04 = DistYCbCr(src[5], src[8]); + dist_03_08 = DistYCbCr(src[7], src[4]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[8]) && (v[1] != v[8]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[4]) && (v[3] != v[4]); + needBlend = (blendResult[0] != BLEND_NONE); + doLineBlend = ( blendResult[0] >= BLEND_DOMINANT || + !((blendResult[3] != BLEND_NONE && !IsPixEqual(src[0], src[8])) || + (blendResult[1] != BLEND_NONE && !IsPixEqual(src[0], src[4])) || + (IsPixEqual(src[8], src[7]) && IsPixEqual(src[7], src[6]) && IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && !IsPixEqual(src[0], src[6])) ) ); + + blendPix = ( DistYCbCr(src[0], src[5]) <= DistYCbCr(src[0], src[7]) ) ? src[5] : src[7]; + dst[ 0] = mix(dst[ 0], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[ 4] = mix(dst[ 4], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[ 5] = mix(dst[ 5], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[ 7] = mix(dst[ 7], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 8] = mix(dst[ 8], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[ 9] = mix(dst[ 9], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + + + dist_01_04 = DistYCbCr(src[3], src[6]); + dist_03_08 = DistYCbCr(src[5], src[2]); + haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_01_04 <= dist_03_08) && (v[0] != v[6]) && (v[7] != v[6]); + haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_03_08 <= dist_01_04) && (v[0] != v[2]) && (v[1] != v[2]); + needBlend = (blendResult[3] != BLEND_NONE); + doLineBlend = ( blendResult[3] >= BLEND_DOMINANT || + !((blendResult[2] != BLEND_NONE && !IsPixEqual(src[0], src[6])) || + (blendResult[0] != BLEND_NONE && !IsPixEqual(src[0], src[2])) || + (IsPixEqual(src[6], src[5]) && IsPixEqual(src[5], src[4]) && IsPixEqual(src[4], src[3]) && IsPixEqual(src[3], src[2]) && !IsPixEqual(src[0], src[4])) ) ); + + blendPix = ( DistYCbCr(src[0], src[3]) <= DistYCbCr(src[0], src[5]) ) ? src[3] : src[5]; + dst[ 3] = mix(dst[ 3], blendPix, (needBlend && doLineBlend) ? ((haveShallowLine) ? ((haveSteepLine) ? 1.0/3.0 : 0.25) : ((haveSteepLine) ? 0.25 : 0.00)) : 0.00); + dst[12] = mix(dst[12], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.25 : 0.00); + dst[13] = mix(dst[13], blendPix, (needBlend && doLineBlend && haveSteepLine) ? 0.75 : 0.00); + dst[14] = mix(dst[14], blendPix, (needBlend) ? ((doLineBlend) ? ((haveSteepLine) ? 1.00 : ((haveShallowLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[15] = mix(dst[15], blendPix, (needBlend) ? ((doLineBlend) ? 1.00 : 0.6848532563) : 0.00); + dst[ 4] = mix(dst[ 4], blendPix, (needBlend) ? ((doLineBlend) ? ((haveShallowLine) ? 1.00 : ((haveSteepLine) ? 0.75 : 0.50)) : 0.08677704501) : 0.00); + dst[ 5] = mix(dst[ 5], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.75 : 0.00); + dst[ 6] = mix(dst[ 6], blendPix, (needBlend && doLineBlend && haveShallowLine) ? 0.25 : 0.00); + } + + vec3 res = mix( mix( mix( mix(dst[ 6], dst[ 7], step(0.25, f.x)), mix(dst[ 8], dst[ 9], step(0.75, f.x)), step(0.50, f.x)), + mix( mix(dst[ 5], dst[ 0], step(0.25, f.x)), mix(dst[ 1], dst[10], step(0.75, f.x)), step(0.50, f.x)), step(0.25, f.y)), + mix( mix( mix(dst[ 4], dst[ 3], step(0.25, f.x)), mix(dst[ 2], dst[11], step(0.75, f.x)), step(0.50, f.x)), + mix( mix(dst[15], dst[14], step(0.25, f.x)), mix(dst[13], dst[12], step(0.75, f.x)), step(0.50, f.x)), step(0.75, f.y)), + step(0.50, f.y)); + + return ivec4(res * vec3(63,63,63), 0); +} + + +void main() +{ + vec2 fTexcoord = vTexCoord.xy; + + ivec4 pixel;// = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); + + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; + + if (dispmode == 1) + { + ivec4 val1;// = pixel; + //ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + + int compmode = val3.a & 0xF; + int eva, evb, evy; + + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = Get3DPixel(vec2(xpos, ypos)); + + if (compmode == 4) + { + // 3D on top, blending + + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + if (eva == 32) + { + val1 = _3dpix; + } + else + { + evb = 32 - eva; + + val1 = GetFiltered2DPixel(0); + + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + } + else + val1 = GetFiltered2DPixel(1); + } + else if (compmode == 1) + { + // 3D on bottom, blending + + if (_3dpix.a > 0) + { + eva = val3.g; + evb = val3.b; + + val1 = GetFiltered2DPixel(0); + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); + } + else + val1 = GetFiltered2DPixel(1); + } + else if (compmode <= 3) + { + // 3D on top, normal/fade + + if (_3dpix.a > 0) + { + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; + } + else + val1 = GetFiltered2DPixel(1); + } + else + val1 = GetFiltered2DPixel(0); + + pixel = val1; + } + else + { + pixel = GetFiltered2DPixel(0); + } + + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + + FragColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); +} +)"; + + + + + + +#endif // GPU_OPENGL_SHADERS_H diff --git a/src/OpenGLSupport.cpp b/src/OpenGLSupport.cpp index f91af9b..27b1480 100644 --- a/src/OpenGLSupport.cpp +++ b/src/OpenGLSupport.cpp @@ -19,18 +19,20 @@ #include "OpenGLSupport.h" +namespace OpenGL +{ DO_PROCLIST(DECLPROC); -bool OpenGL_Init() +bool Init() { DO_PROCLIST(LOADPROC); return true; } -bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name) +bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name) { int len; int res; @@ -89,7 +91,7 @@ bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, cons return true; } -bool OpenGL_LinkShaderProgram(GLuint* ids) +bool LinkShaderProgram(GLuint* ids) { int res; @@ -115,14 +117,16 @@ bool OpenGL_LinkShaderProgram(GLuint* ids) return true; } -void OpenGL_DeleteShaderProgram(GLuint* ids) +void DeleteShaderProgram(GLuint* ids) { glDeleteShader(ids[0]); glDeleteShader(ids[1]); glDeleteProgram(ids[2]); } -void OpenGL_UseShaderProgram(GLuint* ids) +void UseShaderProgram(GLuint* ids) { glUseProgram(ids[2]); } + +} diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 5f92580..360d215 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -21,6 +21,8 @@ #include #include + +// TODO: different includes for each platform #include #include @@ -45,23 +47,11 @@ // if you need more OpenGL functions, add them to the macronator here -// TODO: handle conditionally loading certain functions for different GL versions - -#ifndef __WIN32__ - -#define DO_PROCLIST_1_3(func) -#else -#define DO_PROCLIST_1_3(func) \ +#define DO_PROCLIST(func) \ func(GLACTIVETEXTURE, glActiveTexture); \ func(GLBLENDCOLOR, glBlendColor); \ - -#endif - - -#define DO_PROCLIST(func) \ - DO_PROCLIST_1_3(func) \ \ func(GLGENFRAMEBUFFERS, glGenFramebuffers); \ func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \ @@ -122,14 +112,18 @@ func(GLGETSTRINGI, glGetStringi); \ +namespace OpenGL +{ + DO_PROCLIST(DECLPROC_EXT); +bool Init(); -bool OpenGL_Init(); +bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name); +bool LinkShaderProgram(GLuint* ids); +void DeleteShaderProgram(GLuint* ids); +void UseShaderProgram(GLuint* ids); -bool OpenGL_BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name); -bool OpenGL_LinkShaderProgram(GLuint* ids); -void OpenGL_DeleteShaderProgram(GLuint* ids); -void OpenGL_UseShaderProgram(GLuint* ids); +} #endif // OPENGLSUPPORT_H diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index dd838d7..6b256e0 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -56,6 +56,7 @@ char* EmuDirectory; void emuStop(); +void* oglGetProcAddress(const char* proc); namespace Platform @@ -418,7 +419,7 @@ void Semaphore_Post(void* sema) void* GL_GetProcAddress(const char* proc) { - return NULL;//uiGLGetProcAddress(proc); + return oglGetProcAddress(proc); } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index bb08a87..096b91c 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -45,6 +45,7 @@ #include "NDS.h" #include "GBACart.h" +#include "OpenGLSupport.h" #include "GPU.h" #include "SPU.h" #include "Wifi.h" @@ -258,6 +259,54 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowEmuPause()), mainWindow->actPause, SLOT(trigger())); connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged())); + + initOpenGL(); +} + +void EmuThread::initOpenGL() +{ + QOpenGLContext* windowctx = mainWindow->getOGLContext(); + QSurfaceFormat format = windowctx->format(); + + oglSurface = new QOffscreenSurface(); + oglSurface->setFormat(format); + oglSurface->create(); + if (!oglSurface->isValid()) + { + // TODO handle this! + printf("oglSurface shat itself :(\n"); + delete oglSurface; + return; + } + + oglContext = new QOpenGLContext();//oglSurface); + oglContext->setFormat(oglSurface->format()); + oglContext->setShareContext(windowctx); + if (!oglContext->create()) + { + // TODO handle this! + printf("oglContext shat itself :(\n"); + delete oglContext; + delete oglSurface; + return; + } + + oglContext->moveToThread(this); +} + +void deinitOpenGL() +{ + // TODO!! +} + +void* oglGetProcAddress(const char* proc) +{ + return emuThread->oglGetProcAddress(proc); +} + +void* EmuThread::oglGetProcAddress(const char* proc) +{ + return (void*)oglContext->getProcAddress(proc); } void EmuThread::run() @@ -279,7 +328,11 @@ void EmuThread::run() } else*/ { - GPU3D::InitRenderer(false); + //GPU3D::InitRenderer(false); + bool res = oglContext->makeCurrent(oglSurface); + printf("good? %d\n", res); + OpenGL::Init(); + GPU3D::InitRenderer(res); } Input::Init(); @@ -755,6 +808,11 @@ void ScreenPanelGL::initializeGL() { initializeOpenGLFunctions(); + const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string + const GLubyte* version = glGetString(GL_VERSION); // version as a string + printf("OpenGL: renderer: %s\n", renderer); + printf("OpenGL: version: %s\n", version); + glClearColor(0, 0, 0, 1); screenShader = new QOpenGLShaderProgram(this); @@ -828,14 +886,24 @@ void ScreenPanelGL::paintGL() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, screenTexture); - if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + if (true) + { + // hardware-accelerated render + GPU::GLCompositor::BindOutputTexture(); + } + else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + // regular render + glBindTexture(GL_TEXTURE_2D, screenTexture); + + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) + { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); + } } GLint filter = Config::ScreenFilter ? GL_LINEAR : GL_NEAREST; @@ -1141,6 +1209,13 @@ MainWindow::~MainWindow() { } +QOpenGLContext* MainWindow::getOGLContext() +{ + // TODO: check whether we can actually pull this! + QOpenGLWidget* glpanel = (QOpenGLWidget*)panel; + return glpanel->context(); +} + void MainWindow::resizeEvent(QResizeEvent* event) { int w = event->size().width(); @@ -1755,6 +1830,13 @@ int main(int argc, char** argv) } #endif + QSurfaceFormat format; + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setVersion(3, 2); + format.setProfile(QSurfaceFormat::CoreProfile); + QSurfaceFormat::setDefaultFormat(format); + audioSync = SDL_CreateCond(); audioSyncLock = SDL_CreateMutex(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 8a8c041..67c93d0 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,11 @@ class EmuThread : public QThread public: explicit EmuThread(QObject* parent = nullptr); + void initOpenGL(); + void deinitOpenGL(); + + void* oglGetProcAddress(const char* proc); + void changeWindowTitle(char* title); // to be called from the UI thread @@ -67,6 +73,9 @@ private: volatile int EmuStatus; int PrevEmuStatus; int EmuRunning; + + QOffscreenSurface* oglSurface; + QOpenGLContext* oglContext; }; @@ -161,6 +170,8 @@ public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); + QOpenGLContext* getOGLContext(); + protected: void resizeEvent(QResizeEvent* event) override; -- cgit v1.2.3 From ef2802ae31c4af965457216a190535b41efe749d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 27 May 2020 21:29:47 +0200 Subject: * use GL shim window instead of offscreen surface * disable vsync by default (we'll take care of it later) --- src/frontend/qt_sdl/main.cpp | 19 +++++++++++++++++-- src/frontend/qt_sdl/main.h | 13 ++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 096b91c..8f2a61e 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -268,7 +268,7 @@ void EmuThread::initOpenGL() QOpenGLContext* windowctx = mainWindow->getOGLContext(); QSurfaceFormat format = windowctx->format(); - oglSurface = new QOffscreenSurface(); + /*oglSurface = new QOffscreenSurface(); oglSurface->setFormat(format); oglSurface->create(); if (!oglSurface->isValid()) @@ -277,7 +277,8 @@ void EmuThread::initOpenGL() printf("oglSurface shat itself :(\n"); delete oglSurface; return; - } + }*/ + oglSurface = new GLShim(format); oglContext = new QOpenGLContext();//oglSurface); oglContext->setFormat(oglSurface->format()); @@ -957,6 +958,19 @@ void ScreenPanelGL::onScreenLayoutChanged() } +GLShim::GLShim(QSurfaceFormat& format) : QWindow() +{ + setSurfaceType(QSurface::OpenGLSurface); + setFormat(format); + create(); + hide(); +} + +GLShim::~GLShim() +{ +} + + MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS " MELONDS_VERSION); @@ -1835,6 +1849,7 @@ int main(int argc, char** argv) format.setStencilBufferSize(8); format.setVersion(3, 2); format.setProfile(QSurfaceFormat::CoreProfile); + format.setSwapInterval(0); QSurfaceFormat::setDefaultFormat(format); audioSync = SDL_CreateCond(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 67c93d0..2a24960 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -74,7 +75,7 @@ private: int PrevEmuStatus; int EmuRunning; - QOffscreenSurface* oglSurface; + QSurface* oglSurface; QOpenGLContext* oglContext; }; @@ -162,6 +163,16 @@ private: }; +class GLShim : public QWindow +{ + Q_OBJECT + +public: + explicit GLShim(QSurfaceFormat& format); + ~GLShim(); +}; + + class MainWindow : public QMainWindow { Q_OBJECT -- cgit v1.2.3 From e8849db78abe4db518c7f324323b88f478acc69a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 27 May 2020 21:40:02 +0200 Subject: we don't need a GLShim. blarg. I don't understand this anymore. --- src/GPU3D_OpenGL.cpp | 1 - src/frontend/qt_sdl/main.cpp | 18 ++---------------- src/frontend/qt_sdl/main.h | 12 +----------- 3 files changed, 3 insertions(+), 28 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index dcc4b6b..74760e5 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -199,7 +199,6 @@ bool Init() glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); - glDepthRange(0, 1); glClearDepth(1.0); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8f2a61e..f282310 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -268,7 +268,7 @@ void EmuThread::initOpenGL() QOpenGLContext* windowctx = mainWindow->getOGLContext(); QSurfaceFormat format = windowctx->format(); - /*oglSurface = new QOffscreenSurface(); + oglSurface = new QOffscreenSurface(); oglSurface->setFormat(format); oglSurface->create(); if (!oglSurface->isValid()) @@ -277,8 +277,7 @@ void EmuThread::initOpenGL() printf("oglSurface shat itself :(\n"); delete oglSurface; return; - }*/ - oglSurface = new GLShim(format); + } oglContext = new QOpenGLContext();//oglSurface); oglContext->setFormat(oglSurface->format()); @@ -958,19 +957,6 @@ void ScreenPanelGL::onScreenLayoutChanged() } -GLShim::GLShim(QSurfaceFormat& format) : QWindow() -{ - setSurfaceType(QSurface::OpenGLSurface); - setFormat(format); - create(); - hide(); -} - -GLShim::~GLShim() -{ -} - - MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) { setWindowTitle("melonDS " MELONDS_VERSION); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 2a24960..8759e95 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -75,7 +75,7 @@ private: int PrevEmuStatus; int EmuRunning; - QSurface* oglSurface; + QOffscreenSurface* oglSurface; QOpenGLContext* oglContext; }; @@ -163,16 +163,6 @@ private: }; -class GLShim : public QWindow -{ - Q_OBJECT - -public: - explicit GLShim(QSurfaceFormat& format); - ~GLShim(); -}; - - class MainWindow : public QMainWindow { Q_OBJECT -- cgit v1.2.3 From 0a68eb78039a7a27b16d389844beeebed139f864 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 11:52:12 +0200 Subject: make it hiDPI compliant (I hope) also misc tweaks --- src/GPU3D_OpenGL.cpp | 2 +- src/OpenGLSupport.h | 5 +++++ src/frontend/qt_sdl/AudioSettingsDialog.ui | 7 +++++-- src/frontend/qt_sdl/main.cpp | 6 +++--- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 74760e5..9a78504 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -1236,7 +1236,7 @@ void RenderFrame() glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); } - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); + //glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); FrontBuffer = FrontBuffer ? 0 : 1; } diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index 360d215..edf7eda 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -102,6 +102,11 @@ func(GLGETUNIFORMLOCATION, glGetUniformLocation); \ func(GLGETUNIFORMBLOCKINDEX, glGetUniformBlockIndex); \ \ + func(GLFENCESYNC, glFenceSync); \ + func(GLDELETESYNC, glDeleteSync); \ + func(GLWAITSYNC, glWaitSync); \ + func(GLCLIENTWAITSYNC, glClientWaitSync); \ + \ func(GLDRAWBUFFERS, glDrawBuffers); \ \ func(GLBLENDFUNCSEPARATE, glBlendFuncSeparate); \ diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.ui b/src/frontend/qt_sdl/AudioSettingsDialog.ui index c4e993e..9ae8baa 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.ui +++ b/src/frontend/qt_sdl/AudioSettingsDialog.ui @@ -60,12 +60,15 @@ 0 + + <html><head/><body><p>Forward a WAV file to the emulated microphone.</p><p>This input mode is activated by holding the microphone hotkey (see Input and Hotkeys).</p></body></html> + - <html><head/><body><p>Forward a WAV file to the emulated microphone.</p></body></html> + <html><head/><body><p>Forward a WAV file to the emulated microphone.</p><p>This input mode is activated by holding the microphone hotkey (see Input and Hotkeys).</p></body></html> WAV file: @@ -92,7 +95,7 @@ - <html><head/><body><p>Noise will be forwarded to the emulated microphone, simulating blowing into the microphone.</p></body></html> + <html><head/><body><p>Noise will be forwarded to the emulated microphone, simulating blowing into the microphone.</p><p>This input mode is activated by holding the microphone hotkey (see Input and Hotkeys).</p></body></html> Blow noise diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index f282310..20084ff 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -874,15 +874,15 @@ void ScreenPanelGL::paintGL() { int w = width(); int h = height(); + float factor = devicePixelRatioF(); glClear(GL_COLOR_BUFFER_BIT); - // TODO: check hiDPI compliance of this - glViewport(0, 0, w, h); + glViewport(0, 0, w*factor, h*factor); screenShader->bind(); - screenShader->setUniformValue("uScreenSize", (float)w, (float)h); + screenShader->setUniformValue("uScreenSize", (float)w*factor, (float)h*factor); int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); -- cgit v1.2.3 From 695839bb0ef8173ad2a549dd7766186fa65e949a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 12:32:50 +0200 Subject: lay base for video settings dialog --- src/frontend/qt_sdl/CMakeLists.txt | 1 + src/frontend/qt_sdl/VideoSettingsDialog.cpp | 67 +++++++++ src/frontend/qt_sdl/VideoSettingsDialog.h | 67 +++++++++ src/frontend/qt_sdl/VideoSettingsDialog.ui | 220 ++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 3 +- 5 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 src/frontend/qt_sdl/VideoSettingsDialog.cpp create mode 100644 src/frontend/qt_sdl/VideoSettingsDialog.h create mode 100644 src/frontend/qt_sdl/VideoSettingsDialog.ui (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 5778b40..a4bb5f5 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -5,6 +5,7 @@ SET(SOURCES_QT_SDL main_shaders.h EmuSettingsDialog.cpp InputConfigDialog.cpp + VideoSettingsDialog.cpp AudioSettingsDialog.cpp Input.cpp Platform.cpp diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp new file mode 100644 index 0000000..c0ec42a --- /dev/null +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -0,0 +1,67 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include + +#include "types.h" +#include "Platform.h" +#include "Config.h" +#include "PlatformConfig.h" + +#include "VideoSettingsDialog.h" +#include "ui_VideoSettingsDialog.h" + + +VideoSettingsDialog* VideoSettingsDialog::currentDlg = nullptr; + + +VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::VideoSettingsDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + // + + grp3DRenderer = new QButtonGroup(this); + grp3DRenderer->addButton(ui->rb3DSoftware, 0); + grp3DRenderer->addButton(ui->rb3DOpenGL, 1); + //connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int))); +} + +VideoSettingsDialog::~VideoSettingsDialog() +{ + delete ui; +} + +void VideoSettingsDialog::on_VideoSettingsDialog_accepted() +{ + // + Config::Save(); + + closeDlg(); +} + +void VideoSettingsDialog::on_VideoSettingsDialog_rejected() +{ + // + + closeDlg(); +} + +// diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h new file mode 100644 index 0000000..d64cee2 --- /dev/null +++ b/src/frontend/qt_sdl/VideoSettingsDialog.h @@ -0,0 +1,67 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef VIDEOSETTINGSDIALOG_H +#define VIDEOSETTINGSDIALOG_H + +#include +#include + +namespace Ui { class VideoSettingsDialog; } +class VideoSettingsDialog; + +class VideoSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VideoSettingsDialog(QWidget* parent); + ~VideoSettingsDialog(); + + static VideoSettingsDialog* currentDlg; + static VideoSettingsDialog* openDlg(QWidget* parent) + { + if (currentDlg) + { + currentDlg->activateWindow(); + return currentDlg; + } + + currentDlg = new VideoSettingsDialog(parent); + currentDlg->show(); + return currentDlg; + } + static void closeDlg() + { + currentDlg = nullptr; + } + +private slots: + void on_VideoSettingsDialog_accepted(); + void on_VideoSettingsDialog_rejected(); + + // + +private: + Ui::VideoSettingsDialog* ui; + + QButtonGroup* grp3DRenderer; +}; + +#endif // VIDEOSETTINGSDIALOG_H + diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.ui b/src/frontend/qt_sdl/VideoSettingsDialog.ui new file mode 100644 index 0000000..06670e5 --- /dev/null +++ b/src/frontend/qt_sdl/VideoSettingsDialog.ui @@ -0,0 +1,220 @@ + + + VideoSettingsDialog + + + + 0 + 0 + 482 + 237 + + + + Video settings - melonDS + + + + + + OpenGL renderer + + + + + + Internal resolution: + + + + + + + <html><head/><body><p>The resolution at which the 3D graphics will be rendered. Higher resolutions improve graphics quality when the main window is enlarged, but may also cause glitches.</p></body></html> + + + + + + + + + + Software renderer + + + + + + <html><head/><body><p>Run the software renderer on a separate thread. Yields better performance on multi-core CPUs.</p></body></html> + + + Use separate thread + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Display settings + + + + + + + 0 + 0 + + + + <html><head/><body><p>The interval at which to synchronize to the monitor's refresh rate. Set to 1 for a 60Hz monitor, 2 for 120Hz, ...</p></body></html> + + + VSync interval: + + + + + + + <html><head/><body><p>The interval at which to synchronize to the monitor's refresh rate. Set to 1 for a 60Hz monitor, 2 for 120Hz, ...</p></body></html> + + + 1 + + + 20 + + + + + + + <html><head/><body><p>Use OpenGL to draw the DS screens to the main window. May result in better frame pacing. Mandatory when using the OpenGL 3D renderer.</p></body></html> + + + OpenGL display + + + + + + + <html><head/><body><p>When using OpenGL, synchronize the video output to your monitor's refresh rate.</p></body></html> + + + VSync + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + <html><head/><body><p>The OpenGL renderer may be faster than software and supports graphical enhancements, but is more prone to glitches.</p></body></html> + + + OpenGL + + + + + + + <html><head/><body><p>The software renderer is more accurate and less prone to rendering glitches, but requires more CPU power.</p></body></html> + + + Software + + + + + + + 3D renderer: + + + + + + + + + + + + buttonBox + accepted() + VideoSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + VideoSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 20084ff..ae4bcf3 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -36,6 +36,7 @@ #include "Input.h" #include "EmuSettingsDialog.h" #include "InputConfigDialog.h" +#include "VideoSettingsDialog.h" #include "AudioSettingsDialog.h" #include "types.h" @@ -1573,7 +1574,7 @@ void MainWindow::onInputConfigFinished(int res) void MainWindow::onOpenVideoSettings() { - // + VideoSettingsDialog* dlg = VideoSettingsDialog::openDlg(this); } void MainWindow::onOpenAudioSettings() -- cgit v1.2.3 From 0804ab3c783363e28229a2028dc70b4238cb1802 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 15:53:32 +0200 Subject: * rework GPU's settings interface, make it config-agnostic * make video settings dialog functional, sorta * fix dialogs that were resizable --- src/GPU.cpp | 78 +++++++++++++- src/GPU.h | 22 +++- src/GPU2D.cpp | 14 +-- src/GPU2D.h | 2 +- src/GPU3D.cpp | 57 +---------- src/GPU3D.h | 7 +- src/GPU3D_OpenGL.cpp | 17 +--- src/GPU3D_Soft.cpp | 10 +- src/GPU_OpenGL.cpp | 39 ++++--- src/frontend/qt_sdl/AudioSettingsDialog.ui | 9 ++ src/frontend/qt_sdl/VideoSettingsDialog.cpp | 79 +++++++++++++-- src/frontend/qt_sdl/VideoSettingsDialog.h | 9 +- src/frontend/qt_sdl/VideoSettingsDialog.ui | 9 ++ src/frontend/qt_sdl/main.cpp | 152 +++++++++++++++++++--------- src/frontend/qt_sdl/main.h | 5 + 15 files changed, 342 insertions(+), 167 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 993086e..56db0e2 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -78,6 +78,7 @@ u8* VRAMPtr_BOBJ[0x8]; int FrontBuffer; u32* Framebuffer[2][2]; +int Renderer; bool Accelerated; GPU2D* GPU2D_A; @@ -93,8 +94,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; + Renderer = 0; Accelerated = false; - SetDisplaySettings(false); return true; } @@ -182,6 +183,8 @@ void Reset() int backbuf = FrontBuffer ? 0 : 1; GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); + + ResetRenderer(); } void Stop() @@ -274,8 +277,65 @@ void AssignFramebuffers() } } -void SetDisplaySettings(bool accel) +void InitRenderer(int renderer) +{ + if (renderer == 1) + { + if (!GLCompositor::Init()) + { + renderer = 0; + } + else if (!GPU3D::GLRenderer::Init()) + { + GLCompositor::DeInit(); + renderer = 0; + } + } + + if (renderer == 0) + { + GPU3D::SoftRenderer::Init(); + } + + Renderer = renderer; + Accelerated = renderer != 0; +} + +void DeInitRenderer() +{ + if (Renderer == 0) + { + GPU3D::SoftRenderer::DeInit(); + } + else + { + GPU3D::GLRenderer::DeInit(); + GLCompositor::DeInit(); + } +} + +void ResetRenderer() { + if (Renderer == 0) + { + GPU3D::SoftRenderer::Reset(); + } + else + { + GLCompositor::Reset(); + GPU3D::GLRenderer::Reset(); + } +} + +void SetRenderSettings(int renderer, RenderSettings& settings) +{ + if (renderer != Renderer) + { + DeInitRenderer(); + InitRenderer(renderer); + } + + bool accel = Accelerated; int fbsize; if (accel) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; @@ -296,10 +356,18 @@ void SetDisplaySettings(bool accel) AssignFramebuffers(); - GPU2D_A->SetDisplaySettings(accel); - GPU2D_B->SetDisplaySettings(accel); + GPU2D_A->SetRenderSettings(accel); + GPU2D_B->SetRenderSettings(accel); - Accelerated = accel; + if (Renderer == 0) + { + GPU3D::SoftRenderer::SetRenderSettings(settings); + } + else + { + GLCompositor::SetRenderSettings(settings); + GPU3D::GLRenderer::SetRenderSettings(settings); + } } diff --git a/src/GPU.h b/src/GPU.h index e85a5b4..039e065 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -20,7 +20,6 @@ #define GPU_H #include "GPU2D.h" -#include "GPU3D.h" namespace GPU { @@ -72,6 +71,17 @@ extern u32* Framebuffer[2][2]; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; +extern int Renderer; + + +typedef struct +{ + bool Soft_Threaded; + + int GL_ScaleFactor; + +} RenderSettings; + bool Init(); void DeInit(); @@ -80,7 +90,11 @@ void Stop(); void DoSavestate(Savestate* file); -void SetDisplaySettings(bool accel); +void InitRenderer(int renderer); +void DeInitRenderer(); +void ResetRenderer(); + +void SetRenderSettings(int renderer, RenderSettings& settings); u8* GetUniqueBankPtr(u32 mask, u32 offset); @@ -429,7 +443,7 @@ bool Init(); void DeInit(); void Reset(); -void UpdateDisplaySettings(); +void SetRenderSettings(RenderSettings& settings); void RenderFrame(); void BindOutputTexture(); @@ -438,4 +452,6 @@ void BindOutputTexture(); } +#include "GPU3D.h" + #endif diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 6f950b7..604a4ee 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -202,16 +202,8 @@ void GPU2D::DoSavestate(Savestate* file) file->Var32(&CaptureCnt); } - if (file->IsAtleastVersion(2, 1)) - { - file->Var32(&Win0Active); - file->Var32(&Win1Active); - } - else - { - Win0Active = 0; - Win1Active = 0; - } + file->Var32(&Win0Active); + file->Var32(&Win1Active); if (!file->Saving) { @@ -232,7 +224,7 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetDisplaySettings(bool accel) +void GPU2D::SetRenderSettings(bool accel) { Accelerated = accel; diff --git a/src/GPU2D.h b/src/GPU2D.h index c4bd2f9..521adf0 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetDisplaySettings(bool accel); + void SetRenderSettings(bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index e687e37..bd27783 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -157,8 +157,6 @@ u32 NumCommands, CurCommand, ParamCount, TotalParams; bool GeometryEnabled; bool RenderingEnabled; -int Renderer; - u32 DispCnt; u8 AlphaRefVal, AlphaRef; @@ -280,17 +278,11 @@ bool Init() CmdStallQueue = new FIFO(64); - Renderer = -1; - // SetRenderer() will be called to set it up later - return true; } void DeInit() { - if (Renderer == 0) SoftRenderer::DeInit(); - else GLRenderer::DeInit(); - delete CmdFIFO; delete CmdPIPE; @@ -391,8 +383,6 @@ void Reset() FlushAttributes = 0; ResetRenderingState(); - if (Renderer == 0) SoftRenderer::Reset(); - else GLRenderer::Reset(); } void DoSavestate(Savestate* file) @@ -607,43 +597,6 @@ void SetEnabled(bool geometry, bool rendering) } -int InitRenderer(bool hasGL) -{ - int renderer = hasGL ? Config::_3DRenderer : 0; - - if (renderer == 1) - { - if (!GLRenderer::Init()) - renderer = 0; - } -printf("renderer: %d\n", renderer); - if (renderer == 0) SoftRenderer::Init(); - - Renderer = renderer; - UpdateRendererConfig(); - GPU::SetDisplaySettings(Renderer != 0); - return renderer; -} - -void DeInitRenderer() -{ - if (Renderer == 0) SoftRenderer::DeInit(); - else GLRenderer::DeInit(); -} - -void UpdateRendererConfig() -{ - if (Renderer == 0) - { - SoftRenderer::SetupRenderThread(); - } - else - { - GLRenderer::UpdateDisplaySettings(); - } -} - - void MatrixLoadIdentity(s32* m) { @@ -2470,7 +2423,7 @@ void CheckFIFODMA() void VCount144() { - if (Renderer == 0) SoftRenderer::VCount144(); + if (GPU::Renderer == 0) SoftRenderer::VCount144(); } @@ -2552,14 +2505,14 @@ void VBlank() void VCount215() { - if (Renderer == 0) SoftRenderer::RenderFrame(); - else GLRenderer::RenderFrame(); + if (GPU::Renderer == 0) SoftRenderer::RenderFrame(); + else GLRenderer::RenderFrame(); } u32* GetLine(int line) { - if (Renderer == 0) return SoftRenderer::GetLine(line); - else return GLRenderer::GetLine(line); + if (GPU::Renderer == 0) return SoftRenderer::GetLine(line); + else return GLRenderer::GetLine(line); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 1fd3383..71f069d 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -102,10 +102,6 @@ void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -int InitRenderer(bool hasGL); -void DeInitRenderer(); -void UpdateRendererConfig(); - void ExecuteCommand(); s32 CyclesToRunFor(); @@ -134,6 +130,7 @@ bool Init(); void DeInit(); void Reset(); +void SetRenderSettings(GPU::RenderSettings& settings); void SetupRenderThread(); void VCount144(); @@ -149,7 +146,7 @@ bool Init(); void DeInit(); void Reset(); -void UpdateDisplaySettings(); +void SetRenderSettings(GPU::RenderSettings& settings); void RenderFrame(); void PrepareCaptureFrame(); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 9a78504..8a06874 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -372,19 +372,11 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); - if (!GPU::GLCompositor::Init()) - { - // TODO: clean up things? fail more gracefully?? - return false; - } - return true; } void DeInit() { - GPU::GLCompositor::DeInit(); - glDeleteTextures(1, &TexMemID); glDeleteTextures(1, &TexPalMemID); @@ -407,13 +399,12 @@ void DeInit() void Reset() { - GPU::GLCompositor::Reset(); } -void UpdateDisplaySettings() +void SetRenderSettings(GPU::RenderSettings& settings) { - int scale = Config::GL_ScaleFactor; - bool antialias = false; //Config::GL_Antialias; + int scale = settings.GL_ScaleFactor; + bool antialias = false; // REMOVE ME! if (antialias) scale *= 2; @@ -490,8 +481,6 @@ void UpdateDisplaySettings() //glLineWidth(scale); //glLineWidth(1.5); - - GPU::GLCompositor::UpdateDisplaySettings(); } diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 8397898..e9d8e75 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -60,6 +60,7 @@ bool Enabled; // threading +bool Threaded; void* RenderThread; bool RenderThreadRunning; bool RenderThreadRendering; @@ -83,7 +84,7 @@ void StopRenderThread() void SetupRenderThread() { - if (Config::Threaded3D) + if (Threaded) { if (!RenderThreadRunning) { @@ -112,6 +113,7 @@ bool Init() Sema_RenderDone = Platform::Semaphore_Create(); Sema_ScanlineCount = Platform::Semaphore_Create(); + Threaded = false; RenderThreadRunning = false; RenderThreadRendering = false; @@ -138,6 +140,12 @@ void Reset() SetupRenderThread(); } +void SetRenderSettings(GPU::RenderSettings& settings) +{ + Threaded = settings.Soft_Threaded; + SetupRenderThread(); +} + // Notes on the interpolator: diff --git a/src/GPU_OpenGL.cpp b/src/GPU_OpenGL.cpp index 99eb845..1cb6864 100644 --- a/src/GPU_OpenGL.cpp +++ b/src/GPU_OpenGL.cpp @@ -142,9 +142,9 @@ void Reset() } -void UpdateDisplaySettings() +void SetRenderSettings(RenderSettings& settings) { - int scale = Config::GL_ScaleFactor; + int scale = settings.GL_ScaleFactor; Scale = scale; ScreenW = 256 * scale; @@ -175,28 +175,25 @@ void RenderFrame() OpenGL::UseShaderProgram(CompShader[0]); glUniform1ui(CompScaleLoc[0], Scale); - //if (RunningSomething) + int frontbuf = GPU::FrontBuffer; + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, CompScreenInputTex); + + if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) { - int frontbuf = GPU::FrontBuffer; - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, CompScreenInputTex); - - if (GPU::Framebuffer[frontbuf][0] && GPU::Framebuffer[frontbuf][1]) - { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, - GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); - } - - glActiveTexture(GL_TEXTURE1); - GPU3D::GLRenderer::SetupAccelFrame(); - - glBindBuffer(GL_ARRAY_BUFFER, CompVertexBufferID); - glBindVertexArray(CompVertexArrayID); - glDrawArrays(GL_TRIANGLES, 0, 4*3); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, + GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } + glActiveTexture(GL_TEXTURE1); + GPU3D::GLRenderer::SetupAccelFrame(); + + glBindBuffer(GL_ARRAY_BUFFER, CompVertexBufferID); + glBindVertexArray(CompVertexArrayID); + glDrawArrays(GL_TRIANGLES, 0, 4*3); + glFlush(); } diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.ui b/src/frontend/qt_sdl/AudioSettingsDialog.ui index 9ae8baa..bcaf937 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.ui +++ b/src/frontend/qt_sdl/AudioSettingsDialog.ui @@ -10,10 +10,19 @@ 230 + + + 0 + 0 + + Audio settings - melonDS + + QLayout::SetFixedSize + diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 0aeb154..09f1ab4 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -46,7 +46,7 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui( grp3DRenderer = new QButtonGroup(this); grp3DRenderer->addButton(ui->rb3DSoftware, 0); grp3DRenderer->addButton(ui->rb3DOpenGL, 1); - //connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int))); + connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int))); grp3DRenderer->button(Config::_3DRenderer)->setChecked(true); ui->cbGLDisplay->setChecked(Config::ScreenUseGL != 0); @@ -57,8 +57,21 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui( ui->cbSoftwareThreaded->setChecked(Config::Threaded3D != 0); for (int i = 1; i <= 16; i++) - ui->cbxGLResolution->addItem(QString("%1x native (%2x%3)").arg(i).arg(256*i).arg(192*i), QVariant(i)); - ui->cbxGLResolution->setCurrentIndex(Config::GL_ScaleFactor); + ui->cbxGLResolution->addItem(QString("%1x native (%2x%3)").arg(i).arg(256*i).arg(192*i)); + ui->cbxGLResolution->setCurrentIndex(Config::GL_ScaleFactor-1); + + if (Config::_3DRenderer == 0) + { + ui->cbGLDisplay->setEnabled(true); + ui->cbSoftwareThreaded->setEnabled(true); + ui->cbxGLResolution->setEnabled(false); + } + else + { + ui->cbGLDisplay->setEnabled(false); + ui->cbSoftwareThreaded->setEnabled(false); + ui->cbxGLResolution->setEnabled(true); + } } VideoSettingsDialog::~VideoSettingsDialog() @@ -68,7 +81,6 @@ VideoSettingsDialog::~VideoSettingsDialog() void VideoSettingsDialog::on_VideoSettingsDialog_accepted() { - // Config::Save(); closeDlg(); @@ -76,9 +88,64 @@ void VideoSettingsDialog::on_VideoSettingsDialog_accepted() void VideoSettingsDialog::on_VideoSettingsDialog_rejected() { - // + bool old_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + + Config::_3DRenderer = oldRenderer; + Config::ScreenUseGL = oldGLDisplay; + Config::ScreenVSync = oldVSync; + Config::ScreenVSyncInterval = oldVSyncInterval; + Config::Threaded3D = oldSoftThreaded; + Config::GL_ScaleFactor = oldGLScale; + + bool new_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + emit updateVideoSettings(old_gl != new_gl); closeDlg(); } -// +void VideoSettingsDialog::onChange3DRenderer(int renderer) +{ + bool old_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + + Config::_3DRenderer = renderer; + + if (renderer == 0) + { + ui->cbGLDisplay->setEnabled(true); + ui->cbSoftwareThreaded->setEnabled(true); + ui->cbxGLResolution->setEnabled(false); + } + else + { + ui->cbGLDisplay->setEnabled(false); + ui->cbSoftwareThreaded->setEnabled(false); + ui->cbxGLResolution->setEnabled(true); + } + + bool new_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + emit updateVideoSettings(old_gl != new_gl); +} + +void VideoSettingsDialog::on_cbGLDisplay_stateChanged(int state) +{ + bool old_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + + Config::ScreenUseGL = (state != 0); + + bool new_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + emit updateVideoSettings(old_gl != new_gl); +} + +void VideoSettingsDialog::on_cbSoftwareThreaded_stateChanged(int state) +{ + Config::Threaded3D = (state != 0); + + emit updateVideoSettings(false); +} + +void VideoSettingsDialog::on_cbxGLResolution_currentIndexChanged(int idx) +{ + Config::GL_ScaleFactor = idx+1; + + emit updateVideoSettings(false); +} diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h index 05dfecb..2f6d17c 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.h +++ b/src/frontend/qt_sdl/VideoSettingsDialog.h @@ -51,11 +51,18 @@ public: currentDlg = nullptr; } +signals: + void updateVideoSettings(bool glchange); + private slots: void on_VideoSettingsDialog_accepted(); void on_VideoSettingsDialog_rejected(); - // + void onChange3DRenderer(int renderer); + void on_cbGLDisplay_stateChanged(int state); + void on_cbxGLResolution_currentIndexChanged(int idx); + + void on_cbSoftwareThreaded_stateChanged(int state); private: Ui::VideoSettingsDialog* ui; diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.ui b/src/frontend/qt_sdl/VideoSettingsDialog.ui index 06670e5..6cdd5d8 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.ui +++ b/src/frontend/qt_sdl/VideoSettingsDialog.ui @@ -10,10 +10,19 @@ 237 + + + 0 + 0 + + Video settings - melonDS + + QLayout::SetFixedSize + diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index ae4bcf3..658ae8b 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -68,6 +68,10 @@ EmuThread* emuThread; int autoScreenSizing = 0; +int videoRenderer; +GPU::RenderSettings videoSettings; +bool videoSettingsDirty; + SDL_AudioDeviceID audioDevice; int audioFreq; SDL_cond* audioSync; @@ -251,9 +255,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) EmuRunning = 2; RunningSomething = false; - //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(update())); connect(this, SIGNAL(windowUpdate()), mainWindow->panel, SLOT(update())); - //connect(this, SIGNAL(windowUpdate()), mainWindow, SLOT(repaint())); connect(this, SIGNAL(windowTitleChange(QString)), mainWindow, SLOT(onTitleUpdate(QString))); connect(this, SIGNAL(windowEmuStart()), mainWindow, SLOT(onEmuStart())); connect(this, SIGNAL(windowEmuStop()), mainWindow, SLOT(onEmuStop())); @@ -312,6 +314,7 @@ void* EmuThread::oglGetProcAddress(const char* proc) void EmuThread::run() { + bool hasOGL = mainWindow->hasOGL; u32 mainScreenPos[3]; NDS::Init(); @@ -321,20 +324,20 @@ void EmuThread::run() mainScreenPos[2] = 0; autoScreenSizing = 0; - /*if (Screen_UseGL) - { - uiGLMakeContextCurrent(GLContext); - GPU3D::InitRenderer(true); - uiGLMakeContextCurrent(NULL); - } - else*/ + videoSettingsDirty = false; + videoSettings.Soft_Threaded = Config::Threaded3D != 0; + videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor; + + if (hasOGL) { - //GPU3D::InitRenderer(false); - bool res = oglContext->makeCurrent(oglSurface); - printf("good? %d\n", res); - OpenGL::Init(); - GPU3D::InitRenderer(res); + oglContext->makeCurrent(oglSurface); + videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0; } + else + videoRenderer = 0; + + GPU::InitRenderer(videoRenderer); + GPU::SetRenderSettings(videoRenderer, videoSettings); Input::Init(); @@ -377,6 +380,29 @@ void EmuThread::run() { EmuStatus = 1; + // update render settings if needed + if (videoSettingsDirty) + { + if (hasOGL != mainWindow->hasOGL) + { + hasOGL = mainWindow->hasOGL; + if (hasOGL) + { + oglContext->makeCurrent(oglSurface); + videoRenderer = OpenGL::Init() ? Config::_3DRenderer : 0; + } + else + videoRenderer = 0; + } + else + videoRenderer = hasOGL ? Config::_3DRenderer : 0; + + videoSettingsDirty = false; + videoSettings.Soft_Threaded = Config::Threaded3D != 0; + videoSettings.GL_ScaleFactor = Config::GL_ScaleFactor; + GPU::SetRenderSettings(videoRenderer, videoSettings); + } + // process input and hotkeys NDS::SetKeyMask(Input::InputMask); @@ -390,12 +416,6 @@ void EmuThread::run() // microphone input micProcess(); - /*if (Screen_UseGL) - { - uiGLBegin(GLContext); - uiGLMakeContextCurrent(GLContext); - }*/ - // auto screen layout if (Config::ScreenSizing == 3) { @@ -435,12 +455,6 @@ void EmuThread::run() if (EmuRunning == 0) break; - /*if (Screen_UseGL) - { - GLScreen_DrawScreen(); - uiGLEnd(GLContext); - } - uiAreaQueueRedrawAll(MainDrawArea);*/ emit windowUpdate(); bool fastforward = Input::HotkeyDown(HK_FastForward); @@ -513,18 +527,8 @@ void EmuThread::run() lastmeasuretick = lasttick; fpslimitcount = 0; - /*if (Screen_UseGL) - { - uiGLBegin(GLContext); - uiGLMakeContextCurrent(GLContext); - GLScreen_DrawScreen(); - uiGLEnd(GLContext); - } - uiAreaQueueRedrawAll(MainDrawArea);*/ emit windowUpdate(); - //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); - EmuStatus = EmuRunning; sprintf(melontitle, "melonDS " MELONDS_VERSION); @@ -536,8 +540,7 @@ void EmuThread::run() EmuStatus = 0; - //if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); - + GPU::DeInitRenderer(); NDS::DeInit(); //Platform::LAN_DeInit(); @@ -549,7 +552,8 @@ void EmuThread::run() else OSD::DeInit(false);*/ - //if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + if (hasOGL) + oglContext->doneCurrent(); } void EmuThread::changeWindowTitle(char* title) @@ -794,6 +798,7 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) ScreenPanelGL::~ScreenPanelGL() { // CHECKME!!!! + // ALSO TODO: CLEANUP delete screenShader; } @@ -888,7 +893,7 @@ void ScreenPanelGL::paintGL() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); - if (true) + if (GPU::Renderer != 0) { // hardware-accelerated render GPU::GLCompositor::BindOutputTexture(); @@ -1162,11 +1167,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) } setMenuBar(menubar); - //panel = new ScreenPanelNative(this); - panel = new ScreenPanelGL(this); - setCentralWidget(panel); - connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged())); - emit screenLayoutChange(); + show(); + createScreenPanel(); resize(Config::WindowWidth, Config::WindowHeight); @@ -1210,9 +1212,45 @@ MainWindow::~MainWindow() { } +void MainWindow::createScreenPanel() +{ + hasOGL = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0); + + if (hasOGL) + { + ScreenPanelGL* panelGL = new ScreenPanelGL(this); + panelGL->show(); + + if (!panelGL->isValid()) + hasOGL = false; + else + { + QSurfaceFormat fmt = panelGL->format(); + if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 2)) + hasOGL = false; + } + + if (!hasOGL) + delete panelGL; + else + panel = panelGL; + } + + if (!hasOGL) + { + panel = new ScreenPanelNative(this); + panel->show(); + } + + setCentralWidget(panel); + connect(this, SIGNAL(screenLayoutChange()), panel, SLOT(onScreenLayoutChanged())); + emit screenLayoutChange(); +} + QOpenGLContext* MainWindow::getOGLContext() { - // TODO: check whether we can actually pull this! + if (!hasOGL) return nullptr; + QOpenGLWidget* glpanel = (QOpenGLWidget*)panel; return glpanel->context(); } @@ -1575,6 +1613,7 @@ void MainWindow::onInputConfigFinished(int res) void MainWindow::onOpenVideoSettings() { VideoSettingsDialog* dlg = VideoSettingsDialog::openDlg(this); + connect(dlg, &VideoSettingsDialog::updateVideoSettings, this, &MainWindow::onUpdateVideoSettings); } void MainWindow::onOpenAudioSettings() @@ -1745,6 +1784,23 @@ void MainWindow::onEmuStop() actStop->setEnabled(false); } +void MainWindow::onUpdateVideoSettings(bool glchange) +{ + if (glchange) + { + emuThread->emuPause(); + + delete panel; + createScreenPanel(); + connect(emuThread, SIGNAL(windowUpdate()), panel, SLOT(update())); + } + + videoSettingsDirty = true; + + if (glchange) + emuThread->emuUnpause(); +} + void emuStop() { @@ -1790,6 +1846,9 @@ int main(int argc, char** argv) Config::Load(); #define SANITIZE(var, min, max) { if (var < min) var = min; else if (var > max) var = max; } + SANITIZE(Config::_3DRenderer, 0, 1); + SANITIZE(Config::ScreenVSyncInterval, 1, 20); + SANITIZE(Config::GL_ScaleFactor, 1, 16); SANITIZE(Config::AudioVolume, 0, 256); SANITIZE(Config::MicInputType, 0, 3); SANITIZE(Config::ScreenRotation, 0, 3); @@ -1900,7 +1959,6 @@ int main(int argc, char** argv) Input::OpenJoystick(); mainWindow = new MainWindow(); - mainWindow->show(); emuThread = new EmuThread(); emuThread->start(); diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 8759e95..ef51158 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -171,6 +171,7 @@ public: explicit MainWindow(QWidget* parent = nullptr); ~MainWindow(); + bool hasOGL; QOpenGLContext* getOGLContext(); protected: @@ -221,7 +222,11 @@ private slots: void onEmuStart(); void onEmuStop(); + void onUpdateVideoSettings(bool glchange); + private: + void createScreenPanel(); + QString loadErrorStr(int error); public: -- cgit v1.2.3 From f7e53c6f71c3bf6f082d1e5857f474f79f992602 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 15:58:18 +0200 Subject: so you can't resize() before show()ing?? bullshit. --- src/frontend/qt_sdl/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 658ae8b..b6282fe 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1167,11 +1167,11 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) } setMenuBar(menubar); + resize(Config::WindowWidth, Config::WindowHeight); + show(); createScreenPanel(); - resize(Config::WindowWidth, Config::WindowHeight); - for (int i = 0; i < 9; i++) { actSaveState[i]->setEnabled(false); -- cgit v1.2.3 From 2912a07b8babb602aaf315e62667044a07adf8e7 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 17:00:25 +0200 Subject: fix bugs, clean up some of the shit --- src/GPU.cpp | 8 ++++---- src/frontend/qt_sdl/VideoSettingsDialog.cpp | 2 +- src/frontend/qt_sdl/main.cpp | 14 +++++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 56db0e2..60f863e 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -339,10 +339,10 @@ void SetRenderSettings(int renderer, RenderSettings& settings) int fbsize; if (accel) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; - if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; - if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; - if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; - if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; + if (Framebuffer[0][0]) { delete[] Framebuffer[0][0]; Framebuffer[0][0] = nullptr; } + if (Framebuffer[1][0]) { delete[] Framebuffer[1][0]; Framebuffer[1][0] = nullptr; } + if (Framebuffer[0][1]) { delete[] Framebuffer[0][1]; Framebuffer[0][1] = nullptr; } + if (Framebuffer[1][1]) { delete[] Framebuffer[1][1]; Framebuffer[1][1] = nullptr; } Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 9645a3d..efb5051 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -59,7 +59,7 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui( for (int i = 1; i <= 16; i++) ui->cbxGLResolution->addItem(QString("%1x native (%2x%3)").arg(i).arg(256*i).arg(192*i)); ui->cbxGLResolution->setCurrentIndex(Config::GL_ScaleFactor-1); -printf("GL scale = %d\n", Config::GL_ScaleFactor); + if (Config::_3DRenderer == 0) { ui->cbGLDisplay->setEnabled(true); diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index b6282fe..de71da9 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -282,7 +282,7 @@ void EmuThread::initOpenGL() return; } - oglContext = new QOpenGLContext();//oglSurface); + oglContext = new QOpenGLContext(); oglContext->setFormat(oglSurface->format()); oglContext->setShareContext(windowctx); if (!oglContext->create()) @@ -797,9 +797,16 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) ScreenPanelGL::~ScreenPanelGL() { - // CHECKME!!!! - // ALSO TODO: CLEANUP + makeCurrent(); + + glDeleteTextures(1, &screenTexture); + + glDeleteVertexArrays(1, &screenVertexArray); + glDeleteBuffers(1, &screenVertexBuffer); + delete screenShader; + + doneCurrent(); } void ScreenPanelGL::setupScreenLayout() @@ -1793,6 +1800,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange) delete panel; createScreenPanel(); connect(emuThread, SIGNAL(windowUpdate()), panel, SLOT(update())); + if (hasOGL) emuThread->initOpenGL(); } videoSettingsDirty = true; -- cgit v1.2.3 From 79d4183ccdac6d0b2a82f99ad169b7fe6349febc Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 18:11:41 +0200 Subject: re-add OSD system --- src/frontend/qt_sdl/CMakeLists.txt | 3 + src/frontend/qt_sdl/OSD.cpp | 474 +++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/OSD.h | 36 +++ src/frontend/qt_sdl/OSD_shaders.h | 65 +++++ src/frontend/qt_sdl/font.h | 135 +++++++++++ src/frontend/qt_sdl/main.cpp | 18 +- src/frontend/qt_sdl/main_shaders.h | 50 ---- 7 files changed, 730 insertions(+), 51 deletions(-) create mode 100644 src/frontend/qt_sdl/OSD.cpp create mode 100644 src/frontend/qt_sdl/OSD.h create mode 100644 src/frontend/qt_sdl/OSD_shaders.h create mode 100644 src/frontend/qt_sdl/font.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index a4bb5f5..0b7fa54 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -8,6 +8,9 @@ SET(SOURCES_QT_SDL VideoSettingsDialog.cpp AudioSettingsDialog.cpp Input.cpp + OSD.cpp + OSD_shaders.h + font.h Platform.cpp PlatformConfig.cpp diff --git a/src/frontend/qt_sdl/OSD.cpp b/src/frontend/qt_sdl/OSD.cpp new file mode 100644 index 0000000..4e4e40f --- /dev/null +++ b/src/frontend/qt_sdl/OSD.cpp @@ -0,0 +1,474 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include +#include +#include "../types.h" + +#include "main.h" +#include + +#include "OSD.h" +#include "OSD_shaders.h" +#include "font.h" + +#include "PlatformConfig.h" + +extern MainWindow* mainWindow; + +namespace OSD +{ + +const u32 kOSDMargin = 6; + +struct Item +{ + Uint32 Timestamp; + char Text[256]; + u32 Color; + + u32 Width, Height; + u32* Bitmap; + + bool NativeBitmapLoaded; + QImage NativeBitmap; + + bool GLTextureLoaded; + GLuint GLTexture; + +}; + +std::deque ItemQueue; + +QOpenGLShaderProgram* Shader; +GLint uScreenSize, uOSDPos, uOSDSize; +GLuint OSDVertexArray; +GLuint OSDVertexBuffer; + +volatile bool Rendering; + + +bool Init(QOpenGLFunctions_3_2_Core* f) +{ + if (f) + { + Shader = new QOpenGLShaderProgram(); + Shader->addShaderFromSourceCode(QOpenGLShader::Vertex, kScreenVS_OSD); + Shader->addShaderFromSourceCode(QOpenGLShader::Fragment, kScreenFS_OSD); + + GLuint pid = Shader->programId(); + f->glBindAttribLocation(pid, 0, "vPosition"); + f->glBindFragDataLocation(pid, 0, "oColor"); + + Shader->link(); + + Shader->bind(); + Shader->setUniformValue("OSDTex", (GLint)0); + Shader->release(); + + uScreenSize = Shader->uniformLocation("uScreenSize"); + uOSDPos = Shader->uniformLocation("uOSDPos"); + uOSDSize = Shader->uniformLocation("uOSDSize"); + + float vertices[6*2] = + { + 0, 0, + 1, 1, + 1, 0, + 0, 0, + 0, 1, + 1, 1 + }; + + f->glGenBuffers(1, &OSDVertexBuffer); + f->glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + f->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + f->glGenVertexArrays(1, &OSDVertexArray); + f->glBindVertexArray(OSDVertexArray); + f->glEnableVertexAttribArray(0); // position + f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0)); + } + + return true; +} + +void DeInit(QOpenGLFunctions_3_2_Core* f) +{ + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item& item = *it; + + if (item.GLTextureLoaded && f) f->glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; + + it = ItemQueue.erase(it); + } + + if (f) delete Shader; +} + + +int FindBreakPoint(const char* text, int i) +{ + // i = character that went out of bounds + + for (int j = i; j >= 0; j--) + { + if (text[j] == ' ') + return j; + } + + return i; +} + +void LayoutText(const char* text, u32* width, u32* height, int* breaks) +{ + u32 w = 0; + u32 h = 14; + u32 totalw = 0; + u32 maxw = mainWindow->panel->width() - (kOSDMargin*2); + int lastbreak = -1; + int numbrk = 0; + u16* ptr; + + memset(breaks, 0, sizeof(int)*64); + + for (int i = 0; text[i] != '\0'; ) + { + int glyphsize; + if (text[i] == ' ') + { + glyphsize = 6; + } + else + { + u32 ch = text[i]; + if (ch < 0x10 || ch > 0x7E) ch = 0x7F; + + ptr = &font[(ch-0x10) << 4]; + glyphsize = ptr[0]; + if (!glyphsize) glyphsize = 6; + else glyphsize += 2; // space around the character + } + + w += glyphsize; + if (w > maxw) + { + // wrap shit as needed + if (text[i] == ' ') + { + if (numbrk >= 64) break; + breaks[numbrk++] = i; + i++; + } + else + { + int brk = FindBreakPoint(text, i); + if (brk != lastbreak) i = brk; + + if (numbrk >= 64) break; + breaks[numbrk++] = i; + + lastbreak = brk; + } + + w = 0; + h += 14; + } + else + i++; + + if (w > totalw) totalw = w; + } + + *width = totalw; + *height = h; +} + +u32 RainbowColor(u32 inc) +{ + // inspired from Acmlmboard + + if (inc < 100) return 0xFFFF9B9B + (inc << 8); + else if (inc < 200) return 0xFFFFFF9B - ((inc-100) << 16); + else if (inc < 300) return 0xFF9BFF9B + (inc-200); + else if (inc < 400) return 0xFF9BFFFF - ((inc-300) << 8); + else if (inc < 500) return 0xFF9B9BFF + ((inc-400) << 16); + else return 0xFFFF9BFF - (inc-500); +} + +void RenderText(u32 color, const char* text, Item* item) +{ + u32 w, h; + int breaks[64]; + + bool rainbow = (color == 0); + u32 rainbowinc = ((text[0] * 17) + (SDL_GetTicks() * 13)) % 600; + + color |= 0xFF000000; + const u32 shadow = 0xE0000000; + + LayoutText(text, &w, &h, breaks); + + item->Width = w; + item->Height = h; + item->Bitmap = new u32[w*h]; + memset(item->Bitmap, 0, w*h*sizeof(u32)); + + u32 x = 0, y = 1; + u32 maxw = mainWindow->panel->width() - (kOSDMargin*2); + int curline = 0; + u16* ptr; + + for (int i = 0; text[i] != '\0'; ) + { + int glyphsize; + if (text[i] == ' ') + { + x += 6; + } + else + { + u32 ch = text[i]; + if (ch < 0x10 || ch > 0x7E) ch = 0x7F; + + ptr = &font[(ch-0x10) << 4]; + int glyphsize = ptr[0]; + if (!glyphsize) x += 6; + else + { + x++; + + if (rainbow) + { + color = RainbowColor(rainbowinc); + rainbowinc = (rainbowinc + 30) % 600; + } + + // draw character + for (int cy = 0; cy < 12; cy++) + { + u16 val = ptr[4+cy]; + + for (int cx = 0; cx < glyphsize; cx++) + { + if (val & (1<Bitmap[((y+cy) * w) + x+cx] = color; + } + } + + x += glyphsize; + x++; + } + } + + i++; + if (breaks[curline] && i >= breaks[curline]) + { + i = breaks[curline++]; + if (text[i] == ' ') i++; + + x = 0; + y += 14; + } + } + + // shadow + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + u32 val; + + val = item->Bitmap[(y * w) + x]; + if ((val >> 24) == 0xFF) continue; + + if (x > 0) val = item->Bitmap[(y * w) + x-1]; + if (x < w-1) val |= item->Bitmap[(y * w) + x+1]; + if (y > 0) + { + if (x > 0) val |= item->Bitmap[((y-1) * w) + x-1]; + val |= item->Bitmap[((y-1) * w) + x]; + if (x < w-1) val |= item->Bitmap[((y-1) * w) + x+1]; + } + if (y < h-1) + { + if (x > 0) val |= item->Bitmap[((y+1) * w) + x-1]; + val |= item->Bitmap[((y+1) * w) + x]; + if (x < w-1) val |= item->Bitmap[((y+1) * w) + x+1]; + } + + if ((val >> 24) == 0xFF) + item->Bitmap[(y * w) + x] = shadow; + } + } +} + + +void AddMessage(u32 color, const char* text) +{ + if (!Config::ShowOSD) return; + + while (Rendering); + + Item item; + + item.Timestamp = SDL_GetTicks(); + strncpy(item.Text, text, 255); item.Text[255] = '\0'; + item.Color = color; + item.Bitmap = nullptr; + + item.NativeBitmapLoaded = false; + item.GLTextureLoaded = false; + + ItemQueue.push_back(item); +} + +void Update(QOpenGLFunctions_3_2_Core* f) +{ + if (!Config::ShowOSD) + { + Rendering = true; + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item& item = *it; + + if (item.GLTextureLoaded && f) f->glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; + + it = ItemQueue.erase(it); + } + Rendering = false; + return; + } + + Rendering = true; + + Uint32 tick_now = SDL_GetTicks(); + Uint32 tick_min = tick_now - 2500; + + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item& item = *it; + + if (item.Timestamp < tick_min) + { + if (item.GLTextureLoaded) f->glDeleteTextures(1, &item.GLTexture); + if (item.Bitmap) delete[] item.Bitmap; + + it = ItemQueue.erase(it); + continue; + } + + if (!item.Bitmap) + { + RenderText(item.Color, item.Text, &item); + } + + it++; + } + + Rendering = false; +} + +void DrawNative(QPainter& painter) +{ + if (!Config::ShowOSD) return; + + Rendering = true; + + u32 y = kOSDMargin; + + painter.resetTransform(); + + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item& item = *it; + + if (!item.NativeBitmapLoaded) + { + item.NativeBitmap = QImage((const uchar*)item.Bitmap, item.Width, item.Height, QImage::Format_ARGB32_Premultiplied); + item.NativeBitmapLoaded = true; + } + + painter.drawImage(kOSDMargin, y, item.NativeBitmap); + + y += item.Height; + it++; + } + + Rendering = false; +} + +void DrawGL(QOpenGLFunctions_3_2_Core* f, float w, float h) +{ + if (!Config::ShowOSD) return; + if (!mainWindow || !mainWindow->panel) return; + + Rendering = true; + + u32 y = kOSDMargin; + + Shader->bind(); + + f->glUniform2f(uScreenSize, w, h); + + f->glBindBuffer(GL_ARRAY_BUFFER, OSDVertexBuffer); + f->glBindVertexArray(OSDVertexArray); + + f->glActiveTexture(GL_TEXTURE0); + + f->glEnable(GL_BLEND); + f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + for (auto it = ItemQueue.begin(); it != ItemQueue.end(); ) + { + Item& item = *it; + + if (!item.GLTextureLoaded) + { + f->glGenTextures(1, &item.GLTexture); + f->glBindTexture(GL_TEXTURE_2D, item.GLTexture); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, item.Width, item.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, item.Bitmap); + + item.GLTextureLoaded = true; + } + + f->glBindTexture(GL_TEXTURE_2D, item.GLTexture); + f->glUniform2i(uOSDPos, kOSDMargin, y); + f->glUniform2i(uOSDSize, item.Width, item.Height); + f->glDrawArrays(GL_TRIANGLES, 0, 2*3); + + y += item.Height; + it++; + } + + f->glDisable(GL_BLEND); + Shader->release(); + + Rendering = false; +} + +} diff --git a/src/frontend/qt_sdl/OSD.h b/src/frontend/qt_sdl/OSD.h new file mode 100644 index 0000000..79d9df0 --- /dev/null +++ b/src/frontend/qt_sdl/OSD.h @@ -0,0 +1,36 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef OSD_H +#define OSD_H + +namespace OSD +{ + +bool Init(QOpenGLFunctions_3_2_Core* f); +void DeInit(QOpenGLFunctions_3_2_Core* f); + +void AddMessage(u32 color, const char* text); + +void Update(QOpenGLFunctions_3_2_Core* f); +void DrawNative(QPainter& painter); +void DrawGL(QOpenGLFunctions_3_2_Core* f, float w, float h); + +} + +#endif // OSD_H diff --git a/src/frontend/qt_sdl/OSD_shaders.h b/src/frontend/qt_sdl/OSD_shaders.h new file mode 100644 index 0000000..5a64f66 --- /dev/null +++ b/src/frontend/qt_sdl/OSD_shaders.h @@ -0,0 +1,65 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef OSD_SHADERS_H +#define OSD_SHADERS_H + +const char* kScreenVS_OSD = R"(#version 140 + +uniform vec2 uScreenSize; + +uniform ivec2 uOSDPos; +uniform ivec2 uOSDSize; + +in vec2 vPosition; + +smooth out vec2 fTexcoord; + +void main() +{ + vec4 fpos; + + vec2 osdpos = (vPosition * vec2(uOSDSize)); + fTexcoord = osdpos; + osdpos += uOSDPos; + + fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0; + fpos.y *= -1; + fpos.z = 0.0; + fpos.w = 1.0; + + gl_Position = fpos; +} +)"; + +const char* kScreenFS_OSD = R"(#version 140 + +uniform sampler2D OSDTex; + +smooth in vec2 fTexcoord; + +out vec4 oColor; + +void main() +{ + vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0); + oColor = pixel.bgra; +} +)"; + +#endif // OSD_SHADERS_H diff --git a/src/frontend/qt_sdl/font.h b/src/frontend/qt_sdl/font.h new file mode 100644 index 0000000..f2e4f87 --- /dev/null +++ b/src/frontend/qt_sdl/font.h @@ -0,0 +1,135 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef FONT_H +#define FONT_H +unsigned short font[] = { + 12, 0, 0, 0,0x0C03, 0x0E07, 0x070E, 0x039C, 0x01F8, 0x00F0, 0x00F0, 0x01F8, 0x039C, 0x070E, 0x0E07, 0x0C03, + 12, 0, 0, 0,0x01C0, 0x00E0, 0x0060, 0x0860, 0x0C60, 0x0FE0, 0x07F0, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 12, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, 0x0003, 0x0003, 0x0000, 0x0000, + 9, 0, 0, 0,0x01EF, 0x01EF, 0x018C, 0x01CE, 0x00E7, 0x0063, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 10, 0, 0, 0,0x00CC, 0x00CC, 0x03FF, 0x03FF, 0x00CC, 0x00CC, 0x03FF, 0x03FF, 0x00CC, 0x00CC, 0x0000, 0x0000, + 8, 0, 0, 0,0x0018, 0x00FE, 0x00FF, 0x001B, 0x007F, 0x00FE, 0x00D8, 0x00FF, 0x007F, 0x0018, 0x0000, 0x0000, + 10, 0, 0, 0,0x0306, 0x038F, 0x01CF, 0x00E6, 0x0070, 0x0038, 0x019C, 0x03CE, 0x03C7, 0x0183, 0x0000, 0x0000, + 10, 0, 0, 0,0x007C, 0x00FE, 0x00C6, 0x00EE, 0x007C, 0x037E, 0x03E7, 0x01F3, 0x03BF, 0x031E, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 4, 0, 0, 0,0x000C, 0x000E, 0x0007, 0x0003, 0x0003, 0x0003, 0x0003, 0x0007, 0x000E, 0x000C, 0x0000, 0x0000, + 4, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x000C, 0x000C, 0x000C, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 10, 0, 0, 0,0x0030, 0x0333, 0x03B7, 0x01FE, 0x00FC, 0x00FC, 0x01FE, 0x03B7, 0x0333, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0030, 0x0030, 0x0030, 0x0030, 0x03FF, 0x03FF, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 4, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000F, 0x000F, 0x000C, 0x000E, 0x0007, 0x0003, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x03FF, 0x03FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 3, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0007, 0x0007, 0x0007, 0x0000, 0x0000, + 10, 0, 0, 0,0x0300, 0x0380, 0x01C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 4, 0, 0, 0,0x0006, 0x0007, 0x0007, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x000F, 0x000F, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C0, 0x00FE, 0x007F, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0000, 0x0000, + 8, 0, 0, 0,0x007F, 0x00FF, 0x00C0, 0x00C0, 0x007C, 0x00FC, 0x00C0, 0x00C0, 0x00FF, 0x007F, 0x0000, 0x0000, + 8, 0, 0, 0,0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x00FF, 0x00FE, 0x0060, 0x0060, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FF, 0x00FF, 0x0003, 0x0003, 0x007F, 0x00FF, 0x00C0, 0x00C0, 0x00FF, 0x007F, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x007F, 0x0003, 0x0003, 0x007F, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FF, 0x00FF, 0x00C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000C, 0x000C, 0x000C, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00FF, 0x00FE, 0x00C0, 0x00C0, 0x00FE, 0x007E, 0x0000, 0x0000, + 3, 0, 0, 0,0x0000, 0x0000, 0x0007, 0x0007, 0x0000, 0x0000, 0x0000, 0x0007, 0x0007, 0x0000, 0x0000, 0x0000, + 4, 0, 0, 0,0x0000, 0x0000, 0x000E, 0x000E, 0x0000, 0x0000, 0x000C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 6, 0, 0, 0,0x0030, 0x0038, 0x001C, 0x000E, 0x0007, 0x0007, 0x000E, 0x001C, 0x0038, 0x0030, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x007F, 0x007F, 0x0000, 0x0000, 0x007F, 0x007F, 0x0000, 0x0000, 0x0000, + 6, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0038, 0x001C, 0x000E, 0x0007, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00F0, 0x0078, 0x0018, 0x0000, 0x0018, 0x0018, 0x0000, 0x0000, + 10, 0, 0, 0,0x00FC, 0x01FE, 0x0387, 0x0333, 0x037B, 0x03FB, 0x01F3, 0x0007, 0x03FE, 0x03FC, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FE, 0x01FF, 0x0183, 0x0183, 0x0183, 0x01FF, 0x01FF, 0x0183, 0x0183, 0x0183, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0000, 0x0000, + 8, 0, 0, 0,0x00FE, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x00FF, 0x00FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x007F, 0x00FF, 0x01C3, 0x0183, 0x0183, 0x0183, 0x0183, 0x01C3, 0x00FF, 0x007F, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FF, 0x01FF, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0003, 0x0003, 0x01FF, 0x01FF, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FF, 0x01FF, 0x0003, 0x0003, 0x00FF, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 9, 0, 0, 0,0x01FE, 0x01FF, 0x0003, 0x0003, 0x01F3, 0x01F3, 0x0183, 0x0183, 0x01FF, 0x00FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x0183, 0x0183, 0x0183, 0x01FF, 0x01FF, 0x0183, 0x0183, 0x0183, 0x0183, 0x0000, 0x0000, + 6, 0, 0, 0,0x003F, 0x003F, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x003F, 0x003F, 0x0000, 0x0000, + 9, 0, 0, 0,0x01F0, 0x01F0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x01C3, 0x00E3, 0x0073, 0x003F, 0x003F, 0x0073, 0x00E3, 0x01C3, 0x0183, 0x0000, 0x0000, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x007F, 0x007F, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x03CF, 0x03FF, 0x037B, 0x0333, 0x0303, 0x0303, 0x0303, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0307, 0x030F, 0x031F, 0x033B, 0x0373, 0x03E3, 0x03C3, 0x0383, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x03FF, 0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x03FF, 0x01FE, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x03FF, 0x0303, 0x0303, 0x0333, 0x0373, 0x03E3, 0x01C3, 0x03FF, 0x037E, 0x0000, 0x0000, + 9, 0, 0, 0,0x00FF, 0x01FF, 0x0183, 0x0183, 0x01FF, 0x00FF, 0x0073, 0x00E3, 0x01C3, 0x0183, 0x0000, 0x0000, + 10, 0, 0, 0,0x01FE, 0x01FF, 0x0003, 0x0003, 0x01FF, 0x03FE, 0x0300, 0x0300, 0x03FE, 0x01FE, 0x0000, 0x0000, + 10, 0, 0, 0,0x03FF, 0x03FF, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 9, 0, 0, 0,0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x0183, 0x01FF, 0x00FE, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0303, 0x0303, 0x0303, 0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0303, 0x0303, 0x0303, 0x0333, 0x037B, 0x03FF, 0x03CF, 0x0387, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0078, 0x00FC, 0x01CE, 0x0387, 0x0303, 0x0000, 0x0000, + 10, 0, 0, 0,0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x03FF, 0x03FF, 0x01C0, 0x00E0, 0x0070, 0x0038, 0x001C, 0x000E, 0x03FF, 0x03FF, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x000F, 0x000F, 0x0000, 0x0000, + 10, 0, 0, 0,0x0003, 0x0007, 0x000E, 0x001C, 0x0038, 0x0070, 0x00E0, 0x01C0, 0x0380, 0x0300, 0x0000, 0x0000, + 4, 0, 0, 0,0x000F, 0x000F, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000F, 0x000F, 0x0000, 0x0000, + 8, 0, 0, 0,0x0018, 0x003C, 0x007E, 0x00E7, 0x00C3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FF, 0x03FF, + 4, 0, 0, 0,0x000F, 0x000F, 0x0003, 0x0007, 0x000E, 0x000C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003E, 0x007E, 0x0060, 0x007E, 0x007F, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x007F, 0x003F, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0003, 0x0003, 0x0003, 0x0003, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0060, 0x0060, 0x0060, 0x007E, 0x007F, 0x0063, 0x0063, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003E, 0x007F, 0x0063, 0x007F, 0x003F, 0x0003, 0x003F, 0x003E, 0x0000, 0x0000, + 6, 0, 0, 0,0x003C, 0x003E, 0x0006, 0x0006, 0x001F, 0x001F, 0x0006, 0x0006, 0x0006, 0x0006, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0063, 0x0063, 0x007F, 0x007E, 0x0060, 0x0060, 0x007E, 0x003E, + 7, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0000, 0x0000, + 2, 0, 0, 0,0x0003, 0x0003, 0x0000, 0x0000, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 7, 0, 0, 0,0x0060, 0x0060, 0x0000, 0x0000, 0x0060, 0x0060, 0x0060, 0x0060, 0x0060, 0x0063, 0x007F, 0x003E, + 8, 0, 0, 0,0x0003, 0x0003, 0x00E3, 0x0073, 0x003B, 0x001F, 0x001F, 0x003B, 0x0073, 0x00E3, 0x0000, 0x0000, + 4, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x000F, 0x000E, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x01FF, 0x03FF, 0x0333, 0x0333, 0x0333, 0x0333, 0x0333, 0x0333, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003F, 0x007F, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x00FF, 0x00C3, 0x00C3, 0x00C3, 0x00C3, 0x00FF, 0x007E, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x003F, 0x007F, 0x0063, 0x0063, 0x007F, 0x003F, 0x0003, 0x0003, 0x0003, 0x0003, + 7, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0063, 0x0063, 0x007F, 0x007E, 0x0060, 0x0060, 0x0060, 0x0060, + 7, 0, 0, 0,0x0000, 0x0000, 0x003B, 0x007F, 0x0067, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x007E, 0x007F, 0x0003, 0x007F, 0x00FE, 0x00C0, 0x00FE, 0x007E, 0x0000, 0x0000, + 6, 0, 0, 0,0x0006, 0x0006, 0x003F, 0x003F, 0x0006, 0x0006, 0x0006, 0x0006, 0x003E, 0x003C, 0x0000, 0x0000, + 7, 0, 0, 0,0x0000, 0x0000, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x0063, 0x007F, 0x007E, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0303, 0x0303, 0x0387, 0x01CE, 0x00FC, 0x0078, 0x0030, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0303, 0x0333, 0x037B, 0x03FF, 0x03CF, 0x0387, 0x0303, 0x0000, 0x0000, + 8, 0, 0, 0,0x0000, 0x0000, 0x00C3, 0x00E7, 0x007E, 0x003C, 0x003C, 0x007E, 0x00E7, 0x00C3, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0303, 0x0307, 0x038E, 0x01DC, 0x00F8, 0x0070, 0x0038, 0x001C, 0x000E, 0x0006, + 8, 0, 0, 0,0x0000, 0x0000, 0x00FF, 0x00FF, 0x0070, 0x0038, 0x001C, 0x000E, 0x00FF, 0x00FF, 0x0000, 0x0000, + 6, 0, 0, 0,0x0038, 0x003C, 0x000C, 0x000C, 0x000F, 0x000F, 0x000C, 0x000C, 0x003C, 0x0038, 0x0000, 0x0000, + 2, 0, 0, 0,0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0000, 0x0000, + 6, 0, 0, 0,0x0007, 0x000F, 0x000C, 0x000C, 0x003C, 0x003C, 0x000C, 0x000C, 0x000F, 0x0007, 0x0000, 0x0000, + 10, 0, 0, 0,0x0000, 0x0000, 0x0000, 0x031C, 0x03BE, 0x01F7, 0x00E3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 11, 0, 0, 0,0x0555, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0401, 0x0000, 0x0555, 0x0000, +}; +#endif diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index de71da9..78f64f6 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -43,6 +43,7 @@ #include "version.h" #include "FrontendUtil.h" +#include "OSD.h" #include "NDS.h" #include "GBACart.h" @@ -263,7 +264,7 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent) connect(this, SIGNAL(windowEmuReset()), mainWindow->actReset, SLOT(trigger())); connect(this, SIGNAL(screenLayoutChange()), mainWindow->panel, SLOT(onScreenLayoutChanged())); - initOpenGL(); + if (mainWindow->hasOGL) initOpenGL(); } void EmuThread::initOpenGL() @@ -709,10 +710,13 @@ ScreenPanelNative::ScreenPanelNative(QWidget* parent) : QWidget(parent) screenTrans[1].reset(); touching = false; + + OSD::Init(nullptr); } ScreenPanelNative::~ScreenPanelNative() { + OSD::DeInit(nullptr); } void ScreenPanelNative::setupScreenLayout() @@ -756,6 +760,9 @@ void ScreenPanelNative::paintEvent(QPaintEvent* event) painter.setTransform(screenTrans[1]); painter.drawImage(screenrc, screen[1]); + + OSD::Update(nullptr); + OSD::DrawNative(painter); } void ScreenPanelNative::resizeEvent(QResizeEvent* event) @@ -793,12 +800,16 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) format.setVersion(3, 2); format.setProfile(QSurfaceFormat::CoreProfile); setFormat(format); + + touching = false; } ScreenPanelGL::~ScreenPanelGL() { makeCurrent(); + OSD::DeInit(this); + glDeleteTextures(1, &screenTexture); glDeleteVertexArrays(1, &screenVertexArray); @@ -881,6 +892,8 @@ void ScreenPanelGL::initializeGL() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + OSD::Init(this); } void ScreenPanelGL::paintGL() @@ -935,6 +948,9 @@ void ScreenPanelGL::paintGL() glDrawArrays(GL_TRIANGLES, 2*3, 2*3); screenShader->release(); + + OSD::Update(this); + OSD::DrawGL(this, w*factor, h*factor); } void ScreenPanelGL::resizeEvent(QResizeEvent* event) diff --git a/src/frontend/qt_sdl/main_shaders.h b/src/frontend/qt_sdl/main_shaders.h index 96b9ecd..c55f79e 100644 --- a/src/frontend/qt_sdl/main_shaders.h +++ b/src/frontend/qt_sdl/main_shaders.h @@ -61,54 +61,4 @@ void main() } )"; - - -const char* kScreenVS_OSD = R"(#version 140 - -layout(std140) uniform uConfig -{ - vec2 uScreenSize; - uint u3DScale; - uint uFilterMode; -}; - -uniform ivec2 uOSDPos; -uniform ivec2 uOSDSize; - -in vec2 vPosition; - -smooth out vec2 fTexcoord; - -void main() -{ - vec4 fpos; - - vec2 osdpos = (vPosition * vec2(uOSDSize)); - fTexcoord = osdpos; - osdpos += uOSDPos; - - fpos.xy = ((osdpos * 2.0) / uScreenSize) - 1.0; - fpos.y *= -1; - fpos.z = 0.0; - fpos.w = 1.0; - - gl_Position = fpos; -} -)"; - -const char* kScreenFS_OSD = R"(#version 140 - -uniform sampler2D OSDTex; - -smooth in vec2 fTexcoord; - -out vec4 oColor; - -void main() -{ - vec4 pixel = texelFetch(OSDTex, ivec2(fTexcoord), 0); - oColor = pixel.bgra; -} -)"; - #endif // MAIN_SHADERS_H -- cgit v1.2.3 From a2004785a4d49f02f8257a38489eb57a29ce4e91 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 18:22:02 +0200 Subject: re-add all old OSD messages --- src/frontend/Util_ROM.cpp | 6 ------ src/frontend/qt_sdl/main.cpp | 41 +++++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 22 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index ec3186a..3f64b9d 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -384,10 +384,6 @@ bool SaveState(const char* filename) } } - /*char msg[64]; - if (slot > 0) sprintf(msg, "State saved to slot %d", slot); - else sprintf(msg, "State saved to file"); - OSD::AddMessage(0, msg);*/ return true; } @@ -407,8 +403,6 @@ void UndoStateLoad() strncpy(SRAMPath[ROMSlot_NDS], PrevSRAMPath[ROMSlot_NDS], 1024); NDS::RelocateSave(SRAMPath[ROMSlot_NDS], false); } - - //OSD::AddMessage(0, "State load undone"); } } diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 78f64f6..bea33b0 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -364,16 +364,16 @@ void EmuThread::run() if (Input::HotkeyPressed(HK_SolarSensorDecrease)) { if (GBACart_SolarSensor::LightLevel > 0) GBACart_SolarSensor::LightLevel--; - //char msg[64]; - //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - //OSD::AddMessage(0, msg); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } if (Input::HotkeyPressed(HK_SolarSensorIncrease)) { if (GBACart_SolarSensor::LightLevel < 10) GBACart_SolarSensor::LightLevel++; - //char msg[64]; - //sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); - //OSD::AddMessage(0, msg); + char msg[64]; + sprintf(msg, "Solar sensor level set to %d", GBACart_SolarSensor::LightLevel); + OSD::AddMessage(0, msg); } } @@ -411,7 +411,7 @@ void EmuThread::run() { bool lid = !NDS::IsLidClosed(); NDS::SetLidClosed(lid); - //OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened"); + OSD::AddMessage(0, lid ? "Lid closed" : "Lid opened"); } // microphone input @@ -1493,13 +1493,16 @@ void MainWindow::onSaveState() if (Frontend::SaveState(filename)) { - // TODO: OSD message + char msg[64]; + if (slot > 0) sprintf(msg, "State saved to slot %d", slot); + else sprintf(msg, "State saved to file"); + OSD::AddMessage(0, msg); actLoadState[slot]->setEnabled(true); } else { - // TODO: OSD error message? + OSD::AddMessage(0xFFA0A0, "State save failed"); } emuThread->emuUnpause(); @@ -1534,10 +1537,10 @@ void MainWindow::onLoadState() if (!Platform::FileExists(filename)) { - /*char msg[64]; + char msg[64]; if (slot > 0) sprintf(msg, "State slot %d is empty", slot); else sprintf(msg, "State file does not exist"); - OSD::AddMessage(0xFFA0A0, msg);*/ + OSD::AddMessage(0xFFA0A0, msg); emuThread->emuUnpause(); return; @@ -1545,11 +1548,14 @@ void MainWindow::onLoadState() if (Frontend::LoadState(filename)) { - // TODO: OSD message + char msg[64]; + if (slot > 0) sprintf(msg, "State loaded from slot %d", slot); + else sprintf(msg, "State loaded from file"); + OSD::AddMessage(0, msg); } else { - // TODO: OSD error message? + OSD::AddMessage(0xFFA0A0, "State load failed"); } emuThread->emuUnpause(); @@ -1560,6 +1566,8 @@ void MainWindow::onUndoStateLoad() emuThread->emuPause(); Frontend::UndoStateLoad(); emuThread->emuUnpause(); + + OSD::AddMessage(0, "State load undone"); } void MainWindow::onQuit() @@ -1575,10 +1583,12 @@ void MainWindow::onPause(bool checked) if (checked) { emuThread->emuPause(); + OSD::AddMessage(0, "Paused"); } else { emuThread->emuUnpause(); + OSD::AddMessage(0, "Resumed"); } } @@ -1600,8 +1610,7 @@ void MainWindow::onReset() } else { - // OSD::AddMessage(0, "Reset"); - + OSD::AddMessage(0, "Reset"); emuThread->emuRun(); } } @@ -1835,7 +1844,7 @@ void emuStop() emit emuThread->windowEmuStop(); - //OSD::AddMessage(0xFFC040, "Shutdown"); + OSD::AddMessage(0xFFC040, "Shutdown"); } -- cgit v1.2.3 From 590ab2ac2bdc79e536c0f332cf9f1a4d700fffe9 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 22:37:37 +0200 Subject: fix things --- src/frontend/qt_sdl/CMakeLists.txt | 4 ++++ src/frontend/qt_sdl/main.cpp | 21 +++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 0b7fa54..dbc1e3a 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -7,7 +7,10 @@ SET(SOURCES_QT_SDL InputConfigDialog.cpp VideoSettingsDialog.cpp AudioSettingsDialog.cpp + WifiSettingsDialog.cpp Input.cpp + LAN_PCap.cpp + LAN_Socket.cpp OSD.cpp OSD_shaders.h font.h @@ -40,6 +43,7 @@ pkg_check_modules(SDL2 REQUIRED sdl2) add_executable(melonDS ${SOURCES_QT_SDL}) target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS}) +target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..") target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..") target_link_libraries(melonDS core ${SDL2_LIBRARIES}) diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index bea33b0..e60a58d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -38,6 +38,7 @@ #include "InputConfigDialog.h" #include "VideoSettingsDialog.h" #include "AudioSettingsDialog.h" +#include "WifiSettingsDialog.h" #include "types.h" #include "version.h" @@ -298,9 +299,10 @@ void EmuThread::initOpenGL() oglContext->moveToThread(this); } -void deinitOpenGL() +void EmuThread::deinitOpenGL() { - // TODO!! + delete oglContext; + delete oglSurface; } void* oglGetProcAddress(const char* proc) @@ -545,16 +547,11 @@ void EmuThread::run() NDS::DeInit(); //Platform::LAN_DeInit(); - /*if (Screen_UseGL) - { - OSD::DeInit(true); - GLScreen_DeInit(); - } - else - OSD::DeInit(false);*/ - if (hasOGL) + { oglContext->doneCurrent(); + deinitOpenGL(); + } } void EmuThread::changeWindowTitle(char* title) @@ -844,7 +841,6 @@ void ScreenPanelGL::initializeGL() screenShader->addShaderFromSourceCode(QOpenGLShader::Fragment, kScreenFS); GLuint pid = screenShader->programId(); - printf("program: %d\n", pid); glBindAttribLocation(pid, 0, "vPosition"); glBindAttribLocation(pid, 1, "vTexcoord"); glBindFragDataLocation(pid, 0, "oColor"); @@ -1675,7 +1671,7 @@ void MainWindow::onAudioSettingsFinished(int res) void MainWindow::onOpenWifiSettings() { - // + WifiSettingsDialog::openDlg(this); } void MainWindow::onChangeSavestateSRAMReloc(bool checked) @@ -1822,6 +1818,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange) { emuThread->emuPause(); + if (hasOGL) emuThread->deinitOpenGL(); delete panel; createScreenPanel(); connect(emuThread, SIGNAL(windowUpdate()), panel, SLOT(update())); -- cgit v1.2.3 From a38b20484d72d9d03ac7c807323343c8576c2c35 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 23:12:21 +0200 Subject: finish the wifi dialog also guess who the idiot is who forgot to add their files --- src/frontend/qt_sdl/Platform.cpp | 22 +++-- src/frontend/qt_sdl/WifiSettingsDialog.cpp | 140 +++++++++++++++++++++++++++++ src/frontend/qt_sdl/WifiSettingsDialog.h | 68 ++++++++++++++ src/frontend/qt_sdl/main.cpp | 19 +++- src/frontend/qt_sdl/main.h | 1 + 5 files changed, 237 insertions(+), 13 deletions(-) create mode 100644 src/frontend/qt_sdl/WifiSettingsDialog.cpp create mode 100644 src/frontend/qt_sdl/WifiSettingsDialog.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 6b256e0..edc8d45 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -22,8 +22,8 @@ #include #include "Platform.h" #include "PlatformConfig.h" -//#include "LAN_Socket.h" -//#include "LAN_PCap.h" +#include "LAN_Socket.h" +#include "LAN_PCap.h" #include #ifdef __WIN32__ @@ -559,7 +559,7 @@ int MP_RecvPacket(u8* data, bool block) bool LAN_Init() { - /*if (Config::DirectLAN) + if (Config::DirectLAN) { if (!LAN_PCap::Init(true)) return false; @@ -568,7 +568,7 @@ bool LAN_Init() { if (!LAN_Socket::Init()) return false; - }*/ + } return true; } @@ -580,26 +580,24 @@ void LAN_DeInit() // LAN_PCap::DeInit(); //else // LAN_Socket::DeInit(); - /*LAN_PCap::DeInit(); - LAN_Socket::DeInit();*/ + LAN_PCap::DeInit(); + LAN_Socket::DeInit(); } int LAN_SendPacket(u8* data, int len) { - /*if (Config::DirectLAN) + if (Config::DirectLAN) return LAN_PCap::SendPacket(data, len); else - return LAN_Socket::SendPacket(data, len);*/ - return 0; + return LAN_Socket::SendPacket(data, len); } int LAN_RecvPacket(u8* data) { - /*if (Config::DirectLAN) + if (Config::DirectLAN) return LAN_PCap::RecvPacket(data); else - return LAN_Socket::RecvPacket(data);*/ - return 0; + return LAN_Socket::RecvPacket(data); } diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp new file mode 100644 index 0000000..457a78d --- /dev/null +++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp @@ -0,0 +1,140 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include + +#include "types.h" +#include "Platform.h" +#include "Config.h" +#include "PlatformConfig.h" + +#include "LAN_Socket.h" +#include "LAN_PCap.h" +#include "Wifi.h" + +#include "WifiSettingsDialog.h" +#include "ui_WifiSettingsDialog.h" + + +#ifdef __WIN32__ +#define PCAP_NAME "winpcap/npcap" +#else +#define PCAP_NAME "libpcap" +#endif + + +WifiSettingsDialog* WifiSettingsDialog::currentDlg = nullptr; + + +WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::WifiSettingsDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + + LAN_Socket::Init(); + haspcap = LAN_PCap::Init(false); + + ui->cbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)"); + + ui->cbBindAnyAddr->setChecked(Config::SocketBindAnyAddr != 0); + + int sel = 0; + for (int i = 0; i < LAN_PCap::NumAdapters; i++) + { + LAN_PCap::AdapterData* adapter = &LAN_PCap::Adapters[i]; + + ui->cbxDirectAdapter->addItem(QString(adapter->FriendlyName)); + + if (!strncmp(adapter->DeviceName, Config::LANDevice, 128)) + sel = i; + } + ui->cbxDirectAdapter->setCurrentIndex(sel); + + ui->cbDirectMode->setChecked(Config::DirectLAN != 0); + if (!haspcap) ui->cbDirectMode->setEnabled(false); + + updateAdapterControls(); +} + +WifiSettingsDialog::~WifiSettingsDialog() +{ + delete ui; +} + +void WifiSettingsDialog::on_WifiSettingsDialog_accepted() +{ + Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0; + Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0; + + int sel = ui->cbxDirectAdapter->currentIndex(); + if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0; + if (LAN_PCap::NumAdapters < 1) + { + Config::LANDevice[0] = '\0'; + } + else + { + strncpy(Config::LANDevice, LAN_PCap::Adapters[sel].DeviceName, 127); + Config::LANDevice[127] = '\0'; + } + + Config::Save(); + + closeDlg(); +} + +void WifiSettingsDialog::on_WifiSettingsDialog_rejected() +{ + closeDlg(); +} + +void WifiSettingsDialog::on_cbDirectMode_stateChanged(int state) +{ + updateAdapterControls(); +} + +void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel) +{ + if (!haspcap) return; + + if (sel < 0 || sel >= LAN_PCap::NumAdapters) return; + if (LAN_PCap::NumAdapters < 1) return; + + LAN_PCap::AdapterData* adapter = &LAN_PCap::Adapters[sel]; + char tmp[64]; + + sprintf(tmp, "MAC: %02X:%02X:%02X:%02X:%02X:%02X", + adapter->MAC[0], adapter->MAC[1], adapter->MAC[2], + adapter->MAC[3], adapter->MAC[4], adapter->MAC[5]); + ui->lblAdapterMAC->setText(QString(tmp)); + + sprintf(tmp, "IP: %d.%d.%d.%d", + adapter->IP_v4[0], adapter->IP_v4[1], + adapter->IP_v4[2], adapter->IP_v4[3]); + ui->lblAdapterIP->setText(QString(tmp)); +} + +void WifiSettingsDialog::updateAdapterControls() +{ + bool enable = haspcap && ui->cbDirectMode->isChecked(); + + ui->cbxDirectAdapter->setEnabled(enable); + ui->lblAdapterMAC->setEnabled(enable); + ui->lblAdapterIP->setEnabled(enable); +} diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.h b/src/frontend/qt_sdl/WifiSettingsDialog.h new file mode 100644 index 0000000..f8aad1b --- /dev/null +++ b/src/frontend/qt_sdl/WifiSettingsDialog.h @@ -0,0 +1,68 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef WIFISETTINGSDIALOG_H +#define WIFISETTINGSDIALOG_H + +#include + +namespace Ui { class WifiSettingsDialog; } +class WifiSettingsDialog; + +class WifiSettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit WifiSettingsDialog(QWidget* parent); + ~WifiSettingsDialog(); + + static WifiSettingsDialog* currentDlg; + static WifiSettingsDialog* openDlg(QWidget* parent) + { + if (currentDlg) + { + currentDlg->activateWindow(); + return currentDlg; + } + + currentDlg = new WifiSettingsDialog(parent); + currentDlg->show(); + return currentDlg; + } + static void closeDlg() + { + currentDlg = nullptr; + } + +private slots: + void on_WifiSettingsDialog_accepted(); + void on_WifiSettingsDialog_rejected(); + + void on_cbDirectMode_stateChanged(int state); + void on_cbxDirectAdapter_currentIndexChanged(int sel); + +private: + Ui::WifiSettingsDialog* ui; + + bool haspcap; + + void updateAdapterControls(); +}; + +#endif // WIFISETTINGSDIALOG_H diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index e60a58d..5870d8a 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1671,7 +1671,24 @@ void MainWindow::onAudioSettingsFinished(int res) void MainWindow::onOpenWifiSettings() { - WifiSettingsDialog::openDlg(this); + WifiSettingsDialog* dlg = WifiSettingsDialog::openDlg(this); + connect(dlg, &WifiSettingsDialog::finished, this, &MainWindow::onWifiSettingsFinished); +} + +void MainWindow::onWifiSettingsFinished(int res) +{ + emuThread->emuPause(); + + if (Wifi::MPInited) + { + Platform::MP_DeInit(); + Platform::MP_Init(); + } + + Platform::LAN_DeInit(); + Platform::LAN_Init(); + + emuThread->emuUnpause(); } void MainWindow::onChangeSavestateSRAMReloc(bool checked) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index ef51158..279aed8 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -205,6 +205,7 @@ private slots: void onOpenAudioSettings(); void onAudioSettingsFinished(int res); void onOpenWifiSettings(); + void onWifiSettingsFinished(int res); void onChangeSavestateSRAMReloc(bool checked); void onChangeScreenSize(); void onChangeScreenRotation(QAction* act); -- cgit v1.2.3 From 9557e18b7cd559679552535e4362115b6d249ab3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 29 May 2020 21:27:40 +0200 Subject: fart around --- src/frontend/qt_sdl/main.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 5870d8a..2aaac96 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -273,6 +273,8 @@ void EmuThread::initOpenGL() QOpenGLContext* windowctx = mainWindow->getOGLContext(); QSurfaceFormat format = windowctx->format(); + format.setSwapInterval(0); + oglSurface = new QOffscreenSurface(); oglSurface->setFormat(format); oglSurface->create(); @@ -791,14 +793,9 @@ void ScreenPanelNative::onScreenLayoutChanged() ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) { - QSurfaceFormat format; - format.setDepthBufferSize(24); - format.setStencilBufferSize(8); - format.setVersion(3, 2); - format.setProfile(QSurfaceFormat::CoreProfile); - setFormat(format); - touching = false; + + curVSync = -1; } ScreenPanelGL::~ScreenPanelGL() -- cgit v1.2.3 From 8ddd82ca2c7c8844a1d3c2cc7418d03976c9c52e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 29 May 2020 21:35:06 +0200 Subject: I'm a derp --- src/frontend/qt_sdl/main.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 2aaac96..68a32c8 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -795,7 +795,6 @@ ScreenPanelGL::ScreenPanelGL(QWidget* parent) : QOpenGLWidget(parent) { touching = false; - curVSync = -1; } ScreenPanelGL::~ScreenPanelGL() -- cgit v1.2.3 From 88823f66cb7f053e1d0f22d2eb0510ab32d8e474 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 29 May 2020 22:18:21 +0200 Subject: * fix the OpenGL shito under Linux * make the 'BIOS not found' errors a bit more user-friendly --- src/OpenGLSupport.h | 14 +++++++++++++- src/frontend/qt_sdl/main.cpp | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/src/OpenGLSupport.h b/src/OpenGLSupport.h index edf7eda..925c0ad 100644 --- a/src/OpenGLSupport.h +++ b/src/OpenGLSupport.h @@ -49,9 +49,21 @@ // if you need more OpenGL functions, add them to the macronator here -#define DO_PROCLIST(func) \ +#ifdef __WIN32__ + +#define DO_PROCLIST_1_3(func) \ func(GLACTIVETEXTURE, glActiveTexture); \ func(GLBLENDCOLOR, glBlendColor); \ + +#else + +#define DO_PROCLIST_1_3(func) + +#endif + + +#define DO_PROCLIST(func) \ + DO_PROCLIST_1_3(func) \ \ func(GLGENFRAMEBUFFERS, glGenFramebuffers); \ func(GLDELETEFRAMEBUFFERS, glDeleteFramebuffers); \ diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 68a32c8..8df6ec8 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1360,13 +1360,13 @@ QString MainWindow::loadErrorStr(int error) { switch (error) { - case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed."; + case Frontend::Load_BIOS9Missing: return "DS ARM9 BIOS was not found or could not be accessed. Check your emu settings."; case Frontend::Load_BIOS9Bad: return "DS ARM9 BIOS is not a valid BIOS dump."; - case Frontend::Load_BIOS7Missing: return "DS ARM7 BIOS was not found or could not be accessed."; + case Frontend::Load_BIOS7Missing: return "DS ARM7 BIOS was not found or could not be accessed. Check your emu settings."; case Frontend::Load_BIOS7Bad: return "DS ARM7 BIOS is not a valid BIOS dump."; - case Frontend::Load_FirmwareMissing: return "DS firmware was not found or could not be accessed."; + case Frontend::Load_FirmwareMissing: return "DS firmware was not found or could not be accessed. Check your emu settings."; case Frontend::Load_FirmwareBad: return "DS firmware is not a valid firmware dump."; case Frontend::Load_FirmwareNotBootable: return "DS firmware is not bootable."; -- cgit v1.2.3 From c45068da0eb4dc5ce25524cc0b0a12cd78ed036a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 30 May 2020 00:28:21 +0200 Subject: embed romlist.bin --- CMakeLists.txt | 4 - romlist.bin | Bin 108384 -> 0 bytes src/CMakeLists.txt | 1 + src/NDSCart.cpp | 51 +- src/ROMList.h | 6809 ++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.cpp | 33 - 6 files changed, 6829 insertions(+), 69 deletions(-) delete mode 100644 romlist.bin create mode 100644 src/ROMList.h (limited to 'src/frontend/qt_sdl/main.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 0309725..885f0dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,3 @@ add_subdirectory(src) if (BUILD_QT_SDL) add_subdirectory(src/frontend/qt_sdl) endif() - -configure_file( - ${CMAKE_SOURCE_DIR}/romlist.bin - ${CMAKE_BINARY_DIR}/romlist.bin COPYONLY) diff --git a/romlist.bin b/romlist.bin deleted file mode 100644 index 537439e..0000000 Binary files a/romlist.bin and /dev/null differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 56bb3cb..3dc4243 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,7 @@ add_library(core STATIC NDSCart.cpp OpenGLSupport.cpp Platform.h + ROMList.h RTC.cpp Savestate.cpp SPI.cpp diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 8ced842..a8c6549 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -23,6 +23,7 @@ #include "ARM.h" #include "CRC32.h" #include "Platform.h" +#include "ROMList.h" namespace NDSCart_SRAM @@ -808,34 +809,21 @@ void ApplyDLDIPatch() } -bool ReadROMParams(u32 gamecode, u32* params) +bool ReadROMParams(u32 gamecode, ROMListEntry* params) { - // format for romlist.bin: - // [gamecode] [ROM size] [save type] [reserved] - // list must be sorted by gamecode - - FILE* f = Platform::OpenDataFile("romlist.bin"); - if (!f) return false; - - fseek(f, 0, SEEK_END); - u32 len = (u32)ftell(f); - u32 maxlen = len; - len >>= 4; // 16 bytes per entry + u32 len = sizeof(ROMList) / sizeof(ROMListEntry); u32 offset = 0; u32 chk_size = len >> 1; for (;;) { u32 key = 0; - fseek(f, offset + (chk_size << 4), SEEK_SET); - fread(&key, 4, 1, f); - - printf("chk_size=%d, key=%08X, wanted=%08X, offset=%08X\n", chk_size, key, gamecode, offset); + ROMListEntry* curentry = &ROMList[offset + chk_size]; + key = curentry->GameCode; if (key == gamecode) { - fread(params, 4, 3, f); - fclose(f); + memcpy(params, curentry, sizeof(ROMListEntry)); return true; } else @@ -843,22 +831,20 @@ bool ReadROMParams(u32 gamecode, u32* params) if (key < gamecode) { if (chk_size == 0) - offset += 0x10; + offset++; else - offset += (chk_size << 4); + offset += chk_size; } else if (chk_size == 0) { - fclose(f); return false; } chk_size >>= 1; } - if (offset >= maxlen) + if (offset >= len) { - fclose(f); return false; } } @@ -936,22 +922,23 @@ bool LoadROM(const char* path, const char* sram, bool direct) CartCRC = CRC32(CartROM, CartROMSize); printf("ROM CRC32: %08X\n", CartCRC); - u32 romparams[3]; - if (!ReadROMParams(gamecode, romparams)) + ROMListEntry romparams; + if (!ReadROMParams(gamecode, &romparams)) { // set defaults printf("ROM entry not found\n"); - romparams[0] = CartROMSize; + romparams.GameCode = gamecode; + romparams.ROMSize = CartROMSize; if (*(u32*)&CartROM[0x20] < 0x4000) - romparams[1] = 0; // no saveRAM for homebrew + romparams.SaveMemType = 0; // no saveRAM for homebrew else - romparams[1] = 2; // assume EEPROM 64k (TODO FIXME) + romparams.SaveMemType = 2; // assume EEPROM 64k (TODO FIXME) } else - printf("ROM entry: %08X %08X %08X\n", romparams[0], romparams[1], romparams[2]); + printf("ROM entry: %08X %08X\n", romparams.ROMSize, romparams.SaveMemType); - if (romparams[0] != len) printf("!! bad ROM size %d (expected %d) rounded to %d\n", len, romparams[0], CartROMSize); + if (romparams.ROMSize != len) printf("!! bad ROM size %d (expected %d) rounded to %d\n", len, romparams.ROMSize, CartROMSize); // generate a ROM ID // note: most games don't check the actual value @@ -963,7 +950,7 @@ bool LoadROM(const char* path, const char* sram, bool direct) else CartID |= (0x100 - (CartROMSize >> 28)) << 8; - if (romparams[1] == 8) + if (romparams.SaveMemType == 8) CartID |= 0x08000000; // NAND flag printf("Cart ID: %08X\n", CartID); @@ -1018,7 +1005,7 @@ bool LoadROM(const char* path, const char* sram, bool direct) // save printf("Save file: %s\n", sram); - NDSCart_SRAM::LoadSave(sram, romparams[1]); + NDSCart_SRAM::LoadSave(sram, romparams.SaveMemType); return true; } diff --git a/src/ROMList.h b/src/ROMList.h new file mode 100644 index 0000000..ead3ee4 --- /dev/null +++ b/src/ROMList.h @@ -0,0 +1,6809 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef ROMLIST_H +#define ROMLIST_H + +typedef struct +{ + u32 GameCode; + u32 ROMSize; + u32 SaveMemType; + +} ROMListEntry; + + +ROMListEntry ROMList[] = +{ + {0x41464141, 0x00800000, 0x00000004}, + {0x414D4155, 0x00800000, 0x00000008}, + {0x43363341, 0x02000000, 0x00000008}, + {0x43443241, 0x02000000, 0x00000002}, + {0x43495941, 0x01000000, 0x00000001}, + {0x434D5341, 0x01000000, 0x00000002}, + {0x434E5341, 0x00800000, 0x00000002}, + {0x43575A41, 0x02000000, 0x00000002}, + {0x44323643, 0x04000000, 0x00000001}, + {0x44324254, 0x04000000, 0x00000002}, + {0x44324C43, 0x00800000, 0x00000001}, + {0x44325542, 0x01000000, 0x00000002}, + {0x44325942, 0x00800000, 0x00000001}, + {0x44334444, 0x02000000, 0x00000001}, + {0x44334542, 0x04000000, 0x00000001}, + {0x44334754, 0x00800000, 0x00000002}, + {0x44334756, 0x02000000, 0x00000002}, + {0x44335141, 0x04000000, 0x00000002}, + {0x44335159, 0x04000000, 0x00000002}, + {0x44335254, 0x02000000, 0x00000001}, + {0x44335742, 0x08000000, 0x00000002}, + {0x44335942, 0x00800000, 0x00000001}, + {0x44343642, 0x00800000, 0x00000001}, + {0x44344259, 0x02000000, 0x00000001}, + {0x44344443, 0x00800000, 0x00000001}, + {0x44345254, 0x02000000, 0x00000001}, + {0x44345542, 0x00800000, 0x00000002}, + {0x44345942, 0x00800000, 0x00000001}, + {0x44353243, 0x02000000, 0x00000002}, + {0x44353642, 0x00800000, 0x00000001}, + {0x44353842, 0x01000000, 0x00000001}, + {0x44354259, 0x02000000, 0x00000002}, + {0x44354442, 0x01000000, 0x00000002}, + {0x44354659, 0x01000000, 0x00000001}, + {0x44354841, 0x02000000, 0x00000002}, + {0x44354C42, 0x01000000, 0x00000002}, + {0x44354C43, 0x00000000, 0x00000001}, + {0x44355342, 0x01000000, 0x00000001}, + {0x44355542, 0x02000000, 0x00000002}, + {0x44355942, 0x00800000, 0x00000001}, + {0x44363243, 0x01000000, 0x00000002}, + {0x44364142, 0x02000000, 0x00000002}, + {0x44364341, 0x01000000, 0x00000002}, + {0x44364843, 0x04000000, 0x00000001}, + {0x44364B43, 0x02000000, 0x00000002}, + {0x44364C42, 0x01000000, 0x00000002}, + {0x44365542, 0x01000000, 0x00000002}, + {0x44374543, 0x02000000, 0x00000002}, + {0x44374959, 0x04000000, 0x00000002}, + {0x44375359, 0x02000000, 0x00000001}, + {0x44384243, 0x02000000, 0x00000001}, + {0x44384A59, 0x01000000, 0x00000002}, + {0x44384F42, 0x01000000, 0x00000001}, + {0x44394259, 0x02000000, 0x00000003}, + {0x44394341, 0x04000000, 0x00000001}, + {0x44394543, 0x01000000, 0x00000003}, + {0x44414441, 0x04000000, 0x00000006}, + {0x44414A42, 0x01000000, 0x00000003}, + {0x44414C59, 0x00800000, 0x00000002}, + {0x44414D56, 0x02000000, 0x00000001}, + {0x44414E43, 0x04000000, 0x00000001}, + {0x44415041, 0x04000000, 0x00000006}, + {0x44415249, 0x10000000, 0x00000006}, + {0x44423542, 0x04000000, 0x00000002}, + {0x44424242, 0x00000000, 0x00000001}, + {0x44424354, 0x08000000, 0x00000001}, + {0x44424542, 0x10000000, 0x00000003}, + {0x44424A42, 0x04000000, 0x00000001}, + {0x44424B42, 0x01000000, 0x00000001}, + {0x44424C54, 0x02000000, 0x00000001}, + {0x44425249, 0x10000000, 0x00000006}, + {0x44425642, 0x02000000, 0x00000002}, + {0x44434343, 0x02000000, 0x00000002}, + {0x44434643, 0x02000000, 0x00000002}, + {0x44434842, 0x01000000, 0x00000001}, + {0x44434A42, 0x04000000, 0x00000002}, + {0x44434C54, 0x01000000, 0x00000001}, + {0x44435159, 0x01000000, 0x00000001}, + {0x44435342, 0x08000000, 0x00000002}, + {0x44435359, 0x01000000, 0x00000001}, + {0x44435559, 0x04000000, 0x00000002}, + {0x44435943, 0x02000000, 0x00000002}, + {0x44444254, 0x04000000, 0x00000002}, + {0x44444842, 0x04000000, 0x00000001}, + {0x44444856, 0x02000000, 0x00000002}, + {0x44445054, 0x08000000, 0x00000001}, + {0x44445249, 0x20000000, 0x00000006}, + {0x44445443, 0x00000000, 0x00000002}, + {0x44445459, 0x02000000, 0x00000002}, + {0x44445641, 0x01000000, 0x00000002}, + {0x44454242, 0x01000000, 0x00000001}, + {0x44454542, 0x10000000, 0x00000003}, + {0x44454559, 0x10000000, 0x00000003}, + {0x44454756, 0x02000000, 0x00000002}, + {0x44454842, 0x02000000, 0x00000002}, + {0x44454D54, 0x00800000, 0x00000002}, + {0x44454E42, 0x02000000, 0x00000001}, + {0x44454E59, 0x02000000, 0x00000002}, + {0x44455143, 0x04000000, 0x00000002}, + {0x44455249, 0x20000000, 0x00000006}, + {0x44455342, 0x01000000, 0x00000001}, + {0x44455642, 0x00800000, 0x00000002}, + {0x44464242, 0x02000000, 0x00000001}, + {0x44464B42, 0x04000000, 0x00000002}, + {0x44464B59, 0x02000000, 0x00000001}, + {0x44464C42, 0x10000000, 0x00000003}, + {0x44465343, 0x00800000, 0x00000001}, + {0x44465359, 0x04000000, 0x00000001}, + {0x44465442, 0x01000000, 0x00000002}, + {0x44473242, 0x04000000, 0x00000001}, + {0x44474B42, 0x00800000, 0x00000002}, + {0x44474C43, 0x04000000, 0x00000001}, + {0x44474D41, 0x01000000, 0x00000001}, + {0x44474D43, 0x04000000, 0x00000001}, + {0x44475049, 0x08000000, 0x00000006}, + {0x44475759, 0x01000000, 0x00000001}, + {0x44483842, 0x04000000, 0x00000002}, + {0x44485142, 0x00800000, 0x00000002}, + {0x44485442, 0x01000000, 0x00000002}, + {0x44493643, 0x00800000, 0x00000001}, + {0x44494243, 0x02000000, 0x00000001}, + {0x44494442, 0x04000000, 0x00000001}, + {0x44494C43, 0x04000000, 0x00000001}, + {0x44495443, 0x00000000, 0x00000002}, + {0x44495742, 0x01000000, 0x00000002}, + {0x444A3343, 0x10000000, 0x00000003}, + {0x444A3443, 0x00800000, 0x00000001}, + {0x444A4542, 0x04000000, 0x00000001}, + {0x444A4742, 0x02000000, 0x00000002}, + {0x444A4F42, 0x04000000, 0x00000002}, + {0x444A5543, 0x00000000, 0x00000002}, + {0x444A5641, 0x04000000, 0x00000002}, + {0x444B3842, 0x02000000, 0x00000002}, + {0x444B4159, 0x08000000, 0x00000002}, + {0x444B4356, 0x08000000, 0x00000002}, + {0x444B4C42, 0x04000000, 0x00000001}, + {0x444B5049, 0x08000000, 0x00000006}, + {0x444C3643, 0x01000000, 0x00000001}, + {0x444C4254, 0x00800000, 0x00000001}, + {0x444C4842, 0x04000000, 0x00000002}, + {0x444C5059, 0x00800000, 0x00000001}, + {0x444C5941, 0x01000000, 0x00000002}, + {0x444D3442, 0x02000000, 0x00000001}, + {0x444D4359, 0x02000000, 0x00000001}, + {0x444D4C54, 0x08000000, 0x00000001}, + {0x444D5642, 0x02000000, 0x00000001}, + {0x444E4242, 0x00800000, 0x00000002}, + {0x444E4259, 0x04000000, 0x00000007}, + {0x444E4641, 0x02000000, 0x00000002}, + {0x444E4C54, 0x00800000, 0x00000002}, + {0x444E4D42, 0x01000000, 0x00000001}, + {0x444F4142, 0x04000000, 0x00000001}, + {0x444F4359, 0x04000000, 0x00000001}, + {0x444F4543, 0x02000000, 0x00000002}, + {0x444F4642, 0x00800000, 0x00000001}, + {0x444F4656, 0x02000000, 0x00000002}, + {0x444F5056, 0x02000000, 0x00000002}, + {0x444F5143, 0x02000000, 0x00000001}, + {0x44504C43, 0x04000000, 0x00000003}, + {0x44505041, 0x01000000, 0x00000002}, + {0x44505342, 0x01000000, 0x00000002}, + {0x44505542, 0x01000000, 0x00000001}, + {0x44505A55, 0x08000000, 0x00000003}, + {0x44513343, 0x04000000, 0x00000002}, + {0x44513443, 0x04000000, 0x00000002}, + {0x44513743, 0x02000000, 0x00000002}, + {0x44514543, 0x04000000, 0x00000002}, + {0x44514A59, 0x01000000, 0x00000001}, + {0x44514C54, 0x00800000, 0x00000002}, + {0x44515142, 0x01000000, 0x00000002}, + {0x44515543, 0x04000000, 0x00000002}, + {0x44515642, 0x02000000, 0x00000002}, + {0x44524642, 0x08000000, 0x00000002}, + {0x44524842, 0x02000000, 0x00000001}, + {0x44525359, 0x00000000, 0x00000005}, + {0x44525642, 0x04000000, 0x00000001}, + {0x44533341, 0x02000000, 0x00000001}, + {0x44534F41, 0x08000000, 0x00000005}, + {0x44535143, 0x02000000, 0x00000001}, + {0x44535342, 0x01000000, 0x00000002}, + {0x44535541, 0x04000000, 0x00000001}, + {0x44535642, 0x02000000, 0x00000002}, + {0x44544442, 0x00800000, 0x00000001}, + {0x44544C59, 0x08000000, 0x00000002}, + {0x44545659, 0x02000000, 0x00000001}, + {0x44545759, 0x01000000, 0x00000001}, + {0x44553243, 0x04000000, 0x00000002}, + {0x44553642, 0x00800000, 0x00000001}, + {0x44554254, 0x02000000, 0x00000001}, + {0x44554259, 0x08000000, 0x00000003}, + {0x44554959, 0x04000000, 0x00000001}, + {0x44554D59, 0x04000000, 0x00000002}, + {0x44555043, 0x08000000, 0x00000006}, + {0x44563442, 0x02000000, 0x00000001}, + {0x44564159, 0x04000000, 0x00000002}, + {0x44564643, 0x02000000, 0x00000002}, + {0x44564859, 0x04000000, 0x00000001}, + {0x44564A59, 0x01000000, 0x00000002}, + {0x44564B43, 0x01000000, 0x00000002}, + {0x44564C42, 0x01000000, 0x00000001}, + {0x44564E43, 0x10000000, 0x00000005}, + {0x44565042, 0x00800000, 0x00000002}, + {0x44565841, 0x04000000, 0x00000003}, + {0x44573742, 0x01000000, 0x00000002}, + {0x44574242, 0x01000000, 0x00000002}, + {0x44574642, 0x00800000, 0x00000001}, + {0x44574943, 0x08000000, 0x00000002}, + {0x44574C41, 0x02000000, 0x00000001}, + {0x44574C42, 0x02000000, 0x00000001}, + {0x44575343, 0x04000000, 0x00000001}, + {0x44584D59, 0x00800000, 0x00000001}, + {0x44593443, 0x00000000, 0x00000001}, + {0x44593642, 0x02000000, 0x00000002}, + {0x44594159, 0x02000000, 0x00000001}, + {0x44594442, 0x04000000, 0x00000002}, + {0x44594641, 0x04000000, 0x00000001}, + {0x44594842, 0x01000000, 0x00000001}, + {0x44594A42, 0x04000000, 0x00000001}, + {0x44594A43, 0x04000000, 0x00000001}, + {0x44594A59, 0x00800000, 0x00000001}, + {0x44594C41, 0x04000000, 0x00000001}, + {0x44594D42, 0x01000000, 0x00000002}, + {0x44595143, 0x01000000, 0x00000001}, + {0x445A3643, 0x01000000, 0x00000001}, + {0x445A3659, 0x08000000, 0x00000000}, + {0x445A4341, 0x01000000, 0x00000001}, + {0x445A4641, 0x04000000, 0x00000001}, + {0x445A5054, 0x04000000, 0x00000002}, + {0x445A5142, 0x00000000, 0x00000002}, + {0x445A5359, 0x08000000, 0x00000001}, + {0x445A5442, 0x02000000, 0x00000001}, + {0x445A5443, 0x02000000, 0x00000003}, + {0x445A5942, 0x02000000, 0x00000002}, + {0x45323241, 0x01000000, 0x00000002}, + {0x45323341, 0x04000000, 0x00000008}, + {0x45323343, 0x04000000, 0x00000003}, + {0x45323542, 0x01000000, 0x00000001}, + {0x45323559, 0x08000000, 0x00000008}, + {0x45323643, 0x04000000, 0x00000001}, + {0x45323741, 0x01000000, 0x00000000}, + {0x45323859, 0x00800000, 0x00000000}, + {0x45324142, 0x04000000, 0x00000001}, + {0x45324143, 0x08000000, 0x00000003}, + {0x45324241, 0x02000000, 0x00000002}, + {0x45324242, 0x04000000, 0x00000002}, + {0x45324259, 0x02000000, 0x00000002}, + {0x45324341, 0x04000000, 0x00000001}, + {0x45324343, 0x01000000, 0x00000001}, + {0x45324354, 0x00800000, 0x00000001}, + {0x45324356, 0x02000000, 0x00000001}, + {0x45324359, 0x04000000, 0x00000006}, + {0x45324441, 0x02000000, 0x00000005}, + {0x45324442, 0x01000000, 0x00000002}, + {0x45324456, 0x04000000, 0x00000001}, + {0x45324459, 0x01000000, 0x00000003}, + {0x45324542, 0x00800000, 0x00000003}, + {0x45324643, 0x01000000, 0x00000001}, + {0x45324654, 0x04000000, 0x00000000}, + {0x45324741, 0x04000000, 0x00000001}, + {0x45324759, 0x01000000, 0x00000001}, + {0x45324842, 0x02000000, 0x00000003}, + {0x45324854, 0x01000000, 0x00000001}, + {0x45324859, 0x02000000, 0x00000003}, + {0x45324941, 0x04000000, 0x00000002}, + {0x45324A42, 0x04000000, 0x00000001}, + {0x45324A59, 0x02000000, 0x00000002}, + {0x45324B41, 0x02000000, 0x00000001}, + {0x45324C41, 0x04000000, 0x00000002}, + {0x45324C59, 0x08000000, 0x00000003}, + {0x45324D56, 0x04000000, 0x00000002}, + {0x45324D59, 0x01000000, 0x00000001}, + {0x45325041, 0x02000000, 0x00000001}, + {0x45325042, 0x02000000, 0x00000001}, + {0x45325043, 0x04000000, 0x00000003}, + {0x45325059, 0x04000000, 0x00000005}, + {0x45325141, 0x02000000, 0x00000002}, + {0x45325242, 0x02000000, 0x00000001}, + {0x45325254, 0x02000000, 0x00000002}, + {0x45325341, 0x01000000, 0x00000001}, + {0x45325342, 0x02000000, 0x00000005}, + {0x45325343, 0x00800000, 0x00000001}, + {0x45325359, 0x04000000, 0x00000005}, + {0x45325442, 0x04000000, 0x00000003}, + {0x45325459, 0x00800000, 0x00000001}, + {0x45325642, 0x02000000, 0x00000001}, + {0x45325741, 0x02000000, 0x00000003}, + {0x45325742, 0x01000000, 0x00000002}, + {0x45325759, 0x04000000, 0x00000005}, + {0x45325841, 0x00800000, 0x00000001}, + {0x45325A43, 0x01000000, 0x00000003}, + {0x45333241, 0x01000000, 0x00000008}, + {0x45333259, 0x04000000, 0x00000008}, + {0x45333441, 0x00800000, 0x00000008}, + {0x45333641, 0x02000000, 0x00000008}, + {0x45333759, 0x08000000, 0x00000008}, + {0x45333842, 0x08000000, 0x00000001}, + {0x45333859, 0x00800000, 0x00000000}, + {0x45334159, 0x00800000, 0x00000001}, + {0x45334241, 0x04000000, 0x00000003}, + {0x45334242, 0x08000000, 0x00000001}, + {0x45334259, 0x04000000, 0x00000005}, + {0x45334341, 0x04000000, 0x00000005}, + {0x45334441, 0x02000000, 0x00000005}, + {0x45334442, 0x04000000, 0x00000001}, + {0x45334443, 0x04000000, 0x00000001}, + {0x45334541, 0x04000000, 0x00000001}, + {0x45334641, 0x00800000, 0x00000001}, + {0x45334643, 0x00800000, 0x00000001}, + {0x45334659, 0x02000000, 0x00000002}, + {0x45334741, 0x02000000, 0x00000005}, + {0x45334743, 0x02000000, 0x00000002}, + {0x45334759, 0x02000000, 0x00000003}, + {0x45334841, 0x04000000, 0x00000003}, + {0x45334943, 0x04000000, 0x00000001}, + {0x45334959, 0x04000000, 0x00000002}, + {0x45334A42, 0x04000000, 0x00000005}, + {0x45334A43, 0x00800000, 0x00000001}, + {0x45334A56, 0x02000000, 0x00000001}, + {0x45334B41, 0x02000000, 0x00000002}, + {0x45334C41, 0x02000000, 0x00000001}, + {0x45334C59, 0x04000000, 0x00000002}, + {0x45334D43, 0x08000000, 0x00000003}, + {0x45334D54, 0x02000000, 0x00000001}, + {0x45334F41, 0x02000000, 0x00000001}, + {0x45335043, 0x08000000, 0x00000005}, + {0x45335141, 0x04000000, 0x00000002}, + {0x45335159, 0x04000000, 0x00000002}, + {0x45335341, 0x02000000, 0x00000001}, + {0x45335342, 0x01000000, 0x00000001}, + {0x45335343, 0x04000000, 0x00000003}, + {0x45335356, 0x08000000, 0x00000005}, + {0x45335359, 0x00800000, 0x00000001}, + {0x45335456, 0x04000000, 0x00000002}, + {0x45335459, 0x04000000, 0x00000003}, + {0x45335541, 0x02000000, 0x00000002}, + {0x45335543, 0x02000000, 0x00000001}, + {0x45335741, 0x04000000, 0x00000001}, + {0x45335743, 0x08000000, 0x00000002}, + {0x45335759, 0x01000000, 0x00000001}, + {0x45343243, 0x08000000, 0x00000003}, + {0x45343459, 0x00800000, 0x00000000}, + {0x45343543, 0x02000000, 0x00000003}, + {0x45343559, 0x01000000, 0x00000000}, + {0x45343842, 0x02000000, 0x00000001}, + {0x45344241, 0x04000000, 0x00000005}, + {0x45344259, 0x02000000, 0x00000001}, + {0x45344341, 0x04000000, 0x00000001}, + {0x45344441, 0x02000000, 0x00000005}, + {0x45344643, 0x00800000, 0x00000001}, + {0x45344659, 0x08000000, 0x00000003}, + {0x45344759, 0x10000000, 0x00000003}, + {0x45344842, 0x00800000, 0x00000001}, + {0x45344843, 0x04000000, 0x00000002}, + {0x45344943, 0x04000000, 0x00000002}, + {0x45344A42, 0x00800000, 0x00000001}, + {0x45344A43, 0x01000000, 0x00000001}, + {0x45344A56, 0x02000000, 0x00000001}, + {0x45344C41, 0x00800000, 0x00000001}, + {0x45344D41, 0x00800000, 0x00000000}, + {0x45344D43, 0x01000000, 0x00000003}, + {0x45344D56, 0x02000000, 0x00000002}, + {0x45344E41, 0x04000000, 0x00000001}, + {0x45345059, 0x04000000, 0x00000002}, + {0x45345141, 0x02000000, 0x00000001}, + {0x45345341, 0x02000000, 0x00000003}, + {0x45345342, 0x01000000, 0x00000001}, + {0x45345456, 0x04000000, 0x00000003}, + {0x45345459, 0x02000000, 0x00000001}, + {0x45345642, 0x01000000, 0x00000001}, + {0x45345643, 0x04000000, 0x00000001}, + {0x45345659, 0x08000000, 0x00000003}, + {0x45345741, 0x02000000, 0x00000002}, + {0x45345742, 0x02000000, 0x00000002}, + {0x45345759, 0x04000000, 0x00000003}, + {0x45345A43, 0x04000000, 0x00000001}, + {0x45353541, 0x01000000, 0x00000008}, + {0x45353542, 0x00800000, 0x00000001}, + {0x45353841, 0x02000000, 0x00000008}, + {0x45353941, 0x04000000, 0x00000008}, + {0x45354143, 0x08000000, 0x00000003}, + {0x45354259, 0x02000000, 0x00000002}, + {0x45354359, 0x00800000, 0x00000008}, + {0x45354441, 0x02000000, 0x00000005}, + {0x45354443, 0x02000000, 0x00000001}, + {0x45354643, 0x00800000, 0x00000002}, + {0x45354741, 0x01000000, 0x00000001}, + {0x45354743, 0x04000000, 0x00000001}, + {0x45354841, 0x02000000, 0x00000002}, + {0x45354943, 0x01000000, 0x00000001}, + {0x45354959, 0x04000000, 0x00000002}, + {0x45354B41, 0x02000000, 0x00000001}, + {0x45354B43, 0x04000000, 0x00000005}, + {0x45354C41, 0x04000000, 0x00000001}, + {0x45354D43, 0x04000000, 0x00000001}, + {0x45354E59, 0x04000000, 0x00000002}, + {0x45354F42, 0x10000000, 0x00000005}, + {0x45355043, 0x02000000, 0x00000001}, + {0x45355059, 0x01000000, 0x00000001}, + {0x45355141, 0x00800000, 0x00000001}, + {0x45355241, 0x02000000, 0x00000001}, + {0x45355243, 0x08000000, 0x00000001}, + {0x45355259, 0x02000000, 0x00000002}, + {0x45355341, 0x01000000, 0x00000001}, + {0x45355342, 0x01000000, 0x00000001}, + {0x45355343, 0x04000000, 0x00000001}, + {0x45355356, 0x02000000, 0x00000002}, + {0x45355359, 0x04000000, 0x00000001}, + {0x45355541, 0x00800000, 0x00000001}, + {0x45355643, 0x02000000, 0x00000001}, + {0x45355659, 0x08000000, 0x00000003}, + {0x45355843, 0x01000000, 0x00000001}, + {0x45355941, 0x08000000, 0x00000003}, + {0x45363241, 0x02000000, 0x00000008}, + {0x45363341, 0x02000000, 0x00000008}, + {0x45363359, 0x01000000, 0x00000008}, + {0x45363442, 0x01000000, 0x00000001}, + {0x45363543, 0x02000000, 0x00000002}, + {0x45363559, 0x04000000, 0x00000008}, + {0x45363642, 0x01000000, 0x00000001}, + {0x45363741, 0x04000000, 0x00000008}, + {0x45363742, 0x02000000, 0x00000001}, + {0x45363842, 0x00800000, 0x00000001}, + {0x45364241, 0x02000000, 0x00000001}, + {0x45364243, 0x02000000, 0x00000002}, + {0x45364254, 0x02000000, 0x00000001}, + {0x45364341, 0x01000000, 0x00000002}, + {0x45364356, 0x02000000, 0x00000002}, + {0x45364542, 0x02000000, 0x00000002}, + {0x45364641, 0x02000000, 0x00000002}, + {0x45364643, 0x04000000, 0x00000002}, + {0x45364742, 0x02000000, 0x00000002}, + {0x45364743, 0x08000000, 0x00000002}, + {0x45364759, 0x04000000, 0x00000002}, + {0x45364841, 0x01000000, 0x00000001}, + {0x45364843, 0x04000000, 0x00000001}, + {0x45364A56, 0x02000000, 0x00000001}, + {0x45364B41, 0x01000000, 0x00000001}, + {0x45364B59, 0x00800000, 0x00000008}, + {0x45364C41, 0x01000000, 0x00000001}, + {0x45364C43, 0x02000000, 0x00000001}, + {0x45364D41, 0x02000000, 0x00000005}, + {0x45364D43, 0x08000000, 0x00000002}, + {0x45364D54, 0x01000000, 0x00000001}, + {0x45364E41, 0x02000000, 0x00000001}, + {0x45364F41, 0x08000000, 0x00000001}, + {0x45365042, 0x01000000, 0x00000001}, + {0x45365241, 0x00800000, 0x00000002}, + {0x45365242, 0x02000000, 0x00000002}, + {0x45365259, 0x02000000, 0x00000002}, + {0x45365342, 0x01000000, 0xFFFFFFFF}, + {0x45365343, 0x04000000, 0x00000002}, + {0x45365359, 0x04000000, 0x00000005}, + {0x45365541, 0x00800000, 0x00000002}, + {0x45365559, 0x02000000, 0x00000002}, + {0x45365642, 0x01000000, 0x00000001}, + {0x45365742, 0x01000000, 0x00000001}, + {0x45365743, 0x04000000, 0x00000002}, + {0x45365941, 0x00800000, 0x00000005}, + {0x45365A42, 0x04000000, 0x00000002}, + {0x45373243, 0x08000000, 0x00000003}, + {0x45373359, 0x01000000, 0x00000001}, + {0x45373442, 0x01000000, 0x00000001}, + {0x45373541, 0x01000000, 0x00000008}, + {0x45373542, 0x00800000, 0xFFFFFFFF}, + {0x45373643, 0x00800000, 0x00000001}, + {0x45374143, 0x02000000, 0x00000002}, + {0x45374159, 0x02000000, 0x00000002}, + {0x45374241, 0x00800000, 0x00000001}, + {0x45374242, 0x02000000, 0x00000002}, + {0x45374243, 0x02000000, 0x00000002}, + {0x45374259, 0x04000000, 0x00000002}, + {0x45374341, 0x00800000, 0x00000002}, + {0x45374342, 0x01000000, 0x00000001}, + {0x45374441, 0x04000000, 0x00000005}, + {0x45374442, 0x00800000, 0x00000001}, + {0x45374542, 0x04000000, 0x00000002}, + {0x45374641, 0x02000000, 0x00000002}, + {0x45374659, 0x01000000, 0x00000002}, + {0x45374741, 0x02000000, 0x00000002}, + {0x45374742, 0x04000000, 0x00000001}, + {0x45374842, 0x00800000, 0x00000001}, + {0x45374943, 0x04000000, 0x00000002}, + {0x45374A42, 0x00800000, 0x00000001}, + {0x45374A43, 0x04000000, 0x00000001}, + {0x45374C41, 0x02000000, 0x00000001}, + {0x45374C43, 0x01000000, 0x00000002}, + {0x45374D41, 0x02000000, 0x00000002}, + {0x45374D43, 0x02000000, 0x00000008}, + {0x45374D59, 0x04000000, 0x00000002}, + {0x45374E41, 0x02000000, 0x00000002}, + {0x45375043, 0x04000000, 0x00000002}, + {0x45375141, 0x00800000, 0x00000002}, + {0x45375143, 0x04000000, 0x00000001}, + {0x45375242, 0x02000000, 0x00000002}, + {0x45375341, 0x08000000, 0x00000003}, + {0x45375359, 0x02000000, 0x00000001}, + {0x45375459, 0x04000000, 0x00000002}, + {0x45375541, 0x02000000, 0x00000002}, + {0x45375643, 0x00800000, 0x00000001}, + {0x45375742, 0x02000000, 0x00000002}, + {0x45375759, 0x04000000, 0x00000001}, + {0x45375842, 0x01000000, 0x00000001}, + {0x45375941, 0x08000000, 0x00000005}, + {0x45375943, 0x04000000, 0x00000002}, + {0x45375A42, 0x00800000, 0x00000001}, + {0x45383259, 0x02000000, 0x00000008}, + {0x45383342, 0x00800000, 0x00000001}, + {0x45383343, 0x04000000, 0x00000005}, + {0x45383541, 0x02000000, 0x00000008}, + {0x45383542, 0x00800000, 0x00000001}, + {0x45383559, 0x00800000, 0x00000000}, + {0x45384142, 0x00800000, 0x00000001}, + {0x45384159, 0x01000000, 0x00000002}, + {0x45384241, 0x02000000, 0x00000001}, + {0x45384242, 0x04000000, 0x00000002}, + {0x45384243, 0x02000000, 0x00000001}, + {0x45384342, 0x00800000, 0x00000001}, + {0x45384359, 0x01000000, 0x00000002}, + {0x45384443, 0x02000000, 0x00000002}, + {0x45384643, 0x04000000, 0x00000002}, + {0x45384659, 0x02000000, 0x00000003}, + {0x45384741, 0x04000000, 0x00000003}, + {0x45384759, 0x08000000, 0x00000005}, + {0x45384841, 0x02000000, 0x00000001}, + {0x45384842, 0x01000000, 0x00000001}, + {0x45384941, 0x02000000, 0x00000002}, + {0x45384959, 0x04000000, 0x00000001}, + {0x45384C41, 0x04000000, 0x00000001}, + {0x45384C43, 0x04000000, 0x00000002}, + {0x45384C59, 0x01000000, 0x00000001}, + {0x45384D41, 0x01000000, 0x00000001}, + {0x45384D42, 0x04000000, 0x00000001}, + {0x45384D43, 0x02000000, 0x00000002}, + {0x45384E41, 0x00800000, 0x00000001}, + {0x45384E42, 0x01000000, 0x00000001}, + {0x45384F41, 0x04000000, 0x00000003}, + {0x45384F59, 0x08000000, 0x00000003}, + {0x45385043, 0x02000000, 0x00000002}, + {0x45385059, 0x01000000, 0x00000001}, + {0x45385141, 0x00800000, 0x00000002}, + {0x45385142, 0x04000000, 0x00000002}, + {0x45385143, 0x01000000, 0x00000001}, + {0x45385243, 0x04000000, 0x00000002}, + {0x45385259, 0x02000000, 0x00000002}, + {0x45385342, 0x04000000, 0x00000002}, + {0x45385359, 0x04000000, 0x00000001}, + {0x45385442, 0x08000000, 0x00000001}, + {0x45385459, 0x02000000, 0x00000002}, + {0x45385542, 0x04000000, 0x00000001}, + {0x45385641, 0x01000000, 0x00000001}, + {0x45385643, 0x04000000, 0x00000002}, + {0x45385741, 0x04000000, 0x00000001}, + {0x45385743, 0x02000000, 0x00000002}, + {0x45385759, 0x08000000, 0x00000005}, + {0x45385841, 0x00800000, 0x00000001}, + {0x45385859, 0x08000000, 0x00000001}, + {0x45385941, 0x01000000, 0x00000001}, + {0x45385942, 0x00800000, 0x00000001}, + {0x45385943, 0x10000000, 0x00000003}, + {0x45385A42, 0x00800000, 0x00000001}, + {0x45393241, 0x00800000, 0x00000008}, + {0x45393341, 0x01000000, 0x00000008}, + {0x45393343, 0x02000000, 0x00000002}, + {0x45393443, 0x04000000, 0x00000005}, + {0x45393459, 0x04000000, 0x00000008}, + {0x45393541, 0x04000000, 0x00000008}, + {0x45393643, 0x04000000, 0x00000002}, + {0x45394241, 0x01000000, 0x00000001}, + {0x45394242, 0x02000000, 0x00000001}, + {0x45394243, 0x08000000, 0x00000005}, + {0x45394259, 0x02000000, 0x00000003}, + {0x45394341, 0x04000000, 0x00000001}, + {0x45394441, 0x02000000, 0x00000003}, + {0x45394542, 0x04000000, 0x00000002}, + {0x45394543, 0x01000000, 0x00000003}, + {0x45394641, 0x00800000, 0x00000001}, + {0x45394643, 0x02000000, 0x00000003}, + {0x45394659, 0x02000000, 0x00000001}, + {0x45394841, 0x04000000, 0x00000005}, + {0x45394856, 0x04000000, 0x00000002}, + {0x45394943, 0x01000000, 0x00000002}, + {0x45394A59, 0x00800000, 0x00000005}, + {0x45394B42, 0x10000000, 0x00000003}, + {0x45394C41, 0x02000000, 0x00000002}, + {0x45394C42, 0x08000000, 0x00000001}, + {0x45394D41, 0x01000000, 0x00000002}, + {0x45394D43, 0x01000000, 0x00000001}, + {0x45394D59, 0x01000000, 0x00000001}, + {0x45394E41, 0x01000000, 0x00000001}, + {0x45395042, 0x04000000, 0x00000002}, + {0x45395056, 0x04000000, 0x00000001}, + {0x45395059, 0x04000000, 0x00000003}, + {0x45395141, 0x04000000, 0x00000001}, + {0x45395259, 0x04000000, 0x00000002}, + {0x45395341, 0x02000000, 0x00000001}, + {0x45395343, 0x02000000, 0x00000001}, + {0x45395459, 0x04000000, 0x00000003}, + {0x45395643, 0x01000000, 0x00000001}, + {0x45395742, 0x08000000, 0x00000002}, + {0x45395743, 0x08000000, 0x00000001}, + {0x45395941, 0x08000000, 0x00000003}, + {0x45395943, 0x04000000, 0x00000002}, + {0x45395A43, 0x04000000, 0x00000002}, + {0x45413541, 0x04000000, 0x00000001}, + {0x45413543, 0x02000000, 0x00000002}, + {0x45413641, 0x02000000, 0x00000005}, + {0x45413642, 0x04000000, 0x00000001}, + {0x45413741, 0x01000000, 0x00000001}, + {0x45413956, 0x02000000, 0x00000000}, + {0x45414143, 0x04000000, 0x00000002}, + {0x45414156, 0x02000000, 0x00000007}, + {0x45414159, 0x04000000, 0x00000002}, + {0x45414241, 0x02000000, 0x00000001}, + {0x45414242, 0x02000000, 0x00000002}, + {0x45414243, 0x02000000, 0x00000001}, + {0x45414254, 0x01000000, 0x00000001}, + {0x45414256, 0x02000000, 0x00000001}, + {0x45414341, 0x00800000, 0x00000001}, + {0x45414356, 0x04000000, 0x00000001}, + {0x45414441, 0x04000000, 0x00000006}, + {0x45414442, 0x04000000, 0x00000001}, + {0x45414443, 0x04000000, 0x00000002}, + {0x45414541, 0x08000000, 0x00000001}, + {0x45414559, 0x02000000, 0x00000003}, + {0x45414641, 0x04000000, 0x00000003}, + {0x45414642, 0x02000000, 0x00000003}, + {0x45414643, 0x08000000, 0x00000002}, + {0x45414941, 0x04000000, 0x00000001}, + {0x45414959, 0x02000000, 0x00000001}, + {0x45414A42, 0x01000000, 0x00000002}, + {0x45414A43, 0x04000000, 0x00000003}, + {0x45414A59, 0x04000000, 0x00000002}, + {0x45414B41, 0x08000000, 0x00000005}, + {0x45414C42, 0x04000000, 0x00000002}, + {0x45414C56, 0x04000000, 0x00000002}, + {0x45414E42, 0x02000000, 0x00000001}, + {0x45414E43, 0x04000000, 0x00000001}, + {0x45415041, 0x04000000, 0x00000006}, + {0x45415042, 0x02000000, 0x00000002}, + {0x45415043, 0x02000000, 0x00000001}, + {0x45415054, 0x02000000, 0x00000001}, + {0x45415141, 0x02000000, 0x00000001}, + {0x45415143, 0x01000000, 0x00000002}, + {0x45415241, 0x02000000, 0x00000001}, + {0x45415243, 0x00800000, 0x00000001}, + {0x45415259, 0x01000000, 0x00000001}, + {0x45415343, 0x01000000, 0x00000001}, + {0x45415359, 0x01000000, 0x00000002}, + {0x45415441, 0x01000000, 0x00000001}, + {0x45415443, 0x04000000, 0x00000001}, + {0x45415543, 0x04000000, 0x00000001}, + {0x45415641, 0x04000000, 0x00000002}, + {0x45415643, 0x01000000, 0x00000001}, + {0x45415741, 0x04000000, 0x00000002}, + {0x45415743, 0x00800000, 0x00000001}, + {0x45415941, 0x00800000, 0x00000002}, + {0x45415942, 0x02000000, 0x00000001}, + {0x45415A42, 0x08000000, 0x00000001}, + {0x45415A43, 0x02000000, 0x00000002}, + {0x45423243, 0x02000000, 0x00000001}, + {0x45423342, 0x04000000, 0x00000001}, + {0x45423343, 0x00800000, 0x00000001}, + {0x45423442, 0x04000000, 0x00000002}, + {0x45423443, 0x02000000, 0x00000003}, + {0x45423542, 0x04000000, 0x00000002}, + {0x45423543, 0x01000000, 0x00000002}, + {0x45423641, 0x02000000, 0x00000005}, + {0x45423642, 0x04000000, 0x00000001}, + {0x45423741, 0x01000000, 0x00000001}, + {0x45423743, 0x02000000, 0x00000002}, + {0x45424143, 0x01000000, 0x00000001}, + {0x45424159, 0x00800000, 0x00000001}, + {0x45424243, 0x01000000, 0x00000002}, + {0x45424341, 0x04000000, 0x00000003}, + {0x45424354, 0x08000000, 0x00000001}, + {0x45424442, 0x04000000, 0x00000002}, + {0x45424443, 0x04000000, 0x00000001}, + {0x45424541, 0x00800000, 0x00000008}, + {0x45424641, 0x00800000, 0x00000001}, + {0x45424642, 0x01000000, 0x00000002}, + {0x45424654, 0x01000000, 0x00000001}, + {0x45424656, 0x02000000, 0x00000001}, + {0x45424743, 0x02000000, 0x00000001}, + {0x45424841, 0x02000000, 0x00000002}, + {0x45424842, 0x00800000, 0x00000001}, + {0x45424942, 0x01000000, 0x00000003}, + {0x45424959, 0x02000000, 0x00000001}, + {0x45424A41, 0x04000000, 0x00000005}, + {0x45424A42, 0x04000000, 0x00000001}, + {0x45424A43, 0x01000000, 0x00000001}, + {0x45424A59, 0x04000000, 0x00000001}, + {0x45424B41, 0x02000000, 0x00000003}, + {0x45424B43, 0x02000000, 0x00000002}, + {0x45424B59, 0x04000000, 0x00000003}, + {0x45424C42, 0x04000000, 0x00000002}, + {0x45424C43, 0x08000000, 0x00000003}, + {0x45424C59, 0x04000000, 0x00000002}, + {0x45424E43, 0x04000000, 0x00000003}, + {0x45425141, 0x00800000, 0x00000001}, + {0x45425143, 0x01000000, 0x00000002}, + {0x45425159, 0x00800000, 0x00000001}, + {0x45425241, 0x02000000, 0x00000001}, + {0x45425243, 0x02000000, 0x00000005}, + {0x45425259, 0x08000000, 0x00000003}, + {0x45425341, 0x04000000, 0x00000002}, + {0x45425442, 0x04000000, 0x00000002}, + {0x45425443, 0x08000000, 0x00000005}, + {0x45425543, 0x04000000, 0x00000003}, + {0x45425559, 0x04000000, 0x00000002}, + {0x45425641, 0x01000000, 0x00000001}, + {0x45425741, 0x00800000, 0x00000001}, + {0x45425742, 0x04000000, 0x00000002}, + {0x45425759, 0x02000000, 0x00000002}, + {0x45425942, 0x01000000, 0x00000001}, + {0x45425943, 0x04000000, 0x00000001}, + {0x45425959, 0x04000000, 0x00000005}, + {0x45433342, 0x04000000, 0x00000002}, + {0x45433441, 0x02000000, 0x00000003}, + {0x45433459, 0x04000000, 0x00000008}, + {0x45433542, 0x00800000, 0x00000001}, + {0x45433641, 0x02000000, 0x00000005}, + {0x45433642, 0x08000000, 0x00000002}, + {0x45433643, 0x10000000, 0x00000005}, + {0x45433741, 0x02000000, 0x00000001}, + {0x45433841, 0x02000000, 0x00000002}, + {0x45433859, 0x00800000, 0x00000008}, + {0x45434156, 0x04000000, 0x00000002}, + {0x45434241, 0x04000000, 0x00000005}, + {0x45434259, 0x02000000, 0x00000002}, + {0x45434341, 0x02000000, 0x00000001}, + {0x45434343, 0x01000000, 0x00000001}, + {0x45434354, 0x00800000, 0x00000001}, + {0x45434441, 0x01000000, 0x00000001}, + {0x45434442, 0x02000000, 0x00000001}, + {0x45434443, 0x04000000, 0x00000003}, + {0x45434459, 0x08000000, 0x00000003}, + {0x45434541, 0x00800000, 0x00000001}, + {0x45434559, 0x02000000, 0x00000001}, + {0x45434642, 0x02000000, 0x00000001}, + {0x45434659, 0x08000000, 0x00000002}, + {0x45434741, 0x04000000, 0x00000003}, + {0x45434759, 0x02000000, 0x00000002}, + {0x45434843, 0x01000000, 0x00000001}, + {0x45434941, 0x01000000, 0x00000001}, + {0x45434943, 0x04000000, 0x00000003}, + {0x45434956, 0x04000000, 0x00000002}, + {0x45434959, 0x04000000, 0x00000002}, + {0x45434A42, 0x03E8823C, 0x00000002}, + {0x45434A43, 0x04000000, 0x00000002}, + {0x45434A56, 0x04000000, 0x00000001}, + {0x45434A59, 0x04000000, 0x00000002}, + {0x45434B42, 0x10000000, 0x00000006}, + {0x45434B43, 0x01000000, 0x00000001}, + {0x45434C42, 0x04000000, 0x00000002}, + {0x45434C56, 0x04000000, 0x00000002}, + {0x45434D41, 0x02000000, 0x00000005}, + {0x45434D56, 0x02000000, 0x00000001}, + {0x45434F43, 0x01000000, 0x00000001}, + {0x45435041, 0x01000000, 0x00000001}, + {0x45435043, 0x00800000, 0x00000002}, + {0x45435159, 0x01000000, 0x00000001}, + {0x45435241, 0x02000000, 0x00000002}, + {0x45435243, 0x02000000, 0x00000001}, + {0x45435341, 0x04000000, 0x00000002}, + {0x45435343, 0x04000000, 0x00000001}, + {0x45435359, 0x01000000, 0x00000001}, + {0x45435441, 0x04000000, 0x00000005}, + {0x45435442, 0x01000000, 0x00000001}, + {0x45435641, 0x04000000, 0x00000005}, + {0x45435741, 0x04000000, 0x00000002}, + {0x45435759, 0x02000000, 0x00000002}, + {0x45435842, 0x01000000, 0x00000001}, + {0x45435943, 0x02000000, 0x00000002}, + {0x45435959, 0x02000000, 0x00000001}, + {0x45443241, 0x02000000, 0x00000002}, + {0x45443343, 0x01000000, 0x00000001}, + {0x45443442, 0x00800000, 0x00000001}, + {0x45443643, 0x02000000, 0x00000001}, + {0x45443659, 0x00800000, 0x00000008}, + {0x45443741, 0x02000000, 0x00000001}, + {0x45443759, 0x08000000, 0x00000008}, + {0x45444154, 0x08000000, 0x00000005}, + {0x45444241, 0x01000000, 0x00000001}, + {0x45444243, 0x04000000, 0x00000002}, + {0x45444343, 0x00800000, 0x00000003}, + {0x45444354, 0x02000000, 0x00000001}, + {0x45444356, 0x04000000, 0x00000002}, + {0x45444441, 0x01000000, 0x00000001}, + {0x45444459, 0x01000000, 0x00000001}, + {0x45444559, 0x00800000, 0x00000001}, + {0x45444641, 0x04000000, 0x00000002}, + {0x45444642, 0x00800000, 0x00000001}, + {0x45444643, 0x08000000, 0x00000002}, + {0x45444743, 0x00800000, 0x00000001}, + {0x45444759, 0x00800000, 0x00000003}, + {0x45444841, 0x04000000, 0x00000002}, + {0x45444842, 0x04000000, 0x00000001}, + {0x45444859, 0x04000000, 0x00000001}, + {0x45444943, 0x02000000, 0x00000003}, + {0x45444956, 0x02000000, 0x00000002}, + {0x45444959, 0x02000000, 0x00000005}, + {0x45444A42, 0x01000000, 0x00000002}, + {0x45444A59, 0x02000000, 0x00000002}, + {0x45444B41, 0x01000000, 0x00000002}, + {0x45444C41, 0x04000000, 0x00000003}, + {0x45444C42, 0x04000000, 0x00000002}, + {0x45444C59, 0x04000000, 0x00000005}, + {0x45444D41, 0x01000000, 0x00000005}, + {0x45444D42, 0x04000000, 0x00000001}, + {0x45444D43, 0x02000000, 0x00000005}, + {0x45444D44, 0x20000000, 0x00000000}, + {0x45444E41, 0x01000000, 0x00000005}, + {0x45444E42, 0x02000000, 0x00000001}, + {0x45444E43, 0x04000000, 0x00000002}, + {0x45444E59, 0x02000000, 0x00000001}, + {0x45445041, 0x01000000, 0x00000002}, + {0x45445042, 0x04000000, 0xFFFFFFFF}, + {0x45445043, 0x02000000, 0x00000001}, + {0x45445054, 0x08000000, 0x00000001}, + {0x45445241, 0x02000000, 0x00000001}, + {0x45445243, 0x01000000, 0x00000001}, + {0x45445341, 0x01000000, 0x00000001}, + {0x45445342, 0x04000000, 0x00000002}, + {0x45445343, 0x01000000, 0x00000001}, + {0x45445441, 0x01000000, 0x00000002}, + {0x45445442, 0x01000000, 0x00000001}, + {0x45445443, 0x04000000, 0x00000002}, + {0x45445542, 0x01000000, 0x00000001}, + {0x45445641, 0x01000000, 0x00000002}, + {0x45445642, 0x00800000, 0x00000001}, + {0x45445741, 0x02000000, 0x00000005}, + {0x45445742, 0x04000000, 0x00000001}, + {0x45445759, 0x01000000, 0x00000002}, + {0x45445842, 0x01000000, 0x00000001}, + {0x45445A41, 0x00800000, 0x00000008}, + {0x45445A42, 0x08000000, 0x00000001}, + {0x45453242, 0x00800000, 0x00000001}, + {0x45453341, 0x00800000, 0x00000002}, + {0x45453442, 0x01000000, 0x00000001}, + {0x45453559, 0x04000000, 0x00000000}, + {0x45453642, 0x02000000, 0x00000001}, + {0x45453741, 0x01000000, 0x00000001}, + {0x45453742, 0x02000000, 0x00000001}, + {0x45454241, 0x00800000, 0x00000001}, + {0x45454254, 0x02000000, 0x00000001}, + {0x45454343, 0x01000000, 0x00000005}, + {0x45454359, 0x02000000, 0x00000002}, + {0x45454442, 0x04000000, 0x00000002}, + {0x45454456, 0x10000000, 0x00000006}, + {0x45454641, 0x04000000, 0x00000003}, + {0x45454659, 0x04000000, 0x00000005}, + {0x45454741, 0x01000000, 0x00000001}, + {0x45454742, 0x04000000, 0x00000001}, + {0x45454743, 0x02000000, 0x00000002}, + {0x45454841, 0x08000000, 0x00000005}, + {0x45454943, 0x04000000, 0x00000002}, + {0x45454A59, 0x01000000, 0x00000001}, + {0x45454B42, 0x04000000, 0x00000002}, + {0x45454C59, 0x02000000, 0x00000001}, + {0x45454D44, 0x20000000, 0x00000000}, + {0x45454D56, 0x02000000, 0x00000001}, + {0x45454F59, 0x01000000, 0x00000005}, + {0x45455056, 0x04000000, 0x00000001}, + {0x45455141, 0x00800000, 0x00000002}, + {0x45455143, 0x04000000, 0x00000002}, + {0x45455241, 0x04000000, 0x00000001}, + {0x45455243, 0x04000000, 0x00000001}, + {0x45455341, 0x04000000, 0x00000002}, + {0x45455456, 0x04000000, 0x00000002}, + {0x45455459, 0x02000000, 0x00000003}, + {0x45455641, 0x01000000, 0x00000001}, + {0x45455642, 0x00800000, 0x00000002}, + {0x45455741, 0x04000000, 0x00000005}, + {0x45455742, 0x04000000, 0x00000001}, + {0x45455743, 0x01000000, 0x00000002}, + {0x45455842, 0x04000000, 0x00000001}, + {0x45455943, 0x08000000, 0x00000002}, + {0x45455A41, 0x04000000, 0x00000006}, + {0x45455A42, 0x00800000, 0x00000001}, + {0x45463242, 0x00800000, 0x00000001}, + {0x45463541, 0x04000000, 0x00000002}, + {0x45463641, 0x08000000, 0x00000003}, + {0x45463642, 0x08000000, 0x00000001}, + {0x45463659, 0x02000000, 0x00000000}, + {0x45463742, 0x01000000, 0xFFFFFFFF}, + {0x45463743, 0x01000000, 0x00000003}, + {0x45463859, 0x08000000, 0x00000008}, + {0x45464159, 0x02000000, 0x00000002}, + {0x45464243, 0x08000000, 0x00000003}, + {0x45464341, 0x04000000, 0x00000002}, + {0x45464343, 0x00800000, 0x00000001}, + {0x45464441, 0x01000000, 0x00000001}, + {0x45464443, 0x04000000, 0x00000002}, + {0x45464541, 0x00800000, 0x00000001}, + {0x45464542, 0x00800000, 0x00000001}, + {0x45464543, 0x01000000, 0x00000001}, + {0x45464641, 0x08000000, 0x00000003}, + {0x45464741, 0x04000000, 0x00000002}, + {0x45464743, 0x00800000, 0x00000001}, + {0x45464759, 0x01000000, 0x00000001}, + {0x45464841, 0x02000000, 0x00000001}, + {0x45464843, 0x02000000, 0x00000002}, + {0x45464859, 0x00800000, 0x00000002}, + {0x45464956, 0x02000000, 0x00000002}, + {0x45464959, 0x04000000, 0x00000002}, + {0x45464B43, 0x02000000, 0x00000001}, + {0x45464B59, 0x02000000, 0x00000001}, + {0x45464C42, 0x10000000, 0x00000003}, + {0x45464C43, 0x02000000, 0x00000001}, + {0x45464D41, 0x01000000, 0x00000001}, + {0x45464D44, 0x02000000, 0xFFFFFFFF}, + {0x45464D59, 0x04000000, 0x00000003}, + {0x45464E41, 0x02000000, 0x00000005}, + {0x45465042, 0x04000000, 0x00000002}, + {0x45465043, 0x00800000, 0x00000002}, + {0x45465054, 0x02000000, 0x00000001}, + {0x45465056, 0x04000000, 0x00000002}, + {0x45465241, 0x08000000, 0x00000003}, + {0x45465242, 0x08000000, 0x00000003}, + {0x45465243, 0x02000000, 0x00000002}, + {0x45465259, 0x02000000, 0x00000002}, + {0x45465341, 0x02000000, 0x00000005}, + {0x45465359, 0x04000000, 0x00000001}, + {0x45465443, 0x04000000, 0x00000001}, + {0x45465541, 0x04000000, 0x00000002}, + {0x45465542, 0x01000000, 0x00000002}, + {0x45465742, 0x04000000, 0x00000001}, + {0x45465743, 0x02000000, 0x00000002}, + {0x45465841, 0x08000000, 0x00000003}, + {0x45465842, 0x04000000, 0x00000001}, + {0x45473241, 0x02000000, 0x00000003}, + {0x45473256, 0x02000000, 0x00000006}, + {0x45473459, 0x01000000, 0x00000008}, + {0x45473541, 0x01000000, 0x00000001}, + {0x45473642, 0x00800000, 0x00000001}, + {0x45473741, 0x02000000, 0x00000001}, + {0x45473743, 0x01000000, 0x00000001}, + {0x45473759, 0x08000000, 0x00000000}, + {0x45473859, 0x02000000, 0x00000000}, + {0x45474142, 0x01000000, 0x00000001}, + {0x45474159, 0x01000000, 0x00000001}, + {0x45474243, 0x02000000, 0x00000005}, + {0x45474254, 0x00800000, 0x00000001}, + {0x45474341, 0x00800000, 0x00000002}, + {0x45474342, 0x04000000, 0x00000002}, + {0x45474354, 0x04000000, 0x00000001}, + {0x45474356, 0x04000000, 0x00000002}, + {0x45474359, 0x00800000, 0x00000001}, + {0x45474441, 0x02000000, 0x00000005}, + {0x45474443, 0x04000000, 0x00000006}, + {0x45474541, 0x04000000, 0x00000001}, + {0x45474542, 0x00800000, 0x00000001}, + {0x45474641, 0x04000000, 0x00000001}, + {0x45474642, 0x04000000, 0x00000003}, + {0x45474742, 0x02000000, 0x00000005}, + {0x45474754, 0x00800000, 0x00000001}, + {0x45474842, 0x02000000, 0x00000001}, + {0x45474942, 0x02000000, 0x00000001}, + {0x45474A59, 0x02000000, 0x00000002}, + {0x45474B41, 0x02000000, 0x00000002}, + {0x45474B56, 0x02000000, 0x00000005}, + {0x45474B59, 0x10000000, 0x00000003}, + {0x45474C43, 0x04000000, 0x00000001}, + {0x45474C59, 0x04000000, 0x00000001}, + {0x45474D41, 0x01000000, 0x00000001}, + {0x45474D42, 0x02000000, 0x00000001}, + {0x45474D43, 0x04000000, 0x00000001}, + {0x45474D56, 0x02000000, 0x00000002}, + {0x45474E43, 0x02000000, 0x00000002}, + {0x45474E59, 0x08000000, 0x00000003}, + {0x45474F59, 0x08000000, 0x00000003}, + {0x45475041, 0x01000000, 0x00000001}, + {0x45475049, 0x08000000, 0x00000006}, + {0x45475059, 0x04000000, 0x00000002}, + {0x45475142, 0x04000000, 0x00000001}, + {0x45475241, 0x02000000, 0x00000005}, + {0x45475256, 0x02000000, 0x00000002}, + {0x45475356, 0x02000000, 0x00000001}, + {0x45475541, 0x02000000, 0x00000002}, + {0x45475542, 0x00800000, 0x00000001}, + {0x45475642, 0x01000000, 0x00000002}, + {0x45475842, 0x04000000, 0x00000002}, + {0x45475843, 0x00800000, 0x00000001}, + {0x45475941, 0x04000000, 0x00000002}, + {0x45475A42, 0x02000000, 0x00000001}, + {0x45483241, 0x01000000, 0x00000001}, + {0x45483341, 0x02000000, 0x00000001}, + {0x45483343, 0x00800000, 0x00000001}, + {0x45483442, 0x02000000, 0x00000001}, + {0x45483541, 0x01000000, 0x00000001}, + {0x45483542, 0x01000000, 0x00000001}, + {0x45483559, 0x02000000, 0x00000000}, + {0x45483741, 0x02000000, 0x00000001}, + {0x45483742, 0x04000000, 0x00000002}, + {0x45483842, 0x04000000, 0x00000002}, + {0x45483959, 0x00800000, 0x00000008}, + {0x45484142, 0x04000000, 0x00000001}, + {0x45484159, 0x04000000, 0x00000002}, + {0x45484241, 0x08000000, 0x00000002}, + {0x45484254, 0x01000000, 0x00000001}, + {0x45484342, 0x00800000, 0x00000001}, + {0x45484459, 0x02000000, 0x00000005}, + {0x45484541, 0x04000000, 0x00000002}, + {0x45484542, 0x01000000, 0x00000002}, + {0x45484659, 0x04000000, 0x00000002}, + {0x45484742, 0x10000000, 0x00000001}, + {0x45484743, 0x02000000, 0x00000002}, + {0x45484759, 0x08000000, 0x00000001}, + {0x45484841, 0x04000000, 0x00000001}, + {0x45484942, 0x04000000, 0x00000002}, + {0x45484943, 0x04000000, 0x00000002}, + {0x45484959, 0x02000000, 0x00000002}, + {0x45484B43, 0x02000000, 0x00000002}, + {0x45484B56, 0x02000000, 0x00000002}, + {0x45484B59, 0x08000000, 0x00000005}, + {0x45484C41, 0x02000000, 0x00000001}, + {0x45484C42, 0x08000000, 0x00000001}, + {0x45484C43, 0x01000000, 0x00000002}, + {0x45484C59, 0x04000000, 0x00000002}, + {0x45484D41, 0x04000000, 0x00000005}, + {0x45484D54, 0x00800000, 0x00000001}, + {0x45485041, 0x02000000, 0x00000005}, + {0x45485043, 0x04000000, 0x00000001}, + {0x45485059, 0x00800000, 0x00000002}, + {0x45485341, 0x02000000, 0x00000002}, + {0x45485342, 0x02000000, 0x00000001}, + {0x45485359, 0x02000000, 0x00000001}, + {0x45485441, 0x02000000, 0x00000001}, + {0x45485442, 0x01000000, 0x00000002}, + {0x45485559, 0x01000000, 0x00000002}, + {0x45485641, 0x04000000, 0x00000002}, + {0x45485642, 0x01000000, 0x00000001}, + {0x45485741, 0x01000000, 0x00000001}, + {0x45485843, 0x02000000, 0x00000001}, + {0x45485942, 0x02000000, 0x00000002}, + {0x45485943, 0x04000000, 0x00000002}, + {0x45485A42, 0x00800000, 0x00000001}, + {0x45485A59, 0x04000000, 0x00000001}, + {0x45493241, 0x01000000, 0x00000001}, + {0x45493242, 0x04000000, 0x00000001}, + {0x45493341, 0x08000000, 0x00000002}, + {0x45493441, 0x02000000, 0x00000001}, + {0x45493459, 0x04000000, 0x00000008}, + {0x45493541, 0x01000000, 0x00000001}, + {0x45493642, 0x04000000, 0x00000002}, + {0x45493741, 0x02000000, 0x00000001}, + {0x45493842, 0x04000000, 0x00000001}, + {0x45493859, 0x01000000, 0x00000000}, + {0x45494159, 0x04000000, 0x00000001}, + {0x45494341, 0x02000000, 0x00000002}, + {0x45494342, 0x02000000, 0x00000002}, + {0x45494359, 0x01000000, 0x00000001}, + {0x45494442, 0x04000000, 0x00000001}, + {0x45494459, 0x04000000, 0x00000002}, + {0x45494643, 0x08000000, 0x00000003}, + {0x45494659, 0x04000000, 0x00000001}, + {0x45494742, 0x04000000, 0x00000001}, + {0x45494942, 0x00800000, 0x00000001}, + {0x45494959, 0x00800000, 0x00000001}, + {0x45494B42, 0x08000000, 0x00000007}, + {0x45494C43, 0x04000000, 0x00000001}, + {0x45494C59, 0x04000000, 0x00000002}, + {0x45494D43, 0x00800000, 0x00000001}, + {0x45494E41, 0x08000000, 0x00000005}, + {0x45494E59, 0x08000000, 0x00000002}, + {0x45495056, 0x02000000, 0x00000002}, + {0x45495059, 0x02000000, 0x00000003}, + {0x45495141, 0x02000000, 0x00000005}, + {0x45495241, 0x01000000, 0x00000001}, + {0x45495243, 0x02000000, 0x00000002}, + {0x45495256, 0x02000000, 0x00000001}, + {0x45495259, 0x04000000, 0x00000002}, + {0x45495341, 0x02000000, 0x00000002}, + {0x45495342, 0x04000000, 0x00000001}, + {0x45495343, 0x01000000, 0x00000002}, + {0x45495441, 0x01000000, 0x00000008}, + {0x45495442, 0x01000000, 0x00000001}, + {0x45495456, 0x02000000, 0x00000001}, + {0x45495541, 0x01000000, 0x00000001}, + {0x45495542, 0x01000000, 0x00000001}, + {0x45495543, 0x02000000, 0x00000002}, + {0x45495559, 0x04000000, 0x00000002}, + {0x45495643, 0x04000000, 0x00000002}, + {0x45495659, 0x08000000, 0x00000003}, + {0x45495741, 0x08000000, 0x00000005}, + {0x45495742, 0x01000000, 0x00000002}, + {0x45495743, 0x01000000, 0x00000001}, + {0x45495941, 0x01000000, 0x00000001}, + {0x45495943, 0x02000000, 0x00000002}, + {0x45495A42, 0x00800000, 0x00000001}, + {0x454A3259, 0x02000000, 0x00000008}, + {0x454A3342, 0x08000000, 0x00000002}, + {0x454A3343, 0x10000000, 0x00000003}, + {0x454A3442, 0x00800000, 0x00000001}, + {0x454A3542, 0x00800000, 0x00000001}, + {0x454A3559, 0x08000000, 0x00000000}, + {0x454A3642, 0x00800000, 0x00000001}, + {0x454A3741, 0x02000000, 0x00000001}, + {0x454A4142, 0x01000000, 0x00000001}, + {0x454A4143, 0x01000000, 0x00000001}, + {0x454A4159, 0x01000000, 0x00000002}, + {0x454A4241, 0x04000000, 0x00000005}, + {0x454A4341, 0x04000000, 0x00000001}, + {0x454A4454, 0x00800000, 0x00000001}, + {0x454A4459, 0x01000000, 0x00000001}, + {0x454A4543, 0x01000000, 0x00000001}, + {0x454A4642, 0x01000000, 0x00000002}, + {0x454A4643, 0x02000000, 0x00000002}, + {0x454A4759, 0x02000000, 0x00000001}, + {0x454A4841, 0x01000000, 0x00000002}, + {0x454A4943, 0x00800000, 0x00000001}, + {0x454A4956, 0x04000000, 0x00000003}, + {0x454A4A42, 0x01000000, 0x00000001}, + {0x454A4A43, 0x00800000, 0x00000001}, + {0x454A4C41, 0x01000000, 0x00000001}, + {0x454A4C42, 0x04000000, 0x00000001}, + {0x454A4C43, 0x08000000, 0x00000002}, + {0x454A4C54, 0x08000000, 0x00000002}, + {0x454A4C59, 0x04000000, 0x00000001}, + {0x454A4D42, 0x00800000, 0x00000001}, + {0x454A4D59, 0x04000000, 0x00000001}, + {0x454A4E41, 0x02000000, 0x00000001}, + {0x454A4E43, 0x02000000, 0x00000001}, + {0x454A4E59, 0x02000000, 0x00000001}, + {0x454A4F41, 0x02000000, 0x00000002}, + {0x454A5043, 0x04000000, 0x00000002}, + {0x454A5141, 0x08000000, 0x00000001}, + {0x454A5143, 0x00800000, 0x00000001}, + {0x454A5242, 0x08000000, 0x00000003}, + {0x454A5243, 0x02000000, 0x00000001}, + {0x454A5341, 0x04000000, 0x00000005}, + {0x454A5342, 0x00800000, 0x00000001}, + {0x454A5441, 0x01000000, 0x00000002}, + {0x454A5442, 0x01000000, 0x00000002}, + {0x454A5459, 0x04000000, 0x00000002}, + {0x454A5541, 0x04000000, 0x00000001}, + {0x454A5542, 0x08000000, 0x00000001}, + {0x454A5641, 0x04000000, 0x00000002}, + {0x454A5642, 0x01000000, 0x00000001}, + {0x454A5659, 0x01000000, 0x00000001}, + {0x454A5743, 0x00800000, 0x00000001}, + {0x454A5759, 0x00800000, 0x00000002}, + {0x454A5841, 0x04000000, 0x00000003}, + {0x454A5959, 0x01000000, 0x00000002}, + {0x454A5A42, 0x02000000, 0x00000001}, + {0x454B3243, 0x00800000, 0x00000003}, + {0x454B3342, 0x01000000, 0x00000001}, + {0x454B3641, 0x08000000, 0x00000003}, + {0x454B3741, 0x02000000, 0x00000001}, + {0x454B3842, 0x02000000, 0x00000002}, + {0x454B4143, 0x01000000, 0x00000002}, + {0x454B4241, 0x00800000, 0x00000001}, + {0x454B4242, 0x02000000, 0x00000002}, + {0x454B4243, 0x04000000, 0x00000002}, + {0x454B4343, 0x04000000, 0x00000001}, + {0x454B4356, 0x08000000, 0x00000002}, + {0x454B4541, 0x04000000, 0x00000002}, + {0x454B4559, 0x08000000, 0x00000005}, + {0x454B4841, 0x04000000, 0x00000003}, + {0x454B4843, 0x01000000, 0x00000001}, + {0x454B4959, 0x02000000, 0x00000005}, + {0x454B4A43, 0x08000000, 0x00000003}, + {0x454B4A59, 0x08000000, 0x00000002}, + {0x454B4B41, 0x01000000, 0x00000003}, + {0x454B4C41, 0x08000000, 0x00000003}, + {0x454B4C54, 0x08000000, 0x00000002}, + {0x454B4C59, 0x02000000, 0x00000002}, + {0x454B4D42, 0x04000000, 0x00000001}, + {0x454B4E41, 0x00800000, 0x00000001}, + {0x454B4E59, 0x04000000, 0x00000002}, + {0x454B5049, 0x08000000, 0x00000006}, + {0x454B5142, 0x01000000, 0x00000001}, + {0x454B5159, 0x02000000, 0x00000001}, + {0x454B5243, 0x04000000, 0x00000001}, + {0x454B5341, 0x04000000, 0x00000002}, + {0x454B5342, 0x08000000, 0x00000003}, + {0x454B5356, 0x04000000, 0x00000001}, + {0x454B5441, 0x04000000, 0x00000002}, + {0x454B5559, 0x04000000, 0x00000001}, + {0x454B5641, 0x01000000, 0x00000001}, + {0x454B5741, 0x04000000, 0x00000003}, + {0x454B5759, 0x04000000, 0x00000002}, + {0x454B5943, 0x02000000, 0x00000002}, + {0x454B5959, 0x04000000, 0x00000002}, + {0x454B5A41, 0x00800000, 0x00000002}, + {0x454C3241, 0x01000000, 0x00000003}, + {0x454C3259, 0x04000000, 0x00000005}, + {0x454C3541, 0x08000000, 0x00000002}, + {0x454C3642, 0x08000000, 0x00000002}, + {0x454C3741, 0x02000000, 0x00000001}, + {0x454C3742, 0x00800000, 0x00000001}, + {0x454C3859, 0x08000000, 0x00000000}, + {0x454C4143, 0x04000000, 0x00000001}, + {0x454C4156, 0x04000000, 0x00000002}, + {0x454C4241, 0x08000000, 0x00000002}, + {0x454C4242, 0x02000000, 0x00000001}, + {0x454C4243, 0x00800000, 0x00000002}, + {0x454C4256, 0x02000000, 0x00000002}, + {0x454C4259, 0x00800000, 0x00000001}, + {0x454C4341, 0x04000000, 0x00000003}, + {0x454C4342, 0x01000000, 0x00000002}, + {0x454C4354, 0x02000000, 0x00000001}, + {0x454C4441, 0x04000000, 0x00000003}, + {0x454C4442, 0x01000000, 0x00000001}, + {0x454C4443, 0x02000000, 0x00000005}, + {0x454C4459, 0x01000000, 0x00000008}, + {0x454C4556, 0x02000000, 0x00000003}, + {0x454C4641, 0x00800000, 0x00000001}, + {0x454C4642, 0x04000000, 0x00000002}, + {0x454C4741, 0x02000000, 0x00000001}, + {0x454C4742, 0x01000000, 0x00000001}, + {0x454C4759, 0x04000000, 0x00000002}, + {0x454C4859, 0x08000000, 0x00000003}, + {0x454C4A41, 0x04000000, 0x00000001}, + {0x454C4A42, 0x02000000, 0x00000002}, + {0x454C4A59, 0x01000000, 0x00000002}, + {0x454C4B54, 0x02000000, 0x00000002}, + {0x454C4C42, 0x01000000, 0x00000003}, + {0x454C4C54, 0x04000000, 0x00000001}, + {0x454C4D41, 0x02000000, 0x00000002}, + {0x454C4D42, 0x00800000, 0x00000001}, + {0x454C4D43, 0x04000000, 0x00000002}, + {0x454C4D54, 0x04000000, 0x00000002}, + {0x454C4E41, 0x04000000, 0x00000001}, + {0x454C4E42, 0x01000000, 0x00000001}, + {0x454C4E59, 0x04000000, 0x00000001}, + {0x454C4F43, 0x08000000, 0x00000003}, + {0x454C5041, 0x00800000, 0x00000002}, + {0x454C5043, 0x01000000, 0x00000001}, + {0x454C5059, 0x00800000, 0x00000001}, + {0x454C5141, 0x00800000, 0x00000001}, + {0x454C5142, 0x00800000, 0x00000003}, + {0x454C5159, 0x08000000, 0x00000002}, + {0x454C5242, 0x01000000, 0x00000001}, + {0x454C5243, 0x02000000, 0x00000001}, + {0x454C5259, 0x02000000, 0x00000001}, + {0x454C5341, 0x01000000, 0x00000001}, + {0x454C5342, 0x02000000, 0x00000003}, + {0x454C5343, 0x00800000, 0x00000002}, + {0x454C5359, 0x10000000, 0x00000005}, + {0x454C5441, 0x01000000, 0x00000001}, + {0x454C5459, 0x00800000, 0x00000002}, + {0x454C5541, 0x00800000, 0x00000002}, + {0x454C5741, 0x08000000, 0x00000003}, + {0x454C5759, 0x02000000, 0x00000001}, + {0x454C5841, 0x04000000, 0x00000001}, + {0x454C5942, 0x02000000, 0x00000001}, + {0x454C5A41, 0x08000000, 0x00000007}, + {0x454D3241, 0x00800000, 0x00000001}, + {0x454D3243, 0x02000000, 0x00000002}, + {0x454D3259, 0x02000000, 0x00000008}, + {0x454D3341, 0x08000000, 0x00000002}, + {0x454D3342, 0x04000000, 0x00000002}, + {0x454D3442, 0x02000000, 0x00000001}, + {0x454D3443, 0x04000000, 0x00000001}, + {0x454D3542, 0x01000000, 0x00000001}, + {0x454D3543, 0x01000000, 0x00000001}, + {0x454D3643, 0x04000000, 0x00000002}, + {0x454D3741, 0x02000000, 0x00000001}, + {0x454D3742, 0x01000000, 0x00000001}, + {0x454D3743, 0x01000000, 0x00000003}, + {0x454D4143, 0x01000000, 0x00000002}, + {0x454D4154, 0x02000000, 0x00000001}, + {0x454D4159, 0x00800000, 0x00000001}, + {0x454D4241, 0x00800000, 0x00000001}, + {0x454D4242, 0x00800000, 0x00000001}, + {0x454D4243, 0x02000000, 0x00000002}, + {0x454D4341, 0x01000000, 0x00000001}, + {0x454D4342, 0x04000000, 0x00000001}, + {0x454D4343, 0x04000000, 0x00000002}, + {0x454D4354, 0x04000000, 0x00000002}, + {0x454D4356, 0x04000000, 0x00000002}, + {0x454D4359, 0x02000000, 0x00000001}, + {0x454D4441, 0x02000000, 0x00000005}, + {0x454D4459, 0x02000000, 0x00000002}, + {0x454D4643, 0x04000000, 0x00000003}, + {0x454D4659, 0x04000000, 0x00000003}, + {0x454D4742, 0x04000000, 0x00000003}, + {0x454D4843, 0x04000000, 0x00000002}, + {0x454D4943, 0x01000000, 0x00000002}, + {0x454D4959, 0x04000000, 0x00000001}, + {0x454D4A42, 0x04000000, 0x00000002}, + {0x454D4A59, 0x00800000, 0x00000002}, + {0x454D4C54, 0x08000000, 0x00000001}, + {0x454D4D42, 0x00800000, 0x00000001}, + {0x454D4D59, 0x02000000, 0x00000001}, + {0x454D4E41, 0x02000000, 0x00000005}, + {0x454D4E42, 0x04000000, 0x00000001}, + {0x454D4E43, 0x04000000, 0x00000001}, + {0x454D4E59, 0x01000000, 0x00000002}, + {0x454D5042, 0x02000000, 0x00000001}, + {0x454D5043, 0x04000000, 0x00000002}, + {0x454D5141, 0x00800000, 0x00000001}, + {0x454D5241, 0x04000000, 0x00000002}, + {0x454D5242, 0x01000000, 0x00000002}, + {0x454D5259, 0x02000000, 0x00000003}, + {0x454D5341, 0x01000000, 0x00000002}, + {0x454D5342, 0x01000000, 0x00000002}, + {0x454D5459, 0x04000000, 0x00000002}, + {0x454D5642, 0x02000000, 0x00000001}, + {0x454D5643, 0x02000000, 0x00000002}, + {0x454D5741, 0x00800000, 0x00000001}, + {0x454D5842, 0x04000000, 0x00000002}, + {0x454D5843, 0x04000000, 0x00000003}, + {0x454D5A43, 0x02000000, 0x00000001}, + {0x454E3242, 0x02000000, 0x00000001}, + {0x454E3243, 0x01000000, 0x00000002}, + {0x454E3342, 0x02000000, 0x00000001}, + {0x454E3542, 0x01000000, 0x00000001}, + {0x454E3543, 0x01000000, 0x00000001}, + {0x454E3641, 0x08000000, 0x00000003}, + {0x454E3741, 0x02000000, 0x00000001}, + {0x454E3742, 0x08000000, 0x00000003}, + {0x454E3841, 0x02000000, 0x00000005}, + {0x454E4143, 0x02000000, 0x00000005}, + {0x454E4259, 0x04000000, 0x00000007}, + {0x454E4341, 0x01000000, 0x00000002}, + {0x454E4354, 0x01000000, 0x00000001}, + {0x454E4441, 0x04000000, 0x00000003}, + {0x454E4443, 0x08000000, 0x00000001}, + {0x454E4541, 0x04000000, 0x00000002}, + {0x454E4543, 0x02000000, 0x00000003}, + {0x454E4641, 0x02000000, 0x00000002}, + {0x454E4654, 0x04000000, 0x00000002}, + {0x454E4656, 0x02000000, 0x00000002}, + {0x454E4741, 0x02000000, 0x00000001}, + {0x454E4743, 0x04000000, 0x00000002}, + {0x454E4759, 0x04000000, 0x00000002}, + {0x454E4841, 0x04000000, 0x00000001}, + {0x454E4843, 0x02000000, 0x00000002}, + {0x454E4859, 0x04000000, 0x00000003}, + {0x454E4942, 0x00800000, 0x00000001}, + {0x454E4A41, 0x02000000, 0x00000002}, + {0x454E4A43, 0x01000000, 0x00000001}, + {0x454E4B43, 0x08000000, 0x00000002}, + {0x454E4C41, 0x02000000, 0x00000002}, + {0x454E4C59, 0x08000000, 0x00000002}, + {0x454E4D54, 0x01000000, 0x00000002}, + {0x454E4E42, 0x04000000, 0x00000002}, + {0x454E4E59, 0x08000000, 0x00000003}, + {0x454E5041, 0x02000000, 0x00000001}, + {0x454E5042, 0x01000000, 0x00000002}, + {0x454E5059, 0x00800000, 0x00000001}, + {0x454E5142, 0x04000000, 0x00000001}, + {0x454E5159, 0x04000000, 0x00000002}, + {0x454E5241, 0x01000000, 0x00000001}, + {0x454E5341, 0x00800000, 0x00000002}, + {0x454E5342, 0x02000000, 0x00000001}, + {0x454E5356, 0x04000000, 0x00000002}, + {0x454E5442, 0x04000000, 0x00000002}, + {0x454E5642, 0x04000000, 0x00000001}, + {0x454E5643, 0x04000000, 0x00000001}, + {0x454E5842, 0x01000000, 0x00000001}, + {0x454E5A41, 0x01000000, 0x00000002}, + {0x454E5A43, 0x04000000, 0x00000002}, + {0x454F3241, 0x04000000, 0x00000003}, + {0x454F3341, 0x00800000, 0x00000001}, + {0x454F3441, 0x02000000, 0x00000005}, + {0x454F3541, 0x01000000, 0x00000001}, + {0x454F3542, 0x00800000, 0x00000001}, + {0x454F3559, 0x08000000, 0x00000000}, + {0x454F3642, 0x02000000, 0x00000001}, + {0x454F3659, 0x00800000, 0x00000000}, + {0x454F3741, 0x02000000, 0x00000001}, + {0x454F3743, 0x04000000, 0x00000002}, + {0x454F3842, 0x01000000, 0x00000001}, + {0x454F3959, 0x00800000, 0x00000000}, + {0x454F4142, 0x04000000, 0x00000001}, + {0x454F4143, 0x01000000, 0x00000001}, + {0x454F4156, 0x04000000, 0x00000001}, + {0x454F4241, 0x02000000, 0x00000001}, + {0x454F4259, 0x08000000, 0x00000003}, + {0x454F4341, 0x04000000, 0x00000005}, + {0x454F4359, 0x04000000, 0x00000001}, + {0x454F4641, 0x04000000, 0x00000003}, + {0x454F4842, 0x04000000, 0x00000001}, + {0x454F4843, 0x02000000, 0x00000001}, + {0x454F4942, 0x02000000, 0x00000001}, + {0x454F4943, 0x01000000, 0x00000008}, + {0x454F4A42, 0x04000000, 0x00000001}, + {0x454F4A43, 0x04000000, 0x00000002}, + {0x454F4B42, 0x04000000, 0x00000003}, + {0x454F4D41, 0x04000000, 0x00000002}, + {0x454F4D56, 0x02000000, 0x00000003}, + {0x454F4D59, 0x04000000, 0x00000001}, + {0x454F4E41, 0x02000000, 0x00000002}, + {0x454F4F42, 0x08000000, 0x00000002}, + {0x454F4F43, 0x04000000, 0x00000002}, + {0x454F5043, 0x01000000, 0x00000002}, + {0x454F5059, 0x04000000, 0x00000003}, + {0x454F5259, 0x04000000, 0x00000002}, + {0x454F5342, 0x02000000, 0x00000001}, + {0x454F5356, 0x04000000, 0x00000003}, + {0x454F5541, 0x00800000, 0x00000001}, + {0x454F5741, 0x02000000, 0x00000002}, + {0x454F5742, 0x02000000, 0x00000001}, + {0x454F5743, 0x00800000, 0x00000001}, + {0x454F5843, 0x04000000, 0x00000001}, + {0x454F5A42, 0x04000000, 0x00000003}, + {0x454F5A43, 0x02000000, 0x00000001}, + {0x45503342, 0x04000000, 0x00000001}, + {0x45503343, 0x04000000, 0x00000002}, + {0x45503441, 0x02000000, 0x00000002}, + {0x45503541, 0x04000000, 0x00000001}, + {0x45503643, 0x04000000, 0x00000007}, + {0x45503659, 0x04000000, 0x00000000}, + {0x45503741, 0x02000000, 0x00000001}, + {0x45503743, 0x04000000, 0x00000002}, + {0x45503859, 0x00800000, 0x00000008}, + {0x45504143, 0x02000000, 0x00000003}, + {0x45504243, 0x01000000, 0x00000002}, + {0x45504259, 0x02000000, 0x00000001}, + {0x45504341, 0x00800000, 0x00000002}, + {0x45504342, 0x04000000, 0x00000002}, + {0x45504442, 0x00800000, 0x00000001}, + {0x45504443, 0x01000000, 0x00000002}, + {0x45504542, 0x01000000, 0x00000002}, + {0x45504543, 0x08000000, 0x00000002}, + {0x45504643, 0x04000000, 0x00000002}, + {0x45504659, 0x01000000, 0x00000001}, + {0x45504741, 0x04000000, 0x00000002}, + {0x45504743, 0x02000000, 0x00000001}, + {0x45504754, 0x02000000, 0x00000001}, + {0x45504841, 0x04000000, 0x00000001}, + {0x45504941, 0x00800000, 0x00000008}, + {0x45504A41, 0x00800000, 0x00000001}, + {0x45504A43, 0x04000000, 0x00000002}, + {0x45504B41, 0x01000000, 0x00000001}, + {0x45504C41, 0x00800000, 0x00000001}, + {0x45504C42, 0x04000000, 0x00000002}, + {0x45504C43, 0x04000000, 0x00000003}, + {0x45504C54, 0x02000000, 0x00000001}, + {0x45504C59, 0x00800000, 0x00000002}, + {0x45504D41, 0x02000000, 0x00000002}, + {0x45504D43, 0x04000000, 0x00000001}, + {0x45504E41, 0x01000000, 0x00000001}, + {0x45504E59, 0x04000000, 0x00000002}, + {0x45504F41, 0x00800000, 0x00000001}, + {0x45504F43, 0x01000000, 0x00000003}, + {0x45504F59, 0x01000000, 0x00000001}, + {0x45505041, 0x001A68C8, 0x00000002}, + {0x45505043, 0x04000000, 0x00000005}, + {0x45505056, 0x02000000, 0x00000001}, + {0x45505141, 0x02000000, 0x00000002}, + {0x45505143, 0x01000000, 0x00000001}, + {0x45505159, 0x04000000, 0x00000002}, + {0x45505241, 0x04000000, 0x00000001}, + {0x45505242, 0x08000000, 0x00000002}, + {0x45505243, 0x02000000, 0x00000001}, + {0x45505256, 0x02000000, 0x00000001}, + {0x45505341, 0x02000000, 0x00000003}, + {0x45505342, 0x01000000, 0x00000002}, + {0x45505343, 0x10000000, 0x00000003}, + {0x45505356, 0x02000000, 0x00000002}, + {0x45505359, 0x02000000, 0x00000005}, + {0x45505442, 0x04000000, 0x00000002}, + {0x45505642, 0x08000000, 0x00000006}, + {0x45505659, 0x08000000, 0x00000003}, + {0x45505741, 0x01000000, 0x00000001}, + {0x45505742, 0x00800000, 0x00000001}, + {0x45505743, 0x02000000, 0x00000002}, + {0x45505841, 0x02000000, 0x00000005}, + {0x45505843, 0x02000000, 0x00000001}, + {0x45513543, 0x01000000, 0x00000002}, + {0x45513643, 0x08000000, 0x00000001}, + {0x45513741, 0x02000000, 0x00000001}, + {0x45513841, 0x02000000, 0x00000005}, + {0x45514141, 0x00800000, 0x00000000}, + {0x45514242, 0x00800000, 0x00000001}, + {0x45514243, 0x02000000, 0x00000002}, + {0x45514342, 0x01000000, 0x00000001}, + {0x45514359, 0x04000000, 0x00000002}, + {0x45514441, 0x04000000, 0x00000002}, + {0x45514459, 0x10000000, 0x00000003}, + {0x45514559, 0x00800000, 0x00000001}, + {0x45514641, 0x04000000, 0x00000002}, + {0x45514643, 0x01000000, 0x00000001}, + {0x45514741, 0x02000000, 0x00000003}, + {0x45514742, 0x02000000, 0x00000002}, + {0x45514743, 0x04000000, 0x00000003}, + {0x45514759, 0x04000000, 0x00000002}, + {0x45514841, 0x02000000, 0x00000001}, + {0x45514943, 0x02000000, 0x00000002}, + {0x45514A41, 0x01000000, 0x00000002}, + {0x45514A43, 0x00800000, 0x00000002}, + {0x45514A59, 0x01000000, 0x00000001}, + {0x45514B41, 0x02000000, 0x00000001}, + {0x45514B42, 0x04000000, 0x00000001}, + {0x45514B43, 0x02000000, 0x00000001}, + {0x45514C43, 0x04000000, 0x00000001}, + {0x45514D41, 0x04000000, 0x00000005}, + {0x45514E41, 0x00800000, 0x00000002}, + {0x45514E42, 0x02000000, 0x00000001}, + {0x45514F43, 0x04000000, 0x00000002}, + {0x45515042, 0x02000000, 0x00000001}, + {0x45515043, 0x02000000, 0x00000001}, + {0x45515141, 0x02000000, 0x00000002}, + {0x45515242, 0x01000000, 0x00000001}, + {0x45515243, 0x02000000, 0x00000001}, + {0x45515259, 0x02000000, 0x00000001}, + {0x45515341, 0x00800000, 0x00000002}, + {0x45515343, 0x01000000, 0x00000001}, + {0x45515359, 0x02000000, 0x00000002}, + {0x45515442, 0x01000000, 0x00000001}, + {0x45515641, 0x02000000, 0x00000002}, + {0x45515742, 0x01000000, 0x00000001}, + {0x45515743, 0x02000000, 0x00000001}, + {0x45515759, 0x00800000, 0x00000001}, + {0x45515842, 0x02000000, 0x00000001}, + {0x45515941, 0x00800000, 0x00000002}, + {0x45515943, 0x04000000, 0x00000001}, + {0x45515A43, 0x01000000, 0x00000001}, + {0x45523342, 0x08000000, 0x00000005}, + {0x45523442, 0x02000000, 0x00000001}, + {0x45523443, 0x02000000, 0x00000001}, + {0x45523459, 0x04000000, 0x00000008}, + {0x45523542, 0x10000000, 0x00000001}, + {0x45523559, 0x04000000, 0x00000008}, + {0x45523641, 0x04000000, 0x00000003}, + {0x45523642, 0x08000000, 0x00000002}, + {0x45523659, 0x04000000, 0x00000008}, + {0x45523741, 0x02000000, 0x00000001}, + {0x45524141, 0x00800000, 0x00000008}, + {0x45524143, 0x01000000, 0x00000002}, + {0x45524159, 0x01000000, 0x00000001}, + {0x45524241, 0x04000000, 0x00000002}, + {0x45524254, 0x04000000, 0x00000001}, + {0x45524256, 0x02000000, 0x00000001}, + {0x45524259, 0x04000000, 0x00000001}, + {0x45524341, 0x02000000, 0x00000001}, + {0x45524343, 0x00800000, 0x00000002}, + {0x45524354, 0x00800000, 0x00000001}, + {0x45524441, 0x01000000, 0x00000002}, + {0x45524442, 0x04000000, 0x00000005}, + {0x45524443, 0x00800000, 0x00000001}, + {0x45524459, 0x00800000, 0x00000001}, + {0x45524541, 0x01000000, 0x00000002}, + {0x45524542, 0x02000000, 0x00000001}, + {0x45524543, 0x02000000, 0x00000003}, + {0x45524559, 0x04000000, 0x00000003}, + {0x45524641, 0x04000000, 0x00000001}, + {0x45524643, 0x08000000, 0x00000002}, + {0x45524659, 0x01000000, 0x00000001}, + {0x45524756, 0x04000000, 0x00000001}, + {0x45524841, 0x02000000, 0x00000002}, + {0x45524842, 0x02000000, 0x00000001}, + {0x45524859, 0x01000000, 0x00000002}, + {0x45524942, 0x01000000, 0x00000001}, + {0x45524943, 0x04000000, 0x00000002}, + {0x45524959, 0x04000000, 0x00000001}, + {0x45524A41, 0x08000000, 0x00000005}, + {0x45524A42, 0x01000000, 0x00000001}, + {0x45524A43, 0x08000000, 0x00000003}, + {0x45524B42, 0x02000000, 0x00000001}, + {0x45524C42, 0x10000000, 0x00000001}, + {0x45524C43, 0x04000000, 0x00000003}, + {0x45524C54, 0x08000000, 0x00000001}, + {0x45524C59, 0x01000000, 0x00000002}, + {0x45524D43, 0x02000000, 0x00000002}, + {0x45524E42, 0x04000000, 0x00000003}, + {0x45524E43, 0x04000000, 0x00000002}, + {0x45524F55, 0x08000000, 0x00000008}, + {0x45525041, 0x02000000, 0x00000002}, + {0x45525042, 0x00800000, 0x00000001}, + {0x45525043, 0x04000000, 0x00000002}, + {0x45525059, 0x02000000, 0x00000002}, + {0x45525143, 0x04000000, 0x00000002}, + {0x45525241, 0x02000000, 0x00000002}, + {0x45525243, 0x02000000, 0x00000005}, + {0x45525254, 0x01000000, 0x00000001}, + {0x45525259, 0x02000000, 0x00000002}, + {0x45525342, 0x01000000, 0x00000001}, + {0x45525359, 0x01000000, 0x00000005}, + {0x45525441, 0x01000000, 0x00000002}, + {0x45525443, 0x02000000, 0x00000003}, + {0x45525459, 0x04000000, 0x00000001}, + {0x45525542, 0x01000000, 0x00000001}, + {0x45525741, 0x02000000, 0x00000005}, + {0x45525759, 0x04000000, 0x00000001}, + {0x45525843, 0x04000000, 0x00000001}, + {0x45525942, 0x08000000, 0x00000001}, + {0x45525959, 0x04000000, 0x00000001}, + {0x45525A42, 0x00800000, 0x00000001}, + {0x45525A43, 0x02000000, 0x00000001}, + {0x45533241, 0x04000000, 0x00000002}, + {0x45533242, 0x08000000, 0x00000002}, + {0x45533243, 0x08000000, 0x00000004}, + {0x45533341, 0x02000000, 0x00000001}, + {0x45533459, 0x08000000, 0x00000008}, + {0x45533543, 0x08000000, 0x00000001}, + {0x45533559, 0x04000000, 0x00000008}, + {0x45533641, 0x04000000, 0x00000001}, + {0x45533642, 0x04000000, 0x00000001}, + {0x45533741, 0x02000000, 0x00000001}, + {0x45533759, 0x04000000, 0x00000008}, + {0x45533842, 0x04000000, 0x00000002}, + {0x45533859, 0x00800000, 0x00000000}, + {0x45534143, 0x02000000, 0x00000001}, + {0x45534154, 0x01000000, 0x00000001}, + {0x45534242, 0x02000000, 0x00000001}, + {0x45534243, 0x01000000, 0x00000002}, + {0x45534256, 0x02000000, 0x00000001}, + {0x45534342, 0x04000000, 0x00000002}, + {0x45534354, 0x04000000, 0x00000005}, + {0x45534359, 0x00800000, 0x00000001}, + {0x45534443, 0x08000000, 0x00000001}, + {0x45534542, 0x04000000, 0x00000001}, + {0x45534556, 0x04000000, 0x00000001}, + {0x45534641, 0x02000000, 0x00000002}, + {0x45534656, 0x08000000, 0x00000003}, + {0x45534743, 0x08000000, 0x00000001}, + {0x45534754, 0x02000000, 0x00000001}, + {0x45534759, 0x04000000, 0x00000003}, + {0x45534841, 0x02000000, 0x00000002}, + {0x45534844, 0x02000000, 0xFFFFFFFF}, + {0x45534859, 0x02000000, 0x00000003}, + {0x45534941, 0x01000000, 0x00000001}, + {0x45534959, 0x04000000, 0x00000002}, + {0x45534A42, 0x04000000, 0x00000003}, + {0x45534A56, 0x04000000, 0x00000003}, + {0x45534B54, 0x02000000, 0x00000002}, + {0x45534C42, 0x04000000, 0x00000001}, + {0x45534C54, 0x01000000, 0x00000001}, + {0x45534D43, 0x02000000, 0x00000003}, + {0x45534D54, 0x01000000, 0x00000001}, + {0x45534E41, 0x01000000, 0x00000001}, + {0x45534E42, 0x01000000, 0x00000001}, + {0x45534E43, 0x04000000, 0x00000002}, + {0x45534F41, 0x08000000, 0x00000005}, + {0x45534F43, 0x02000000, 0x00000001}, + {0x45535043, 0x04000000, 0x00000002}, + {0x45535143, 0x02000000, 0x00000001}, + {0x45535243, 0x00800000, 0x00000001}, + {0x45535341, 0x04000000, 0x00000002}, + {0x45535342, 0x01000000, 0x00000002}, + {0x45535359, 0x04000000, 0x00000003}, + {0x45535541, 0x04000000, 0x00000001}, + {0x45535543, 0x02000000, 0x00000001}, + {0x45535559, 0x00800000, 0x00000001}, + {0x45535641, 0x02000000, 0x00000002}, + {0x45535643, 0x02000000, 0x00000001}, + {0x45535659, 0x02000000, 0x00000003}, + {0x45535741, 0x01000000, 0x00000002}, + {0x45535759, 0x08000000, 0x00000003}, + {0x45535842, 0x04000000, 0x00000003}, + {0x45535843, 0x01000000, 0x00000001}, + {0x45535943, 0x04000000, 0x00000002}, + {0x45535A42, 0x00800000, 0x00000001}, + {0x45543241, 0x02000000, 0x00000001}, + {0x45543341, 0x02000000, 0x00000002}, + {0x45543343, 0x04000000, 0x00000003}, + {0x45543442, 0x01000000, 0x00000002}, + {0x45543541, 0x02000000, 0x00000005}, + {0x45543542, 0x00800000, 0x00000001}, + {0x45543543, 0x02000000, 0x00000005}, + {0x45543559, 0x00800000, 0x00000008}, + {0x45543641, 0x04000000, 0x00000001}, + {0x45543642, 0x04000000, 0x00000002}, + {0x45543643, 0x01000000, 0x00000002}, + {0x45543741, 0x02000000, 0x00000001}, + {0x45543841, 0x02000000, 0x00000002}, + {0x45544142, 0x04000000, 0x00000002}, + {0x45544143, 0x02000000, 0x00000002}, + {0x45544154, 0x02000000, 0x00000001}, + {0x45544156, 0x02000000, 0x00000001}, + {0x45544159, 0x01000000, 0x00000002}, + {0x45544241, 0x02000000, 0x00000001}, + {0x45544254, 0x01000000, 0x00000001}, + {0x45544256, 0x02000000, 0x00000002}, + {0x45544259, 0x08000000, 0x00000003}, + {0x45544341, 0x02000000, 0x00000001}, + {0x45544359, 0x02000000, 0x00000001}, + {0x45544454, 0x10000000, 0x00000008}, + {0x45544459, 0x04000000, 0x00000003}, + {0x45544559, 0x01000000, 0x00000001}, + {0x45544641, 0x00800000, 0x00000001}, + {0x45544659, 0x04000000, 0x00000005}, + {0x45544742, 0x08000000, 0x00000002}, + {0x45544759, 0x02000000, 0x00000001}, + {0x45544941, 0x00800000, 0x00000001}, + {0x45544943, 0x01000000, 0x00000001}, + {0x45544959, 0x01000000, 0x00000001}, + {0x45544A41, 0x02000000, 0x00000001}, + {0x45544A56, 0x04000000, 0x00000001}, + {0x45544B43, 0x04000000, 0x00000002}, + {0x45544C41, 0x00800000, 0x00000001}, + {0x45544C42, 0x00800000, 0x00000001}, + {0x45544C59, 0x08000000, 0x00000002}, + {0x45544D41, 0x04000000, 0x00000002}, + {0x45544D42, 0x08000000, 0x00000003}, + {0x45544D43, 0x02000000, 0x00000001}, + {0x45544D54, 0x04000000, 0x00000002}, + {0x45544E41, 0x04000000, 0x00000002}, + {0x45545041, 0x01000000, 0x00000002}, + {0x45545054, 0x08000000, 0x00000001}, + {0x45545059, 0x02000000, 0x00000005}, + {0x45545141, 0x01000000, 0x00000002}, + {0x45545143, 0x04000000, 0x00000003}, + {0x45545259, 0x02000000, 0x00000002}, + {0x45545341, 0x02000000, 0x00000001}, + {0x45545343, 0x04000000, 0x00000001}, + {0x45545359, 0x04000000, 0x00000001}, + {0x45545541, 0x01000000, 0x00000001}, + {0x45545543, 0x01000000, 0x00000001}, + {0x45545559, 0x04000000, 0x00000002}, + {0x45545659, 0x02000000, 0x00000001}, + {0x45545741, 0x00800000, 0x00000001}, + {0x45545743, 0x02000000, 0x00000001}, + {0x45545841, 0x00800000, 0x00000001}, + {0x45545942, 0x08000000, 0x00000002}, + {0x45545959, 0x01000000, 0x00000002}, + {0x45545A41, 0x01000000, 0x00000005}, + {0x45545A59, 0x01000000, 0x00000005}, + {0x45553242, 0x02000000, 0x00000001}, + {0x45553342, 0x02000000, 0x00000002}, + {0x45553459, 0x02000000, 0x00000008}, + {0x45553541, 0x02000000, 0x00000005}, + {0x45553542, 0x04000000, 0x00000002}, + {0x45553543, 0x02000000, 0x00000002}, + {0x45553559, 0x01000000, 0x00000000}, + {0x45553659, 0x01000000, 0x00000000}, + {0x45553743, 0x02000000, 0x00000001}, + {0x45554159, 0x04000000, 0x00000003}, + {0x45554241, 0x04000000, 0x00000005}, + {0x45554242, 0x04000000, 0x00000003}, + {0x45554259, 0x08000000, 0x00000003}, + {0x45554341, 0x04000000, 0x00000005}, + {0x45554342, 0x01000000, 0x00000001}, + {0x45554359, 0x00400000, 0x00000003}, + {0x45554442, 0x02000000, 0x00000001}, + {0x45554443, 0x01000000, 0x00000003}, + {0x45554454, 0x00800000, 0x00000001}, + {0x45554543, 0x04000000, 0x00000002}, + {0x45554641, 0x01000000, 0x00000003}, + {0x45554642, 0x01000000, 0x00000001}, + {0x45554854, 0x02000000, 0x00000001}, + {0x45554859, 0x00800000, 0x00000001}, + {0x45554942, 0x01000000, 0x00000001}, + {0x45554943, 0x04000000, 0x00000002}, + {0x45554A59, 0x04000000, 0x00000002}, + {0x45554B41, 0x04000000, 0x00000001}, + {0x45554B42, 0x08000000, 0x00000005}, + {0x45554B56, 0x04000000, 0x00000001}, + {0x45554C54, 0x04000000, 0x00000001}, + {0x45554D41, 0x00800000, 0x00000001}, + {0x45554D42, 0x04000000, 0x00000001}, + {0x45554D43, 0x01000000, 0x00000003}, + {0x45554D59, 0x04000000, 0x00000002}, + {0x45554E41, 0x01000000, 0x00000001}, + {0x45554F43, 0x00800000, 0x00000003}, + {0x45555043, 0x08000000, 0x00000006}, + {0x45555054, 0x01000000, 0x00000001}, + {0x45555159, 0x08000000, 0x00000003}, + {0x45555242, 0x01000000, 0x00000001}, + {0x45555341, 0x04000000, 0x00000003}, + {0x45555343, 0x02000000, 0x00000001}, + {0x45555442, 0x04000000, 0x00000002}, + {0x45555741, 0x02000000, 0x00000001}, + {0x45555742, 0x01000000, 0x00000002}, + {0x45555743, 0x04000000, 0x00000001}, + {0x45555841, 0x02000000, 0x00000001}, + {0x45555843, 0x08000000, 0x00000002}, + {0x45555943, 0x01000000, 0x00000002}, + {0x45555959, 0x04000000, 0x00000001}, + {0x45555A42, 0x02000000, 0x00000002}, + {0x45555A56, 0x02000000, 0x00000002}, + {0x45563241, 0x00800000, 0x00000001}, + {0x45563242, 0x01000000, 0x00000001}, + {0x45563341, 0x04000000, 0x00000003}, + {0x45563342, 0x02000000, 0x00000001}, + {0x45563542, 0x04000000, 0x00000001}, + {0x45563559, 0x00800000, 0x00000008}, + {0x45563642, 0x00800000, 0x00000001}, + {0x45563643, 0x02000000, 0x00000001}, + {0x45563742, 0x00800000, 0x00000001}, + {0x45564142, 0x04000000, 0x00000001}, + {0x45564143, 0x02000000, 0x00000002}, + {0x45564156, 0x04000000, 0x00000001}, + {0x45564159, 0x04000000, 0x00000002}, + {0x45564242, 0x00800000, 0x00000001}, + {0x45564256, 0x02000000, 0x00000001}, + {0x45564259, 0x02000000, 0x00000002}, + {0x45564341, 0x04000000, 0x00000002}, + {0x45564359, 0x01000000, 0x00000003}, + {0x45564441, 0x01000000, 0x00000001}, + {0x45564442, 0x02000000, 0x00000001}, + {0x45564443, 0x01000000, 0x00000001}, + {0x45564454, 0x08000000, 0x00000003}, + {0x45564459, 0x00800000, 0x00000002}, + {0x45564641, 0x04000000, 0x00000001}, + {0x45564643, 0x02000000, 0x00000002}, + {0x45564741, 0x02000000, 0x00000002}, + {0x45564841, 0x01000000, 0x00000001}, + {0x45564842, 0x02000000, 0x00000001}, + {0x45564843, 0x02000000, 0x00000003}, + {0x45564854, 0x04000000, 0x00000001}, + {0x45564942, 0x00800000, 0x00000001}, + {0x45564959, 0x08000000, 0x00000003}, + {0x45564A59, 0x01000000, 0x00000002}, + {0x45564C41, 0x01000000, 0x00000002}, + {0x45564C54, 0x02000000, 0x00000002}, + {0x45564D41, 0x04000000, 0x00000001}, + {0x45564D42, 0x00800000, 0x00000001}, + {0x45564D43, 0x00800000, 0x00000001}, + {0x45564D59, 0x00800000, 0x00000001}, + {0x45564E43, 0x10000000, 0x00000005}, + {0x45564F59, 0x00800000, 0x00000001}, + {0x45565041, 0x00800000, 0x00000002}, + {0x45565042, 0x00800000, 0x00000004}, + {0x45565043, 0x04000000, 0x00000002}, + {0x45565056, 0x04000000, 0x00000002}, + {0x45565059, 0x04000000, 0x00000001}, + {0x45565141, 0x01000000, 0x00000002}, + {0x45565143, 0x04000000, 0x00000001}, + {0x45565159, 0x01000000, 0x00000001}, + {0x45565241, 0x02000000, 0x00000003}, + {0x45565242, 0x01000000, 0x00000002}, + {0x45565259, 0x02000000, 0x00000005}, + {0x45565341, 0x00800000, 0x00000001}, + {0x45565342, 0x02000000, 0x00000001}, + {0x45565343, 0x02000000, 0x00000005}, + {0x45565441, 0x01000000, 0x00000001}, + {0x45565442, 0x02000000, 0x00000002}, + {0x45565459, 0x08000000, 0x00000003}, + {0x45565642, 0x01000000, 0x00000002}, + {0x45565741, 0x01000000, 0x00000001}, + {0x45565742, 0x02000000, 0x00000001}, + {0x45565756, 0x04000000, 0x00000001}, + {0x45565841, 0x04000000, 0x00000003}, + {0x45565842, 0x02000000, 0x00000001}, + {0x45565A41, 0x00800000, 0x00000001}, + {0x45565A42, 0x04000000, 0x00000002}, + {0x45565A43, 0x02000000, 0x00000001}, + {0x45573241, 0x04000000, 0x00000001}, + {0x45573259, 0x04000000, 0x00000008}, + {0x45573341, 0x04000000, 0x00000002}, + {0x45573342, 0x04000000, 0x00000002}, + {0x45573543, 0x01000000, 0x00000002}, + {0x45573641, 0x02000000, 0x00000002}, + {0x45573642, 0x08000000, 0x00000002}, + {0x45573643, 0x02000000, 0x00000002}, + {0x45573742, 0x01000000, 0x00000002}, + {0x45573759, 0x00800000, 0x00000001}, + {0x45574159, 0x04000000, 0x00000002}, + {0x45574259, 0x01000000, 0x00000002}, + {0x45574343, 0x02000000, 0x00000002}, + {0x45574354, 0x02000000, 0x00000001}, + {0x45574356, 0x02000000, 0x00000002}, + {0x45574442, 0x02000000, 0x00000001}, + {0x45574459, 0x02000000, 0x00000005}, + {0x45574542, 0x04000000, 0x00000002}, + {0x45574641, 0x01000000, 0x00000001}, + {0x45574643, 0x01000000, 0x00000001}, + {0x45574659, 0x00800000, 0x00000001}, + {0x45574741, 0x01000000, 0x00000002}, + {0x45574743, 0x00800000, 0x00000001}, + {0x45574759, 0x00800000, 0x00000001}, + {0x45574842, 0x00800000, 0x00000001}, + {0x45574856, 0x04000000, 0x00000002}, + {0x45574859, 0x02000000, 0x00000001}, + {0x45574942, 0x02000000, 0x00000002}, + {0x45574A43, 0x00800000, 0x00000001}, + {0x45574A56, 0x02000000, 0x00000003}, + {0x45574B41, 0x04000000, 0x00000002}, + {0x45574B42, 0x00800000, 0x00000002}, + {0x45574B59, 0x08000000, 0x00000003}, + {0x45574C41, 0x02000000, 0x00000001}, + {0x45574C43, 0x10000000, 0x00000002}, + {0x45574D41, 0x04000000, 0x00000002}, + {0x45574D49, 0x04000000, 0x00000007}, + {0x45574E41, 0x02000000, 0x00000002}, + {0x45574E59, 0x02000000, 0x00000001}, + {0x45574F41, 0x00800000, 0x00000001}, + {0x45575041, 0x02000000, 0x00000001}, + {0x45575042, 0x01000000, 0x00000001}, + {0x45575043, 0x04000000, 0x00000002}, + {0x45575141, 0x01000000, 0x00000001}, + {0x45575243, 0x02000000, 0x00000002}, + {0x45575254, 0x02000000, 0x00000002}, + {0x45575259, 0x02000000, 0x00000005}, + {0x45575341, 0x02000000, 0x00000001}, + {0x45575343, 0x04000000, 0x00000001}, + {0x45575359, 0x00800000, 0x00000001}, + {0x45575441, 0x02000000, 0x00000002}, + {0x45575442, 0x02000000, 0x00000001}, + {0x45575443, 0x08000000, 0x00000001}, + {0x45575641, 0x02000000, 0x00000002}, + {0x45575741, 0x02000000, 0x00000001}, + {0x45575842, 0x00800000, 0x00000001}, + {0x45575941, 0x02000000, 0x00000002}, + {0x45575943, 0x01000000, 0x00000001}, + {0x45575959, 0x02000000, 0x00000001}, + {0x45575A41, 0x02000000, 0x00000002}, + {0x45583242, 0x02000000, 0x00000002}, + {0x45583341, 0x04000000, 0x00000001}, + {0x45583342, 0x01000000, 0x00000001}, + {0x45583659, 0x00800000, 0x00000000}, + {0x45584154, 0x00800000, 0x00000001}, + {0x45584241, 0x02000000, 0x00000002}, + {0x45584242, 0x00800000, 0x00000001}, + {0x45584243, 0x01000000, 0x00000003}, + {0x45584259, 0x00800000, 0x00000001}, + {0x45584341, 0x01000000, 0x00000003}, + {0x45584343, 0x01000000, 0x00000003}, + {0x45584359, 0x02000000, 0x00000002}, + {0x45584456, 0x04000000, 0x00000001}, + {0x45584542, 0x01000000, 0x00000001}, + {0x45584559, 0x02000000, 0x00000002}, + {0x45584641, 0x08000000, 0x00000003}, + {0x45584642, 0x04000000, 0x00000002}, + {0x45584643, 0x01000000, 0x00000001}, + {0x45584659, 0x02000000, 0x00000001}, + {0x45584741, 0x08000000, 0x00000003}, + {0x45584759, 0x08000000, 0x00000002}, + {0x45584841, 0x00800000, 0x00000001}, + {0x45584843, 0x02000000, 0x00000003}, + {0x45584859, 0x01000000, 0x00000001}, + {0x45584A43, 0x01000000, 0x00000001}, + {0x45584B43, 0x01000000, 0x00000001}, + {0x45584C41, 0x02000000, 0x00000001}, + {0x45584C59, 0x00800000, 0x00000001}, + {0x45584D41, 0x01000000, 0x00000001}, + {0x45584D42, 0x02000000, 0x00000001}, + {0x45584D43, 0x01000000, 0x00000001}, + {0x45584D59, 0x00800000, 0x00000001}, + {0x45584E41, 0x02000000, 0x00000001}, + {0x45584E42, 0x04000000, 0x00000002}, + {0x45584E59, 0x00800000, 0x00000002}, + {0x45585159, 0x01000000, 0x00000001}, + {0x45585343, 0x01000000, 0x00000001}, + {0x45585359, 0x01000000, 0x00000001}, + {0x45585441, 0x01000000, 0x00000002}, + {0x45585442, 0x04000000, 0x00000001}, + {0x45585443, 0x01000000, 0x00000001}, + {0x45585543, 0x04000000, 0x00000001}, + {0x45585559, 0x04000000, 0x00000003}, + {0x45585641, 0x01000000, 0x00000001}, + {0x45585643, 0x04000000, 0x00000002}, + {0x45585741, 0x01000000, 0x00000002}, + {0x45585842, 0x02000000, 0x00000001}, + {0x45585859, 0x04000000, 0x00000002}, + {0x45585941, 0x08000000, 0x00000005}, + {0x45585942, 0x10000000, 0x00000003}, + {0x45585943, 0x02000000, 0x00000001}, + {0x45585A42, 0x02000000, 0x00000001}, + {0x45585A59, 0x04000000, 0x00000002}, + {0x45593341, 0x04000000, 0x00000003}, + {0x45593342, 0x02000000, 0x00000001}, + {0x45593459, 0x01000000, 0x00000008}, + {0x45593559, 0x01000000, 0x00000008}, + {0x45593641, 0x01000000, 0x00000002}, + {0x45593742, 0x01000000, 0x00000002}, + {0x45593759, 0x00800000, 0x00000008}, + {0x45594143, 0x02000000, 0x00000001}, + {0x45594159, 0x02000000, 0x00000001}, + {0x45594242, 0x00800000, 0x00000001}, + {0x45594243, 0x02000000, 0x00000001}, + {0x45594259, 0x02000000, 0x00000001}, + {0x45594343, 0x01000000, 0x00000001}, + {0x45594354, 0x04000000, 0x00000002}, + {0x45594359, 0x00800000, 0x00000001}, + {0x45594442, 0x04000000, 0x00000002}, + {0x45594542, 0x01000000, 0x00000001}, + {0x45594543, 0x02000000, 0x00000001}, + {0x45594641, 0x04000000, 0x00000001}, + {0x45594659, 0x04000000, 0x00000005}, + {0x45594741, 0x04000000, 0x00000005}, + {0x45594756, 0x02000000, 0x00000002}, + {0x45594842, 0x01000000, 0x00000001}, + {0x45594843, 0x01000000, 0x00000001}, + {0x45594941, 0x02000000, 0x00000001}, + {0x45594943, 0x04000000, 0x00000002}, + {0x45594959, 0x01000000, 0x00000001}, + {0x45594B41, 0x01000000, 0x00000003}, + {0x45594B42, 0x02000000, 0x00000002}, + {0x45594C41, 0x04000000, 0x00000001}, + {0x45594C59, 0x02000000, 0x00000002}, + {0x45594D42, 0x01000000, 0x00000002}, + {0x45594D56, 0x04000000, 0x00000001}, + {0x45594D59, 0x08000000, 0x00000002}, + {0x45594E41, 0x04000000, 0x00000003}, + {0x45594E42, 0x04000000, 0x00000001}, + {0x45594E43, 0x04000000, 0x00000002}, + {0x45594E59, 0x00800000, 0x00000001}, + {0x45594F41, 0x01000000, 0x00000002}, + {0x45594F43, 0x04000000, 0x00000002}, + {0x45595041, 0x02000000, 0x00000002}, + {0x45595042, 0x00800000, 0x00000001}, + {0x45595142, 0x04000000, 0x00000001}, + {0x45595241, 0x02000000, 0x00000002}, + {0x45595243, 0x01000000, 0x00000001}, + {0x45595254, 0x02000000, 0x00000001}, + {0x45595342, 0x02000000, 0x00000002}, + {0x45595343, 0x01000000, 0x00000001}, + {0x45595344, 0x02000000, 0x00000001}, + {0x45595359, 0x01000000, 0x00000001}, + {0x45595543, 0x02000000, 0x00000001}, + {0x45595642, 0x08000000, 0x00000001}, + {0x45595842, 0x04000000, 0x00000002}, + {0x45595859, 0x00800000, 0x00000001}, + {0x45595941, 0x01000000, 0x00000002}, + {0x45595942, 0x08000000, 0x00000003}, + {0x45595A41, 0x04000000, 0x00000002}, + {0x45595A42, 0x00800000, 0x00000001}, + {0x45595A59, 0x01000000, 0x00000002}, + {0x455A3441, 0x00800000, 0x00000001}, + {0x455A3443, 0x04000000, 0x00000002}, + {0x455A3541, 0x04000000, 0x00000001}, + {0x455A3542, 0x00800000, 0x00000001}, + {0x455A3543, 0x00800000, 0x00000001}, + {0x455A3642, 0x04000000, 0x00000003}, + {0x455A3659, 0x08000000, 0x00000000}, + {0x455A3742, 0x04000000, 0x00000001}, + {0x455A4159, 0x01000000, 0x00000001}, + {0x455A4241, 0x08000000, 0x00000003}, + {0x455A4242, 0x01000000, 0x00000001}, + {0x455A4259, 0x01000000, 0x00000001}, + {0x455A4341, 0x01000000, 0x00000001}, + {0x455A4343, 0x00800000, 0x00000001}, + {0x455A4354, 0x04000000, 0x00000002}, + {0x455A4441, 0x02000000, 0x00000002}, + {0x455A4442, 0x04000000, 0x00000003}, + {0x455A4443, 0x04000000, 0x00000002}, + {0x455A4641, 0x04000000, 0x00000001}, + {0x455A4642, 0x00800000, 0x00000001}, + {0x455A4656, 0x02000000, 0x00000001}, + {0x455A4742, 0x01000000, 0x00000002}, + {0x455A4841, 0x04000000, 0x00000001}, + {0x455A4842, 0x02000000, 0x00000003}, + {0x455A4859, 0x04000000, 0x00000002}, + {0x455A4941, 0x01000000, 0x00000002}, + {0x455A4943, 0x02000000, 0x00000001}, + {0x455A4959, 0x04000000, 0x00000002}, + {0x455A4A59, 0x04000000, 0x00000005}, + {0x455A4B43, 0x01000000, 0x00000005}, + {0x455A4C43, 0x04000000, 0x00000001}, + {0x455A4C59, 0x08000000, 0x00000002}, + {0x455A4D56, 0x04000000, 0x00000001}, + {0x455A4D59, 0x01000000, 0x00000001}, + {0x455A4E41, 0x01000000, 0x00000001}, + {0x455A4E59, 0x04000000, 0x00000002}, + {0x455A4F41, 0x01000000, 0x00000002}, + {0x455A4F42, 0x02000000, 0x00000001}, + {0x455A4F43, 0x08000000, 0x00000002}, + {0x455A5042, 0x00800000, 0x00000001}, + {0x455A5043, 0x02000000, 0x00000002}, + {0x455A5143, 0x02000000, 0x00000001}, + {0x455A5241, 0x04000000, 0x00000002}, + {0x455A5242, 0x04000000, 0x00000003}, + {0x455A5243, 0x00800000, 0x00000002}, + {0x455A5254, 0x02000000, 0x00000002}, + {0x455A5341, 0x01000000, 0x00000001}, + {0x455A5343, 0x02000000, 0x00000005}, + {0x455A5359, 0x08000000, 0x00000001}, + {0x455A5442, 0x02000000, 0x00000001}, + {0x455A5443, 0x02000000, 0x00000003}, + {0x455A5459, 0x02000000, 0x00000001}, + {0x455A5541, 0x04000000, 0x00000005}, + {0x455A5543, 0x04000000, 0x00000001}, + {0x455A5759, 0x04000000, 0x00000001}, + {0x455A5A42, 0x00800000, 0x00000001}, + {0x46323643, 0x04000000, 0x00000001}, + {0x46324543, 0x02000000, 0x00000001}, + {0x46324C42, 0x01000000, 0x00000001}, + {0x46324E42, 0x01000000, 0x00000002}, + {0x46325959, 0x00800000, 0x00000001}, + {0x46334343, 0x01000000, 0x00000001}, + {0x46334E42, 0x01000000, 0x00000002}, + {0x46335141, 0x04000000, 0x00000002}, + {0x46335159, 0x04000000, 0x00000002}, + {0x46335742, 0x08000000, 0x00000002}, + {0x46344259, 0x02000000, 0x00000001}, + {0x46344559, 0x02000000, 0x00000001}, + {0x46344E42, 0x01000000, 0x00000002}, + {0x46354243, 0x01000000, 0x00000001}, + {0x46354841, 0x02000000, 0x00000002}, + {0x46354E42, 0x01000000, 0x00000002}, + {0x46363443, 0x00800000, 0x00000001}, + {0x46364E42, 0x01000000, 0x00000002}, + {0x46373343, 0x02000000, 0x00000001}, + {0x46373443, 0x02000000, 0x00000001}, + {0x46373543, 0x02000000, 0x00000001}, + {0x46373742, 0x00800000, 0x00000001}, + {0x46374559, 0x00800000, 0x00000001}, + {0x46375443, 0x00800000, 0x00000002}, + {0x46375959, 0x01000000, 0x00000001}, + {0x46383643, 0x02000000, 0x00000001}, + {0x46383742, 0x00800000, 0x00000001}, + {0x46384343, 0x02000000, 0x00000001}, + {0x46384543, 0x02000000, 0x00000001}, + {0x46384C59, 0x01000000, 0x00000001}, + {0x46394341, 0x04000000, 0x00000001}, + {0x46394343, 0x02000000, 0x00000001}, + {0x46394943, 0x01000000, 0x00000002}, + {0x46395342, 0x00800000, 0x00000001}, + {0x46395942, 0x00800000, 0x00000001}, + {0x46413343, 0x00800000, 0x00000001}, + {0x46414441, 0x04000000, 0x00000006}, + {0x46414759, 0x01000000, 0x00000001}, + {0x46414C59, 0x00800000, 0x00000002}, + {0x46414E43, 0x02000000, 0x00000001}, + {0x46414F43, 0x00800000, 0x00000001}, + {0x46415041, 0x04000000, 0x00000006}, + {0x46415249, 0x10000000, 0x00000006}, + {0x46415843, 0x00800000, 0x00000001}, + {0x46423542, 0x04000000, 0x00000002}, + {0x46424354, 0x08000000, 0x00000001}, + {0x46424542, 0x10000000, 0x00000003}, + {0x46424659, 0x01000000, 0x00000001}, + {0x46424A42, 0x04000000, 0x00000001}, + {0x46424D43, 0x01000000, 0x00000001}, + {0x46424F43, 0x00800000, 0x00000001}, + {0x46425042, 0x01000000, 0x00000001}, + {0x46425043, 0x01000000, 0x00000001}, + {0x46425249, 0x10000000, 0x00000006}, + {0x46425254, 0x00800000, 0x00000001}, + {0x46425843, 0x00800000, 0x00000001}, + {0x46433243, 0x00800000, 0x00000001}, + {0x46434143, 0x01000000, 0x00000002}, + {0x46434A42, 0x04000000, 0x00000002}, + {0x46435843, 0x00800000, 0x00000001}, + {0x46435943, 0x02000000, 0x00000002}, + {0x46444143, 0x01000000, 0x00000002}, + {0x46444359, 0x02000000, 0x00000001}, + {0x46445054, 0x08000000, 0x00000001}, + {0x46445249, 0x20000000, 0x00000006}, + {0x46445443, 0x04000000, 0x00000002}, + {0x46445641, 0x01000000, 0x00000002}, + {0x46445843, 0x00800000, 0x00000001}, + {0x46454143, 0x01000000, 0x00000002}, + {0x46454542, 0x10000000, 0x00000003}, + {0x46454543, 0x00800000, 0x00000001}, + {0x46454559, 0x10000000, 0x00000003}, + {0x46454741, 0x01000000, 0x00000001}, + {0x46454959, 0x02000000, 0x00000002}, + {0x46455249, 0x20000000, 0x00000006}, + {0x46455542, 0x02000000, 0x00000001}, + {0x46455843, 0x00800000, 0x00000001}, + {0x46464143, 0x01000000, 0x00000001}, + {0x46464459, 0x01000000, 0x00000001}, + {0x46464A43, 0x01000000, 0x00000001}, + {0x46464B59, 0x02000000, 0x00000001}, + {0x46464C42, 0x10000000, 0x00000003}, + {0x46464D43, 0x00800000, 0x00000001}, + {0x46465059, 0x02000000, 0x00000001}, + {0x46465359, 0x04000000, 0x00000001}, + {0x46465843, 0x00800000, 0x00000001}, + {0x46465959, 0x00800000, 0x00000001}, + {0x46474D41, 0x01000000, 0x00000001}, + {0x46474D43, 0x04000000, 0x00000001}, + {0x46475049, 0x08000000, 0x00000006}, + {0x46483842, 0x04000000, 0x00000002}, + {0x46484143, 0x00800000, 0x00000001}, + {0x46484259, 0x02000000, 0x00000002}, + {0x46484A42, 0x01000000, 0x00000001}, + {0x46495443, 0x02000000, 0x00000002}, + {0x464A3343, 0x10000000, 0x00000003}, + {0x464A3743, 0x00800000, 0x00000001}, + {0x464A4754, 0x00800000, 0x00000001}, + {0x464A4959, 0x04000000, 0x00000002}, + {0x464A4F41, 0x02000000, 0x00000002}, + {0x464A4F42, 0x04000000, 0x00000002}, + {0x464A4F43, 0x00800000, 0x00000001}, + {0x464A5641, 0x04000000, 0x00000002}, + {0x464A5759, 0x00800000, 0x00000002}, + {0x464B4159, 0x08000000, 0x00000002}, + {0x464B4356, 0x08000000, 0x00000002}, + {0x464B4841, 0x04000000, 0x00000003}, + {0x464B5049, 0x08000000, 0x00000006}, + {0x464C4343, 0x02000000, 0x00000002}, + {0x464C4359, 0x01000000, 0x00000002}, + {0x464C4842, 0x04000000, 0x00000002}, + {0x464C4D59, 0x00800000, 0x00000001}, + {0x464C4F41, 0x00800000, 0x00000001}, + {0x464D4443, 0x00800000, 0x00000001}, + {0x464D4C54, 0x08000000, 0x00000001}, + {0x464D5141, 0x00800000, 0x00000001}, + {0x464E4243, 0x02000000, 0x00000001}, + {0x464E4259, 0x04000000, 0x00000007}, + {0x464E5243, 0x01000000, 0x00000001}, + {0x464E5759, 0x02000000, 0x00000001}, + {0x464F4359, 0x04000000, 0x00000001}, + {0x46504242, 0x00800000, 0x00000001}, + {0x46504A59, 0x01000000, 0x00000001}, + {0x46504B43, 0x02000000, 0x00000001}, + {0x46504C43, 0x04000000, 0x00000003}, + {0x46504F42, 0x01000000, 0x00000001}, + {0x46505041, 0x01000000, 0x00000002}, + {0x46505942, 0x02000000, 0x00000001}, + {0x46505A55, 0x08000000, 0x00000003}, + {0x46514343, 0x02000000, 0x00000001}, + {0x46514C59, 0x04000000, 0x00000001}, + {0x46514D43, 0x02000000, 0x00000001}, + {0x46524359, 0x02000000, 0x00000001}, + {0x46525141, 0x01000000, 0x00000002}, + {0x46525359, 0x01000000, 0x00000005}, + {0x46533341, 0x02000000, 0x00000001}, + {0x46534343, 0x02000000, 0x00000001}, + {0x46534959, 0x02000000, 0x00000002}, + {0x46534F41, 0x08000000, 0x00000005}, + {0x46535541, 0x04000000, 0x00000001}, + {0x46543242, 0x00800000, 0x00000001}, + {0x46543743, 0x01000000, 0x00000002}, + {0x46544159, 0x01000000, 0x00000002}, + {0x46544443, 0x02000000, 0x00000001}, + {0x46544C43, 0x00800000, 0x00000001}, + {0x46544C59, 0x08000000, 0x00000002}, + {0x46545643, 0x02000000, 0x00000001}, + {0x46554243, 0x01000000, 0x00000001}, + {0x46554259, 0x08000000, 0x00000003}, + {0x46554559, 0x01000000, 0x00000001}, + {0x46554743, 0x01000000, 0x00000002}, + {0x46554F59, 0x02000000, 0x00000001}, + {0x46555043, 0x08000000, 0x00000006}, + {0x46555643, 0x01000000, 0x00000001}, + {0x46563742, 0x01000000, 0x00000001}, + {0x46564559, 0x01000000, 0x00000001}, + {0x46564643, 0x02000000, 0x00000002}, + {0x46564859, 0x04000000, 0x00000001}, + {0x46564E43, 0x10000000, 0x00000005}, + {0x46565841, 0x04000000, 0x00000003}, + {0x46573743, 0x00800000, 0x00000001}, + {0x46574243, 0x02000000, 0x00000001}, + {0x46574356, 0x02000000, 0x00000002}, + {0x46574959, 0x04000000, 0x00000001}, + {0x46575959, 0x02000000, 0x00000001}, + {0x46583543, 0x02000000, 0x00000001}, + {0x46583743, 0x00800000, 0x00000001}, + {0x46585059, 0x00800000, 0x00000003}, + {0x46585441, 0x01000000, 0x00000002}, + {0x46585959, 0x01000000, 0x00000001}, + {0x46593743, 0x00800000, 0x00000001}, + {0x46594342, 0x04000000, 0x00000001}, + {0x46594442, 0x04000000, 0x00000002}, + {0x46594443, 0x02000000, 0x00000002}, + {0x46594641, 0x04000000, 0x00000001}, + {0x46594642, 0x01000000, 0x00000001}, + {0x46594A59, 0x00800000, 0x00000001}, + {0x46594C41, 0x04000000, 0x00000001}, + {0x46595559, 0x00800000, 0x00000001}, + {0x46595A41, 0x04000000, 0x00000002}, + {0x465A3659, 0x08000000, 0x00000008}, + {0x465A3743, 0x00800000, 0x00000001}, + {0x465A4142, 0x04000000, 0x00000001}, + {0x465A4641, 0x04000000, 0x00000001}, + {0x465A4F41, 0x01000000, 0x00000002}, + {0x465A5359, 0x08000000, 0x00000001}, + {0x474C4443, 0x02000000, 0x00000004}, + {0x47595543, 0x02000000, 0x00000001}, + {0x48334B54, 0x01000000, 0x00000001}, + {0x48335159, 0x04000000, 0x00000002}, + {0x48344259, 0x02000000, 0x00000001}, + {0x48344559, 0x02000000, 0x00000001}, + {0x48354841, 0x02000000, 0x00000002}, + {0x48373642, 0x01000000, 0x00000002}, + {0x48374E43, 0x01000000, 0x00000002}, + {0x48384C59, 0x01000000, 0x00000001}, + {0x48414B54, 0x02000000, 0x00000001}, + {0x48414C59, 0x00800000, 0x00000002}, + {0x48434842, 0x01000000, 0x00000001}, + {0x48435943, 0x02000000, 0x00000002}, + {0x48454E42, 0x02000000, 0x00000001}, + {0x48455142, 0x02000000, 0x00000002}, + {0x48464B59, 0x02000000, 0x00000001}, + {0x48464C42, 0x10000000, 0x00000003}, + {0x48464E42, 0x02000000, 0x00000001}, + {0x48474D41, 0x01000000, 0x00000001}, + {0x48474D43, 0x04000000, 0x00000001}, + {0x48494759, 0x00800000, 0x00000002}, + {0x48495959, 0x01000000, 0x00000001}, + {0x484A3343, 0x10000000, 0x00000003}, + {0x484A4D43, 0x01000000, 0x00000002}, + {0x484B5242, 0x00800000, 0x00000002}, + {0x484C3542, 0x01000000, 0x00000001}, + {0x484C4842, 0x04000000, 0x00000002}, + {0x484C5143, 0x00800000, 0x00000002}, + {0x484C5442, 0x00800000, 0x00000002}, + {0x484C5459, 0x00800000, 0x00000002}, + {0x484D5742, 0x01000000, 0x00000001}, + {0x484E4242, 0x00800000, 0x00000002}, + {0x48504A59, 0x01000000, 0x00000001}, + {0x48505443, 0x00800000, 0x00000002}, + {0x48515443, 0x00800000, 0x00000001}, + {0x48533341, 0x02000000, 0x00000001}, + {0x48544C59, 0x08000000, 0x00000002}, + {0x48565742, 0x02000000, 0x00000001}, + {0x48565841, 0x04000000, 0x00000003}, + {0x48575143, 0x02000000, 0x00000008}, + {0x48594559, 0x01000000, 0x00000001}, + {0x48595759, 0x04000000, 0x00000002}, + {0x485A3243, 0x00800000, 0x00000002}, + {0x485A4841, 0x04000000, 0x00000001}, + {0x485A4942, 0x01000000, 0x00000001}, + {0x49323643, 0x04000000, 0x00000001}, + {0x49334943, 0x04000000, 0x00000001}, + {0x49335141, 0x04000000, 0x00000002}, + {0x49335159, 0x04000000, 0x00000002}, + {0x49335742, 0x08000000, 0x00000002}, + {0x49344259, 0x02000000, 0x00000001}, + {0x49354841, 0x02000000, 0x00000002}, + {0x49364959, 0x04000000, 0x00000002}, + {0x49384C59, 0x01000000, 0x00000001}, + {0x49394341, 0x04000000, 0x00000001}, + {0x49413643, 0x00800000, 0x00000001}, + {0x49414441, 0x04000000, 0x00000006}, + {0x49414C59, 0x00800000, 0x00000002}, + {0x49415041, 0x04000000, 0x00000006}, + {0x49415249, 0x10000000, 0x00000006}, + {0x49424542, 0x10000000, 0x00000003}, + {0x49425249, 0x10000000, 0x00000006}, + {0x49434A42, 0x04000000, 0x00000002}, + {0x49434D43, 0x02000000, 0x00000002}, + {0x49435141, 0x02000000, 0x00000002}, + {0x49435943, 0x02000000, 0x00000002}, + {0x49445249, 0x20000000, 0x00000006}, + {0x49445641, 0x01000000, 0x00000002}, + {0x49454542, 0x10000000, 0x00000003}, + {0x49454559, 0x10000000, 0x00000003}, + {0x49455249, 0x20000000, 0x00000006}, + {0x49464B59, 0x02000000, 0x00000001}, + {0x49464C42, 0x10000000, 0x00000003}, + {0x49465359, 0x04000000, 0x00000001}, + {0x49474354, 0x04000000, 0x00000001}, + {0x49474D41, 0x01000000, 0x00000001}, + {0x49474D43, 0x04000000, 0x00000001}, + {0x49475049, 0x08000000, 0x00000006}, + {0x49483642, 0x02000000, 0x00000001}, + {0x494A3343, 0x10000000, 0x00000003}, + {0x494A4D54, 0x02000000, 0x00000001}, + {0x494A4F41, 0x02000000, 0x00000002}, + {0x494A5641, 0x04000000, 0x00000002}, + {0x494B4356, 0x08000000, 0x00000002}, + {0x494B5049, 0x08000000, 0x00000006}, + {0x494B5356, 0x04000000, 0x00000001}, + {0x494C4C43, 0x00800000, 0x00000002}, + {0x494C5842, 0x01000000, 0x00000002}, + {0x494D4359, 0x02000000, 0x00000001}, + {0x494E5243, 0x01000000, 0x00000001}, + {0x494F4359, 0x04000000, 0x00000001}, + {0x49505A55, 0x08000000, 0xFFFFFFFF}, + {0x49525359, 0x01000000, 0x00000005}, + {0x49525643, 0x00800000, 0x00000001}, + {0x49533341, 0x02000000, 0x00000001}, + {0x49534F41, 0x08000000, 0x00000005}, + {0x49535541, 0x04000000, 0x00000001}, + {0x49544C59, 0x08000000, 0x00000002}, + {0x49554259, 0x08000000, 0x00000003}, + {0x49555043, 0x08000000, 0x00000006}, + {0x49564E43, 0x10000000, 0x00000005}, + {0x49565841, 0x04000000, 0x00000003}, + {0x49574342, 0x01000000, 0x00000001}, + {0x49585059, 0x00800000, 0x00000003}, + {0x49594641, 0x04000000, 0x00000001}, + {0x49594C41, 0x04000000, 0x00000001}, + {0x49595543, 0x02000000, 0x00000001}, + {0x495A3659, 0x08000000, 0x00000008}, + {0x495A4341, 0x01000000, 0x00000001}, + {0x495A4641, 0x04000000, 0x00000001}, + {0x495A4F41, 0x01000000, 0x00000002}, + {0x495A5359, 0x08000000, 0x00000001}, + {0x4A323242, 0x08000000, 0x00000003}, + {0x4A323243, 0x04000000, 0x00000002}, + {0x4A323342, 0x04000000, 0x00000001}, + {0x4A323343, 0x04000000, 0x00000003}, + {0x4A323442, 0x04000000, 0x00000002}, + {0x4A323443, 0x04000000, 0x00000002}, + {0x4A323543, 0x04000000, 0x00000002}, + {0x4A323642, 0x04000000, 0x00000005}, + {0x4A323742, 0x01000000, 0x00000001}, + {0x4A324143, 0x08000000, 0x00000003}, + {0x4A324159, 0x08000000, 0x00000001}, + {0x4A324243, 0x02000000, 0x00000002}, + {0x4A324259, 0x02000000, 0x00000002}, + {0x4A324341, 0x04000000, 0x00000001}, + {0x4A324359, 0x04000000, 0x00000006}, + {0x4A324441, 0x02000000, 0x00000005}, + {0x4A324442, 0x01000000, 0x00000002}, + {0x4A324443, 0x04000000, 0x00000002}, + {0x4A324541, 0x08000000, 0x00000001}, + {0x4A324559, 0x04000000, 0x00000002}, + {0x4A324641, 0x01000000, 0x00000002}, + {0x4A324642, 0x04000000, 0x00000005}, + {0x4A324659, 0x10000000, 0x00000003}, + {0x4A324742, 0x08000000, 0x00000005}, + {0x4A324759, 0x01000000, 0x00000001}, + {0x4A324841, 0x00800000, 0x00000003}, + {0x4A324842, 0x02000000, 0x00000003}, + {0x4A324843, 0x04000000, 0x00000002}, + {0x4A324956, 0x08000000, 0x00000005}, + {0x4A324A43, 0x01000000, 0x00000002}, + {0x4A324B41, 0x02000000, 0x00000001}, + {0x4A324B54, 0x04000000, 0x00000001}, + {0x4A324B59, 0x02000000, 0x00000003}, + {0x4A324C41, 0x04000000, 0x00000002}, + {0x4A324C59, 0x08000000, 0x00000003}, + {0x4A324D41, 0x04000000, 0x00000005}, + {0x4A324D42, 0x02000000, 0x00000003}, + {0x4A324E41, 0x02000000, 0x00000002}, + {0x4A324E43, 0x04000000, 0x00000005}, + {0x4A324F41, 0x08000000, 0x00000005}, + {0x4A324F42, 0x04000000, 0x00000002}, + {0x4A324F43, 0x10000000, 0x00000001}, + {0x4A324F59, 0x02000000, 0x00000002}, + {0x4A325041, 0x02000000, 0x00000001}, + {0x4A325043, 0x04000000, 0x00000003}, + {0x4A325054, 0x08000000, 0x00000002}, + {0x4A325059, 0x04000000, 0x00000005}, + {0x4A325142, 0x10000000, 0x00000003}, + {0x4A325143, 0x01000000, 0x00000003}, + {0x4A325159, 0x04000000, 0x00000002}, + {0x4A325241, 0x02000000, 0x00000005}, + {0x4A325243, 0x04000000, 0x00000002}, + {0x4A325341, 0x01000000, 0x00000001}, + {0x4A325359, 0x04000000, 0x00000005}, + {0x4A325443, 0x04000000, 0x00000002}, + {0x4A325541, 0x04000000, 0x00000001}, + {0x4A325543, 0x01000000, 0x00000002}, + {0x4A325559, 0x01000000, 0x00000005}, + {0x4A325641, 0x02000000, 0x00000001}, + {0x4A325659, 0x02000000, 0x00000002}, + {0x4A325743, 0x01000000, 0x00000001}, + {0x4A325843, 0x04000000, 0x00000003}, + {0x4A325859, 0x00800000, 0x00000002}, + {0x4A325943, 0x04000000, 0x00000001}, + {0x4A325A41, 0x02000000, 0x00000002}, + {0x4A325A42, 0x04000000, 0x00000002}, + {0x4A325A59, 0x00800000, 0x00000002}, + {0x4A333242, 0x04000000, 0x00000005}, + {0x4A333243, 0x02000000, 0x00000002}, + {0x4A333342, 0x04000000, 0x00000002}, + {0x4A333343, 0x04000000, 0x00000001}, + {0x4A333441, 0x00800000, 0x00000000}, + {0x4A333442, 0x04000000, 0x00000003}, + {0x4A333542, 0x02000000, 0x00000003}, + {0x4A333643, 0x02000000, 0x00000002}, + {0x4A334241, 0x04000000, 0x00000003}, + {0x4A334259, 0x04000000, 0x00000005}, + {0x4A334341, 0x02000000, 0x00000005}, + {0x4A334441, 0x02000000, 0x00000005}, + {0x4A334543, 0x10000000, 0x00000003}, + {0x4A334559, 0x02000000, 0x00000002}, + {0x4A334741, 0x02000000, 0x00000005}, + {0x4A334742, 0x04000000, 0x00000002}, + {0x4A334743, 0x02000000, 0x00000002}, + {0x4A334759, 0x02000000, 0x00000003}, + {0x4A334841, 0x02000000, 0x00000003}, + {0x4A334843, 0x04000000, 0x00000002}, + {0x4A334854, 0x20000000, 0x00000002}, + {0x4A334859, 0x10000000, 0x00000002}, + {0x4A334A42, 0x02000000, 0x00000005}, + {0x4A334A59, 0x04000000, 0x00000002}, + {0x4A334B41, 0x02000000, 0x00000002}, + {0x4A334B42, 0x02000000, 0x00000003}, + {0x4A334B59, 0x02000000, 0x00000003}, + {0x4A334C41, 0x02000000, 0x00000001}, + {0x4A334C42, 0x08000000, 0x00000002}, + {0x4A334C56, 0x08000000, 0x00000005}, + {0x4A334C59, 0x04000000, 0x00000002}, + {0x4A334D42, 0x08000000, 0x00000003}, + {0x4A334D43, 0x08000000, 0x00000003}, + {0x4A334D59, 0x02000000, 0x00000002}, + {0x4A334E43, 0x08000000, 0x00000002}, + {0x4A334E54, 0x20000000, 0x00000005}, + {0x4A334F43, 0x10000000, 0x00000001}, + {0x4A334F59, 0x02000000, 0x00000001}, + {0x4A335141, 0x04000000, 0x00000001}, + {0x4A335142, 0x04000000, 0x00000002}, + {0x4A335143, 0x01000000, 0x00000003}, + {0x4A335241, 0x04000000, 0x00000003}, + {0x4A335242, 0x08000000, 0x00000002}, + {0x4A335243, 0x08000000, 0x00000002}, + {0x4A335259, 0x10000000, 0x00000003}, + {0x4A335442, 0x00800000, 0x00000003}, + {0x4A335443, 0x04000000, 0x00000003}, + {0x4A335456, 0x04000000, 0x00000001}, + {0x4A335459, 0x04000000, 0x00000003}, + {0x4A335559, 0x01000000, 0x00000001}, + {0x4A335641, 0x02000000, 0x00000001}, + {0x4A335642, 0x01000000, 0x00000002}, + {0x4A335643, 0x01000000, 0x00000001}, + {0x4A335741, 0x04000000, 0x00000001}, + {0x4A335759, 0x01000000, 0x00000001}, + {0x4A335841, 0x08000000, 0x00000001}, + {0x4A335843, 0x02000000, 0x00000002}, + {0x4A335941, 0x04000000, 0x00000002}, + {0x4A335959, 0x02000000, 0x00000002}, + {0x4A335A41, 0x02000000, 0x00000002}, + {0x4A335A42, 0x08000000, 0x00000003}, + {0x4A335A43, 0x02000000, 0x00000003}, + {0x4A335A59, 0x02000000, 0x00000002}, + {0x4A343243, 0x08000000, 0x00000003}, + {0x4A343342, 0x02000000, 0x00000001}, + {0x4A343343, 0x04000000, 0x00000003}, + {0x4A343442, 0x01000000, 0x00000002}, + {0x4A343443, 0x08000000, 0x00000002}, + {0x4A343541, 0x02000000, 0x00000000}, + {0x4A343542, 0x01000000, 0x00000002}, + {0x4A343559, 0x00400000, 0x00000000}, + {0x4A343643, 0x04000000, 0x00000003}, + {0x4A343742, 0x04000000, 0x00000002}, + {0x4A344142, 0x01000000, 0x00000002}, + {0x4A344241, 0x04000000, 0x00000005}, + {0x4A344242, 0x04000000, 0x00000002}, + {0x4A344254, 0x10000000, 0x00000006}, + {0x4A344341, 0x04000000, 0x00000001}, + {0x4A344342, 0x10000000, 0x00000002}, + {0x4A344343, 0x04000000, 0x00000003}, + {0x4A344354, 0x04000000, 0x00000007}, + {0x4A344359, 0x02000000, 0x00000003}, + {0x4A344454, 0x02000000, 0x00000001}, + {0x4A344541, 0x04000000, 0x00000002}, + {0x4A344543, 0x01000000, 0x00000003}, + {0x4A344642, 0x10000000, 0x00000002}, + {0x4A344654, 0x04000000, 0x00000005}, + {0x4A344659, 0x08000000, 0x00000003}, + {0x4A344742, 0x08000000, 0x00000002}, + {0x4A344743, 0x04000000, 0x00000003}, + {0x4A344754, 0x04000000, 0x00000003}, + {0x4A344759, 0x10000000, 0x00000003}, + {0x4A344841, 0x00800000, 0x00000001}, + {0x4A344859, 0x04000000, 0x00000001}, + {0x4A344941, 0x01000000, 0x00000003}, + {0x4A344A59, 0x01000000, 0x00000002}, + {0x4A344B41, 0x02000000, 0x00000003}, + {0x4A344B42, 0x08000000, 0x00000002}, + {0x4A344B43, 0x04000000, 0x00000003}, + {0x4A344B59, 0x04000000, 0x00000002}, + {0x4A344C41, 0x00800000, 0x00000001}, + {0x4A344C42, 0x04000000, 0x00000002}, + {0x4A344C43, 0x08000000, 0x00000002}, + {0x4A344C59, 0x00800000, 0x00000002}, + {0x4A344D54, 0x04000000, 0x00000002}, + {0x4A344D59, 0x04000000, 0x00000002}, + {0x4A344E41, 0x04000000, 0x00000001}, + {0x4A344F41, 0x02000000, 0x00000002}, + {0x4A344F42, 0x04000000, 0x00000003}, + {0x4A344F43, 0x00800000, 0x00000006}, + {0x4A344F59, 0x08000000, 0x00000002}, + {0x4A345043, 0x08000000, 0x00000002}, + {0x4A345054, 0x04000000, 0x00000002}, + {0x4A345056, 0x08000000, 0x00000006}, + {0x4A345059, 0x04000000, 0x00000002}, + {0x4A345142, 0x04000000, 0x00000002}, + {0x4A345159, 0x00800000, 0x00000002}, + {0x4A345241, 0x01000000, 0x00000002}, + {0x4A345259, 0x01000000, 0x00000003}, + {0x4A345343, 0x08000000, 0x00000003}, + {0x4A345359, 0x04000000, 0x00000002}, + {0x4A345541, 0x01000000, 0x00000001}, + {0x4A345559, 0x02000000, 0x00000003}, + {0x4A345641, 0x02000000, 0x00000001}, + {0x4A345659, 0x08000000, 0x00000003}, + {0x4A345743, 0x10000000, 0x00000003}, + {0x4A345759, 0x04000000, 0x00000003}, + {0x4A345841, 0x08000000, 0x00000001}, + {0x4A345843, 0x04000000, 0x00000005}, + {0x4A345941, 0x08000000, 0x00000001}, + {0x4A345959, 0x04000000, 0x00000003}, + {0x4A345A41, 0x00800000, 0x00000002}, + {0x4A345A59, 0x02000000, 0x00000001}, + {0x4A353342, 0x04000000, 0x00000005}, + {0x4A353443, 0x01000000, 0x00000002}, + {0x4A353543, 0x04000000, 0x00000003}, + {0x4A353742, 0x01000000, 0x00000002}, + {0x4A354143, 0x08000000, 0x00000003}, + {0x4A354241, 0x02000000, 0x00000001}, + {0x4A354341, 0x02000000, 0x00000005}, + {0x4A354354, 0x02000000, 0x00000002}, + {0x4A354459, 0x00800000, 0x00000002}, + {0x4A354541, 0x01000000, 0x00000003}, + {0x4A354542, 0x04000000, 0x00000002}, + {0x4A354742, 0x04000000, 0x00000002}, + {0x4A354843, 0x04000000, 0x00000002}, + {0x4A354859, 0x04000000, 0x00000002}, + {0x4A354941, 0x04000000, 0x00000002}, + {0x4A354A43, 0x02000000, 0x00000002}, + {0x4A354B41, 0x01000000, 0x00000001}, + {0x4A354B43, 0x04000000, 0x00000005}, + {0x4A354B54, 0x00800000, 0x00000003}, + {0x4A354B56, 0x04000000, 0x00000003}, + {0x4A354C59, 0x08000000, 0x00000003}, + {0x4A354D41, 0x04000000, 0x00000005}, + {0x4A354E41, 0x01000000, 0x00000003}, + {0x4A354E43, 0x04000000, 0x00000003}, + {0x4A354F41, 0x02000000, 0x00000005}, + {0x4A354F42, 0x10000000, 0x00000005}, + {0x4A354F59, 0x04000000, 0x00000003}, + {0x4A355154, 0x04000000, 0xFFFFFFFF}, + {0x4A355159, 0x01000000, 0x00000002}, + {0x4A355442, 0x08000000, 0x00000002}, + {0x4A355543, 0x04000000, 0x00000002}, + {0x4A355559, 0x08000000, 0x00000002}, + {0x4A355641, 0x02000000, 0x00000001}, + {0x4A355643, 0x02000000, 0x00000001}, + {0x4A355659, 0x08000000, 0x00000003}, + {0x4A355741, 0x01000000, 0x00000003}, + {0x4A355841, 0x08000000, 0x00000001}, + {0x4A355941, 0x08000000, 0x00000003}, + {0x4A355959, 0x04000000, 0x00000003}, + {0x4A355A43, 0x02000000, 0x00000003}, + {0x4A355A59, 0x02000000, 0x00000002}, + {0x4A363243, 0x00800000, 0x00000002}, + {0x4A363341, 0x02000000, 0x00000000}, + {0x4A363343, 0x04000000, 0x00000001}, + {0x4A363542, 0x04000000, 0x00000005}, + {0x4A363643, 0x04000000, 0x00000002}, + {0x4A364143, 0x04000000, 0x00000002}, + {0x4A364241, 0x02000000, 0x00000001}, + {0x4A364243, 0x01000000, 0x00000002}, + {0x4A364259, 0x01000000, 0x00000002}, + {0x4A364359, 0x01000000, 0x00000003}, + {0x4A364443, 0x08000000, 0x00000003}, + {0x4A364541, 0x04000000, 0x00000003}, + {0x4A364543, 0x01000000, 0x00000002}, + {0x4A364559, 0x04000000, 0x00000003}, + {0x4A364659, 0x04000000, 0x00000003}, + {0x4A364741, 0x02000000, 0x00000002}, + {0x4A364841, 0x01000000, 0x00000001}, + {0x4A364842, 0x04000000, 0x00000002}, + {0x4A364843, 0x04000000, 0x00000001}, + {0x4A364859, 0x04000000, 0x00000001}, + {0x4A364943, 0x02000000, 0x00000003}, + {0x4A364A43, 0x08000000, 0x00000002}, + {0x4A364B42, 0x02000000, 0x00000002}, + {0x4A364B59, 0x00800000, 0x00000003}, + {0x4A364C59, 0x04000000, 0x00000001}, + {0x4A364D43, 0x08000000, 0x00000002}, + {0x4A364E43, 0x04000000, 0x00000002}, + {0x4A364F41, 0x08000000, 0x00000001}, + {0x4A364F42, 0x01000000, 0x00000002}, + {0x4A364F43, 0x04000000, 0x00000002}, + {0x4A364F59, 0x02000000, 0x00000001}, + {0x4A365141, 0x00800000, 0x00000002}, + {0x4A365142, 0x02000000, 0x00000003}, + {0x4A365241, 0x00800000, 0x00000002}, + {0x4A365243, 0x04000000, 0x00000002}, + {0x4A365341, 0x04000000, 0x00000005}, + {0x4A365359, 0x04000000, 0x00000005}, + {0x4A365443, 0x04000000, 0x00000002}, + {0x4A365459, 0x01000000, 0x00000003}, + {0x4A365559, 0x02000000, 0x00000002}, + {0x4A365641, 0x02000000, 0x00000001}, + {0x4A365659, 0x00800000, 0x00000001}, + {0x4A365759, 0x02000000, 0x00000002}, + {0x4A365841, 0x08000000, 0x00000001}, + {0x4A365843, 0x08000000, 0x00000002}, + {0x4A365941, 0x00800000, 0x00000005}, + {0x4A365A41, 0x01000000, 0x00000005}, + {0x4A365A59, 0x02000000, 0x00000002}, + {0x4A373243, 0x08000000, 0x00000003}, + {0x4A374142, 0x02000000, 0x00000002}, + {0x4A374341, 0x00800000, 0x00000002}, + {0x4A374359, 0x02000000, 0x00000002}, + {0x4A374459, 0x04000000, 0x00000002}, + {0x4A374541, 0x08000000, 0x00000002}, + {0x4A374741, 0x02000000, 0x00000002}, + {0x4A374743, 0x04000000, 0x00000002}, + {0x4A374759, 0x04000000, 0x00000002}, + {0x4A374841, 0x04000000, 0x00000002}, + {0x4A374843, 0x10000000, 0x00000003}, + {0x4A374859, 0x08000000, 0x00000001}, + {0x4A374A43, 0x04000000, 0x00000001}, + {0x4A374A54, 0x04000000, 0x00000002}, + {0x4A374A59, 0x01000000, 0x00000002}, + {0x4A374B41, 0x02000000, 0x00000005}, + {0x4A374B59, 0x01000000, 0x00000002}, + {0x4A374C41, 0x02000000, 0x00000001}, + {0x4A374C59, 0x04000000, 0x00000003}, + {0x4A374D41, 0x02000000, 0x00000002}, + {0x4A374D42, 0x04000000, 0x00000003}, + {0x4A374D59, 0x04000000, 0x00000002}, + {0x4A374E54, 0x20000000, 0x00000005}, + {0x4A374F41, 0x04000000, 0x00000002}, + {0x4A374F42, 0x01000000, 0x00000005}, + {0x4A374F59, 0x01000000, 0x00000002}, + {0x4A375141, 0x00800000, 0x00000002}, + {0x4A375241, 0x04000000, 0x00000002}, + {0x4A375259, 0x04000000, 0x00000002}, + {0x4A375341, 0x08000000, 0x00000003}, + {0x4A375342, 0x04000000, 0x00000001}, + {0x4A375343, 0x10000000, 0x00000003}, + {0x4A375541, 0x02000000, 0x00000002}, + {0x4A375641, 0x02000000, 0x00000002}, + {0x4A375659, 0x00800000, 0x00000001}, + {0x4A375741, 0x02000000, 0x00000002}, + {0x4A375841, 0x08000000, 0x00000003}, + {0x4A375859, 0x01000000, 0x00000003}, + {0x4A375941, 0x08000000, 0x00000005}, + {0x4A375A41, 0x01000000, 0x00000002}, + {0x4A375A59, 0x02000000, 0x00000001}, + {0x4A383343, 0x04000000, 0x00000005}, + {0x4A383442, 0x00800000, 0x00000002}, + {0x4A384154, 0x01000000, 0x00000001}, + {0x4A384259, 0x02000000, 0x00000003}, + {0x4A384359, 0x01000000, 0x00000002}, + {0x4A384441, 0x01000000, 0x00000002}, + {0x4A384443, 0x02000000, 0x00000002}, + {0x4A384459, 0x04000000, 0x00000003}, + {0x4A384541, 0x04000000, 0x00000002}, + {0x4A384542, 0x20000000, 0x00000003}, + {0x4A384641, 0x01000000, 0x00000002}, + {0x4A384741, 0x04000000, 0x00000003}, + {0x4A384742, 0x01000000, 0x00000003}, + {0x4A384743, 0x02000000, 0x00000002}, + {0x4A384759, 0x08000000, 0x00000005}, + {0x4A384841, 0x02000000, 0x00000001}, + {0x4A384943, 0x04000000, 0x00000002}, + {0x4A384A43, 0x04000000, 0x00000002}, + {0x4A384A54, 0x04000000, 0x00000002}, + {0x4A384B43, 0x02000000, 0x00000003}, + {0x4A384B59, 0x04000000, 0x00000003}, + {0x4A384D41, 0x01000000, 0x00000001}, + {0x4A384D43, 0x02000000, 0x00000002}, + {0x4A384D59, 0x01000000, 0x00000002}, + {0x4A384E43, 0x10000000, 0x00000003}, + {0x4A385041, 0x02000000, 0x00000005}, + {0x4A385043, 0x02000000, 0x00000002}, + {0x4A385141, 0x00800000, 0x00000002}, + {0x4A385142, 0x04000000, 0x00000002}, + {0x4A385154, 0x04000000, 0x00000003}, + {0x4A385159, 0x04000000, 0x00000003}, + {0x4A385241, 0x04000000, 0x00000002}, + {0x4A385242, 0x01000000, 0x00000001}, + {0x4A385341, 0x00800000, 0x00000002}, + {0x4A385443, 0x04000000, 0x00000003}, + {0x4A385541, 0x04000000, 0x00000002}, + {0x4A385641, 0x01000000, 0x00000001}, + {0x4A385643, 0x04000000, 0x00000002}, + {0x4A385659, 0x00800000, 0x00000001}, + {0x4A385759, 0x08000000, 0x00000005}, + {0x4A385843, 0x02000000, 0x00000002}, + {0x4A385943, 0x10000000, 0x00000003}, + {0x4A385959, 0x04000000, 0x00000002}, + {0x4A385A41, 0x00800000, 0x00000002}, + {0x4A385A59, 0x02000000, 0x00000002}, + {0x4A393243, 0x04000000, 0x00000005}, + {0x4A393256, 0x02000000, 0x00000005}, + {0x4A393341, 0x02000000, 0x00000000}, + {0x4A393342, 0x08000000, 0x00000002}, + {0x4A393441, 0x02000000, 0x00000000}, + {0x4A393443, 0x04000000, 0x00000005}, + {0x4A393542, 0x01000000, 0x00000002}, + {0x4A393543, 0x04000000, 0x00000002}, + {0x4A393741, 0x02000000, 0x00000000}, + {0x4A393842, 0x04000000, 0x00000005}, + {0x4A394142, 0x04000000, 0x00000002}, + {0x4A394154, 0x01000000, 0x00000001}, + {0x4A394241, 0x01000000, 0x00000001}, + {0x4A394243, 0x08000000, 0x00000005}, + {0x4A394441, 0x02000000, 0x00000003}, + {0x4A394443, 0x04000000, 0x00000003}, + {0x4A394541, 0x04000000, 0x00000002}, + {0x4A394559, 0x04000000, 0x00000003}, + {0x4A394741, 0x02000000, 0x00000003}, + {0x4A394742, 0x04000000, 0x00000005}, + {0x4A394743, 0x01000000, 0x00000002}, + {0x4A394842, 0x20000000, 0x00000002}, + {0x4A394843, 0x02000000, 0x00000003}, + {0x4A394859, 0x02000000, 0x00000002}, + {0x4A394941, 0x04000000, 0x00000002}, + {0x4A394A42, 0x01000000, 0x00000002}, + {0x4A394A54, 0x04000000, 0x00000002}, + {0x4A394A59, 0x00800000, 0x00000005}, + {0x4A394B41, 0x01000000, 0x00000002}, + {0x4A394B42, 0x10000000, 0x00000003}, + {0x4A394B43, 0x04000000, 0x00000005}, + {0x4A394B54, 0x08000000, 0x00000002}, + {0x4A394B59, 0x08000000, 0x00000002}, + {0x4A394C59, 0x04000000, 0x00000003}, + {0x4A394D41, 0x01000000, 0x00000002}, + {0x4A394D42, 0x04000000, 0x00000003}, + {0x4A394E41, 0x01000000, 0x00000001}, + {0x4A394E59, 0x02000000, 0x00000002}, + {0x4A394F41, 0x04000000, 0x00000002}, + {0x4A394F42, 0x04000000, 0x00000003}, + {0x4A394F59, 0x02000000, 0x00000003}, + {0x4A395041, 0x01000000, 0x00000002}, + {0x4A395059, 0x04000000, 0x00000003}, + {0x4A395141, 0x04000000, 0x00000001}, + {0x4A395142, 0x00800000, 0x00000002}, + {0x4A395143, 0x00800000, 0x00000002}, + {0x4A395241, 0x02000000, 0x00000002}, + {0x4A395243, 0x01000000, 0x00000002}, + {0x4A395259, 0x04000000, 0x00000002}, + {0x4A395359, 0x04000000, 0x00000003}, + {0x4A395541, 0x01000000, 0x00000002}, + {0x4A395559, 0x04000000, 0x00000002}, + {0x4A395659, 0x00800000, 0x00000001}, + {0x4A395841, 0x04000000, 0x00000002}, + {0x4A395843, 0x08000000, 0x00000003}, + {0x4A395859, 0x01000000, 0x00000003}, + {0x4A395941, 0x08000000, 0x00000003}, + {0x4A395959, 0x02000000, 0x00000002}, + {0x4A395A41, 0x02000000, 0x00000003}, + {0x4A395A42, 0x04000000, 0x00000002}, + {0x4A395A59, 0x02000000, 0x00000002}, + {0x4A413241, 0x04000000, 0x00000002}, + {0x4A413243, 0x08000000, 0x00000002}, + {0x4A413341, 0x04000000, 0x00000006}, + {0x4A413442, 0x01000000, 0x00000002}, + {0x4A413443, 0x04000000, 0x00000001}, + {0x4A413541, 0x04000000, 0x00000001}, + {0x4A413641, 0x02000000, 0x00000005}, + {0x4A413841, 0x00800000, 0x00000001}, + {0x4A414154, 0x02000000, 0x00000004}, + {0x4A414156, 0x02000000, 0x00000008}, + {0x4A414159, 0x04000000, 0x00000002}, + {0x4A414259, 0x02000000, 0x00000002}, + {0x4A414356, 0x04000000, 0x00000001}, + {0x4A414441, 0x04000000, 0x00000006}, + {0x4A414459, 0x02000000, 0x00000003}, + {0x4A414543, 0x02000000, 0x00000003}, + {0x4A414559, 0x02000000, 0x00000003}, + {0x4A414641, 0x04000000, 0x00000003}, + {0x4A414659, 0x02000000, 0x00000003}, + {0x4A414843, 0x04000000, 0x00000003}, + {0x4A414859, 0x01000000, 0x00000003}, + {0x4A414941, 0x04000000, 0x00000001}, + {0x4A414943, 0x08000000, 0x00000003}, + {0x4A414A41, 0x08000000, 0x00000003}, + {0x4A414A59, 0x04000000, 0x00000002}, + {0x4A414B41, 0x08000000, 0x00000005}, + {0x4A414B42, 0x08000000, 0x00000003}, + {0x4A414B59, 0x04000000, 0x00000003}, + {0x4A414C41, 0x04000000, 0x00000005}, + {0x4A414D41, 0x01000000, 0x00000002}, + {0x4A414D43, 0x08000000, 0x00000002}, + {0x4A414D59, 0x02000000, 0x00000002}, + {0x4A414E41, 0x02000000, 0x00000002}, + {0x4A414E59, 0x04000000, 0x00000002}, + {0x4A414F59, 0x02000000, 0x00000002}, + {0x4A415041, 0x04000000, 0x00000006}, + {0x4A415142, 0x01000000, 0x00000005}, + {0x4A415154, 0x08000000, 0x00000004}, + {0x4A415242, 0x04000000, 0x00000002}, + {0x4A415249, 0x10000000, 0x00000006}, + {0x4A415342, 0x04000000, 0x00000003}, + {0x4A415441, 0x01000000, 0x00000001}, + {0x4A415442, 0x08000000, 0x00000003}, + {0x4A415541, 0x04000000, 0x00000005}, + {0x4A415559, 0x04000000, 0x00000001}, + {0x4A415643, 0x04000000, 0x00000002}, + {0x4A415741, 0x04000000, 0x00000002}, + {0x4A415841, 0x08000000, 0x00000002}, + {0x4A415859, 0x04000000, 0x00000003}, + {0x4A415941, 0x00800000, 0x00000002}, + {0x4A415943, 0x04000000, 0x00000006}, + {0x4A415959, 0x02000000, 0x00000003}, + {0x4A415A41, 0x02000000, 0x00000002}, + {0x4A415A59, 0x01000000, 0x00000002}, + {0x4A423241, 0x01000000, 0x00000001}, + {0x4A423242, 0x08000000, 0x00000002}, + {0x4A423341, 0x08000000, 0x00000002}, + {0x4A423442, 0x04000000, 0x00000002}, + {0x4A423443, 0x01000000, 0x00000003}, + {0x4A423541, 0x04000000, 0x00000002}, + {0x4A423641, 0x02000000, 0x00000005}, + {0x4A424241, 0x01000000, 0x00000005}, + {0x4A424341, 0x04000000, 0x00000003}, + {0x4A424359, 0x04000000, 0x00000001}, + {0x4A424441, 0x04000000, 0x00000002}, + {0x4A424442, 0x04000000, 0x00000002}, + {0x4A424454, 0x04000000, 0x00000002}, + {0x4A424542, 0x10000000, 0x00000003}, + {0x4A424543, 0x02000000, 0x00000003}, + {0x4A424556, 0x02000000, 0x00000007}, + {0x4A424559, 0x02000000, 0x00000002}, + {0x4A424754, 0x08000000, 0x00000002}, + {0x4A424759, 0x01000000, 0x00000002}, + {0x4A424843, 0x04000000, 0x00000001}, + {0x4A424859, 0x04000000, 0x00000003}, + {0x4A424941, 0x08000000, 0x00000002}, + {0x4A424943, 0x01000000, 0x00000002}, + {0x4A424A41, 0x04000000, 0x00000005}, + {0x4A424A59, 0x04000000, 0x00000001}, + {0x4A424B41, 0x02000000, 0x00000003}, + {0x4A424B59, 0x04000000, 0x00000003}, + {0x4A424C41, 0x08000000, 0x00000003}, + {0x4A424C43, 0x04000000, 0x00000003}, + {0x4A424D41, 0x04000000, 0x00000002}, + {0x4A424E41, 0x04000000, 0x00000005}, + {0x4A424E42, 0x04000000, 0x00000003}, + {0x4A424E59, 0x04000000, 0x00000002}, + {0x4A424F42, 0x02000000, 0x00000001}, + {0x4A425041, 0x02000000, 0x00000001}, + {0x4A425059, 0x08000000, 0x00000003}, + {0x4A425141, 0x01000000, 0x00000001}, + {0x4A425142, 0x04000000, 0x00000002}, + {0x4A425154, 0x02000000, 0x00000003}, + {0x4A425241, 0x02000000, 0x00000001}, + {0x4A425243, 0x02000000, 0x00000005}, + {0x4A425249, 0x10000000, 0x00000006}, + {0x4A425259, 0x08000000, 0x00000003}, + {0x4A425341, 0x04000000, 0x00000002}, + {0x4A425441, 0x04000000, 0x00000002}, + {0x4A425442, 0x04000000, 0x00000002}, + {0x4A425459, 0x08000000, 0x00000003}, + {0x4A425541, 0x04000000, 0x00000005}, + {0x4A425643, 0x02000000, 0x00000003}, + {0x4A425659, 0x08000000, 0x00000002}, + {0x4A425841, 0x04000000, 0x00000008}, + {0x4A425859, 0x08000000, 0x00000003}, + {0x4A425941, 0x02000000, 0x00000002}, + {0x4A425959, 0x04000000, 0x00000005}, + {0x4A425A41, 0x00800000, 0x00000001}, + {0x4A425A42, 0x02000000, 0x00000003}, + {0x4A425A59, 0x02000000, 0x00000002}, + {0x4A433342, 0x04000000, 0x00000002}, + {0x4A433343, 0x02000000, 0x00000001}, + {0x4A433441, 0x01000000, 0x00000003}, + {0x4A433442, 0x08000000, 0x00000002}, + {0x4A433443, 0x01000000, 0x00000002}, + {0x4A433541, 0x01000000, 0x00000001}, + {0x4A433641, 0x02000000, 0x00000005}, + {0x4A433643, 0x10000000, 0x00000005}, + {0x4A433841, 0x02000000, 0x00000002}, + {0x4A434154, 0x02000000, 0x00000002}, + {0x4A434159, 0x04000000, 0x00000003}, + {0x4A434241, 0x02000000, 0x00000005}, + {0x4A434254, 0x00800000, 0x00000001}, + {0x4A434341, 0x02000000, 0x00000001}, + {0x4A434441, 0x01000000, 0x00000001}, + {0x4A434459, 0x08000000, 0x00000003}, + {0x4A434541, 0x00800000, 0x00000001}, + {0x4A434554, 0x08000000, 0x00000005}, + {0x4A434559, 0x02000000, 0x00000001}, + {0x4A434741, 0x04000000, 0x00000003}, + {0x4A434743, 0x04000000, 0x00000002}, + {0x4A434754, 0x04000000, 0x00000003}, + {0x4A434941, 0x01000000, 0x00000001}, + {0x4A434A41, 0x00800000, 0x00000002}, + {0x4A434B59, 0x02000000, 0x00000002}, + {0x4A434C56, 0x04000000, 0x00000002}, + {0x4A434D41, 0x02000000, 0x00000005}, + {0x4A434E41, 0x04000000, 0x00000002}, + {0x4A434E42, 0x08000000, 0x00000002}, + {0x4A434E43, 0x04000000, 0x00000002}, + {0x4A434F41, 0x01000000, 0x00000003}, + {0x4A434F42, 0x00800000, 0x00000003}, + {0x4A434F59, 0x02000000, 0x00000002}, + {0x4A435041, 0x01000000, 0x00000001}, + {0x4A435054, 0x08000000, 0x00000002}, + {0x4A435141, 0x04000000, 0x00000002}, + {0x4A435154, 0x08000000, 0x00000004}, + {0x4A435259, 0x08000000, 0x00000002}, + {0x4A435341, 0x04000000, 0x00000002}, + {0x4A435459, 0x08000000, 0x00000003}, + {0x4A435541, 0x04000000, 0x00000005}, + {0x4A435542, 0x04000000, 0x00000002}, + {0x4A435641, 0x04000000, 0x00000005}, + {0x4A435643, 0x02000000, 0x00000001}, + {0x4A435741, 0x04000000, 0x00000002}, + {0x4A435742, 0x02000000, 0x00000002}, + {0x4A435743, 0x02000000, 0x00000001}, + {0x4A435841, 0x02000000, 0x00000003}, + {0x4A435859, 0x04000000, 0x00000003}, + {0x4A435941, 0x04000000, 0x00000003}, + {0x4A435A41, 0x00800000, 0x00000001}, + {0x4A435A42, 0x02000000, 0x00000003}, + {0x4A435A43, 0x02000000, 0x00000002}, + {0x4A435A55, 0x08000000, 0xFFFFFFFF}, + {0x4A435A59, 0x01000000, 0x00000002}, + {0x4A443241, 0x02000000, 0x00000002}, + {0x4A443243, 0x04000000, 0x00000002}, + {0x4A443341, 0x08000000, 0x00000003}, + {0x4A443342, 0x04000000, 0x00000002}, + {0x4A443441, 0x04000000, 0x00000003}, + {0x4A443443, 0x04000000, 0x00000002}, + {0x4A443541, 0x00800000, 0x00000002}, + {0x4A443542, 0x04000000, 0x00000002}, + {0x4A443543, 0x02000000, 0x00000001}, + {0x4A443641, 0x04000000, 0x00000002}, + {0x4A443841, 0x04000000, 0x00000002}, + {0x4A444154, 0x08000000, 0x00000005}, + {0x4A444259, 0x08000000, 0x00000002}, + {0x4A444342, 0x04000000, 0x00000002}, + {0x4A444356, 0x04000000, 0x00000002}, + {0x4A444441, 0x01000000, 0x00000001}, + {0x4A444443, 0x04000000, 0x00000002}, + {0x4A444459, 0x01000000, 0x00000001}, + {0x4A444543, 0x04000000, 0x00000002}, + {0x4A444554, 0x02000000, 0x00000003}, + {0x4A444741, 0x02000000, 0x00000003}, + {0x4A444754, 0x10000000, 0x00000002}, + {0x4A444841, 0x04000000, 0x00000002}, + {0x4A444843, 0x08000000, 0x00000002}, + {0x4A444941, 0x02000000, 0x00000002}, + {0x4A444942, 0x08000000, 0x00000003}, + {0x4A444A41, 0x00800000, 0x00000002}, + {0x4A444A43, 0x00800000, 0x00000001}, + {0x4A444B41, 0x01000000, 0x00000002}, + {0x4A444B43, 0x02000000, 0x00000002}, + {0x4A444B54, 0x02000000, 0x00000002}, + {0x4A444B59, 0x08000000, 0x00000005}, + {0x4A444C41, 0x04000000, 0x00000005}, + {0x4A444C59, 0x04000000, 0x00000005}, + {0x4A444D59, 0x02000000, 0x00000003}, + {0x4A444E41, 0x01000000, 0x00000005}, + {0x4A444F41, 0x02000000, 0x00000003}, + {0x4A444F59, 0x04000000, 0x00000002}, + {0x4A445041, 0x01000000, 0x00000002}, + {0x4A445059, 0x02000000, 0x00000005}, + {0x4A445141, 0x02000000, 0x00000003}, + {0x4A445142, 0x04000000, 0x00000002}, + {0x4A445143, 0x01000000, 0x00000002}, + {0x4A445154, 0x02000000, 0x00000003}, + {0x4A445159, 0x02000000, 0x00000002}, + {0x4A445249, 0x20000000, 0x00000006}, + {0x4A445342, 0x04000000, 0x00000002}, + {0x4A445359, 0x04000000, 0x00000005}, + {0x4A445441, 0x01000000, 0x00000002}, + {0x4A445541, 0x04000000, 0x00000005}, + {0x4A445542, 0x01000000, 0x00000001}, + {0x4A445559, 0x01000000, 0x00000005}, + {0x4A445841, 0x01000000, 0x00000002}, + {0x4A445859, 0x02000000, 0x00000003}, + {0x4A445941, 0x04000000, 0x00000002}, + {0x4A445A43, 0x02000000, 0x00000002}, + {0x4A445A59, 0x04000000, 0x00000002}, + {0x4A453243, 0x02000000, 0x00000003}, + {0x4A453343, 0x02000000, 0x00000002}, + {0x4A453541, 0x04000000, 0x00000001}, + {0x4A453542, 0x10000000, 0x00000003}, + {0x4A453543, 0x02000000, 0x00000005}, + {0x4A453641, 0x04000000, 0x00000003}, + {0x4A453841, 0x00800000, 0x00000001}, + {0x4A454159, 0x08000000, 0x00000002}, + {0x4A454243, 0x02000000, 0x00000001}, + {0x4A454341, 0x01000000, 0x00000002}, + {0x4A454441, 0x08000000, 0x00000003}, + {0x4A454442, 0x04000000, 0x00000002}, + {0x4A454456, 0x10000000, 0x00000006}, + {0x4A454541, 0x04000000, 0x00000003}, + {0x4A454542, 0x10000000, 0x00000003}, + {0x4A454559, 0x08000000, 0x00000003}, + {0x4A454641, 0x04000000, 0x00000003}, + {0x4A454643, 0x02000000, 0x00000001}, + {0x4A454659, 0x04000000, 0x00000005}, + {0x4A454741, 0x01000000, 0x00000001}, + {0x4A454759, 0x04000000, 0x00000002}, + {0x4A454841, 0x08000000, 0x00000005}, + {0x4A454859, 0x08000000, 0x00000003}, + {0x4A454A41, 0x08000000, 0x00000003}, + {0x4A454A42, 0x02000000, 0x00000003}, + {0x4A454A43, 0x02000000, 0x00000003}, + {0x4A454B41, 0x04000000, 0x00000002}, + {0x4A454B43, 0x01000000, 0x00000002}, + {0x4A454B59, 0x04000000, 0x00000002}, + {0x4A454C41, 0x08000000, 0x00000002}, + {0x4A454C42, 0x04000000, 0x00000003}, + {0x4A454C59, 0x02000000, 0x00000001}, + {0x4A454D41, 0x02000000, 0x00000002}, + {0x4A454D42, 0x10000000, 0x00000003}, + {0x4A454D43, 0x04000000, 0x00000002}, + {0x4A454D59, 0x00800000, 0x00000002}, + {0x4A454E41, 0x04000000, 0x00000002}, + {0x4A454E43, 0x02000000, 0x00000002}, + {0x4A454F41, 0x04000000, 0x00000003}, + {0x4A454F42, 0x20000000, 0x00000003}, + {0x4A454F43, 0x01000000, 0x00000002}, + {0x4A455041, 0x04000000, 0x00000001}, + {0x4A455043, 0x02000000, 0x00000002}, + {0x4A455059, 0x04000000, 0x00000002}, + {0x4A455241, 0x02000000, 0x00000001}, + {0x4A455249, 0x20000000, 0x00000006}, + {0x4A455259, 0x02000000, 0x00000002}, + {0x4A455341, 0x04000000, 0x00000002}, + {0x4A455343, 0x04000000, 0x00000002}, + {0x4A455441, 0x02000000, 0x00000001}, + {0x4A455541, 0x04000000, 0x00000005}, + {0x4A455643, 0x04000000, 0x00000002}, + {0x4A455741, 0x04000000, 0x00000005}, + {0x4A455759, 0x01000000, 0x00000002}, + {0x4A455841, 0x00800000, 0x00000002}, + {0x4A455859, 0x02000000, 0x00000003}, + {0x4A455941, 0x04000000, 0x00000002}, + {0x4A455A41, 0x04000000, 0x00000006}, + {0x4A455A59, 0x02000000, 0x00000003}, + {0x4A463241, 0x08000000, 0x00000003}, + {0x4A463243, 0x08000000, 0x00000002}, + {0x4A463341, 0x04000000, 0x00000005}, + {0x4A463442, 0x04000000, 0x00000003}, + {0x4A463443, 0x01000000, 0x00000003}, + {0x4A463541, 0x04000000, 0x00000003}, + {0x4A463542, 0x04000000, 0x00000005}, + {0x4A463543, 0x04000000, 0x00000002}, + {0x4A463641, 0x08000000, 0x00000003}, + {0x4A463643, 0x10000000, 0x00000002}, + {0x4A463841, 0x00800000, 0x00000001}, + {0x4A464241, 0x01000000, 0x00000005}, + {0x4A464254, 0x04000000, 0x00000003}, + {0x4A464259, 0x08000000, 0x00000003}, + {0x4A464341, 0x04000000, 0x00000002}, + {0x4A464443, 0x04000000, 0x00000002}, + {0x4A464641, 0x08000000, 0x00000003}, + {0x4A464741, 0x04000000, 0x00000002}, + {0x4A464842, 0x10000000, 0x00000003}, + {0x4A464941, 0x04000000, 0x00000002}, + {0x4A464B41, 0x00800000, 0x00000001}, + {0x4A464B54, 0x04000000, 0x00000005}, + {0x4A464B59, 0x02000000, 0x00000001}, + {0x4A464C42, 0x10000000, 0x00000003}, + {0x4A464D44, 0x02000000, 0xFFFFFFFF}, + {0x4A464F41, 0x02000000, 0x00000003}, + {0x4A464F59, 0x02000000, 0x00000003}, + {0x4A465041, 0x04000000, 0x00000002}, + {0x4A465141, 0x04000000, 0x00000002}, + {0x4A465142, 0x04000000, 0x00000002}, + {0x4A465143, 0x02000000, 0x00000008}, + {0x4A465154, 0x02000000, 0x00000003}, + {0x4A465241, 0x08000000, 0x00000003}, + {0x4A465242, 0x08000000, 0x00000003}, + {0x4A465341, 0x02000000, 0x00000005}, + {0x4A465459, 0x08000000, 0x00000003}, + {0x4A465541, 0x04000000, 0x00000002}, + {0x4A465559, 0x04000000, 0x00000002}, + {0x4A465641, 0x01000000, 0x00000002}, + {0x4A465759, 0x02000000, 0x00000003}, + {0x4A465841, 0x08000000, 0x00000003}, + {0x4A465859, 0x02000000, 0x00000003}, + {0x4A465A59, 0x02000000, 0x00000002}, + {0x4A473241, 0x02000000, 0x00000003}, + {0x4A473243, 0x04000000, 0x00000002}, + {0x4A473256, 0x02000000, 0x00000006}, + {0x4A473341, 0x04000000, 0x00000005}, + {0x4A473342, 0x04000000, 0x00000002}, + {0x4A473441, 0x02000000, 0x00000002}, + {0x4A473442, 0x08000000, 0x00000002}, + {0x4A473443, 0x10000000, 0x00000003}, + {0x4A473542, 0x04000000, 0x00000006}, + {0x4A473543, 0x01000000, 0x00000002}, + {0x4A473641, 0x04000000, 0x00000002}, + {0x4A473643, 0x01000000, 0x00000003}, + {0x4A473841, 0x04000000, 0x00000002}, + {0x4A474342, 0x04000000, 0x00000002}, + {0x4A474343, 0x10000000, 0x00000003}, + {0x4A474356, 0x04000000, 0x00000002}, + {0x4A474441, 0x02000000, 0x00000005}, + {0x4A474442, 0x10000000, 0x00000002}, + {0x4A474443, 0x04000000, 0x00000006}, + {0x4A474543, 0x10000000, 0x00000003}, + {0x4A474559, 0x04000000, 0x00000003}, + {0x4A474643, 0x02000000, 0x00000002}, + {0x4A474741, 0x02000000, 0x00000002}, + {0x4A474743, 0x02000000, 0x00000002}, + {0x4A474841, 0x02000000, 0x00000003}, + {0x4A474843, 0x10000000, 0x00000003}, + {0x4A474854, 0x04000000, 0x00000002}, + {0x4A474859, 0x04000000, 0x00000003}, + {0x4A474941, 0x04000000, 0x00000003}, + {0x4A474943, 0x01000000, 0x00000002}, + {0x4A474A41, 0x00800000, 0x00000005}, + {0x4A474A59, 0x04000000, 0x00000002}, + {0x4A474B41, 0x02000000, 0x00000002}, + {0x4A474B54, 0x04000000, 0x00000002}, + {0x4A474B56, 0x02000000, 0x00000005}, + {0x4A474B59, 0x10000000, 0x00000003}, + {0x4A474C41, 0x04000000, 0x00000001}, + {0x4A474D41, 0x01000000, 0x00000001}, + {0x4A474E41, 0x08000000, 0x00000005}, + {0x4A474E42, 0x04000000, 0x00000005}, + {0x4A474E59, 0x08000000, 0x00000003}, + {0x4A474F59, 0x08000000, 0x00000003}, + {0x4A475041, 0x01000000, 0x00000001}, + {0x4A475043, 0x02000000, 0x00000003}, + {0x4A475049, 0x08000000, 0x00000006}, + {0x4A475054, 0x10000000, 0x00000003}, + {0x4A475056, 0x08000000, 0x00000002}, + {0x4A475141, 0x04000000, 0x00000002}, + {0x4A475143, 0x04000000, 0x00000002}, + {0x4A475154, 0x04000000, 0x00000004}, + {0x4A475241, 0x02000000, 0x00000005}, + {0x4A475242, 0x04000000, 0x00000002}, + {0x4A475254, 0x08000000, 0x00000002}, + {0x4A475259, 0x04000000, 0x00000002}, + {0x4A475341, 0x02000000, 0x00000005}, + {0x4A475343, 0x08000000, 0x00000003}, + {0x4A475441, 0x00800000, 0x00000002}, + {0x4A475442, 0x10000000, 0x00000003}, + {0x4A475443, 0x10000000, 0x00000003}, + {0x4A475459, 0x08000000, 0x00000003}, + {0x4A475559, 0x02000000, 0x00000003}, + {0x4A475641, 0x04000000, 0x00000002}, + {0x4A475659, 0x08000000, 0x00000002}, + {0x4A475741, 0x08000000, 0x00000005}, + {0x4A475743, 0x01000000, 0x00000002}, + {0x4A475859, 0x02000000, 0x00000003}, + {0x4A475941, 0x04000000, 0x00000002}, + {0x4A475942, 0x02000000, 0x00000002}, + {0x4A475943, 0x04000000, 0x00000001}, + {0x4A475959, 0x04000000, 0x00000002}, + {0x4A475A41, 0x01000000, 0x00000003}, + {0x4A475A59, 0x02000000, 0x00000002}, + {0x4A483241, 0x01000000, 0x00000005}, + {0x4A483342, 0x04000000, 0x00000002}, + {0x4A483441, 0x02000000, 0x00000002}, + {0x4A483443, 0x08000000, 0x00000002}, + {0x4A483641, 0x02000000, 0x00000002}, + {0x4A483643, 0x01000000, 0x00000001}, + {0x4A483841, 0x00800000, 0x00000001}, + {0x4A484241, 0x08000000, 0x00000002}, + {0x4A484341, 0x04000000, 0x00000005}, + {0x4A484354, 0x04000000, 0x00000002}, + {0x4A484359, 0x04000000, 0x00000005}, + {0x4A484441, 0x04000000, 0x00000005}, + {0x4A484443, 0x01000000, 0x00000002}, + {0x4A484541, 0x04000000, 0x00000002}, + {0x4A484543, 0x08000000, 0x00000002}, + {0x4A484641, 0x01000000, 0x00000002}, + {0x4A484759, 0x08000000, 0x00000001}, + {0x4A484843, 0x01000000, 0x00000003}, + {0x4A484859, 0x02000000, 0x00000002}, + {0x4A484941, 0x08000000, 0x00000002}, + {0x4A484A41, 0x01000000, 0x00000002}, + {0x4A484A43, 0x04000000, 0x00000003}, + {0x4A484A54, 0x04000000, 0x00000005}, + {0x4A484A59, 0x01000000, 0x00000002}, + {0x4A484B41, 0x04000000, 0x00000002}, + {0x4A484B42, 0x04000000, 0x00000003}, + {0x4A484B59, 0x08000000, 0x00000005}, + {0x4A484C41, 0x02000000, 0x00000001}, + {0x4A484C59, 0x04000000, 0x00000002}, + {0x4A484D41, 0x04000000, 0x00000005}, + {0x4A484D59, 0x04000000, 0x00000003}, + {0x4A484E41, 0x08000000, 0x00000006}, + {0x4A484E42, 0x01000000, 0x00000002}, + {0x4A484E59, 0x02000000, 0x00000003}, + {0x4A484F41, 0x02000000, 0x00000003}, + {0x4A484F42, 0x00800000, 0x00000003}, + {0x4A484F43, 0x10000000, 0x00000002}, + {0x4A484F59, 0x02000000, 0x00000002}, + {0x4A485041, 0x02000000, 0x00000003}, + {0x4A485042, 0x02000000, 0x00000005}, + {0x4A485054, 0x04000000, 0x00000005}, + {0x4A485141, 0x04000000, 0x00000002}, + {0x4A485143, 0x04000000, 0x00000001}, + {0x4A485154, 0x08000000, 0x00000004}, + {0x4A485159, 0x01000000, 0x00000002}, + {0x4A485242, 0x08000000, 0x00000002}, + {0x4A485259, 0x02000000, 0x00000001}, + {0x4A485341, 0x02000000, 0x00000002}, + {0x4A485343, 0x02000000, 0x00000002}, + {0x4A485443, 0x01000000, 0x00000002}, + {0x4A485459, 0x08000000, 0x00000003}, + {0x4A485541, 0x01000000, 0x00000001}, + {0x4A485543, 0x02000000, 0x00000003}, + {0x4A485659, 0x01000000, 0x00000003}, + {0x4A485841, 0x01000000, 0x00000003}, + {0x4A485856, 0x08000000, 0x00000002}, + {0x4A485859, 0x02000000, 0x00000003}, + {0x4A485941, 0x04000000, 0x00000002}, + {0x4A485A41, 0x04000000, 0x00000002}, + {0x4A493241, 0x01000000, 0x00000005}, + {0x4A493341, 0x08000000, 0x00000002}, + {0x4A493342, 0x04000000, 0x00000002}, + {0x4A493442, 0x08000000, 0x00000005}, + {0x4A493443, 0x04000000, 0x00000002}, + {0x4A493543, 0x04000000, 0x00000002}, + {0x4A493641, 0x08000000, 0x00000003}, + {0x4A493841, 0x02000000, 0x00000002}, + {0x4A494143, 0x02000000, 0x00000002}, + {0x4A494241, 0x00800000, 0x00000005}, + {0x4A494259, 0x04000000, 0x00000002}, + {0x4A494341, 0x01000000, 0x00000002}, + {0x4A494441, 0x08000000, 0x00000001}, + {0x4A494459, 0x04000000, 0x00000002}, + {0x4A494555, 0x04000000, 0x00000002}, + {0x4A494559, 0x04000000, 0x00000002}, + {0x4A494643, 0x08000000, 0x00000003}, + {0x4A494841, 0x04000000, 0x00000003}, + {0x4A494843, 0x10000000, 0x00000003}, + {0x4A494859, 0x04000000, 0x00000001}, + {0x4A494941, 0x01000000, 0x00000002}, + {0x4A494959, 0x00800000, 0x00000001}, + {0x4A494B42, 0x08000000, 0x00000007}, + {0x4A494B59, 0x04000000, 0x00000003}, + {0x4A494C42, 0x04000000, 0x00000003}, + {0x4A494C59, 0x04000000, 0x00000002}, + {0x4A494D41, 0x00800000, 0x00000002}, + {0x4A494E41, 0x08000000, 0x00000005}, + {0x4A494F41, 0x02000000, 0x00000006}, + {0x4A494F43, 0x10000000, 0x00000002}, + {0x4A495041, 0x04000000, 0x00000005}, + {0x4A495059, 0x01000000, 0x00000003}, + {0x4A495141, 0x02000000, 0x00000005}, + {0x4A495142, 0x08000000, 0x00000002}, + {0x4A495143, 0x01000000, 0x00000002}, + {0x4A495241, 0x01000000, 0x00000001}, + {0x4A495242, 0x04000000, 0x00000001}, + {0x4A495243, 0x02000000, 0x00000002}, + {0x4A495341, 0x02000000, 0x00000002}, + {0x4A495441, 0x01000000, 0x00000008}, + {0x4A495459, 0x08000000, 0x00000003}, + {0x4A495559, 0x01000000, 0x00000002}, + {0x4A495641, 0x02000000, 0x00000001}, + {0x4A495642, 0x04000000, 0x00000002}, + {0x4A495643, 0x04000000, 0x00000002}, + {0x4A495659, 0x08000000, 0x00000003}, + {0x4A495741, 0x08000000, 0x00000005}, + {0x4A495759, 0x02000000, 0x00000002}, + {0x4A495841, 0x02000000, 0x00000002}, + {0x4A495843, 0x04000000, 0x00000005}, + {0x4A495859, 0x02000000, 0x00000003}, + {0x4A495941, 0x01000000, 0x00000001}, + {0x4A495A41, 0x00800000, 0x00000002}, + {0x4A495A59, 0x01000000, 0x00000002}, + {0x4A4A3241, 0x04000000, 0x00000003}, + {0x4A4A3242, 0x10000000, 0x00000003}, + {0x4A4A3343, 0x10000000, 0x00000003}, + {0x4A4A3441, 0x00800000, 0x00000002}, + {0x4A4A3543, 0x01000000, 0x00000002}, + {0x4A4A3641, 0x04000000, 0x00000002}, + {0x4A4A3842, 0x10000000, 0x00000005}, + {0x4A4A4241, 0x04000000, 0x00000005}, + {0x4A4A4242, 0x04000000, 0x00000003}, + {0x4A4A4441, 0x04000000, 0x00000005}, + {0x4A4A4541, 0x02000000, 0x00000002}, + {0x4A4A4659, 0x04000000, 0x00000003}, + {0x4A4A4843, 0x04000000, 0x00000002}, + {0x4A4A4859, 0x00800000, 0x00000003}, + {0x4A4A4941, 0x02000000, 0x00000003}, + {0x4A4A4A59, 0x04000000, 0x00000002}, + {0x4A4A4B41, 0x01000000, 0x00000003}, + {0x4A4A4B42, 0x01000000, 0x00000002}, + {0x4A4A4B59, 0x08000000, 0x00000002}, + {0x4A4A4C43, 0x08000000, 0x00000002}, + {0x4A4A4D41, 0x02000000, 0x00000005}, + {0x4A4A4D59, 0x04000000, 0x00000001}, + {0x4A4A4F41, 0x02000000, 0x00000002}, + {0x4A4A4F42, 0x04000000, 0x00000002}, + {0x4A4A4F59, 0x01000000, 0x00000002}, + {0x4A4A5041, 0x04000000, 0x00000005}, + {0x4A4A5059, 0x04000000, 0x00000005}, + {0x4A4A5142, 0x02000000, 0x00000003}, + {0x4A4A5154, 0x04000000, 0x00000003}, + {0x4A4A5241, 0x08000000, 0x00000003}, + {0x4A4A5242, 0x08000000, 0x00000003}, + {0x4A4A5341, 0x04000000, 0x00000005}, + {0x4A4A5343, 0x08000000, 0x00000002}, + {0x4A4A5443, 0x08000000, 0x00000002}, + {0x4A4A5559, 0x04000000, 0x00000001}, + {0x4A4A5641, 0x04000000, 0x00000002}, + {0x4A4A5643, 0x04000000, 0x00000002}, + {0x4A4A5841, 0x04000000, 0x00000003}, + {0x4A4A5859, 0x08000000, 0x00000005}, + {0x4A4A5941, 0x02000000, 0x00000005}, + {0x4A4A5943, 0x04000000, 0x00000002}, + {0x4A4A5959, 0x01000000, 0x00000002}, + {0x4A4A5A59, 0x01000000, 0x00000002}, + {0x4A4B3241, 0x04000000, 0x00000005}, + {0x4A4B3242, 0x20000000, 0x00000003}, + {0x4A4B3341, 0x00800000, 0x00000003}, + {0x4A4B3343, 0x00800000, 0x00000003}, + {0x4A4B3441, 0x00800000, 0x00000002}, + {0x4A4B3442, 0x01000000, 0x00000002}, + {0x4A4B3541, 0x01000000, 0x00000003}, + {0x4A4B3542, 0x04000000, 0x00000002}, + {0x4A4B3543, 0x04000000, 0x00000002}, + {0x4A4B3641, 0x08000000, 0x00000003}, + {0x4A4B3643, 0x04000000, 0x00000002}, + {0x4A4B3742, 0x04000000, 0x00000002}, + {0x4A4B3743, 0x04000000, 0x00000002}, + {0x4A4B3841, 0x02000000, 0x00000003}, + {0x4A4B4154, 0x04000000, 0x00000002}, + {0x4A4B4241, 0x01000000, 0x00000001}, + {0x4A4B4243, 0x04000000, 0x00000002}, + {0x4A4B4341, 0x02000000, 0x00000005}, + {0x4A4B4342, 0x04000000, 0x00000002}, + {0x4A4B4354, 0x02000000, 0x00000001}, + {0x4A4B4441, 0x04000000, 0x00000005}, + {0x4A4B4443, 0x01000000, 0x00000002}, + {0x4A4B4459, 0x01000000, 0x00000002}, + {0x4A4B4542, 0x08000000, 0x00000003}, + {0x4A4B4543, 0x04000000, 0x00000002}, + {0x4A4B4559, 0x08000000, 0x00000005}, + {0x4A4B4659, 0x04000000, 0x00000002}, + {0x4A4B4743, 0x02000000, 0x00000001}, + {0x4A4B4754, 0x04000000, 0x00000001}, + {0x4A4B4841, 0x04000000, 0x00000003}, + {0x4A4B4842, 0x01000000, 0x00000002}, + {0x4A4B4859, 0x01000000, 0x00000002}, + {0x4A4B4941, 0x02000000, 0x00000002}, + {0x4A4B4942, 0x04000000, 0x00000005}, + {0x4A4B4943, 0x04000000, 0x00000001}, + {0x4A4B4959, 0x02000000, 0x00000005}, + {0x4A4B4A41, 0x08000000, 0x00000002}, + {0x4A4B4A42, 0x01000000, 0x00000002}, + {0x4A4B4A43, 0x08000000, 0x00000003}, + {0x4A4B4B41, 0x01000000, 0x00000003}, + {0x4A4B4B42, 0x08000000, 0x00000003}, + {0x4A4B4B43, 0x10000000, 0x00000002}, + {0x4A4B4B59, 0x02000000, 0x00000002}, + {0x4A4B4C41, 0x08000000, 0x00000003}, + {0x4A4B4C59, 0x02000000, 0x00000002}, + {0x4A4B4D41, 0x00800000, 0x00000002}, + {0x4A4B4D54, 0x04000000, 0x00000002}, + {0x4A4B4D59, 0x08000000, 0x00000001}, + {0x4A4B4E41, 0x00800000, 0x00000001}, + {0x4A4B4E42, 0x02000000, 0x00000003}, + {0x4A4B4E43, 0x04000000, 0x00000002}, + {0x4A4B4E59, 0x04000000, 0x00000002}, + {0x4A4B4F42, 0x10000000, 0x00000002}, + {0x4A4B4F43, 0x00800000, 0x00000002}, + {0x4A4B4F59, 0x01000000, 0x00000002}, + {0x4A4B5041, 0x02000000, 0x00000005}, + {0x4A4B5049, 0x08000000, 0x00000006}, + {0x4A4B5059, 0x04000000, 0x00000002}, + {0x4A4B5141, 0x02000000, 0x00000002}, + {0x4A4B5154, 0x02000000, 0x00000003}, + {0x4A4B5241, 0x04000000, 0x00000002}, + {0x4A4B5341, 0x04000000, 0x00000002}, + {0x4A4B5342, 0x08000000, 0x00000003}, + {0x4A4B5343, 0x08000000, 0x00000003}, + {0x4A4B5359, 0x08000000, 0x00000003}, + {0x4A4B5441, 0x04000000, 0x00000002}, + {0x4A4B5443, 0x08000000, 0x00000002}, + {0x4A4B5459, 0x04000000, 0x00000003}, + {0x4A4B5541, 0x01000000, 0x00000001}, + {0x4A4B5542, 0x08000000, 0x00000002}, + {0x4A4B5543, 0x08000000, 0x00000002}, + {0x4A4B5641, 0x01000000, 0x00000001}, + {0x4A4B5743, 0x02000000, 0x00000003}, + {0x4A4B5841, 0x01000000, 0x00000002}, + {0x4A4B5859, 0x08000000, 0x00000005}, + {0x4A4B5941, 0x02000000, 0x00000005}, + {0x4A4B5959, 0x04000000, 0x00000002}, + {0x4A4B5A41, 0x00800000, 0x00000002}, + {0x4A4B5A42, 0x02000000, 0x00000003}, + {0x4A4B5A43, 0x04000000, 0x00000002}, + {0x4A4B5A59, 0x10000000, 0x00000003}, + {0x4A4C3243, 0x04000000, 0x00000002}, + {0x4A4C3341, 0x00800000, 0x00000002}, + {0x4A4C3342, 0x20000000, 0x00000003}, + {0x4A4C3441, 0x01000000, 0x00000002}, + {0x4A4C3442, 0x02000000, 0x00000002}, + {0x4A4C3641, 0x00800000, 0x00000002}, + {0x4A4C4142, 0x10000000, 0x00000003}, + {0x4A4C4159, 0x02000000, 0x00000003}, + {0x4A4C4241, 0x08000000, 0x00000002}, + {0x4A4C4341, 0x04000000, 0x00000003}, + {0x4A4C4342, 0x01000000, 0x00000002}, + {0x4A4C4441, 0x04000000, 0x00000003}, + {0x4A4C4541, 0x04000000, 0x00000002}, + {0x4A4C4542, 0x02000000, 0x00000002}, + {0x4A4C4559, 0x02000000, 0x00000001}, + {0x4A4C4654, 0x08000000, 0x00000003}, + {0x4A4C4659, 0x04000000, 0x00000003}, + {0x4A4C4741, 0x02000000, 0x00000001}, + {0x4A4C4841, 0x01000000, 0x00000003}, + {0x4A4C4843, 0x04000000, 0x00000002}, + {0x4A4C4854, 0x20000000, 0x00000002}, + {0x4A4C4859, 0x08000000, 0x00000003}, + {0x4A4C4941, 0x00800000, 0x00000002}, + {0x4A4C4943, 0x02000000, 0x00000001}, + {0x4A4C4959, 0x10000000, 0x00000002}, + {0x4A4C4B41, 0x04000000, 0x00000005}, + {0x4A4C4B42, 0x10000000, 0x00000002}, + {0x4A4C4C41, 0x00800000, 0x00000003}, + {0x4A4C4C59, 0x00800000, 0x00000002}, + {0x4A4C4E43, 0x04000000, 0x00000001}, + {0x4A4C4F42, 0x01000000, 0x00000003}, + {0x4A4C4F43, 0x08000000, 0x00000003}, + {0x4A4C4F59, 0x08000000, 0x00000002}, + {0x4A4C5041, 0x00800000, 0x00000002}, + {0x4A4C5056, 0x08000000, 0x00000006}, + {0x4A4C5154, 0x02000000, 0x00000003}, + {0x4A4C5241, 0x01000000, 0x00000005}, + {0x4A4C5342, 0x02000000, 0x00000003}, + {0x4A4C5359, 0x10000000, 0x00000005}, + {0x4A4C5559, 0x04000000, 0x00000002}, + {0x4A4C5641, 0x02000000, 0x00000002}, + {0x4A4C5642, 0x04000000, 0x00000002}, + {0x4A4C5659, 0x04000000, 0x00000003}, + {0x4A4C5741, 0x08000000, 0x00000003}, + {0x4A4C5759, 0x02000000, 0x00000001}, + {0x4A4C5859, 0x08000000, 0x00000005}, + {0x4A4C5A41, 0x08000000, 0x00000007}, + {0x4A4C5A59, 0x08000000, 0x00000001}, + {0x4A4D3341, 0x08000000, 0x00000002}, + {0x4A4D3541, 0x02000000, 0x00000002}, + {0x4A4D3842, 0x10000000, 0x00000005}, + {0x4A4D4241, 0x00800000, 0x00000001}, + {0x4A4D4259, 0x01000000, 0x00000002}, + {0x4A4D4341, 0x01000000, 0x00000001}, + {0x4A4D4354, 0x04000000, 0x00000002}, + {0x4A4D4441, 0x02000000, 0x00000005}, + {0x4A4D4541, 0x08000000, 0x00000003}, + {0x4A4D4559, 0x02000000, 0x00000003}, + {0x4A4D4641, 0x04000000, 0x00000002}, + {0x4A4D4643, 0x04000000, 0x00000003}, + {0x4A4D4659, 0x04000000, 0x00000003}, + {0x4A4D4743, 0x08000000, 0x00000003}, + {0x4A4D4759, 0x04000000, 0x00000002}, + {0x4A4D4841, 0x02000000, 0x00000002}, + {0x4A4D4854, 0x10000000, 0x00000005}, + {0x4A4D4859, 0x02000000, 0x00000002}, + {0x4A4D4941, 0x01000000, 0x00000005}, + {0x4A4D4942, 0x04000000, 0x00000005}, + {0x4A4D4956, 0x10000000, 0x00000003}, + {0x4A4D4A41, 0x01000000, 0x00000003}, + {0x4A4D4A42, 0x04000000, 0x00000001}, + {0x4A4D4B41, 0x08000000, 0x00000003}, + {0x4A4D4B42, 0x02000000, 0x00000002}, + {0x4A4D4B43, 0x01000000, 0x00000003}, + {0x4A4D4B54, 0x04000000, 0x00000005}, + {0x4A4D4B59, 0x01000000, 0x00000005}, + {0x4A4D4C43, 0x08000000, 0x00000003}, + {0x4A4D4D41, 0x00800000, 0x00000001}, + {0x4A4D4D43, 0x02000000, 0x00000003}, + {0x4A4D4D56, 0x04000000, 0x00000003}, + {0x4A4D4E41, 0x02000000, 0x00000005}, + {0x4A4D4E59, 0x01000000, 0x00000002}, + {0x4A4D4F41, 0x01000000, 0x00000002}, + {0x4A4D4F59, 0x04000000, 0x00000002}, + {0x4A4D5041, 0x01000000, 0x00000001}, + {0x4A4D5043, 0x04000000, 0x00000002}, + {0x4A4D5142, 0x01000000, 0x00000001}, + {0x4A4D5154, 0x08000000, 0x00000004}, + {0x4A4D5159, 0x04000000, 0x00000002}, + {0x4A4D5241, 0x04000000, 0x00000002}, + {0x4A4D5242, 0x01000000, 0x00000002}, + {0x4A4D5243, 0x02000000, 0x00000003}, + {0x4A4D5341, 0x01000000, 0x00000002}, + {0x4A4D5359, 0x08000000, 0x00000003}, + {0x4A4D5441, 0x08000000, 0x00000002}, + {0x4A4D5443, 0x04000000, 0x00000002}, + {0x4A4D5459, 0x04000000, 0x00000002}, + {0x4A4D5541, 0x02000000, 0x00000005}, + {0x4A4D5543, 0x02000000, 0x00000002}, + {0x4A4D5559, 0x00800000, 0x00000002}, + {0x4A4D5641, 0x04000000, 0x00000006}, + {0x4A4D5743, 0x10000000, 0x00000003}, + {0x4A4D5843, 0x04000000, 0x00000003}, + {0x4A4D5859, 0x02000000, 0x00000003}, + {0x4A4D5941, 0x01000000, 0x00000003}, + {0x4A4D5942, 0x04000000, 0x00000002}, + {0x4A4D5943, 0x02000000, 0x00000002}, + {0x4A4D5959, 0x10000000, 0x00000003}, + {0x4A4D5A41, 0x01000000, 0x00000002}, + {0x4A4D5A42, 0x04000000, 0x00000006}, + {0x4A4D5A59, 0x01000000, 0x00000002}, + {0x4A4E3242, 0x02000000, 0x00000001}, + {0x4A4E3343, 0x04000000, 0x00000003}, + {0x4A4E3441, 0x00800000, 0x00000002}, + {0x4A4E3442, 0x00800000, 0x00000002}, + {0x4A4E3443, 0x04000000, 0x00000003}, + {0x4A4E3641, 0x08000000, 0x00000003}, + {0x4A4E3841, 0x02000000, 0x00000005}, + {0x4A4E4156, 0x02000000, 0x00000007}, + {0x4A4E4159, 0x04000000, 0x00000002}, + {0x4A4E4241, 0x04000000, 0x00000002}, + {0x4A4E4259, 0x02000000, 0x00000007}, + {0x4A4E4341, 0x01000000, 0x00000002}, + {0x4A4E4342, 0x08000000, 0x00000005}, + {0x4A4E4359, 0x08000000, 0x00000001}, + {0x4A4E4441, 0x04000000, 0x00000003}, + {0x4A4E4442, 0x04000000, 0x00000003}, + {0x4A4E4459, 0x04000000, 0x00000002}, + {0x4A4E4541, 0x04000000, 0x00000002}, + {0x4A4E4554, 0x20000000, 0x00000002}, + {0x4A4E4641, 0x02000000, 0x00000002}, + {0x4A4E4643, 0x04000000, 0x00000002}, + {0x4A4E4842, 0x10000000, 0x00000002}, + {0x4A4E4859, 0x04000000, 0x00000003}, + {0x4A4E4941, 0x04000000, 0x00000002}, + {0x4A4E4943, 0x08000000, 0x00000002}, + {0x4A4E4959, 0x00800000, 0x00000001}, + {0x4A4E4A41, 0x02000000, 0x00000002}, + {0x4A4E4A59, 0x04000000, 0x00000002}, + {0x4A4E4B41, 0x01000000, 0x00000001}, + {0x4A4E4B43, 0x08000000, 0x00000002}, + {0x4A4E4B54, 0x04000000, 0x00000002}, + {0x4A4E4B56, 0x02000000, 0x00000003}, + {0x4A4E4B59, 0x01000000, 0x00000002}, + {0x4A4E4D41, 0x01000000, 0x00000005}, + {0x4A4E4E41, 0x04000000, 0x00000003}, + {0x4A4E4E42, 0x04000000, 0x00000002}, + {0x4A4E4E59, 0x08000000, 0x00000003}, + {0x4A4E4F41, 0x02000000, 0x00000005}, + {0x4A4E4F42, 0x08000000, 0x00000003}, + {0x4A4E4F43, 0x01000000, 0x00000005}, + {0x4A4E4F59, 0x01000000, 0x00000003}, + {0x4A4E5041, 0x02000000, 0x00000001}, + {0x4A4E5141, 0x01000000, 0x00000002}, + {0x4A4E5143, 0x02000000, 0x00000002}, + {0x4A4E5154, 0x04000000, 0x00000000}, + {0x4A4E5159, 0x04000000, 0x00000002}, + {0x4A4E5241, 0x01000000, 0x00000001}, + {0x4A4E5341, 0x00800000, 0x00000002}, + {0x4A4E5459, 0x08000000, 0x00000003}, + {0x4A4E5541, 0x00800000, 0x00000002}, + {0x4A4E5543, 0x10000000, 0x00000003}, + {0x4A4E5559, 0x04000000, 0x00000003}, + {0x4A4E5641, 0x08000000, 0x00000002}, + {0x4A4E5741, 0x08000000, 0x00000002}, + {0x4A4E5742, 0x02000000, 0x00000002}, + {0x4A4E5743, 0x04000000, 0x00000002}, + {0x4A4E5841, 0x00800000, 0x00000002}, + {0x4A4E5859, 0x02000000, 0x00000003}, + {0x4A4E5941, 0x04000000, 0x00000003}, + {0x4A4E5942, 0x04000000, 0x00000003}, + {0x4A4E5959, 0x02000000, 0x00000001}, + {0x4A4E5A59, 0x04000000, 0x00000002}, + {0x4A4F3241, 0x04000000, 0x00000003}, + {0x4A4F3242, 0x02000000, 0x00000005}, + {0x4A4F3341, 0x00800000, 0x00000001}, + {0x4A4F3343, 0x08000000, 0x00000002}, + {0x4A4F3441, 0x02000000, 0x00000005}, + {0x4A4F3641, 0x02000000, 0x00000002}, + {0x4A4F3643, 0x08000000, 0x00000003}, + {0x4A4F4242, 0x00800000, 0x00000001}, + {0x4A4F4243, 0x02000000, 0x00000005}, + {0x4A4F4341, 0x04000000, 0x00000005}, + {0x4A4F4359, 0x04000000, 0x00000001}, + {0x4A4F4459, 0x02000000, 0x00000002}, + {0x4A4F4541, 0x02000000, 0x00000001}, + {0x4A4F4559, 0x04000000, 0x00000003}, + {0x4A4F4641, 0x04000000, 0x00000003}, + {0x4A4F4741, 0x04000000, 0x00000005}, + {0x4A4F4841, 0x01000000, 0x00000002}, + {0x4A4F4859, 0x01000000, 0x00000002}, + {0x4A4F4941, 0x08000000, 0x00000005}, + {0x4A4F4B41, 0x08000000, 0x00000003}, + {0x4A4F4B59, 0x02000000, 0x00000006}, + {0x4A4F4C43, 0x01000000, 0x00000001}, + {0x4A4F4D41, 0x04000000, 0x00000002}, + {0x4A4F4D42, 0x08000000, 0x00000005}, + {0x4A4F4D43, 0x02000000, 0x00000003}, + {0x4A4F4E41, 0x02000000, 0x00000002}, + {0x4A4F4E43, 0x04000000, 0x00000002}, + {0x4A4F4F41, 0x01000000, 0x00000002}, + {0x4A4F4F42, 0x08000000, 0x00000002}, + {0x4A4F4F59, 0x04000000, 0x00000003}, + {0x4A4F5041, 0x04000000, 0x00000001}, + {0x4A4F5042, 0x04000000, 0x00000003}, + {0x4A4F5059, 0x04000000, 0x00000003}, + {0x4A4F5141, 0x04000000, 0x00000003}, + {0x4A4F5241, 0x08000000, 0x00000003}, + {0x4A4F5242, 0x04000000, 0x00000003}, + {0x4A4F5259, 0x04000000, 0x00000002}, + {0x4A4F5441, 0x04000000, 0x00000002}, + {0x4A4F5442, 0x04000000, 0x00000002}, + {0x4A4F5443, 0x04000000, 0x00000001}, + {0x4A4F5459, 0x04000000, 0x00000002}, + {0x4A4F5559, 0x10000000, 0x00000003}, + {0x4A4F5641, 0x01000000, 0x00000003}, + {0x4A4F5659, 0x02000000, 0x00000002}, + {0x4A4F5842, 0x04000000, 0x00000003}, + {0x4A4F5859, 0x04000000, 0x00000005}, + {0x4A4F5941, 0x04000000, 0x00000003}, + {0x4A4F5942, 0x04000000, 0x00000003}, + {0x4A4F5A59, 0x08000000, 0x00000002}, + {0x4A503242, 0x04000000, 0x00000005}, + {0x4A503243, 0x04000000, 0x00000003}, + {0x4A503341, 0x02000000, 0x00000001}, + {0x4A503443, 0x01000000, 0x00000002}, + {0x4A503541, 0x04000000, 0x00000001}, + {0x4A503542, 0x10000000, 0x00000001}, + {0x4A503543, 0x02000000, 0x00000002}, + {0x4A503641, 0x00800000, 0x00000003}, + {0x4A503643, 0x02000000, 0x00000007}, + {0x4A503742, 0x08000000, 0x00000003}, + {0x4A503841, 0x02000000, 0x00000002}, + {0x4A503842, 0x02000000, 0x00000003}, + {0x4A504142, 0x04000000, 0x00000001}, + {0x4A504341, 0x00800000, 0x00000002}, + {0x4A504356, 0x04000000, 0x00000003}, + {0x4A504359, 0x04000000, 0x00000001}, + {0x4A504441, 0x00800000, 0x00000002}, + {0x4A504459, 0x02000000, 0x00000001}, + {0x4A504541, 0x01000000, 0x00000003}, + {0x4A504641, 0x04000000, 0x00000001}, + {0x4A504642, 0x04000000, 0x00000002}, + {0x4A504654, 0x04000000, 0x00000005}, + {0x4A504741, 0x04000000, 0x00000002}, + {0x4A504759, 0x02000000, 0x00000003}, + {0x4A504841, 0x04000000, 0x00000001}, + {0x4A504843, 0x01000000, 0x00000001}, + {0x4A504859, 0x01000000, 0x00000002}, + {0x4A504942, 0x04000000, 0x00000002}, + {0x4A504943, 0x02000000, 0x00000002}, + {0x4A504959, 0x04000000, 0x00000001}, + {0x4A504A42, 0x02000000, 0x00000002}, + {0x4A504B42, 0x04000000, 0x00000002}, + {0x4A504B56, 0x02000000, 0x00000005}, + {0x4A504C59, 0x00800000, 0x00000002}, + {0x4A504D54, 0x08000000, 0x00000003}, + {0x4A504D59, 0x08000000, 0x00000005}, + {0x4A505042, 0x04000000, 0x00000005}, + {0x4A505054, 0x04000000, 0x00000007}, + {0x4A505059, 0x01000000, 0x00000001}, + {0x4A505142, 0x04000000, 0x00000002}, + {0x4A505159, 0x02000000, 0x00000002}, + {0x4A505242, 0x08000000, 0x00000003}, + {0x4A505341, 0x02000000, 0x00000003}, + {0x4A505343, 0x02000000, 0x00000003}, + {0x4A505359, 0x02000000, 0x00000005}, + {0x4A505441, 0x04000000, 0x00000005}, + {0x4A505541, 0x00800000, 0x00000001}, + {0x4A505559, 0x04000000, 0x00000002}, + {0x4A505641, 0x04000000, 0x00000002}, + {0x4A505643, 0x10000000, 0x00000002}, + {0x4A505659, 0x08000000, 0x00000003}, + {0x4A505759, 0x04000000, 0x00000002}, + {0x4A505841, 0x02000000, 0x00000005}, + {0x4A505842, 0x04000000, 0x00000002}, + {0x4A505859, 0x02000000, 0x00000003}, + {0x4A505A41, 0x01000000, 0x00000002}, + {0x4A505A55, 0x08000000, 0x00000003}, + {0x4A505A59, 0x02000000, 0x00000002}, + {0x4A513242, 0x04000000, 0x00000001}, + {0x4A513341, 0x04000000, 0x00000003}, + {0x4A513441, 0x01000000, 0x00000001}, + {0x4A513442, 0x02000000, 0x00000002}, + {0x4A513541, 0x01000000, 0x00000001}, + {0x4A513641, 0x01000000, 0x00000001}, + {0x4A513742, 0x04000000, 0x00000005}, + {0x4A513841, 0x02000000, 0x00000005}, + {0x4A514154, 0x04000000, 0x00000004}, + {0x4A514159, 0x04000000, 0x00000003}, + {0x4A514254, 0x04000000, 0x00000002}, + {0x4A514341, 0x02000000, 0x00000001}, + {0x4A514359, 0x04000000, 0x00000002}, + {0x4A514441, 0x04000000, 0x00000002}, + {0x4A514443, 0x08000000, 0x00000001}, + {0x4A514459, 0x10000000, 0x00000003}, + {0x4A514541, 0x00800000, 0x00000002}, + {0x4A514542, 0x04000000, 0x00000002}, + {0x4A514641, 0x02000000, 0x00000002}, + {0x4A514654, 0x04000000, 0x00000007}, + {0x4A514659, 0x04000000, 0x00000002}, + {0x4A514842, 0x04000000, 0x00000002}, + {0x4A514859, 0x04000000, 0x00000003}, + {0x4A514941, 0x00800000, 0x00000002}, + {0x4A514959, 0x08000000, 0x00000002}, + {0x4A514A41, 0x02000000, 0x00000002}, + {0x4A514B41, 0x02000000, 0x00000001}, + {0x4A514B59, 0x04000000, 0x00000003}, + {0x4A514D41, 0x04000000, 0x00000005}, + {0x4A514E41, 0x00800000, 0x00000002}, + {0x4A514E43, 0x02000000, 0x00000003}, + {0x4A514E59, 0x00800000, 0x00000002}, + {0x4A514F41, 0x04000000, 0x00000001}, + {0x4A514F42, 0x02000000, 0x00000005}, + {0x4A514F59, 0x08000000, 0x00000002}, + {0x4A515054, 0x04000000, 0x00000002}, + {0x4A515059, 0x01000000, 0x00000001}, + {0x4A515141, 0x02000000, 0x00000002}, + {0x4A515241, 0x04000000, 0x00000003}, + {0x4A515242, 0x04000000, 0x00000005}, + {0x4A515341, 0x00800000, 0x00000002}, + {0x4A515541, 0x01000000, 0x00000002}, + {0x4A515542, 0x08000000, 0x00000001}, + {0x4A515559, 0x01000000, 0x00000002}, + {0x4A515741, 0x01000000, 0x00000001}, + {0x4A515859, 0x02000000, 0x00000003}, + {0x4A515942, 0x02000000, 0x00000002}, + {0x4A515959, 0x01000000, 0x00000002}, + {0x4A515A42, 0x08000000, 0x00000003}, + {0x4A515A59, 0x01000000, 0x00000005}, + {0x4A523241, 0x01000000, 0x00000003}, + {0x4A523342, 0x08000000, 0x00000005}, + {0x4A523343, 0x04000000, 0x00000002}, + {0x4A523356, 0x02000000, 0x00000003}, + {0x4A523441, 0x02000000, 0x00000002}, + {0x4A523541, 0x01000000, 0x00000002}, + {0x4A523543, 0x08000000, 0x00000003}, + {0x4A523641, 0x04000000, 0x00000003}, + {0x4A523643, 0x04000000, 0x00000003}, + {0x4A523841, 0x04000000, 0x00000005}, + {0x4A523842, 0x04000000, 0x00000002}, + {0x4A524142, 0x02000000, 0x00000005}, + {0x4A524255, 0x00800000, 0x00000005}, + {0x4A524259, 0x04000000, 0x00000001}, + {0x4A524441, 0x01000000, 0x00000002}, + {0x4A524541, 0x01000000, 0x00000002}, + {0x4A524559, 0x04000000, 0x00000003}, + {0x4A524643, 0x08000000, 0x00000002}, + {0x4A524741, 0x04000000, 0x00000005}, + {0x4A524742, 0x02000000, 0x00000002}, + {0x4A524743, 0x04000000, 0x00000001}, + {0x4A524759, 0x08000000, 0x00000002}, + {0x4A524841, 0x02000000, 0x00000002}, + {0x4A524854, 0x20000000, 0x00000003}, + {0x4A524856, 0x04000000, 0x00000002}, + {0x4A524941, 0x01000000, 0x00000001}, + {0x4A524A41, 0x08000000, 0x00000005}, + {0x4A524A43, 0x08000000, 0x00000003}, + {0x4A524A59, 0x08000000, 0x00000002}, + {0x4A524B41, 0x04000000, 0x00000002}, + {0x4A524B43, 0x04000000, 0x00000003}, + {0x4A524B59, 0x04000000, 0x00000005}, + {0x4A524C41, 0x00800000, 0x00000002}, + {0x4A524D41, 0x01000000, 0x00000003}, + {0x4A524E41, 0x04000000, 0x00000001}, + {0x4A524E43, 0x04000000, 0x00000002}, + {0x4A524E54, 0x10000000, 0x00000003}, + {0x4A524E59, 0x04000000, 0x00000002}, + {0x4A524F42, 0x01000000, 0x00000003}, + {0x4A524F55, 0x02000000, 0x00000008}, + {0x4A525041, 0x02000000, 0x00000002}, + {0x4A525142, 0x02000000, 0x00000002}, + {0x4A525143, 0x04000000, 0x00000002}, + {0x4A525242, 0x10000000, 0x00000003}, + {0x4A525243, 0x02000000, 0x00000005}, + {0x4A525341, 0x04000000, 0x00000003}, + {0x4A525343, 0x10000000, 0x00000002}, + {0x4A525359, 0x01000000, 0x00000005}, + {0x4A525441, 0x01000000, 0x00000002}, + {0x4A52544E, 0x00180AC8, 0x00000000}, + {0x4A525541, 0x04000000, 0x00000002}, + {0x4A525543, 0x04000000, 0x00000001}, + {0x4A525559, 0x04000000, 0x00000003}, + {0x4A525641, 0x04000000, 0x00000002}, + {0x4A525659, 0x08000000, 0x00000002}, + {0x4A525741, 0x02000000, 0x00000005}, + {0x4A525742, 0x02000000, 0x00000003}, + {0x4A525841, 0x01000000, 0x00000002}, + {0x4A525959, 0x04000000, 0x00000001}, + {0x4A525A41, 0x08000000, 0x00000002}, + {0x4A525A59, 0x01000000, 0x00000002}, + {0x4A533243, 0x08000000, 0x00000004}, + {0x4A533342, 0x20000000, 0x00000003}, + {0x4A534159, 0x10000000, 0x00000005}, + {0x4A534241, 0x01000000, 0x00000005}, + {0x4A534254, 0x02000000, 0x00000002}, + {0x4A534259, 0x08000000, 0x00000003}, + {0x4A534342, 0x04000000, 0x00000002}, + {0x4A534459, 0x04000000, 0x00000002}, + {0x4A534559, 0x04000000, 0x00000003}, + {0x4A534654, 0x02000000, 0x00000003}, + {0x4A534659, 0x04000000, 0x00000002}, + {0x4A534841, 0x02000000, 0x00000002}, + {0x4A534A41, 0x001998C8, 0x00000002}, + {0x4A534A59, 0x02000000, 0x00000002}, + {0x4A534B41, 0x02000000, 0x00000002}, + {0x4A534B42, 0x02000000, 0x00000002}, + {0x4A534C41, 0x04000000, 0x00000002}, + {0x4A534C59, 0x04000000, 0x00000001}, + {0x4A534D41, 0x04000000, 0x00000003}, + {0x4A534D43, 0x02000000, 0x00000003}, + {0x4A534D59, 0x04000000, 0x00000005}, + {0x4A534E41, 0x01000000, 0x00000001}, + {0x4A534E43, 0x04000000, 0x00000002}, + {0x4A534E55, 0x00800000, 0x00000006}, + {0x4A534F41, 0x04000000, 0x00000002}, + {0x4A534F42, 0x01000000, 0x00000003}, + {0x4A534F56, 0x02000000, 0x00000007}, + {0x4A534F59, 0x00800000, 0x00000002}, + {0x4A535041, 0x04000000, 0x00000005}, + {0x4A535054, 0x04000000, 0x00000005}, + {0x4A535059, 0x01000000, 0x00000002}, + {0x4A535141, 0x02000000, 0x00000002}, + {0x4A535142, 0x01000000, 0x00000003}, + {0x4A535241, 0x08000000, 0x00000002}, + {0x4A535359, 0x04000000, 0x00000003}, + {0x4A535443, 0x04000000, 0x00000001}, + {0x4A535641, 0x02000000, 0x00000002}, + {0x4A535659, 0x02000000, 0x00000003}, + {0x4A535841, 0x04000000, 0x00000002}, + {0x4A535842, 0x04000000, 0x00000003}, + {0x4A535859, 0x02000000, 0x00000003}, + {0x4A535941, 0x04000000, 0x00000005}, + {0x4A535942, 0x04000000, 0x00000003}, + {0x4A535959, 0x01000000, 0x00000002}, + {0x4A535A41, 0x01000000, 0x00000003}, + {0x4A535A43, 0x04000000, 0x00000001}, + {0x4A535A59, 0x01000000, 0x00000002}, + {0x4A543243, 0x04000000, 0x00000003}, + {0x4A543342, 0x02000000, 0x00000001}, + {0x4A543442, 0x02000000, 0x00000002}, + {0x4A543443, 0x08000000, 0x00000002}, + {0x4A543541, 0x02000000, 0x00000005}, + {0x4A543841, 0x02000000, 0x00000002}, + {0x4A543842, 0x01000000, 0x00000001}, + {0x4A544143, 0x02000000, 0x00000002}, + {0x4A544259, 0x08000000, 0x00000003}, + {0x4A544341, 0x02000000, 0x00000001}, + {0x4A544343, 0x08000000, 0x00000003}, + {0x4A544354, 0x02000000, 0x00000005}, + {0x4A544356, 0x04000000, 0x00000003}, + {0x4A544359, 0x02000000, 0x00000001}, + {0x4A544459, 0x04000000, 0x00000003}, + {0x4A544541, 0x04000000, 0x00000001}, + {0x4A544542, 0x04000000, 0x00000005}, + {0x4A544543, 0x08000000, 0x00000002}, + {0x4A544654, 0x04000000, 0x00000002}, + {0x4A544659, 0x04000000, 0x00000005}, + {0x4A544741, 0x02000000, 0x00000002}, + {0x4A544742, 0x08000000, 0x00000002}, + {0x4A544843, 0x04000000, 0x00000002}, + {0x4A544854, 0x20000000, 0x00000003}, + {0x4A544859, 0x01000000, 0x00000001}, + {0x4A544942, 0x08000000, 0x00000005}, + {0x4A544A59, 0x08000000, 0x00000002}, + {0x4A544B41, 0x01000000, 0x00000001}, + {0x4A544B42, 0x04000000, 0x00000002}, + {0x4A544B54, 0x04000000, 0x00000002}, + {0x4A544B59, 0x02000000, 0x00000002}, + {0x4A544C54, 0x04000000, 0x00000003}, + {0x4A544C59, 0x08000000, 0x00000002}, + {0x4A544D41, 0x04000000, 0x00000002}, + {0x4A544D42, 0x08000000, 0x00000003}, + {0x4A544D56, 0x10000000, 0x00000002}, + {0x4A544E41, 0x04000000, 0x00000002}, + {0x4A544E43, 0x10000000, 0x00000003}, + {0x4A544E59, 0x10000000, 0x00000001}, + {0x4A544F41, 0x01000000, 0x00000002}, + {0x4A544F42, 0x01000000, 0x00000005}, + {0x4A544F43, 0x01000000, 0x00000005}, + {0x4A544F59, 0x04000000, 0x00000003}, + {0x4A545041, 0x01000000, 0x00000002}, + {0x4A545043, 0x04000000, 0x00000005}, + {0x4A545056, 0x08000000, 0x00000006}, + {0x4A545059, 0x02000000, 0x00000005}, + {0x4A545143, 0x04000000, 0x00000003}, + {0x4A545241, 0x08000000, 0x00000002}, + {0x4A545341, 0x02000000, 0x00000001}, + {0x4A545359, 0x04000000, 0x00000001}, + {0x4A545442, 0x04000000, 0x00000002}, + {0x4A545443, 0x08000000, 0x00000003}, + {0x4A545459, 0x08000000, 0x00000003}, + {0x4A545641, 0x04000000, 0x00000002}, + {0x4A545741, 0x00800000, 0x00000001}, + {0x4A545843, 0x10000000, 0x00000003}, + {0x4A545859, 0x02000000, 0x00000003}, + {0x4A545941, 0x08000000, 0x00000003}, + {0x4A545943, 0x04000000, 0x00000003}, + {0x4A545A41, 0x01000000, 0x00000005}, + {0x4A545A43, 0x02000000, 0x00000002}, + {0x4A545A59, 0x01000000, 0x00000005}, + {0x4A553241, 0x04000000, 0x00000002}, + {0x4A553341, 0x02000000, 0x00000001}, + {0x4A553343, 0x08000000, 0x00000002}, + {0x4A553441, 0x02000000, 0x00000002}, + {0x4A553442, 0x02000000, 0x00000003}, + {0x4A553443, 0x04000000, 0x00000001}, + {0x4A553641, 0x02000000, 0x00000001}, + {0x4A553841, 0x02000000, 0x00000002}, + {0x4A554241, 0x04000000, 0x00000005}, + {0x4A554242, 0x04000000, 0x00000003}, + {0x4A554259, 0x08000000, 0x00000003}, + {0x4A554341, 0x04000000, 0x00000005}, + {0x4A554343, 0x04000000, 0x00000006}, + {0x4A554441, 0x02000000, 0x00000003}, + {0x4A554459, 0x04000000, 0x00000003}, + {0x4A554541, 0x04000000, 0x00000003}, + {0x4A554542, 0x10000000, 0x00000003}, + {0x4A554641, 0x01000000, 0x00000003}, + {0x4A554656, 0x10000000, 0x00000005}, + {0x4A554659, 0x04000000, 0x00000002}, + {0x4A554741, 0x02000000, 0x00000002}, + {0x4A554742, 0x08000000, 0x00000003}, + {0x4A554759, 0x01000000, 0x00000002}, + {0x4A554843, 0x10000000, 0x00000003}, + {0x4A554A41, 0x04000000, 0x00000003}, + {0x4A554A42, 0x02000000, 0x00000003}, + {0x4A554A43, 0x04000000, 0x00000003}, + {0x4A554A59, 0x04000000, 0x00000002}, + {0x4A554B42, 0x08000000, 0x00000005}, + {0x4A554B43, 0x04000000, 0x00000003}, + {0x4A554B59, 0x04000000, 0x00000003}, + {0x4A554C41, 0x02000000, 0x00000002}, + {0x4A554C42, 0x08000000, 0x00000003}, + {0x4A554C59, 0x08000000, 0x00000005}, + {0x4A554E43, 0x02000000, 0x00000002}, + {0x4A554E59, 0x04000000, 0x00000003}, + {0x4A554F41, 0x01000000, 0x00000003}, + {0x4A555041, 0x02000000, 0x00000003}, + {0x4A555042, 0x04000000, 0x00000005}, + {0x4A555043, 0x08000000, 0x00000006}, + {0x4A555141, 0x08000000, 0x00000002}, + {0x4A555142, 0x04000000, 0x00000002}, + {0x4A555143, 0x02000000, 0x00000002}, + {0x4A555159, 0x08000000, 0x00000003}, + {0x4A555241, 0x02000000, 0x00000003}, + {0x4A555259, 0x00800000, 0x00000001}, + {0x4A555341, 0x04000000, 0x00000003}, + {0x4A555359, 0x00800000, 0x00000003}, + {0x4A555441, 0x04000000, 0x00000002}, + {0x4A555442, 0x04000000, 0x00000002}, + {0x4A555443, 0x10000000, 0x00000003}, + {0x4A555459, 0x04000000, 0x00000003}, + {0x4A555541, 0x00800000, 0x00000003}, + {0x4A555543, 0x00800000, 0x00000002}, + {0x4A555559, 0x02000000, 0x00000002}, + {0x4A555641, 0x08000000, 0x00000003}, + {0x4A555643, 0x04000000, 0x00000002}, + {0x4A555659, 0x04000000, 0x00000005}, + {0x4A555759, 0x02000000, 0x00000001}, + {0x4A555859, 0x02000000, 0x00000003}, + {0x4A555941, 0x02000000, 0x00000002}, + {0x4A555A41, 0x01000000, 0x00000002}, + {0x4A555A59, 0x04000000, 0x00000001}, + {0x4A563243, 0x10000000, 0x00000003}, + {0x4A563341, 0x04000000, 0x00000003}, + {0x4A563441, 0x08000000, 0x00000005}, + {0x4A563841, 0x04000000, 0x00000002}, + {0x4A563842, 0x02000000, 0x00000003}, + {0x4A564156, 0x04000000, 0x00000001}, + {0x4A564241, 0x02000000, 0x00000002}, + {0x4A564341, 0x04000000, 0x00000002}, + {0x4A564441, 0x01000000, 0x00000001}, + {0x4A564454, 0x08000000, 0x00000003}, + {0x4A564541, 0x04000000, 0x00000002}, + {0x4A564542, 0x10000000, 0x00000003}, + {0x4A564742, 0x04000000, 0x00000002}, + {0x4A564759, 0x04000000, 0x00000002}, + {0x4A564843, 0x01000000, 0x00000003}, + {0x4A564941, 0x02000000, 0x00000002}, + {0x4A564942, 0x00800000, 0x00000001}, + {0x4A564943, 0x08000000, 0x00000003}, + {0x4A564959, 0x08000000, 0x00000003}, + {0x4A564A41, 0x01000000, 0x00000001}, + {0x4A564B41, 0x04000000, 0x00000001}, + {0x4A564B59, 0x08000000, 0x00000003}, + {0x4A564C41, 0x02000000, 0x00000002}, + {0x4A564C59, 0x04000000, 0x00000002}, + {0x4A564D59, 0x00800000, 0x00000001}, + {0x4A564E43, 0x08000000, 0x00000005}, + {0x4A564E59, 0x02000000, 0x00000002}, + {0x4A564F41, 0x04000000, 0x00000002}, + {0x4A564F43, 0x02000000, 0x00000005}, + {0x4A565041, 0x00800000, 0x00000002}, + {0x4A565142, 0x04000000, 0x00000003}, + {0x4A565259, 0x02000000, 0x00000005}, + {0x4A565359, 0x04000000, 0x00000003}, + {0x4A565541, 0x08000000, 0x00000002}, + {0x4A565559, 0x02000000, 0x00000003}, + {0x4A565641, 0x00800000, 0x00000003}, + {0x4A565643, 0x01000000, 0x00000001}, + {0x4A565659, 0x00800000, 0x00000001}, + {0x4A565741, 0x01000000, 0x00000001}, + {0x4A565743, 0x04000000, 0x00000002}, + {0x4A565759, 0x04000000, 0x00000002}, + {0x4A565841, 0x04000000, 0x00000003}, + {0x4A565843, 0x02000000, 0x00000003}, + {0x4A565942, 0x08000000, 0x00000003}, + {0x4A565943, 0x04000000, 0x00000002}, + {0x4A565A41, 0x00800000, 0x00000001}, + {0x4A565A59, 0x02000000, 0x00000002}, + {0x4A573241, 0x04000000, 0x00000001}, + {0x4A573242, 0x08000000, 0x00000003}, + {0x4A573243, 0x02000000, 0x00000002}, + {0x4A573343, 0x02000000, 0x00000003}, + {0x4A573443, 0x02000000, 0x00000002}, + {0x4A573643, 0x02000000, 0x00000002}, + {0x4A573841, 0x00800000, 0x00000001}, + {0x4A574159, 0x04000000, 0x00000002}, + {0x4A574254, 0x02000000, 0x00000001}, + {0x4A574341, 0x00800000, 0x00000002}, + {0x4A574359, 0x00800000, 0x00000002}, + {0x4A574459, 0x02000000, 0x00000005}, + {0x4A574541, 0x04000000, 0x00000002}, + {0x4A574543, 0x08000000, 0x00000002}, + {0x4A574559, 0x04000000, 0x00000008}, + {0x4A574741, 0x01000000, 0x00000002}, + {0x4A574742, 0x02000000, 0x00000002}, + {0x4A574743, 0x00800000, 0x00000001}, + {0x4A574941, 0x01000000, 0x00000002}, + {0x4A574A41, 0x01000000, 0x00000001}, + {0x4A574B41, 0x04000000, 0x00000002}, + {0x4A574B43, 0x10000000, 0x00000001}, + {0x4A574B59, 0x08000000, 0x00000003}, + {0x4A574C41, 0x02000000, 0x00000001}, + {0x4A574D49, 0x04000000, 0x00000007}, + {0x4A574F43, 0x10000000, 0x00000002}, + {0x4A574F59, 0x02000000, 0x00000002}, + {0x4A575141, 0x02000000, 0x00000002}, + {0x4A575142, 0x08000000, 0x00000003}, + {0x4A575241, 0x01000000, 0x00000002}, + {0x4A575242, 0x08000000, 0x00000005}, + {0x4A575259, 0x02000000, 0x00000005}, + {0x4A575342, 0x08000000, 0x00000006}, + {0x4A575441, 0x02000000, 0x00000002}, + {0x4A575443, 0x01000000, 0x00000003}, + {0x4A575459, 0x08000000, 0x00000003}, + {0x4A575541, 0x04000000, 0x00000003}, + {0x4A575543, 0x04000000, 0x00000003}, + {0x4A575659, 0x10000000, 0x00000003}, + {0x4A575742, 0x08000000, 0x00000003}, + {0x4A575759, 0x02000000, 0x00000002}, + {0x4A575841, 0x00800000, 0x00000002}, + {0x4A575843, 0x02000000, 0x00000003}, + {0x4A575859, 0x01000000, 0x00000003}, + {0x4A575941, 0x02000000, 0x00000002}, + {0x4A575943, 0x01000000, 0x00000001}, + {0x4A575A41, 0x02000000, 0x00000002}, + {0x4A575A43, 0x04000000, 0x00000002}, + {0x4A575A59, 0x02000000, 0x00000002}, + {0x4A583241, 0x01000000, 0x00000002}, + {0x4A583243, 0x02000000, 0x00000003}, + {0x4A583342, 0x01000000, 0x00000001}, + {0x4A583343, 0x08000000, 0x00000002}, + {0x4A583442, 0x04000000, 0x00000002}, + {0x4A583641, 0x02000000, 0x00000002}, + {0x4A583642, 0x01000000, 0x00000003}, + {0x4A583643, 0x00800000, 0x00000002}, + {0x4A583742, 0x08000000, 0x00000003}, + {0x4A583841, 0x04000000, 0x00000002}, + {0x4A584241, 0x02000000, 0x00000002}, + {0x4A584342, 0x04000000, 0x00000005}, + {0x4A584359, 0x02000000, 0x00000002}, + {0x4A584441, 0x02000000, 0x00000002}, + {0x4A584442, 0x01000000, 0x00000001}, + {0x4A584541, 0x08000000, 0x00000002}, + {0x4A584559, 0x02000000, 0x00000002}, + {0x4A584641, 0x08000000, 0x00000003}, + {0x4A584642, 0x04000000, 0x00000002}, + {0x4A584743, 0x10000000, 0x00000001}, + {0x4A584759, 0x08000000, 0x00000002}, + {0x4A584842, 0x04000000, 0x00000002}, + {0x4A584941, 0x04000000, 0x00000002}, + {0x4A584959, 0x08000000, 0x00000003}, + {0x4A584A41, 0x02000000, 0x00000001}, + {0x4A584B41, 0x08000000, 0x00000002}, + {0x4A584B42, 0x04000000, 0x00000003}, + {0x4A584B59, 0x00800000, 0x00000002}, + {0x4A584C54, 0x01000000, 0x00000002}, + {0x4A584D54, 0x04000000, 0x00000003}, + {0x4A584E42, 0x04000000, 0x00000002}, + {0x4A584F42, 0x20000000, 0x00000005}, + {0x4A584F59, 0x04000000, 0x00000003}, + {0x4A585041, 0x04000000, 0x00000005}, + {0x4A585141, 0x08000000, 0x00000003}, + {0x4A585241, 0x04000000, 0x00000001}, + {0x4A585259, 0x04000000, 0x00000002}, + {0x4A585341, 0x01000000, 0x00000002}, + {0x4A585459, 0x04000000, 0x00000002}, + {0x4A585541, 0x01000000, 0x00000001}, + {0x4A585559, 0x04000000, 0x00000003}, + {0x4A585659, 0x04000000, 0x00000002}, + {0x4A585841, 0x04000000, 0x00000002}, + {0x4A585843, 0x02000000, 0x00000003}, + {0x4A585859, 0x04000000, 0x00000002}, + {0x4A585941, 0x08000000, 0x00000005}, + {0x4A585942, 0x10000000, 0x00000003}, + {0x4A585A41, 0x04000000, 0x00000002}, + {0x4A585A59, 0x04000000, 0x00000002}, + {0x4A593241, 0x01000000, 0x00000007}, + {0x4A593243, 0x08000000, 0x00000003}, + {0x4A593341, 0x04000000, 0x00000003}, + {0x4A593343, 0x08000000, 0x00000002}, + {0x4A593441, 0x00800000, 0x00000003}, + {0x4A593442, 0x00800000, 0x00000001}, + {0x4A593543, 0x08000000, 0x00000002}, + {0x4A593643, 0x04000000, 0x00000002}, + {0x4A593841, 0x00800000, 0x00000001}, + {0x4A594159, 0x02000000, 0x00000001}, + {0x4A594341, 0x01000000, 0x00000005}, + {0x4A594541, 0x04000000, 0x00000002}, + {0x4A594659, 0x04000000, 0x00000005}, + {0x4A594741, 0x04000000, 0x00000005}, + {0x4A594743, 0x04000000, 0x00000002}, + {0x4A594759, 0x00800000, 0x00000002}, + {0x4A594942, 0x04000000, 0x00000005}, + {0x4A594A41, 0x04000000, 0x00000006}, + {0x4A594B41, 0x01000000, 0x00000003}, + {0x4A594B43, 0x02000000, 0x00000003}, + {0x4A594B59, 0x02000000, 0x00000002}, + {0x4A594D41, 0x04000000, 0x00000003}, + {0x4A594D43, 0x01000000, 0x00000003}, + {0x4A594E41, 0x04000000, 0x00000003}, + {0x4A594F42, 0x04000000, 0x00000002}, + {0x4A594F59, 0x01000000, 0x00000002}, + {0x4A595041, 0x02000000, 0x00000002}, + {0x4A595056, 0x10000000, 0x00000005}, + {0x4A595141, 0x04000000, 0x00000002}, + {0x4A595159, 0x01000000, 0x00000002}, + {0x4A595242, 0x10000000, 0x00000002}, + {0x4A595259, 0x02000000, 0x00000001}, + {0x4A595341, 0x00800000, 0x00000001}, + {0x4A595541, 0x02000000, 0x00000002}, + {0x4A595542, 0x04000000, 0x00000002}, + {0x4A595543, 0x02000000, 0x00000001}, + {0x4A595641, 0x04000000, 0x00000002}, + {0x4A595659, 0x08000000, 0x00000001}, + {0x4A595741, 0x02000000, 0x00000003}, + {0x4A595742, 0x04000000, 0x00000003}, + {0x4A595841, 0x08000000, 0x00000001}, + {0x4A595843, 0x02000000, 0x00000003}, + {0x4A595942, 0x08000000, 0x00000003}, + {0x4A595959, 0x04000000, 0x00000003}, + {0x4A595A43, 0x02000000, 0x00000002}, + {0x4A5A3241, 0x02000000, 0x00000001}, + {0x4A5A3341, 0x04000000, 0x00000002}, + {0x4A5A3342, 0x02000000, 0x00000001}, + {0x4A5A3641, 0x08000000, 0x00000002}, + {0x4A5A3642, 0x04000000, 0x00000003}, + {0x4A5A3841, 0x02000000, 0x00000002}, + {0x4A5A4143, 0x04000000, 0x00000002}, + {0x4A5A4241, 0x08000000, 0x00000003}, + {0x4A5A4341, 0x01000000, 0x00000001}, + {0x4A5A4441, 0x02000000, 0x00000002}, + {0x4A5A4459, 0x01000000, 0x00000002}, + {0x4A5A4541, 0x04000000, 0x00000002}, + {0x4A5A4542, 0x20000000, 0x00000003}, + {0x4A5A4543, 0x08000000, 0x00000002}, + {0x4A5A4559, 0x04000000, 0x00000002}, + {0x4A5A4741, 0x04000000, 0x00000001}, + {0x4A5A4843, 0x04000000, 0x00000002}, + {0x4A5A4854, 0x20000000, 0x00000002}, + {0x4A5A4941, 0x00800000, 0x00000002}, + {0x4A5A4959, 0x04000000, 0x00000002}, + {0x4A5A4A41, 0x00800000, 0x00000002}, + {0x4A5A4A59, 0x02000000, 0x00000005}, + {0x4A5A4B41, 0x01000000, 0x00000002}, + {0x4A5A4B54, 0x02000000, 0x00000002}, + {0x4A5A4B59, 0x01000000, 0x00000002}, + {0x4A5A4C41, 0x02000000, 0x00000002}, + {0x4A5A4C59, 0x08000000, 0x00000002}, + {0x4A5A4D41, 0x00800000, 0x00000002}, + {0x4A5A4D43, 0x04000000, 0x00000003}, + {0x4A5A4E41, 0x01000000, 0x00000001}, + {0x4A5A4E43, 0x02000000, 0x00000002}, + {0x4A5A4E59, 0x04000000, 0x00000002}, + {0x4A5A4F41, 0x01000000, 0x00000002}, + {0x4A5A4F43, 0x08000000, 0x00000002}, + {0x4A5A5041, 0x01000000, 0x00000002}, + {0x4A5A5141, 0x02000000, 0x00000002}, + {0x4A5A5159, 0x00800000, 0x00000001}, + {0x4A5A5241, 0x04000000, 0x00000002}, + {0x4A5A5242, 0x04000000, 0x00000003}, + {0x4A5A5641, 0x01000000, 0x00000001}, + {0x4A5A5643, 0x10000000, 0x00000003}, + {0x4A5A5659, 0x00800000, 0x00000001}, + {0x4A5A5741, 0x02000000, 0x00000002}, + {0x4A5A5742, 0x04000000, 0x00000003}, + {0x4A5A5759, 0x04000000, 0x00000001}, + {0x4A5A5841, 0x08000000, 0x00000001}, + {0x4A5A5843, 0x02000000, 0x00000003}, + {0x4A5A5941, 0x02000000, 0x00000003}, + {0x4A5A5A41, 0x04000000, 0x00000005}, + {0x4A5A5A59, 0x02000000, 0x00000001}, + {0x4B324359, 0x04000000, 0x00000006}, + {0x4B324441, 0x02000000, 0x00000005}, + {0x4B325043, 0x04000000, 0x00000003}, + {0x4B325359, 0x04000000, 0x00000005}, + {0x4B325859, 0x00800000, 0x00000002}, + {0x4B334341, 0x02000000, 0x00000005}, + {0x4B334359, 0x04000000, 0x00000006}, + {0x4B334441, 0x02000000, 0x00000005}, + {0x4B334741, 0x02000000, 0x00000005}, + {0x4B334C41, 0x02000000, 0x00000001}, + {0x4B334D43, 0x08000000, 0x00000003}, + {0x4B344241, 0x04000000, 0x00000005}, + {0x4B344759, 0x10000000, 0x00000003}, + {0x4B344C43, 0x08000000, 0x00000002}, + {0x4B345043, 0x08000000, 0x00000002}, + {0x4B345759, 0x04000000, 0x00000003}, + {0x4B354459, 0x00800000, 0x00000002}, + {0x4B354759, 0x04000000, 0x00000003}, + {0x4B354B43, 0x04000000, 0x00000005}, + {0x4B355443, 0x08000000, 0x00000002}, + {0x4B363643, 0x04000000, 0x00000002}, + {0x4B364843, 0x04000000, 0x00000001}, + {0x4B364C59, 0x04000000, 0x00000001}, + {0x4B374743, 0x04000000, 0x00000002}, + {0x4B374D41, 0x02000000, 0x00000002}, + {0x4B374D59, 0x04000000, 0x00000002}, + {0x4B375241, 0x04000000, 0x00000002}, + {0x4B383443, 0x04000000, 0x00000006}, + {0x4B384659, 0x02000000, 0x00000003}, + {0x4B384759, 0x08000000, 0x00000005}, + {0x4B385741, 0x04000000, 0x00000001}, + {0x4B385943, 0x10000000, 0x00000003}, + {0x4B394559, 0x04000000, 0x00000003}, + {0x4B394643, 0x02000000, 0x00000003}, + {0x4B395259, 0x04000000, 0x00000002}, + {0x4B395343, 0x02000000, 0x00000001}, + {0x4B395759, 0x08000000, 0x00000001}, + {0x4B395941, 0x08000000, 0x00000003}, + {0x4B413242, 0x04000000, 0x00000003}, + {0x4B414156, 0x02000000, 0x00000008}, + {0x4B414441, 0x04000000, 0x00000006}, + {0x4B414641, 0x04000000, 0x00000003}, + {0x4B414642, 0x02000000, 0x00000003}, + {0x4B415041, 0x04000000, 0x00000006}, + {0x4B415249, 0x10000000, 0x00000006}, + {0x4B415941, 0x00800000, 0x00000002}, + {0x4B424B59, 0x04000000, 0x00000003}, + {0x4B425249, 0x10000000, 0x00000006}, + {0x4B425259, 0x08000000, 0x00000003}, + {0x4B433841, 0x02000000, 0x00000002}, + {0x4B434241, 0x02000000, 0x00000005}, + {0x4B434341, 0x02000000, 0x00000001}, + {0x4B434D41, 0x02000000, 0x00000005}, + {0x4B435041, 0x01000000, 0x00000001}, + {0x4B435141, 0x04000000, 0x00000002}, + {0x4B435259, 0x08000000, 0x00000002}, + {0x4B443241, 0x02000000, 0x00000002}, + {0x4B444154, 0x04000000, 0x00000005}, + {0x4B444342, 0x02000000, 0x00000002}, + {0x4B444E41, 0x01000000, 0x00000005}, + {0x4B444E43, 0x04000000, 0x00000002}, + {0x4B445041, 0x01000000, 0x00000002}, + {0x4B445059, 0x02000000, 0x00000003}, + {0x4B445249, 0x20000000, 0x00000006}, + {0x4B454641, 0x04000000, 0x00000003}, + {0x4B455249, 0x20000000, 0x00000006}, + {0x4B455741, 0x04000000, 0x00000005}, + {0x4B455A41, 0x04000000, 0x00000006}, + {0x4B463341, 0x04000000, 0x00000005}, + {0x4B463541, 0x04000000, 0x00000002}, + {0x4B464B59, 0x02000000, 0x00000001}, + {0x4B465241, 0x08000000, 0x00000003}, + {0x4B473341, 0x04000000, 0x00000005}, + {0x4B473641, 0x04000000, 0x00000002}, + {0x4B474441, 0x02000000, 0x00000005}, + {0x4B474E41, 0x08000000, 0x00000005}, + {0x4B474E59, 0x08000000, 0x00000003}, + {0x4B475049, 0x08000000, 0x00000006}, + {0x4B475059, 0x04000000, 0x00000002}, + {0x4B483643, 0x01000000, 0x00000001}, + {0x4B484759, 0x08000000, 0x00000001}, + {0x4B484D41, 0x04000000, 0x00000005}, + {0x4B484E41, 0x08000000, 0x00000006}, + {0x4B485041, 0x02000000, 0x00000005}, + {0x4B494459, 0x04000000, 0x00000002}, + {0x4B495041, 0x00800000, 0x00000002}, + {0x4B495141, 0x02000000, 0x00000005}, + {0x4B495243, 0x02000000, 0x00000002}, + {0x4B495741, 0x08000000, 0x00000005}, + {0x4B4A4241, 0x04000000, 0x00000005}, + {0x4B4A4342, 0x10000000, 0x00000003}, + {0x4B4A4C43, 0x08000000, 0x00000002}, + {0x4B4A5159, 0x08000000, 0x00000005}, + {0x4B4B4343, 0x02000000, 0x00000001}, + {0x4B4B4841, 0x04000000, 0x00000003}, + {0x4B4B5049, 0x08000000, 0x00000006}, + {0x4B4B5659, 0x08000000, 0x00000002}, + {0x4B4C4143, 0x04000000, 0x00000001}, + {0x4B4C4443, 0x02000000, 0x00000005}, + {0x4B4C4542, 0x02000000, 0x00000002}, + {0x4B4C4F43, 0x08000000, 0x00000003}, + {0x4B4C5759, 0x02000000, 0x00000001}, + {0x4B4C5A41, 0x08000000, 0x00000007}, + {0x4B4D3341, 0x08000000, 0x00000002}, + {0x4B4D4441, 0x02000000, 0x00000005}, + {0x4B4D4641, 0x04000000, 0x00000002}, + {0x4B4D4E41, 0x02000000, 0x00000005}, + {0x4B4D5241, 0x04000000, 0x00000002}, + {0x4B4D5341, 0x01000000, 0x00000001}, + {0x4B4E3442, 0x00800000, 0x00000002}, + {0x4B4E5041, 0x02000000, 0x00000001}, + {0x4B4E5943, 0x01000000, 0x00000002}, + {0x4B4F3242, 0x02000000, 0x00000005}, + {0x4B4F4359, 0x04000000, 0x00000001}, + {0x4B4F4443, 0x04000000, 0x00000005}, + {0x4B4F4559, 0x04000000, 0x00000003}, + {0x4B4F4E59, 0x08000000, 0x00000003}, + {0x4B4F5259, 0x02000000, 0x00000002}, + {0x4B504441, 0x00800000, 0x00000002}, + {0x4B504D59, 0x08000000, 0x00000005}, + {0x4B504E59, 0x04000000, 0x00000002}, + {0x4B505142, 0x04000000, 0x00000002}, + {0x4B505359, 0x02000000, 0x00000005}, + {0x4B505759, 0x04000000, 0x00000002}, + {0x4B505841, 0x02000000, 0x00000005}, + {0x4B514641, 0x04000000, 0x00000003}, + {0x4B514B42, 0x04000000, 0x00000001}, + {0x4B524559, 0x04000000, 0x00000003}, + {0x4B524E41, 0x04000000, 0x00000001}, + {0x4B524E59, 0x04000000, 0x00000002}, + {0x4B525441, 0x01000000, 0x00000002}, + {0x4B534743, 0x08000000, 0x00000001}, + {0x4B534E43, 0x04000000, 0x00000002}, + {0x4B534F41, 0x08000000, 0x00000005}, + {0x4B535043, 0x04000000, 0x00000002}, + {0x4B535143, 0x02000000, 0x00000001}, + {0x4B535659, 0x02000000, 0x00000003}, + {0x4B543841, 0x02000000, 0x00000002}, + {0x4B544659, 0x04000000, 0x00000005}, + {0x4B544C59, 0x08000000, 0x00000002}, + {0x4B545041, 0x01000000, 0x00000002}, + {0x4B545359, 0x04000000, 0x00000001}, + {0x4B545A59, 0x01000000, 0x00000005}, + {0x4B554242, 0x04000000, 0x00000003}, + {0x4B554D42, 0x02000000, 0x00000001}, + {0x4B555043, 0x08000000, 0x00000006}, + {0x4B564143, 0x02000000, 0x00000002}, + {0x4B564C59, 0x04000000, 0x00000002}, + {0x4B573443, 0x02000000, 0x00000002}, + {0x4B574441, 0x04000000, 0x00000002}, + {0x4B574459, 0x02000000, 0x00000005}, + {0x4B574B41, 0x04000000, 0x00000002}, + {0x4B574B59, 0x08000000, 0x00000003}, + {0x4B574F42, 0x04000000, 0x00000002}, + {0x4B575241, 0x01000000, 0x00000002}, + {0x4B575941, 0x02000000, 0x00000002}, + {0x4B575A41, 0x02000000, 0x00000002}, + {0x4B583241, 0x01000000, 0x00000002}, + {0x4B584241, 0x02000000, 0x00000002}, + {0x4B584559, 0x02000000, 0x00000002}, + {0x4B585541, 0x01000000, 0x00000001}, + {0x4B585942, 0x10000000, 0x00000003}, + {0x4B585A43, 0x08000000, 0x00000002}, + {0x4B593242, 0x02000000, 0x00000002}, + {0x4B593341, 0x04000000, 0x00000003}, + {0x4B593441, 0x00800000, 0x00000003}, + {0x4B594541, 0x04000000, 0x00000002}, + {0x4B594659, 0x04000000, 0x00000005}, + {0x4B595543, 0x02000000, 0x00000001}, + {0x4B595942, 0x08000000, 0x00000003}, + {0x4B5A4459, 0x00800000, 0x00000002}, + {0x4B5A4C59, 0x08000000, 0x00000002}, + {0x4B5A5242, 0x04000000, 0x00000003}, + {0x4B5A5A43, 0x10000000, 0x00000005}, + {0x4C464B59, 0x04000000, 0x00000001}, + {0x4C474D43, 0x04000000, 0x00000001}, + {0x4D374C42, 0x04000000, 0x00000001}, + {0x4D375042, 0x02000000, 0x00000001}, + {0x4D385042, 0x04000000, 0x00000001}, + {0x4D435143, 0x02000000, 0x00000001}, + {0x4D474D43, 0x04000000, 0x00000001}, + {0x4D503642, 0x02000000, 0x00000001}, + {0x4E374C42, 0x04000000, 0x00000001}, + {0x4E374E42, 0x02000000, 0x00000001}, + {0x4E375042, 0x02000000, 0x00000001}, + {0x4E385042, 0x04000000, 0x00000001}, + {0x4E435143, 0x02000000, 0x00000001}, + {0x4E454642, 0x04000000, 0x00000001}, + {0x4E503642, 0x02000000, 0x00000001}, + {0x4E573542, 0x02000000, 0x00000001}, + {0x4E584C42, 0x04000000, 0x00000008}, + {0x4E594C42, 0x04000000, 0x00000008}, + {0x4F415249, 0x10000000, 0x00000006}, + {0x4F425249, 0x10000000, 0x00000006}, + {0x4F445249, 0x20000000, 0x00000006}, + {0x4F455249, 0x20000000, 0x00000006}, + {0x50323241, 0x01000000, 0x00000002}, + {0x50323343, 0x04000000, 0x00000003}, + {0x50323542, 0x01000000, 0x00000001}, + {0x50323641, 0x04000000, 0x00000008}, + {0x50323643, 0x04000000, 0x00000001}, + {0x50323743, 0x00800000, 0x00000002}, + {0x50323842, 0x01000000, 0x00000001}, + {0x50324241, 0x02000000, 0x00000002}, + {0x50324242, 0x04000000, 0x00000002}, + {0x50324259, 0x04000000, 0x00000002}, + {0x50324341, 0x04000000, 0x00000001}, + {0x50324343, 0x01000000, 0x00000001}, + {0x50324354, 0x00800000, 0x00000001}, + {0x50324359, 0x00000000, 0x00000006}, + {0x50324441, 0x04000000, 0x00000005}, + {0x50324442, 0x01000000, 0x00000002}, + {0x50324459, 0x01000000, 0x00000003}, + {0x50324643, 0x01000000, 0x00000001}, + {0x50324741, 0x08000000, 0x00000001}, + {0x50324743, 0x02000000, 0x00000002}, + {0x50324759, 0x01000000, 0x00000001}, + {0x50324842, 0x02000000, 0x00000003}, + {0x50324854, 0x01000000, 0x00000001}, + {0x50324859, 0x02000000, 0x00000003}, + {0x50324941, 0x04000000, 0x00000002}, + {0x50324943, 0x00800000, 0x00000001}, + {0x50324959, 0x00800000, 0x00000001}, + {0x50324A41, 0x00800000, 0x00000008}, + {0x50324A42, 0x04000000, 0x00000001}, + {0x50324A43, 0x01000000, 0x00000002}, + {0x50324A56, 0x02000000, 0x00000001}, + {0x50324A59, 0x02000000, 0x00000002}, + {0x50324B43, 0x02000000, 0x00000001}, + {0x50324C41, 0x04000000, 0x00000002}, + {0x50324C59, 0x08000000, 0x00000003}, + {0x50325041, 0x02000000, 0x00000001}, + {0x50325042, 0x02000000, 0x00000001}, + {0x50325059, 0x04000000, 0x00000005}, + {0x50325141, 0x02000000, 0x00000002}, + {0x50325254, 0x02000000, 0x00000002}, + {0x50325259, 0x08000000, 0x00000003}, + {0x50325341, 0x01000000, 0x00000001}, + {0x50325359, 0x04000000, 0x00000005}, + {0x50325442, 0x04000000, 0x00000003}, + {0x50325459, 0x00800000, 0x00000001}, + {0x50325559, 0x01000000, 0x00000003}, + {0x50325642, 0x02000000, 0x00000001}, + {0x50325741, 0x02000000, 0x00000003}, + {0x50325759, 0x04000000, 0x00000005}, + {0x50325841, 0x00800000, 0x00000001}, + {0x50325842, 0x00800000, 0x00000001}, + {0x50325A43, 0x01000000, 0x00000003}, + {0x50333441, 0x01000000, 0x00000008}, + {0x50333543, 0x00800000, 0x00000001}, + {0x50333743, 0x00800000, 0x00000002}, + {0x50333842, 0x08000000, 0x00000001}, + {0x50334142, 0x04000000, 0x00000001}, + {0x50334159, 0x00800000, 0x00000001}, + {0x50334241, 0x04000000, 0x00000003}, + {0x50334242, 0x08000000, 0x00000001}, + {0x50334243, 0x02000000, 0x00000002}, + {0x50334259, 0x04000000, 0x00000005}, + {0x50334341, 0x04000000, 0x00000005}, + {0x50334342, 0x00800000, 0x00000001}, + {0x50334354, 0x04000000, 0x00000002}, + {0x50334441, 0x04000000, 0x00000005}, + {0x50334442, 0x04000000, 0x00000001}, + {0x50334444, 0x02000000, 0x00000001}, + {0x50334542, 0x04000000, 0x00000001}, + {0x50334641, 0x00800000, 0x00000001}, + {0x50334643, 0x01000000, 0x00000001}, + {0x50334659, 0x02000000, 0x00000002}, + {0x50334741, 0x04000000, 0x00000005}, + {0x50334743, 0x02000000, 0x00000002}, + {0x50334759, 0x02000000, 0x00000003}, + {0x50334841, 0x02000000, 0x00000003}, + {0x50334842, 0x02000000, 0x00000002}, + {0x50334941, 0x01000000, 0x00000002}, + {0x50334943, 0x04000000, 0x00000001}, + {0x50334959, 0x04000000, 0x00000002}, + {0x50334A43, 0x00800000, 0x00000001}, + {0x50334A54, 0x01000000, 0x00000001}, + {0x50334A56, 0x02000000, 0x00000001}, + {0x50334B41, 0x02000000, 0x00000002}, + {0x50334B59, 0x02000000, 0x00000003}, + {0x50334C41, 0x02000000, 0x00000001}, + {0x50334C43, 0x01000000, 0x00000001}, + {0x50334C59, 0x04000000, 0x00000002}, + {0x50334D43, 0x08000000, 0x00000003}, + {0x50334D54, 0x04000000, 0x00000001}, + {0x50334F41, 0x02000000, 0x00000001}, + {0x50335043, 0x08000000, 0x00000005}, + {0x50335059, 0x02000000, 0x00000008}, + {0x50335141, 0x04000000, 0x00000002}, + {0x50335154, 0x04000000, 0x00000001}, + {0x50335159, 0x04000000, 0x00000002}, + {0x50335341, 0x02000000, 0x00000001}, + {0x50335343, 0x04000000, 0x00000003}, + {0x50335359, 0x00800000, 0x00000001}, + {0x50335459, 0x04000000, 0x00000003}, + {0x50335543, 0x02000000, 0x00000001}, + {0x50335559, 0x02000000, 0x00000001}, + {0x50335741, 0x04000000, 0x00000001}, + {0x50335742, 0x08000000, 0x00000002}, + {0x50335759, 0x01000000, 0x00000001}, + {0x50335842, 0x00800000, 0x00000001}, + {0x50335941, 0x04000000, 0x00000002}, + {0x50343242, 0x00800000, 0x00000001}, + {0x50343243, 0x08000000, 0x00000003}, + {0x50343543, 0x02000000, 0x00000003}, + {0x50343559, 0x02000000, 0x00000008}, + {0x50343741, 0x04000000, 0x00000008}, + {0x50343743, 0x00800000, 0x00000002}, + {0x50344259, 0x02000000, 0x00000001}, + {0x50344341, 0x04000000, 0x00000001}, + {0x50344441, 0x02000000, 0x00000005}, + {0x50344443, 0x00800000, 0x00000001}, + {0x50344456, 0x04000000, 0x00000001}, + {0x50344643, 0x00800000, 0x00000001}, + {0x50344659, 0x08000000, 0x00000003}, + {0x50344759, 0x10000000, 0x00000003}, + {0x50344843, 0x04000000, 0x00000002}, + {0x50344943, 0x04000000, 0x00000002}, + {0x50344A42, 0x00800000, 0x00000001}, + {0x50344A43, 0x01000000, 0x00000001}, + {0x50344A56, 0x02000000, 0x00000001}, + {0x50344C41, 0x00800000, 0x00000001}, + {0x50344D41, 0x00800000, 0x00000002}, + {0x50344D42, 0x00000000, 0x00000002}, + {0x50344D43, 0x01000000, 0x00000003}, + {0x50344D56, 0x02000000, 0x00000002}, + {0x50344E41, 0x04000000, 0x00000001}, + {0x50345059, 0x04000000, 0x00000002}, + {0x50345141, 0x02000000, 0x00000001}, + {0x50345159, 0x00800000, 0x00000002}, + {0x50345242, 0x08000000, 0x00000003}, + {0x50345243, 0x04000000, 0x00000002}, + {0x50345341, 0x04000000, 0x00000003}, + {0x50345442, 0x01000000, 0x00000008}, + {0x50345443, 0x01000000, 0x00000001}, + {0x50345543, 0x02000000, 0x00000002}, + {0x50345659, 0x08000000, 0x00000003}, + {0x50345742, 0x02000000, 0x00000002}, + {0x50345759, 0x04000000, 0x00000003}, + {0x50345842, 0x00800000, 0x00000001}, + {0x50345A43, 0x04000000, 0x00000001}, + {0x50353441, 0x01000000, 0x00000008}, + {0x50353542, 0x00800000, 0x00000001}, + {0x50353643, 0x02000000, 0x00000001}, + {0x50353743, 0x00800000, 0x00000002}, + {0x50353841, 0x02000000, 0x00000008}, + {0x50353859, 0x00800000, 0x00000000}, + {0x50354142, 0x01000000, 0x00000001}, + {0x50354242, 0x00800000, 0x00000002}, + {0x50354259, 0x02000000, 0x00000002}, + {0x50354342, 0x04000000, 0x00000002}, + {0x50354359, 0x00800000, 0x00000008}, + {0x50354443, 0x02000000, 0x00000001}, + {0x50354642, 0x00800000, 0x00000002}, + {0x50354643, 0x00800000, 0x00000002}, + {0x50354741, 0x01000000, 0x00000001}, + {0x50354743, 0x04000000, 0x00000001}, + {0x50354841, 0x02000000, 0x00000002}, + {0x50354943, 0x01000000, 0x00000001}, + {0x50354A42, 0x02000000, 0x00000001}, + {0x50354A54, 0x01000000, 0x00000002}, + {0x50354A59, 0x08000000, 0x00000002}, + {0x50354B43, 0x04000000, 0x00000005}, + {0x50354C41, 0x04000000, 0x00000001}, + {0x50354D43, 0x04000000, 0x00000001}, + {0x50354F41, 0x02000000, 0x00000005}, + {0x50354F42, 0x10000000, 0x00000005}, + {0x50354F43, 0x04000000, 0x00000001}, + {0x50355043, 0x02000000, 0x00000001}, + {0x50355059, 0x01000000, 0x00000001}, + {0x50355141, 0x04000000, 0x00000001}, + {0x50355241, 0x02000000, 0x00000001}, + {0x50355242, 0x01000000, 0x00000002}, + {0x50355259, 0x02000000, 0x00000002}, + {0x50355341, 0x01000000, 0x00000001}, + {0x50355343, 0x04000000, 0x00000001}, + {0x50355359, 0x02000000, 0x00000001}, + {0x50355459, 0x00800000, 0x00000002}, + {0x50355541, 0x00800000, 0x00000001}, + {0x50355643, 0x02000000, 0x00000001}, + {0x50355659, 0x08000000, 0x00000003}, + {0x50355743, 0x00000000, 0x00000001}, + {0x50355759, 0x01000000, 0x00000001}, + {0x50355842, 0x00800000, 0x00000001}, + {0x50355941, 0x08000000, 0x00000003}, + {0x50363241, 0x01000000, 0x00000008}, + {0x50363242, 0x00800000, 0x00000002}, + {0x50363341, 0x04000000, 0x00000008}, + {0x50363442, 0x01000000, 0x00000001}, + {0x50363642, 0x01000000, 0x00000001}, + {0x50363742, 0x02000000, 0x00000001}, + {0x50363743, 0x02000000, 0x00000002}, + {0x50363842, 0x00800000, 0x00000001}, + {0x50363859, 0x00800000, 0x00000000}, + {0x50364241, 0x02000000, 0x00000001}, + {0x50364243, 0x02000000, 0x00000002}, + {0x50364254, 0x02000000, 0x00000001}, + {0x50364341, 0x01000000, 0x00000002}, + {0x50364542, 0x02000000, 0x00000002}, + {0x50364641, 0x02000000, 0x00000002}, + {0x50364642, 0x00800000, 0x00000001}, + {0x50364743, 0x08000000, 0x00000002}, + {0x50364759, 0x04000000, 0x00000002}, + {0x50364841, 0x02000000, 0x00000001}, + {0x50364843, 0x04000000, 0x00000001}, + {0x50364A56, 0x02000000, 0x00000001}, + {0x50364B41, 0x01000000, 0x00000001}, + {0x50364B59, 0x00800000, 0x00000008}, + {0x50364D41, 0x02000000, 0x00000005}, + {0x50364D43, 0x08000000, 0x00000002}, + {0x50364D54, 0x01000000, 0x00000001}, + {0x50364D59, 0x00800000, 0x00000001}, + {0x50364E41, 0x02000000, 0x00000001}, + {0x50365043, 0x00000000, 0x00000002}, + {0x50365059, 0x01000000, 0x00000001}, + {0x50365241, 0x01000000, 0x00000002}, + {0x50365242, 0x02000000, 0x00000002}, + {0x50365259, 0x02000000, 0x00000002}, + {0x50365342, 0x02000000, 0x00000001}, + {0x50365343, 0x04000000, 0x00000002}, + {0x50365359, 0x04000000, 0x00000005}, + {0x50365541, 0x00800000, 0x00000002}, + {0x50365559, 0x04000000, 0x00000002}, + {0x50365642, 0x01000000, 0x00000001}, + {0x50365643, 0x01000000, 0x00000001}, + {0x50365741, 0x00800000, 0x00000001}, + {0x50365743, 0x04000000, 0x00000002}, + {0x50365842, 0x00800000, 0x00000001}, + {0x50365941, 0x00800000, 0x00000005}, + {0x50365942, 0x01000000, 0x00000001}, + {0x50365A41, 0x01000000, 0x00000005}, + {0x50365A42, 0x04000000, 0x00000002}, + {0x50373241, 0x01000000, 0x00000008}, + {0x50373242, 0x00800000, 0x00000001}, + {0x50373243, 0x08000000, 0x00000003}, + {0x50373442, 0x01000000, 0x00000001}, + {0x50373541, 0x01000000, 0x00000008}, + {0x50373743, 0x02000000, 0x00000003}, + {0x50374143, 0x02000000, 0x00000002}, + {0x50374159, 0x02000000, 0x00000002}, + {0x50374241, 0x00800000, 0x00000001}, + {0x50374242, 0x04000000, 0x00000002}, + {0x50374243, 0x02000000, 0x00000002}, + {0x50374259, 0x04000000, 0x00000002}, + {0x50374341, 0x00800000, 0x00000002}, + {0x50374441, 0x04000000, 0x00000005}, + {0x50374443, 0x01000000, 0x00000001}, + {0x50374542, 0x04000000, 0x00000002}, + {0x50374641, 0x02000000, 0x00000002}, + {0x50374642, 0x00800000, 0x00000001}, + {0x50374659, 0x01000000, 0x00000002}, + {0x50374741, 0x04000000, 0x00000002}, + {0x50374943, 0x04000000, 0x00000002}, + {0x50374A42, 0x00800000, 0x00000001}, + {0x50374C41, 0x02000000, 0x00000001}, + {0x50374C43, 0x01000000, 0x00000002}, + {0x50374D54, 0x04000000, 0x00000002}, + {0x50374D59, 0x04000000, 0x00000002}, + {0x50374E41, 0x02000000, 0x00000002}, + {0x50374E43, 0x01000000, 0x00000002}, + {0x50375141, 0x00800000, 0x00000002}, + {0x50375143, 0x04000000, 0x00000001}, + {0x50375241, 0x08000000, 0x00000002}, + {0x50375259, 0x04000000, 0x00000002}, + {0x50375359, 0x02000000, 0x00000001}, + {0x50375443, 0x00800000, 0x00000002}, + {0x50375459, 0x04000000, 0x00000002}, + {0x50375541, 0x02000000, 0x00000002}, + {0x50375542, 0x08000000, 0x00000001}, + {0x50375643, 0x00800000, 0x00000001}, + {0x50375941, 0x08000000, 0x00000005}, + {0x50375942, 0x00800000, 0x00000001}, + {0x50375943, 0x04000000, 0x00000002}, + {0x50383242, 0x04000000, 0x00000001}, + {0x50383259, 0x02000000, 0x00000008}, + {0x50383342, 0x01000000, 0x00000001}, + {0x50383343, 0x04000000, 0x00000005}, + {0x50383541, 0x02000000, 0x00000008}, + {0x50383542, 0x01000000, 0x00000001}, + {0x50383543, 0x04000000, 0x00000001}, + {0x50383642, 0x00800000, 0x00000001}, + {0x50384149, 0x04000000, 0x00000005}, + {0x50384159, 0x01000000, 0x00000002}, + {0x50384241, 0x02000000, 0x00000001}, + {0x50384243, 0x02000000, 0x00000001}, + {0x50384359, 0x01000000, 0x00000002}, + {0x50384443, 0x02000000, 0x00000002}, + {0x50384642, 0x00800000, 0x00000001}, + {0x50384643, 0x04000000, 0x00000002}, + {0x50384659, 0x02000000, 0x00000003}, + {0x50384741, 0x04000000, 0x00000003}, + {0x50384759, 0x08000000, 0x00000005}, + {0x50384841, 0x02000000, 0x00000001}, + {0x50384843, 0x02000000, 0x00000001}, + {0x50384941, 0x02000000, 0x00000002}, + {0x50384A42, 0x04000000, 0x00000002}, + {0x50384C41, 0x04000000, 0x00000001}, + {0x50384C43, 0x04000000, 0x00000002}, + {0x50384D41, 0x01000000, 0x00000001}, + {0x50384D42, 0x04000000, 0x00000001}, + {0x50384D43, 0x02000000, 0x00000002}, + {0x50384E41, 0x00800000, 0x00000001}, + {0x50384F41, 0x04000000, 0x00000003}, + {0x50384F59, 0x08000000, 0x00000003}, + {0x50385043, 0x02000000, 0x00000002}, + {0x50385059, 0x01000000, 0x00000001}, + {0x50385141, 0x00800000, 0x00000002}, + {0x50385143, 0x01000000, 0x00000001}, + {0x50385243, 0x04000000, 0x00000002}, + {0x50385259, 0x02000000, 0x00000002}, + {0x50385342, 0x04000000, 0x00000002}, + {0x50385343, 0x04000000, 0x00000003}, + {0x50385359, 0x04000000, 0x00000001}, + {0x50385442, 0x08000000, 0x00000001}, + {0x50385459, 0x02000000, 0x00000002}, + {0x50385542, 0x04000000, 0x00000001}, + {0x50385543, 0x00800000, 0x00000001}, + {0x50385642, 0x01000000, 0x00000002}, + {0x50385643, 0x04000000, 0x00000002}, + {0x50385741, 0x04000000, 0x00000001}, + {0x50385742, 0x01000000, 0x00000001}, + {0x50385759, 0x08000000, 0x00000005}, + {0x50385859, 0x08000000, 0x00000001}, + {0x50385942, 0x00800000, 0x00000001}, + {0x50385943, 0x10000000, 0x00000003}, + {0x50385A42, 0x01000000, 0x00000001}, + {0x50393241, 0x00800000, 0x00000008}, + {0x50393343, 0x02000000, 0x00000002}, + {0x50393442, 0x04000000, 0x00000001}, + {0x50393443, 0x04000000, 0x00000005}, + {0x50393459, 0x04000000, 0x00000008}, + {0x50393642, 0x01000000, 0x00000001}, + {0x50393643, 0x04000000, 0x00000002}, + {0x50393741, 0x02000000, 0x00000008}, + {0x50393742, 0x02000000, 0x00000001}, + {0x50394159, 0x00800000, 0x00000001}, + {0x50394241, 0x01000000, 0x00000001}, + {0x50394242, 0x02000000, 0x00000001}, + {0x50394243, 0x08000000, 0x00000005}, + {0x50394259, 0x02000000, 0x00000003}, + {0x50394341, 0x04000000, 0x00000001}, + {0x50394441, 0x04000000, 0x00000003}, + {0x50394442, 0x00800000, 0x00000002}, + {0x50394542, 0x04000000, 0x00000002}, + {0x50394543, 0x01000000, 0x00000003}, + {0x50394641, 0x00800000, 0x00000001}, + {0x50394642, 0x00800000, 0x00000001}, + {0x50394643, 0x02000000, 0x00000003}, + {0x50394659, 0x02000000, 0x00000001}, + {0x50394841, 0x04000000, 0x00000005}, + {0x50394943, 0x01000000, 0x00000002}, + {0x50394A59, 0x00800000, 0x00000005}, + {0x50394B42, 0x10000000, 0x00000003}, + {0x50394C42, 0x08000000, 0x00000001}, + {0x50394D41, 0x01000000, 0x00000002}, + {0x50394D43, 0x01000000, 0x00000001}, + {0x50394D59, 0x01000000, 0x00000001}, + {0x50394E41, 0x01000000, 0x00000001}, + {0x50395042, 0x04000000, 0x00000002}, + {0x50395141, 0x04000000, 0x00000001}, + {0x50395242, 0x01000000, 0x00000001}, + {0x50395259, 0x04000000, 0x00000002}, + {0x50395341, 0x02000000, 0x00000001}, + {0x50395343, 0x00000000, 0x00000001}, + {0x50395442, 0x00800000, 0x00000001}, + {0x50395459, 0x04000000, 0x00000003}, + {0x50395542, 0x04000000, 0x00000001}, + {0x50395642, 0x01000000, 0x00000001}, + {0x50395643, 0x01000000, 0x00000001}, + {0x50395742, 0x08000000, 0x00000002}, + {0x50395759, 0x08000000, 0x00000001}, + {0x50395941, 0x08000000, 0x00000003}, + {0x50395943, 0x04000000, 0x00000001}, + {0x50413342, 0x02000000, 0x00000001}, + {0x50413459, 0x04000000, 0x00000008}, + {0x50413541, 0x04000000, 0x00000001}, + {0x50413542, 0x00800000, 0x00000001}, + {0x50413543, 0x02000000, 0x00000002}, + {0x50413641, 0x02000000, 0x00000005}, + {0x50413741, 0x02000000, 0x00000001}, + {0x50413742, 0x00800000, 0x00000001}, + {0x50413842, 0x02000000, 0x00000001}, + {0x50413859, 0x04000000, 0x00000000}, + {0x50414159, 0x04000000, 0x00000002}, + {0x50414241, 0x02000000, 0x00000001}, + {0x50414254, 0x01000000, 0x00000001}, + {0x50414259, 0x02000000, 0x00000002}, + {0x50414341, 0x00800000, 0x00000001}, + {0x50414342, 0x01000000, 0x00000002}, + {0x50414443, 0x04000000, 0x00000002}, + {0x50414541, 0x08000000, 0x00000001}, + {0x50414642, 0x00000000, 0x00000003}, + {0x50414643, 0x08000000, 0x00000002}, + {0x50414754, 0x01000000, 0x00000001}, + {0x50414759, 0x01000000, 0x00000001}, + {0x50414941, 0x04000000, 0x00000001}, + {0x50414A54, 0x00800000, 0x00000001}, + {0x50414B41, 0x08000000, 0x00000005}, + {0x50414B43, 0x04000000, 0x00000002}, + {0x50414C54, 0x00800000, 0x00000001}, + {0x50414C59, 0x00800000, 0x00000002}, + {0x50414D54, 0x00800000, 0x00000001}, + {0x50414E42, 0x02000000, 0x00000001}, + {0x50414E43, 0x02000000, 0x00000001}, + {0x50414F42, 0x04000000, 0x00000001}, + {0x50415042, 0x02000000, 0x00000002}, + {0x50415043, 0x02000000, 0x00000001}, + {0x50415054, 0x02000000, 0x00000001}, + {0x50415141, 0x02000000, 0x00000001}, + {0x50415241, 0x02000000, 0x00000001}, + {0x50415243, 0x00800000, 0x00000001}, + {0x50415254, 0x00800000, 0x00000001}, + {0x50415343, 0x01000000, 0x00000001}, + {0x50415443, 0x04000000, 0x00000001}, + {0x50415543, 0x04000000, 0x00000001}, + {0x50415641, 0x04000000, 0x00000002}, + {0x50415642, 0x00800000, 0x00000001}, + {0x50415741, 0x04000000, 0x00000002}, + {0x50415742, 0x02000000, 0x00000002}, + {0x50415743, 0x00800000, 0x00000001}, + {0x50415941, 0x02000000, 0x00000002}, + {0x50415A42, 0x08000000, 0x00000001}, + {0x50415A43, 0x02000000, 0x00000002}, + {0x50423342, 0x04000000, 0x00000001}, + {0x50423343, 0x00800000, 0x00000001}, + {0x50423442, 0x04000000, 0x00000002}, + {0x50423443, 0x02000000, 0x00000003}, + {0x50423542, 0x04000000, 0x00000002}, + {0x50423543, 0x01000000, 0x00000003}, + {0x50423641, 0x02000000, 0x00000005}, + {0x50423642, 0x04000000, 0x00000001}, + {0x50423643, 0x02000000, 0x00000002}, + {0x50423741, 0x01000000, 0x00000001}, + {0x50423841, 0x00800000, 0x00000002}, + {0x50423842, 0x01000000, 0x00000002}, + {0x50423959, 0x08000000, 0x00000000}, + {0x50424142, 0x01000000, 0x00000002}, + {0x50424243, 0x01000000, 0x00000002}, + {0x50424259, 0x02000000, 0x00000001}, + {0x50424341, 0x04000000, 0x00000003}, + {0x50424354, 0x08000000, 0x00000001}, + {0x50424441, 0x04000000, 0x00000002}, + {0x50424442, 0x04000000, 0x00000002}, + {0x50424443, 0x04000000, 0x00000001}, + {0x50424542, 0x10000000, 0x00000003}, + {0x50424641, 0x00800000, 0x00000001}, + {0x50424642, 0x01000000, 0x00000002}, + {0x50424654, 0x01000000, 0x00000001}, + {0x50424742, 0x00800000, 0x00000002}, + {0x50424841, 0x02000000, 0x00000002}, + {0x50424842, 0x00800000, 0x00000001}, + {0x50424942, 0x01000000, 0x00000003}, + {0x50424959, 0x02000000, 0x00000001}, + {0x50424A42, 0x04000000, 0x00000001}, + {0x50424A59, 0x04000000, 0x00000001}, + {0x50424B41, 0x04000000, 0x00000003}, + {0x50424C42, 0x04000000, 0x00000002}, + {0x50424C43, 0x08000000, 0x00000003}, + {0x50424E43, 0x04000000, 0x00000003}, + {0x50425054, 0x00800000, 0x00000002}, + {0x50425141, 0x02000000, 0x00000001}, + {0x50425159, 0x00800000, 0x00000001}, + {0x50425241, 0x02000000, 0x00000001}, + {0x50425341, 0x04000000, 0x00000002}, + {0x50425343, 0x01000000, 0x00000002}, + {0x50425359, 0x02000000, 0x00000002}, + {0x50425442, 0x04000000, 0x00000002}, + {0x50425543, 0x04000000, 0x00000003}, + {0x50425559, 0x04000000, 0x00000002}, + {0x50425741, 0x00800000, 0x00000001}, + {0x50425742, 0x04000000, 0x00000002}, + {0x50425743, 0x00800000, 0x00000001}, + {0x50425759, 0x02000000, 0x00000002}, + {0x50425855, 0x08000000, 0x00000008}, + {0x50425942, 0x01000000, 0x00000001}, + {0x50425943, 0x04000000, 0x00000001}, + {0x50425959, 0x08000000, 0x00000005}, + {0x50425A41, 0x00800000, 0x00000001}, + {0x50433342, 0x04000000, 0x00000002}, + {0x50433441, 0x02000000, 0x00000003}, + {0x50433459, 0x08000000, 0x00000008}, + {0x50433543, 0x01000000, 0x00000003}, + {0x50433641, 0x02000000, 0x00000005}, + {0x50433643, 0x10000000, 0x00000005}, + {0x50433741, 0x01000000, 0x00000001}, + {0x50433742, 0x00800000, 0x00000002}, + {0x50433841, 0x02000000, 0x00000002}, + {0x50433859, 0x00800000, 0x00000008}, + {0x50434241, 0x04000000, 0x00000005}, + {0x50434259, 0x02000000, 0x00000002}, + {0x50434341, 0x02000000, 0x00000001}, + {0x50434342, 0x04000000, 0x00000002}, + {0x50434354, 0x00800000, 0x00000001}, + {0x50434441, 0x02000000, 0x00000001}, + {0x50434443, 0x04000000, 0x00000003}, + {0x50434541, 0x04000000, 0x00000001}, + {0x50434543, 0x04000000, 0x00000002}, + {0x50434559, 0x02000000, 0x00000001}, + {0x50434641, 0x00800000, 0x00000001}, + {0x50434659, 0x08000000, 0x00000002}, + {0x50434741, 0x04000000, 0x00000003}, + {0x50434742, 0x00800000, 0x00000001}, + {0x50434759, 0x02000000, 0x00000002}, + {0x50434859, 0x00800000, 0x00000001}, + {0x50434941, 0x01000000, 0x00000001}, + {0x50434943, 0x04000000, 0x00000003}, + {0x50434956, 0x08000000, 0x00000002}, + {0x50434A42, 0x04000000, 0x00000002}, + {0x50434A43, 0x04000000, 0x00000002}, + {0x50434A59, 0x04000000, 0x00000002}, + {0x50434C41, 0x01000000, 0x00000008}, + {0x50434C42, 0x04000000, 0x00000002}, + {0x50434C43, 0x02000000, 0x00000001}, + {0x50434D41, 0x02000000, 0x00000005}, + {0x50434D42, 0x01000000, 0x00000001}, + {0x50434D54, 0x04000000, 0x00000003}, + {0x50435041, 0x01000000, 0x00000001}, + {0x50435043, 0x00800000, 0x00000002}, + {0x50435159, 0x01000000, 0x00000001}, + {0x50435242, 0x04000000, 0x00000003}, + {0x50435243, 0x02000000, 0x00000001}, + {0x50435254, 0x04000000, 0x00000001}, + {0x50435341, 0x04000000, 0x00000002}, + {0x50435343, 0x08000000, 0x00000001}, + {0x50435441, 0x04000000, 0x00000005}, + {0x50435442, 0x01000000, 0x00000001}, + {0x50435641, 0x04000000, 0x00000005}, + {0x50435642, 0x00800000, 0x00000001}, + {0x50435759, 0x02000000, 0x00000002}, + {0x50435842, 0x01000000, 0x00000001}, + {0x50435943, 0x02000000, 0x00000002}, + {0x50435959, 0x04000000, 0x00000001}, + {0x50443241, 0x02000000, 0x00000002}, + {0x50443242, 0x02000000, 0x00000002}, + {0x50443343, 0x01000000, 0x00000001}, + {0x50443442, 0x01000000, 0x00000001}, + {0x50443741, 0x01000000, 0x00000001}, + {0x50443841, 0x04000000, 0x00000002}, + {0x50444154, 0x08000000, 0x00000005}, + {0x50444156, 0x02000000, 0x00000001}, + {0x50444159, 0x01000000, 0x00000001}, + {0x50444343, 0x00000000, 0x00000003}, + {0x50444354, 0x02000000, 0x00000001}, + {0x50444441, 0x01000000, 0x00000001}, + {0x50444442, 0x01000000, 0x00000001}, + {0x50444454, 0x00800000, 0x00000001}, + {0x50444459, 0x01000000, 0x00000001}, + {0x50444541, 0x00800000, 0x00000001}, + {0x50444559, 0x00800000, 0x00000001}, + {0x50444641, 0x04000000, 0x00000002}, + {0x50444643, 0x08000000, 0x00000002}, + {0x50444743, 0x01000000, 0x00000001}, + {0x50444759, 0x00800000, 0x00000002}, + {0x50444841, 0x04000000, 0x00000002}, + {0x50444842, 0x04000000, 0x00000001}, + {0x50444859, 0x04000000, 0x00000001}, + {0x50444943, 0x02000000, 0x00000003}, + {0x50444A54, 0x01000000, 0x00000001}, + {0x50444A59, 0x02000000, 0x00000002}, + {0x50444B41, 0x02000000, 0x00000002}, + {0x50444C41, 0x04000000, 0x00000003}, + {0x50444C42, 0x04000000, 0x00000002}, + {0x50444C54, 0x02000000, 0x00000001}, + {0x50444C59, 0x04000000, 0x00000005}, + {0x50444D42, 0x00000000, 0x00000001}, + {0x50444D43, 0x02000000, 0x00000005}, + {0x50444D54, 0x04000000, 0x00000002}, + {0x50444E41, 0x01000000, 0x00000005}, + {0x50444E42, 0x02000000, 0x00000001}, + {0x50444E43, 0x04000000, 0x00000002}, + {0x50445041, 0x02000000, 0x00000002}, + {0x50445042, 0x04000000, 0x00000002}, + {0x50445043, 0x02000000, 0x00000001}, + {0x50445054, 0x08000000, 0x00000001}, + {0x50445059, 0x04000000, 0x00000003}, + {0x50445241, 0x02000000, 0x00000001}, + {0x50445243, 0x01000000, 0x00000001}, + {0x50445259, 0x02000000, 0x00000001}, + {0x50445341, 0x01000000, 0x00000001}, + {0x50445343, 0x02000000, 0x00000001}, + {0x50445441, 0x01000000, 0x00000002}, + {0x50445442, 0x01000000, 0x00000001}, + {0x50445443, 0x04000000, 0x00000002}, + {0x50445641, 0x01000000, 0x00000002}, + {0x50445643, 0x00800000, 0x00000001}, + {0x50445741, 0x02000000, 0x00000005}, + {0x50445743, 0x02000000, 0x00000003}, + {0x50445759, 0x01000000, 0x00000002}, + {0x50445A42, 0x08000000, 0x00000001}, + {0x50453242, 0x00800000, 0x00000001}, + {0x50453341, 0x00800000, 0x00000002}, + {0x50453442, 0x01000000, 0x00000001}, + {0x50453642, 0x02000000, 0x00000001}, + {0x50453643, 0x00800000, 0x00000002}, + {0x50453741, 0x02000000, 0x00000001}, + {0x50454156, 0x02000000, 0x00000001}, + {0x50454254, 0x04000000, 0x00000001}, + {0x50454342, 0x02000000, 0x00000002}, + {0x50454343, 0x00000000, 0x00000005}, + {0x50454359, 0x02000000, 0x00000002}, + {0x50454442, 0x04000000, 0x00000002}, + {0x50454443, 0x00800000, 0x00000001}, + {0x50454542, 0x10000000, 0x00000003}, + {0x50454559, 0x10000000, 0x00000003}, + {0x50454641, 0x04000000, 0x00000003}, + {0x50454659, 0x04000000, 0x00000005}, + {0x50454741, 0x01000000, 0x00000001}, + {0x50454742, 0x04000000, 0x00000001}, + {0x50454841, 0x08000000, 0x00000005}, + {0x50454843, 0x02000000, 0x00000002}, + {0x50454854, 0x01000000, 0x00000001}, + {0x50454A59, 0x01000000, 0x00000001}, + {0x50454B42, 0x04000000, 0x00000002}, + {0x50454C43, 0x02000000, 0x00000001}, + {0x50454C54, 0x02000000, 0x00000001}, + {0x50454C59, 0x02000000, 0x00000001}, + {0x50454D56, 0x02000000, 0x00000001}, + {0x50454F59, 0x01000000, 0x00000005}, + {0x50455141, 0x00800000, 0x00000002}, + {0x50455143, 0x04000000, 0x00000002}, + {0x50455241, 0x04000000, 0x00000001}, + {0x50455341, 0x08000000, 0x00000002}, + {0x50455443, 0x00800000, 0x00000001}, + {0x50455459, 0x02000000, 0x00000003}, + {0x50455542, 0x02000000, 0x00000001}, + {0x50455543, 0x01000000, 0x00000002}, + {0x50455641, 0x01000000, 0x00000001}, + {0x50455642, 0x00800000, 0x00000002}, + {0x50455741, 0x04000000, 0x00000005}, + {0x50455743, 0x01000000, 0x00000002}, + {0x50455842, 0x04000000, 0x00000001}, + {0x50455942, 0x02000000, 0x00000001}, + {0x50455959, 0x00000000, 0x00000002}, + {0x50455A41, 0x08000000, 0x00000006}, + {0x50463259, 0x04000000, 0x00000008}, + {0x50463342, 0x00800000, 0x00000001}, + {0x50463343, 0x00000000, 0x00000002}, + {0x50463541, 0x08000000, 0x00000002}, + {0x50463641, 0x08000000, 0x00000003}, + {0x50463642, 0x08000000, 0x00000001}, + {0x50463741, 0x02000000, 0x00000001}, + {0x50463743, 0x01000000, 0x00000003}, + {0x50464156, 0x02000000, 0x00000001}, + {0x50464159, 0x02000000, 0x00000002}, + {0x50464243, 0x00000000, 0x00000003}, + {0x50464341, 0x04000000, 0x00000002}, + {0x50464342, 0x01000000, 0x00000002}, + {0x50464343, 0x00800000, 0x00000001}, + {0x50464354, 0x04000000, 0x00000002}, + {0x50464441, 0x01000000, 0x00000001}, + {0x50464443, 0x04000000, 0x00000002}, + {0x50464542, 0x00800000, 0x00000001}, + {0x50464543, 0x01000000, 0x00000001}, + {0x50464641, 0x08000000, 0x00000003}, + {0x50464643, 0x00800000, 0x00000005}, + {0x50464741, 0x04000000, 0x00000002}, + {0x50464743, 0x00800000, 0x00000001}, + {0x50464759, 0x01000000, 0x00000001}, + {0x50464841, 0x02000000, 0x00000001}, + {0x50464843, 0x02000000, 0x00000002}, + {0x50464859, 0x00800000, 0x00000002}, + {0x50464943, 0x02000000, 0x00000001}, + {0x50464959, 0x04000000, 0x00000002}, + {0x50464A59, 0x08000000, 0x00000002}, + {0x50464B43, 0x02000000, 0x00000001}, + {0x50464B59, 0x02000000, 0x00000001}, + {0x50464C42, 0x10000000, 0x00000003}, + {0x50464C43, 0x02000000, 0x00000001}, + {0x50464C54, 0x01000000, 0x00000001}, + {0x50464C59, 0x04000000, 0x00000001}, + {0x50464D41, 0x01000000, 0x00000001}, + {0x50464D42, 0x02000000, 0x00000002}, + {0x50464D59, 0x04000000, 0x00000003}, + {0x50464E41, 0x02000000, 0x00000005}, + {0x50464F41, 0x01000000, 0x00000001}, + {0x50465042, 0x04000000, 0x00000002}, + {0x50465054, 0x02000000, 0x00000001}, + {0x50465159, 0x02000000, 0x00000002}, + {0x50465241, 0x08000000, 0x00000003}, + {0x50465242, 0x08000000, 0x00000003}, + {0x50465243, 0x02000000, 0x00000002}, + {0x50465259, 0x02000000, 0x00000002}, + {0x50465341, 0x04000000, 0x00000005}, + {0x50465342, 0x02000000, 0x00000001}, + {0x50465359, 0x04000000, 0x00000001}, + {0x50465441, 0x01000000, 0x00000001}, + {0x50465443, 0x08000000, 0x00000001}, + {0x50465541, 0x04000000, 0x00000002}, + {0x50465543, 0x01000000, 0x00000001}, + {0x50465643, 0x01000000, 0x00000001}, + {0x50465659, 0x02000000, 0x00000001}, + {0x50465743, 0x02000000, 0x00000002}, + {0x50465841, 0x08000000, 0x00000003}, + {0x50465842, 0x04000000, 0x00000001}, + {0x50465943, 0x08000000, 0x00000003}, + {0x50465956, 0x02000000, 0x00000001}, + {0x50465A42, 0x04000000, 0x00000001}, + {0x50473241, 0x02000000, 0x00000003}, + {0x50473459, 0x01000000, 0x00000008}, + {0x50473559, 0x01000000, 0x00000002}, + {0x50473642, 0x01000000, 0x00000001}, + {0x50473742, 0x00800000, 0x00000001}, + {0x50473743, 0x01000000, 0x00000001}, + {0x50473759, 0x08000000, 0x00000008}, + {0x50474142, 0x01000000, 0x00000001}, + {0x50474143, 0x02000000, 0x00000001}, + {0x50474159, 0x04000000, 0x00000001}, + {0x50474243, 0x02000000, 0x00000005}, + {0x50474254, 0x00800000, 0x00000001}, + {0x50474259, 0x00800000, 0x00000001}, + {0x50474354, 0x04000000, 0x00000001}, + {0x50474441, 0x04000000, 0x00000005}, + {0x50474443, 0x04000000, 0x00000006}, + {0x50474541, 0x04000000, 0x00000001}, + {0x50474542, 0x00800000, 0x00000001}, + {0x50474641, 0x04000000, 0x00000001}, + {0x50474659, 0x01000000, 0x00000001}, + {0x50474742, 0x02000000, 0x00000005}, + {0x50474754, 0x00800000, 0x00000001}, + {0x50474842, 0x02000000, 0x00000001}, + {0x50474942, 0x02000000, 0x00000001}, + {0x50474959, 0x02000000, 0x00000001}, + {0x50474B41, 0x02000000, 0x00000002}, + {0x50474B59, 0x10000000, 0x00000003}, + {0x50474C59, 0x04000000, 0x00000001}, + {0x50474D41, 0x01000000, 0x00000001}, + {0x50474D42, 0x02000000, 0x00000001}, + {0x50474D43, 0x04000000, 0x00000001}, + {0x50474D54, 0x04000000, 0x00000002}, + {0x50474E41, 0x08000000, 0x00000005}, + {0x50474E59, 0x08000000, 0x00000003}, + {0x50474F41, 0x00800000, 0x00000001}, + {0x50474F59, 0x08000000, 0x00000003}, + {0x50475041, 0x01000000, 0x00000001}, + {0x50475059, 0x04000000, 0x00000002}, + {0x50475241, 0x02000000, 0x00000005}, + {0x50475243, 0x01000000, 0x00000001}, + {0x50475541, 0x02000000, 0x00000002}, + {0x50475543, 0x02000000, 0x00000002}, + {0x50475842, 0x04000000, 0x00000002}, + {0x50475843, 0x00800000, 0x00000001}, + {0x50475941, 0x04000000, 0x00000002}, + {0x50475956, 0x04000000, 0x00000001}, + {0x50483241, 0x02000000, 0x00000005}, + {0x50483243, 0x02000000, 0x00000002}, + {0x50483341, 0x02000000, 0x00000001}, + {0x50483343, 0x00800000, 0x00000001}, + {0x50483442, 0x02000000, 0x00000001}, + {0x50483741, 0x02000000, 0x00000001}, + {0x50483742, 0x04000000, 0x00000002}, + {0x50483842, 0x04000000, 0x00000002}, + {0x50484159, 0x04000000, 0x00000002}, + {0x50484241, 0x08000000, 0x00000002}, + {0x50484259, 0x02000000, 0x00000002}, + {0x50484341, 0x04000000, 0x00000005}, + {0x50484342, 0x00800000, 0x00000001}, + {0x50484442, 0x02000000, 0x00000002}, + {0x50484459, 0x02000000, 0x00000005}, + {0x50484541, 0x04000000, 0x00000002}, + {0x50484542, 0x01000000, 0x00000002}, + {0x50484559, 0x04000000, 0x00000001}, + {0x50484643, 0x04000000, 0x00000003}, + {0x50484659, 0x04000000, 0x00000002}, + {0x50484742, 0x10000000, 0x00000001}, + {0x50484743, 0x02000000, 0x00000002}, + {0x50484759, 0x08000000, 0x00000001}, + {0x50484841, 0x04000000, 0x00000001}, + {0x50484842, 0x01000000, 0x00000001}, + {0x50484943, 0x04000000, 0x00000002}, + {0x50484959, 0x02000000, 0x00000002}, + {0x50484A42, 0x01000000, 0x00000001}, + {0x50484B43, 0x02000000, 0x00000002}, + {0x50484B56, 0x02000000, 0x00000002}, + {0x50484C41, 0x02000000, 0x00000001}, + {0x50484C42, 0x08000000, 0x00000001}, + {0x50484C54, 0x01000000, 0x00000001}, + {0x50484D41, 0x04000000, 0x00000005}, + {0x50484D42, 0x04000000, 0x00000001}, + {0x50484D54, 0x00800000, 0x00000001}, + {0x50484E41, 0x08000000, 0x00000006}, + {0x50484E43, 0x04000000, 0x00000002}, + {0x50485041, 0x02000000, 0x00000005}, + {0x50485043, 0x04000000, 0x00000001}, + {0x50485243, 0x02000000, 0x00000002}, + {0x50485254, 0x02000000, 0x00000001}, + {0x50485341, 0x02000000, 0x00000002}, + {0x50485441, 0x04000000, 0x00000001}, + {0x50485641, 0x04000000, 0x00000002}, + {0x50485643, 0x04000000, 0x00000002}, + {0x50485741, 0x01000000, 0x00000001}, + {0x50485759, 0x01000000, 0x00000001}, + {0x50485843, 0x02000000, 0x00000001}, + {0x50485959, 0x04000000, 0x00000001}, + {0x50485A42, 0x01000000, 0x00000001}, + {0x50485A59, 0x04000000, 0x00000001}, + {0x50493241, 0x02000000, 0x00000005}, + {0x50493242, 0x04000000, 0x00000001}, + {0x50493341, 0x08000000, 0x00000002}, + {0x50493441, 0x04000000, 0x00000001}, + {0x50493642, 0x04000000, 0x00000002}, + {0x50493741, 0x02000000, 0x00000001}, + {0x50493742, 0x02000000, 0x00000001}, + {0x50493842, 0x04000000, 0x00000001}, + {0x50494159, 0x04000000, 0x00000001}, + {0x50494341, 0x02000000, 0x00000002}, + {0x50494342, 0x02000000, 0x00000002}, + {0x50494359, 0x01000000, 0x00000001}, + {0x50494442, 0x04000000, 0x00000001}, + {0x50494443, 0x02000000, 0x00000001}, + {0x50494542, 0x01000000, 0x00000001}, + {0x50494641, 0x02000000, 0x00000002}, + {0x50494643, 0x08000000, 0x00000003}, + {0x50494659, 0x04000000, 0x00000001}, + {0x50494742, 0x04000000, 0x00000001}, + {0x50494759, 0x00800000, 0x00000002}, + {0x50494842, 0x04000000, 0x00000002}, + {0x50494959, 0x00800000, 0x00000001}, + {0x50494A43, 0x02000000, 0x00000002}, + {0x50494B42, 0x08000000, 0x00000007}, + {0x50494C43, 0x04000000, 0x00000001}, + {0x50494C56, 0x02000000, 0x00000001}, + {0x50494C59, 0x04000000, 0x00000002}, + {0x50494D43, 0x00800000, 0x00000001}, + {0x50494E41, 0x08000000, 0x00000005}, + {0x50494E42, 0x02000000, 0x00000001}, + {0x50494E43, 0x04000000, 0x00000001}, + {0x50494E59, 0x08000000, 0x00000002}, + {0x50494F42, 0x02000000, 0x00000002}, + {0x50495042, 0x00800000, 0x00000001}, + {0x50495043, 0x01000000, 0x00000002}, + {0x50495056, 0x02000000, 0x00000002}, + {0x50495059, 0x02000000, 0x00000003}, + {0x50495141, 0x02000000, 0x00000005}, + {0x50495241, 0x01000000, 0x00000001}, + {0x50495243, 0x02000000, 0x00000002}, + {0x50495259, 0x04000000, 0x00000002}, + {0x50495341, 0x02000000, 0x00000002}, + {0x50495342, 0x04000000, 0x00000001}, + {0x50495441, 0x01000000, 0x00000008}, + {0x50495442, 0x01000000, 0x00000001}, + {0x50495456, 0x02000000, 0x00000001}, + {0x50495541, 0x02000000, 0x00000001}, + {0x50495543, 0x02000000, 0x00000002}, + {0x50495559, 0x04000000, 0x00000002}, + {0x50495641, 0x04000000, 0x00000001}, + {0x50495659, 0x08000000, 0x00000003}, + {0x50495741, 0x08000000, 0x00000005}, + {0x50495742, 0x01000000, 0x00000002}, + {0x50495941, 0x01000000, 0x00000001}, + {0x50495A41, 0x00800000, 0x00000002}, + {0x504A3259, 0x04000000, 0x00000008}, + {0x504A3343, 0x10000000, 0x00000003}, + {0x504A3356, 0x04000000, 0x00000001}, + {0x504A3442, 0x00800000, 0x00000001}, + {0x504A3542, 0x01000000, 0x00000001}, + {0x504A3642, 0x00800000, 0x00000001}, + {0x504A3742, 0x01000000, 0x00000001}, + {0x504A4241, 0x04000000, 0x00000005}, + {0x504A4243, 0x08000000, 0x00000003}, + {0x504A4259, 0x00800000, 0x00000001}, + {0x504A4341, 0x04000000, 0x00000001}, + {0x504A4343, 0x04000000, 0x00000002}, + {0x504A4359, 0x02000000, 0x00000005}, + {0x504A4559, 0x01000000, 0x00000002}, + {0x504A4643, 0x02000000, 0x00000002}, + {0x504A4743, 0x02000000, 0x00000002}, + {0x504A4759, 0x02000000, 0x00000001}, + {0x504A4841, 0x01000000, 0x00000002}, + {0x504A4943, 0x00800000, 0x00000001}, + {0x504A4959, 0x00000000, 0x00000002}, + {0x504A4A43, 0x00800000, 0x00000002}, + {0x504A4B43, 0x02000000, 0x00000001}, + {0x504A4C41, 0x01000000, 0x00000001}, + {0x504A4C42, 0x04000000, 0x00000001}, + {0x504A4C43, 0x08000000, 0x00000002}, + {0x504A4C54, 0x08000000, 0x00000002}, + {0x504A4C59, 0x04000000, 0x00000001}, + {0x504A4D43, 0x01000000, 0x00000002}, + {0x504A4D59, 0x04000000, 0x00000001}, + {0x504A4E41, 0x02000000, 0x00000001}, + {0x504A4E42, 0x01000000, 0x00000001}, + {0x504A4E43, 0x02000000, 0x00000001}, + {0x504A4E59, 0x02000000, 0x00000001}, + {0x504A4F42, 0x04000000, 0x00000002}, + {0x504A5042, 0x00800000, 0x00000001}, + {0x504A5043, 0x04000000, 0x00000002}, + {0x504A5141, 0x08000000, 0x00000001}, + {0x504A5143, 0x00800000, 0x00000001}, + {0x504A5243, 0x02000000, 0x00000001}, + {0x504A5259, 0x08000000, 0x00000002}, + {0x504A5341, 0x04000000, 0x00000005}, + {0x504A5342, 0x01000000, 0x00000001}, + {0x504A5359, 0x00800000, 0x00000001}, + {0x504A5441, 0x01000000, 0x00000002}, + {0x504A5541, 0x04000000, 0x00000001}, + {0x504A5542, 0x08000000, 0x00000001}, + {0x504A5641, 0x04000000, 0x00000002}, + {0x504A5659, 0x01000000, 0x00000001}, + {0x504A5743, 0x00000000, 0x00000001}, + {0x504A5759, 0x00800000, 0x00000002}, + {0x504A5841, 0x08000000, 0x00000003}, + {0x504A5842, 0x00000000, 0x00000001}, + {0x504A5A43, 0x01000000, 0x00000001}, + {0x504B3342, 0x01000000, 0x00000001}, + {0x504B3443, 0x00800000, 0x00000001}, + {0x504B3641, 0x08000000, 0x00000003}, + {0x504B3642, 0x08000000, 0x00000003}, + {0x504B3842, 0x02000000, 0x00000002}, + {0x504B3859, 0x00800000, 0x00000008}, + {0x504B4159, 0x08000000, 0x00000002}, + {0x504B4241, 0x00800000, 0x00000001}, + {0x504B4242, 0x02000000, 0x00000002}, + {0x504B4243, 0x04000000, 0x00000002}, + {0x504B4343, 0x04000000, 0x00000001}, + {0x504B4541, 0x04000000, 0x00000002}, + {0x504B4641, 0x00800000, 0x00000001}, + {0x504B4742, 0x01000000, 0x00000001}, + {0x504B4841, 0x04000000, 0x00000003}, + {0x504B4843, 0x01000000, 0x00000001}, + {0x504B4A59, 0x08000000, 0x00000002}, + {0x504B4B41, 0x01000000, 0x00000003}, + {0x504B4C41, 0x08000000, 0x00000003}, + {0x504B4C43, 0x04000000, 0x00000001}, + {0x504B4C54, 0x10000000, 0x00000002}, + {0x504B4C59, 0x02000000, 0x00000002}, + {0x504B4E41, 0x01000000, 0x00000001}, + {0x504B4E59, 0x04000000, 0x00000002}, + {0x504B5043, 0x02000000, 0x00000008}, + {0x504B5142, 0x01000000, 0x00000001}, + {0x504B5143, 0x04000000, 0x00000001}, + {0x504B5159, 0x02000000, 0x00000001}, + {0x504B5243, 0x00000000, 0x00000001}, + {0x504B5341, 0x04000000, 0x00000002}, + {0x504B5441, 0x04000000, 0x00000002}, + {0x504B5559, 0x04000000, 0x00000001}, + {0x504B5641, 0x01000000, 0x00000001}, + {0x504B5642, 0x04000000, 0x00000002}, + {0x504B5741, 0x04000000, 0x00000003}, + {0x504B5759, 0x04000000, 0x00000002}, + {0x504B5842, 0x02000000, 0x00000001}, + {0x504B5843, 0x04000000, 0x00000001}, + {0x504B5943, 0x02000000, 0x00000002}, + {0x504B5A41, 0x00800000, 0x00000002}, + {0x504C3241, 0x01000000, 0x00000003}, + {0x504C3242, 0x02000000, 0x00000001}, + {0x504C3541, 0x08000000, 0x00000002}, + {0x504C3543, 0x02000000, 0x00000001}, + {0x504C3742, 0x00800000, 0x00000001}, + {0x504C3743, 0x08000000, 0x00000002}, + {0x504C3859, 0x08000000, 0x00000000}, + {0x504C4143, 0x04000000, 0x00000001}, + {0x504C4241, 0x08000000, 0x00000002}, + {0x504C4242, 0x02000000, 0x00000001}, + {0x504C4259, 0x00800000, 0x00000001}, + {0x504C4341, 0x08000000, 0x00000003}, + {0x504C4354, 0x02000000, 0x00000001}, + {0x504C4441, 0x04000000, 0x00000003}, + {0x504C4443, 0x02000000, 0x00000005}, + {0x504C4642, 0x04000000, 0x00000002}, + {0x504C4741, 0x02000000, 0x00000001}, + {0x504C4742, 0x01000000, 0x00000001}, + {0x504C4759, 0x04000000, 0x00000002}, + {0x504C4859, 0x08000000, 0x00000003}, + {0x504C4A41, 0x04000000, 0x00000001}, + {0x504C4A43, 0x02000000, 0x00000002}, + {0x504C4A54, 0x00800000, 0x00000001}, + {0x504C4A59, 0x01000000, 0x00000002}, + {0x504C4D41, 0x02000000, 0x00000002}, + {0x504C4E41, 0x04000000, 0x00000001}, + {0x504C4E59, 0x04000000, 0x00000001}, + {0x504C4F41, 0x00800000, 0x00000001}, + {0x504C4F43, 0x08000000, 0x00000003}, + {0x504C5041, 0x00800000, 0x00000002}, + {0x504C5042, 0x02000000, 0x00000001}, + {0x504C5043, 0x02000000, 0x00000001}, + {0x504C5054, 0x04000000, 0x00000001}, + {0x504C5059, 0x00800000, 0x00000001}, + {0x504C5141, 0x00800000, 0x00000001}, + {0x504C5159, 0x08000000, 0x00000002}, + {0x504C5243, 0x02000000, 0x00000001}, + {0x504C5259, 0x02000000, 0x00000001}, + {0x504C5342, 0x02000000, 0x00000003}, + {0x504C5441, 0x01000000, 0x00000001}, + {0x504C5443, 0x02000000, 0x00000003}, + {0x504C5459, 0x00800000, 0x00000002}, + {0x504C5643, 0x01000000, 0x00000001}, + {0x504C5741, 0x08000000, 0x00000003}, + {0x504C5742, 0x04000000, 0x00000003}, + {0x504C5759, 0x02000000, 0x00000001}, + {0x504C5841, 0x04000000, 0x00000001}, + {0x504C5843, 0x04000000, 0x00000002}, + {0x504C5941, 0x02000000, 0x00000002}, + {0x504C5943, 0x04000000, 0x00000002}, + {0x504C5956, 0x04000000, 0x00000001}, + {0x504C5A41, 0x10000000, 0x00000007}, + {0x504C5A42, 0x00800000, 0x00000002}, + {0x504C5A43, 0x02000000, 0x00000002}, + {0x504D3241, 0x00800000, 0x00000001}, + {0x504D3242, 0x08000000, 0x00000002}, + {0x504D3243, 0x02000000, 0x00000002}, + {0x504D3341, 0x08000000, 0x00000002}, + {0x504D3443, 0x04000000, 0x00000001}, + {0x504D3643, 0x04000000, 0x00000002}, + {0x504D3743, 0x00000000, 0x00000003}, + {0x504D4142, 0x02000000, 0x00000002}, + {0x504D4154, 0x02000000, 0x00000001}, + {0x504D4156, 0x02000000, 0x00000001}, + {0x504D4159, 0x00800000, 0x00000001}, + {0x504D4241, 0x00800000, 0x00000001}, + {0x504D4242, 0x00800000, 0x00000001}, + {0x504D4243, 0x02000000, 0x00000002}, + {0x504D4254, 0x04000000, 0x00000001}, + {0x504D4341, 0x01000000, 0x00000001}, + {0x504D4342, 0x04000000, 0x00000001}, + {0x504D4343, 0x04000000, 0x00000002}, + {0x504D4354, 0x04000000, 0x00000002}, + {0x504D4356, 0x04000000, 0x00000002}, + {0x504D4359, 0x02000000, 0x00000001}, + {0x504D4441, 0x04000000, 0x00000005}, + {0x504D4442, 0x04000000, 0x00000002}, + {0x504D4459, 0x02000000, 0x00000002}, + {0x504D4556, 0x04000000, 0x00000001}, + {0x504D4559, 0x04000000, 0x00000003}, + {0x504D4642, 0x02000000, 0x00000002}, + {0x504D4742, 0x04000000, 0x00000003}, + {0x504D4843, 0x04000000, 0x00000002}, + {0x504D4943, 0x00000000, 0x00000002}, + {0x504D4959, 0x04000000, 0x00000001}, + {0x504D4A54, 0x00800000, 0x00000001}, + {0x504D4C42, 0x02000000, 0x00000001}, + {0x504D4C54, 0x08000000, 0x00000001}, + {0x504D4D59, 0x02000000, 0x00000001}, + {0x504D4E41, 0x04000000, 0x00000005}, + {0x504D4E43, 0x04000000, 0x00000001}, + {0x504D4E59, 0x01000000, 0x00000002}, + {0x504D5042, 0x02000000, 0x00000001}, + {0x504D5043, 0x04000000, 0x00000002}, + {0x504D5141, 0x00800000, 0x00000001}, + {0x504D5143, 0x00000000, 0x00000001}, + {0x504D5241, 0x04000000, 0x00000002}, + {0x504D5242, 0x01000000, 0x00000002}, + {0x504D5259, 0x02000000, 0x00000003}, + {0x504D5341, 0x01000000, 0x00000002}, + {0x504D5342, 0x01000000, 0x00000002}, + {0x504D5343, 0x01000000, 0x00000003}, + {0x504D5442, 0x00800000, 0x00000002}, + {0x504D5459, 0x04000000, 0x00000002}, + {0x504D5642, 0x02000000, 0x00000001}, + {0x504D5643, 0x02000000, 0x00000002}, + {0x504D5742, 0x01000000, 0x00000001}, + {0x504D5842, 0x04000000, 0x00000002}, + {0x504D5A43, 0x02000000, 0x00000001}, + {0x504E3242, 0x02000000, 0x00000001}, + {0x504E3342, 0x02000000, 0x00000001}, + {0x504E3542, 0x01000000, 0x00000001}, + {0x504E3543, 0x01000000, 0x00000001}, + {0x504E3641, 0x08000000, 0x00000003}, + {0x504E3642, 0x00800000, 0x00000001}, + {0x504E3742, 0x08000000, 0x00000003}, + {0x504E3841, 0x02000000, 0x00000005}, + {0x504E3842, 0x01000000, 0x00000001}, + {0x504E4142, 0x01000000, 0x00000002}, + {0x504E4143, 0x02000000, 0x00000005}, + {0x504E4241, 0x08000000, 0x00000002}, + {0x504E4243, 0x02000000, 0x00000001}, + {0x504E4259, 0x04000000, 0x00000007}, + {0x504E4341, 0x01000000, 0x00000002}, + {0x504E4343, 0x00000000, 0x00000001}, + {0x504E4443, 0x08000000, 0x00000001}, + {0x504E4541, 0x04000000, 0x00000002}, + {0x504E4542, 0x00800000, 0x00000001}, + {0x504E4559, 0x00800000, 0x00000001}, + {0x504E4641, 0x02000000, 0x00000002}, + {0x504E4642, 0x00800000, 0x00000001}, + {0x504E4654, 0x04000000, 0x00000002}, + {0x504E4741, 0x02000000, 0x00000001}, + {0x504E4743, 0x04000000, 0x00000002}, + {0x504E4759, 0x04000000, 0x00000002}, + {0x504E4841, 0x02000000, 0x00000001}, + {0x504E4843, 0x02000000, 0x00000002}, + {0x504E4859, 0x00000000, 0x00000003}, + {0x504E4A41, 0x02000000, 0x00000002}, + {0x504E4A42, 0x02000000, 0x00000001}, + {0x504E4C43, 0x02000000, 0x00000002}, + {0x504E4C59, 0x08000000, 0x00000002}, + {0x504E4D54, 0x01000000, 0x00000002}, + {0x504E4D59, 0x01000000, 0x00000002}, + {0x504E4E42, 0x04000000, 0x00000002}, + {0x504E4E59, 0x08000000, 0x00000003}, + {0x504E4F41, 0x02000000, 0x00000005}, + {0x504E4F43, 0x02000000, 0x00000001}, + {0x504E4F59, 0x04000000, 0x00000003}, + {0x504E5041, 0x02000000, 0x00000001}, + {0x504E5042, 0x02000000, 0x00000002}, + {0x504E5043, 0x02000000, 0x00000008}, + {0x504E5142, 0x04000000, 0x00000001}, + {0x504E5159, 0x04000000, 0x00000002}, + {0x504E5241, 0x02000000, 0x00000001}, + {0x504E5243, 0x01000000, 0x00000001}, + {0x504E5341, 0x00800000, 0x00000002}, + {0x504E5342, 0x02000000, 0x00000001}, + {0x504E5343, 0x08000000, 0x00000003}, + {0x504E5359, 0x04000000, 0x00000002}, + {0x504E5442, 0x04000000, 0x00000002}, + {0x504E5443, 0x01000000, 0x00000002}, + {0x504E5642, 0x04000000, 0x00000001}, + {0x504E5656, 0x02000000, 0x00000002}, + {0x504E5A43, 0x04000000, 0x00000002}, + {0x504F3241, 0x04000000, 0x00000003}, + {0x504F3341, 0x01000000, 0x00000001}, + {0x504F3441, 0x02000000, 0x00000005}, + {0x504F3442, 0x00800000, 0x00000001}, + {0x504F3541, 0x01000000, 0x00000001}, + {0x504F3543, 0x01000000, 0x00000001}, + {0x504F3642, 0x02000000, 0x00000001}, + {0x504F3743, 0x04000000, 0x00000002}, + {0x504F3959, 0x00800000, 0x00000000}, + {0x504F4142, 0x04000000, 0x00000001}, + {0x504F4143, 0x02000000, 0x00000001}, + {0x504F4156, 0x04000000, 0x00000001}, + {0x504F4241, 0x02000000, 0x00000001}, + {0x504F4259, 0x08000000, 0x00000003}, + {0x504F4341, 0x04000000, 0x00000005}, + {0x504F4342, 0x01000000, 0x00000001}, + {0x504F4359, 0x04000000, 0x00000001}, + {0x504F4742, 0x00800000, 0x00000002}, + {0x504F4743, 0x01000000, 0x00000001}, + {0x504F4759, 0x02000000, 0x00000001}, + {0x504F4842, 0x04000000, 0x00000001}, + {0x504F4843, 0x02000000, 0x00000001}, + {0x504F4941, 0x08000000, 0x00000005}, + {0x504F4942, 0x02000000, 0x00000001}, + {0x504F4959, 0x00800000, 0x00000001}, + {0x504F4A42, 0x04000000, 0x00000001}, + {0x504F4A43, 0x04000000, 0x00000002}, + {0x504F4C42, 0x00800000, 0x00000001}, + {0x504F4D41, 0x04000000, 0x00000002}, + {0x504F4D59, 0x04000000, 0x00000001}, + {0x504F4E41, 0x02000000, 0x00000002}, + {0x504F4E42, 0x01000000, 0x00000001}, + {0x504F4F42, 0x00400000, 0x00000002}, + {0x504F4F43, 0x04000000, 0x00000002}, + {0x504F5043, 0x01000000, 0x00000002}, + {0x504F5059, 0x04000000, 0x00000003}, + {0x504F5143, 0x02000000, 0x00000001}, + {0x504F5159, 0x00800000, 0x00000001}, + {0x504F5259, 0x04000000, 0x00000002}, + {0x504F5342, 0x02000000, 0x00000001}, + {0x504F5343, 0x00000000, 0x00000002}, + {0x504F5359, 0x01000000, 0x00000002}, + {0x504F5541, 0x00800000, 0x00000001}, + {0x504F5741, 0x02000000, 0x00000002}, + {0x504F5743, 0x00800000, 0x00000001}, + {0x504F5759, 0x00800000, 0x00000001}, + {0x504F5841, 0x01000000, 0x00000002}, + {0x504F5843, 0x04000000, 0x00000001}, + {0x504F5A42, 0x04000000, 0x00000003}, + {0x504F5A43, 0x02000000, 0x00000001}, + {0x50503342, 0x04000000, 0x00000001}, + {0x50503343, 0x04000000, 0x00000002}, + {0x50503441, 0x02000000, 0x00000002}, + {0x50503541, 0x04000000, 0x00000001}, + {0x50503643, 0x04000000, 0x00000007}, + {0x50503659, 0x04000000, 0x00000008}, + {0x50504143, 0x02000000, 0x00000003}, + {0x50504159, 0x01000000, 0x00000001}, + {0x50504243, 0x01000000, 0x00000002}, + {0x50504259, 0x02000000, 0x00000001}, + {0x50504341, 0x01000000, 0x00000002}, + {0x50504441, 0x00800000, 0x00000002}, + {0x50504442, 0x00800000, 0x00000001}, + {0x50504443, 0x00000000, 0x00000002}, + {0x50504459, 0x02000000, 0x00000001}, + {0x50504542, 0x01000000, 0x00000002}, + {0x50504543, 0x08000000, 0x00000002}, + {0x50504741, 0x04000000, 0x00000002}, + {0x50504742, 0x04000000, 0x00000002}, + {0x50504743, 0x02000000, 0x00000001}, + {0x50504754, 0x02000000, 0x00000001}, + {0x50504841, 0x04000000, 0x00000001}, + {0x50504941, 0x00800000, 0x00000008}, + {0x50504A41, 0x00800000, 0x00000001}, + {0x50504A43, 0x04000000, 0x00000002}, + {0x50504B41, 0x01000000, 0x00000001}, + {0x50504C42, 0x04000000, 0x00000002}, + {0x50504C43, 0x04000000, 0x00000003}, + {0x50504C59, 0x00800000, 0x00000002}, + {0x50504D43, 0x04000000, 0x00000001}, + {0x50504D44, 0x10000000, 0xFFFFFFFF}, + {0x50504E41, 0x01000000, 0x00000001}, + {0x50504E42, 0x04000000, 0x00000001}, + {0x50504E43, 0x01000000, 0x00000002}, + {0x50504E59, 0x04000000, 0x00000002}, + {0x50504F43, 0x01000000, 0x00000003}, + {0x50505041, 0x01000000, 0x00000002}, + {0x50505141, 0x02000000, 0x00000002}, + {0x50505143, 0x01000000, 0x00000001}, + {0x50505241, 0x04000000, 0x00000001}, + {0x50505242, 0x08000000, 0x00000002}, + {0x50505341, 0x02000000, 0x00000003}, + {0x50505343, 0x02000000, 0x00000003}, + {0x50505359, 0x02000000, 0x00000005}, + {0x50505543, 0x00800000, 0x00000001}, + {0x50505642, 0x08000000, 0x00000006}, + {0x50505659, 0x08000000, 0x00000003}, + {0x50505741, 0x01000000, 0x00000001}, + {0x50505742, 0x00800000, 0x00000001}, + {0x50505743, 0x02000000, 0x00000002}, + {0x50505841, 0x02000000, 0x00000005}, + {0x50505843, 0x02000000, 0x00000001}, + {0x50505943, 0x04000000, 0x00000002}, + {0x50505A41, 0x01000000, 0x00000002}, + {0x50505A42, 0x01000000, 0x00000001}, + {0x50505A55, 0x08000000, 0x00000003}, + {0x50513243, 0x00800000, 0x00000001}, + {0x50513342, 0x00800000, 0x00000001}, + {0x50513543, 0x01000000, 0x00000002}, + {0x50513642, 0x00800000, 0x00000001}, + {0x50513643, 0x08000000, 0x00000001}, + {0x50513841, 0x02000000, 0x00000005}, + {0x50513842, 0x00800000, 0x00000001}, + {0x50513859, 0x00800000, 0x00000000}, + {0x50514143, 0x02000000, 0x00000002}, + {0x50514242, 0x00800000, 0x00000001}, + {0x50514243, 0x02000000, 0x00000002}, + {0x50514259, 0x02000000, 0x00000002}, + {0x50514359, 0x04000000, 0x00000002}, + {0x50514459, 0x10000000, 0x00000003}, + {0x50514559, 0x00800000, 0x00000001}, + {0x50514641, 0x04000000, 0x00000002}, + {0x50514642, 0x00800000, 0x00000001}, + {0x50514742, 0x02000000, 0x00000002}, + {0x50514743, 0x04000000, 0x00000003}, + {0x50514759, 0x04000000, 0x00000002}, + {0x50514841, 0x02000000, 0x00000001}, + {0x50514943, 0x02000000, 0x00000002}, + {0x50514A41, 0x04000000, 0x00000002}, + {0x50514A43, 0x00800000, 0x00000002}, + {0x50514A59, 0x01000000, 0x00000001}, + {0x50514B41, 0x02000000, 0x00000001}, + {0x50514B43, 0x02000000, 0x00000001}, + {0x50514C41, 0x00800000, 0x00000001}, + {0x50514C43, 0x04000000, 0x00000001}, + {0x50514D41, 0x04000000, 0x00000005}, + {0x50514D42, 0x04000000, 0x00000001}, + {0x50514D54, 0x02000000, 0x00000002}, + {0x50514E41, 0x00800000, 0x00000002}, + {0x50514E42, 0x02000000, 0x00000001}, + {0x50514F41, 0x01000000, 0x00000001}, + {0x50514F43, 0x04000000, 0x00000002}, + {0x50515043, 0x02000000, 0x00000001}, + {0x50515141, 0x02000000, 0x00000002}, + {0x50515143, 0x04000000, 0x00000001}, + {0x50515243, 0x02000000, 0x00000001}, + {0x50515259, 0x02000000, 0x00000001}, + {0x50515341, 0x01000000, 0x00000002}, + {0x50515343, 0x01000000, 0x00000001}, + {0x50515359, 0x02000000, 0x00000002}, + {0x50515442, 0x01000000, 0x00000001}, + {0x50515641, 0x02000000, 0x00000002}, + {0x50515643, 0x02000000, 0x00000002}, + {0x50515741, 0x01000000, 0x00000001}, + {0x50515743, 0x02000000, 0x00000001}, + {0x50515842, 0x04000000, 0x00000001}, + {0x50515941, 0x01000000, 0x00000002}, + {0x50515943, 0x04000000, 0x00000001}, + {0x50515A41, 0x01000000, 0x00000002}, + {0x50523341, 0x01000000, 0x00000002}, + {0x50523342, 0x08000000, 0x00000005}, + {0x50523443, 0x02000000, 0x00000001}, + {0x50523459, 0x04000000, 0x00000008}, + {0x50523542, 0x10000000, 0x00000001}, + {0x50523559, 0x04000000, 0x00000008}, + {0x50523642, 0x08000000, 0x00000002}, + {0x50523743, 0x00800000, 0x00000001}, + {0x50524241, 0x04000000, 0x00000002}, + {0x50524243, 0x01000000, 0x00000002}, + {0x50524254, 0x04000000, 0x00000001}, + {0x50524255, 0x00800000, 0x00000005}, + {0x50524259, 0x04000000, 0x00000001}, + {0x50524341, 0x02000000, 0x00000001}, + {0x50524343, 0x00800000, 0x00000002}, + {0x50524354, 0x00800000, 0x00000001}, + {0x50524441, 0x01000000, 0x00000002}, + {0x50524442, 0x04000000, 0x00000005}, + {0x50524459, 0x00800000, 0x00000001}, + {0x50524541, 0x01000000, 0x00000002}, + {0x50524543, 0x02000000, 0x00000003}, + {0x50524554, 0x00800000, 0x00000001}, + {0x50524559, 0x04000000, 0x00000003}, + {0x50524641, 0x04000000, 0x00000001}, + {0x50524659, 0x01000000, 0x00000001}, + {0x50524741, 0x02000000, 0x00000005}, + {0x50524754, 0x01000000, 0x00000001}, + {0x50524841, 0x02000000, 0x00000002}, + {0x50524942, 0x01000000, 0x00000001}, + {0x50524943, 0x04000000, 0x00000002}, + {0x50524A41, 0x08000000, 0x00000005}, + {0x50524A42, 0x01000000, 0x00000001}, + {0x50524A43, 0x08000000, 0x00000003}, + {0x50524C42, 0x10000000, 0x00000001}, + {0x50524C43, 0x04000000, 0x00000003}, + {0x50524C54, 0x08000000, 0x00000001}, + {0x50524D43, 0x02000000, 0x00000002}, + {0x50524D59, 0x01000000, 0x00000001}, + {0x50524E41, 0x04000000, 0x00000001}, + {0x50524E42, 0x04000000, 0x00000003}, + {0x50524E43, 0x04000000, 0x00000002}, + {0x50524F55, 0x08000000, 0x00000008}, + {0x50525041, 0x02000000, 0x00000002}, + {0x50525042, 0x00800000, 0x00000001}, + {0x50525054, 0x02000000, 0x00000001}, + {0x50525059, 0x02000000, 0x00000002}, + {0x50525141, 0x01000000, 0x00000002}, + {0x50525143, 0x04000000, 0x00000002}, + {0x50525159, 0x02000000, 0x00000001}, + {0x50525254, 0x01000000, 0x00000001}, + {0x50525259, 0x02000000, 0x00000002}, + {0x50525359, 0x01000000, 0x00000005}, + {0x50525441, 0x01000000, 0x00000002}, + {0x50525442, 0x02000000, 0x00000002}, + {0x50525443, 0x02000000, 0x00000003}, + {0x50525459, 0x00000000, 0x00000001}, + {0x50525741, 0x02000000, 0x00000005}, + {0x50525743, 0x02000000, 0x00000001}, + {0x50525759, 0x04000000, 0x00000001}, + {0x50525843, 0x04000000, 0x00000001}, + {0x50525941, 0x00800000, 0x00000001}, + {0x50525943, 0x02000000, 0x00000001}, + {0x50525959, 0x04000000, 0x00000001}, + {0x50525A43, 0x02000000, 0x00000001}, + {0x50533242, 0x08000000, 0x00000002}, + {0x50533243, 0x08000000, 0x00000004}, + {0x50533341, 0x02000000, 0x00000001}, + {0x50533343, 0x01000000, 0x00000002}, + {0x50533543, 0x08000000, 0x00000001}, + {0x50533641, 0x04000000, 0x00000001}, + {0x50533642, 0x04000000, 0x00000001}, + {0x50533659, 0x04000000, 0x00000008}, + {0x50533759, 0x04000000, 0x00000008}, + {0x50533841, 0x00800000, 0x00000002}, + {0x50534143, 0x02000000, 0x00000001}, + {0x50534156, 0x02000000, 0x00000001}, + {0x50534359, 0x00800000, 0x00000001}, + {0x50534443, 0x08000000, 0x00000001}, + {0x50534556, 0x04000000, 0x00000001}, + {0x50534641, 0x02000000, 0x00000002}, + {0x50534643, 0x02000000, 0x00000001}, + {0x50534743, 0x08000000, 0x00000001}, + {0x50534759, 0x04000000, 0x00000003}, + {0x50534841, 0x02000000, 0x00000002}, + {0x50534843, 0x02000000, 0x00000001}, + {0x50534859, 0x02000000, 0x00000003}, + {0x50534941, 0x01000000, 0x00000001}, + {0x50534943, 0x04000000, 0x00000001}, + {0x50534959, 0x04000000, 0x00000002}, + {0x50534A42, 0x04000000, 0x00000003}, + {0x50534A43, 0x01000000, 0x00000002}, + {0x50534A54, 0x00800000, 0x00000001}, + {0x50534C42, 0x04000000, 0x00000001}, + {0x50534C54, 0x02000000, 0x00000001}, + {0x50534D43, 0x02000000, 0x00000003}, + {0x50534D54, 0x01000000, 0x00000001}, + {0x50534E41, 0x01000000, 0x00000001}, + {0x50534F41, 0x08000000, 0x00000005}, + {0x50534F43, 0x02000000, 0x00000001}, + {0x50535042, 0x04000000, 0x00000002}, + {0x50535043, 0x04000000, 0x00000002}, + {0x50535143, 0x02000000, 0x00000001}, + {0x50535154, 0x00800000, 0x00000001}, + {0x50535159, 0x02000000, 0x00000002}, + {0x50535243, 0x00800000, 0x00000001}, + {0x50535341, 0x04000000, 0x00000002}, + {0x50535343, 0x00800000, 0x00000001}, + {0x50535459, 0x01000000, 0x00000001}, + {0x50535541, 0x04000000, 0x00000001}, + {0x50535542, 0x00800000, 0x00000002}, + {0x50535543, 0x02000000, 0x00000001}, + {0x50535559, 0x00800000, 0x00000001}, + {0x50535641, 0x02000000, 0x00000002}, + {0x50535643, 0x02000000, 0x00000001}, + {0x50535659, 0x02000000, 0x00000003}, + {0x50535741, 0x01000000, 0x00000002}, + {0x50535743, 0x00000000, 0x00000002}, + {0x50535842, 0x04000000, 0x00000003}, + {0x50535843, 0x00000000, 0x00000001}, + {0x50535941, 0x04000000, 0x00000001}, + {0x50543241, 0x02000000, 0x00000001}, + {0x50543341, 0x02000000, 0x00000002}, + {0x50543343, 0x08000000, 0x00000003}, + {0x50543442, 0x01000000, 0x00000002}, + {0x50543541, 0x04000000, 0x00000005}, + {0x50543641, 0x04000000, 0x00000001}, + {0x50543642, 0x04000000, 0x00000001}, + {0x50543643, 0x01000000, 0x00000002}, + {0x50543743, 0x01000000, 0x00000002}, + {0x50543841, 0x02000000, 0x00000002}, + {0x50544142, 0x04000000, 0x00000002}, + {0x50544143, 0x02000000, 0x00000002}, + {0x50544159, 0x01000000, 0x00000002}, + {0x50544241, 0x02000000, 0x00000001}, + {0x50544243, 0x02000000, 0x00000001}, + {0x50544254, 0x01000000, 0x00000001}, + {0x50544256, 0x02000000, 0x00000002}, + {0x50544259, 0x08000000, 0x00000003}, + {0x50544341, 0x02000000, 0x00000001}, + {0x50544459, 0x04000000, 0x00000003}, + {0x50544556, 0x08000000, 0x00000007}, + {0x50544559, 0x01000000, 0x00000001}, + {0x50544641, 0x00800000, 0x00000001}, + {0x50544642, 0x01000000, 0x00000001}, + {0x50544659, 0x08000000, 0x00000005}, + {0x50544742, 0x08000000, 0x00000002}, + {0x50544754, 0x04000000, 0x00000002}, + {0x50544759, 0x02000000, 0x00000001}, + {0x50544841, 0x01000000, 0x00000001}, + {0x50544941, 0x00800000, 0x00000001}, + {0x50544943, 0x01000000, 0x00000001}, + {0x50544A41, 0x02000000, 0x00000001}, + {0x50544A56, 0x04000000, 0x00000001}, + {0x50544B43, 0x04000000, 0x00000002}, + {0x50544C41, 0x00800000, 0x00000001}, + {0x50544C59, 0x08000000, 0x00000002}, + {0x50544D41, 0x04000000, 0x00000002}, + {0x50544D43, 0x02000000, 0x00000001}, + {0x50544D54, 0x04000000, 0x00000003}, + {0x50544D59, 0x02000000, 0x00000002}, + {0x50544F43, 0x02000000, 0x00000001}, + {0x50545041, 0x01000000, 0x00000002}, + {0x50545054, 0x08000000, 0x00000001}, + {0x50545059, 0x02000000, 0x00000005}, + {0x50545154, 0x02000000, 0x00000002}, + {0x50545259, 0x02000000, 0x00000002}, + {0x50545341, 0x02000000, 0x00000001}, + {0x50545359, 0x04000000, 0x00000001}, + {0x50545456, 0x04000000, 0x00000001}, + {0x50545541, 0x02000000, 0x00000001}, + {0x50545542, 0x02000000, 0x00000001}, + {0x50545559, 0x04000000, 0x00000002}, + {0x50545642, 0x01000000, 0x00000001}, + {0x50545643, 0x02000000, 0x00000001}, + {0x50545659, 0x02000000, 0x00000001}, + {0x50545841, 0x00800000, 0x00000001}, + {0x50545942, 0x08000000, 0x00000002}, + {0x50545959, 0x02000000, 0x00000002}, + {0x50545A41, 0x01000000, 0x00000005}, + {0x50545A59, 0x01000000, 0x00000005}, + {0x50553242, 0x02000000, 0x00000001}, + {0x50553342, 0x02000000, 0x00000002}, + {0x50553459, 0x02000000, 0x00000008}, + {0x50553541, 0x02000000, 0x00000005}, + {0x50553659, 0x01000000, 0x00000008}, + {0x50553743, 0x02000000, 0x00000001}, + {0x50553842, 0x01000000, 0x00000001}, + {0x50554159, 0x04000000, 0x00000003}, + {0x50554241, 0x04000000, 0x00000005}, + {0x50554242, 0x08000000, 0x00000003}, + {0x50554259, 0x08000000, 0x00000003}, + {0x50554359, 0x00000000, 0x00000003}, + {0x50554442, 0x02000000, 0x00000001}, + {0x50554443, 0x01000000, 0x00000003}, + {0x50554454, 0x00800000, 0x00000001}, + {0x50554641, 0x01000000, 0x00000003}, + {0x50554643, 0x02000000, 0x00000002}, + {0x50554842, 0x04000000, 0x00000001}, + {0x50554854, 0x02000000, 0x00000001}, + {0x50554859, 0x00800000, 0x00000008}, + {0x50554943, 0x04000000, 0x00000002}, + {0x50554B41, 0x04000000, 0x00000001}, + {0x50554B42, 0x08000000, 0x00000005}, + {0x50554C41, 0x02000000, 0x00000002}, + {0x50554C54, 0x04000000, 0x00000001}, + {0x50554C59, 0x08000000, 0x00000005}, + {0x50554D41, 0x00800000, 0x00000001}, + {0x50554D42, 0x04000000, 0x00000001}, + {0x50554D43, 0x01000000, 0x00000003}, + {0x50554D54, 0x04000000, 0x00000003}, + {0x50554D59, 0x04000000, 0x00000002}, + {0x50554E41, 0x01000000, 0x00000001}, + {0x50554E42, 0x01000000, 0x00000001}, + {0x50554F42, 0x02000000, 0x00000001}, + {0x50555054, 0x01000000, 0x00000001}, + {0x50555059, 0x02000000, 0x00000008}, + {0x50555154, 0x00800000, 0x00000001}, + {0x50555159, 0x08000000, 0x00000003}, + {0x50555341, 0x04000000, 0x00000003}, + {0x50555342, 0x02000000, 0x00000001}, + {0x50555343, 0x02000000, 0x00000001}, + {0x50555442, 0x04000000, 0x00000002}, + {0x50555542, 0x04000000, 0x00000001}, + {0x50555741, 0x02000000, 0x00000001}, + {0x50555743, 0x04000000, 0x00000001}, + {0x50555841, 0x02000000, 0x00000001}, + {0x50555842, 0x04000000, 0x00000001}, + {0x50555843, 0x08000000, 0x00000002}, + {0x50555942, 0x00800000, 0x00000001}, + {0x50555943, 0x01000000, 0x00000002}, + {0x50555959, 0x04000000, 0x00000001}, + {0x50555A42, 0x02000000, 0x00000002}, + {0x50563241, 0x00800000, 0x00000001}, + {0x50563342, 0x02000000, 0x00000001}, + {0x50563343, 0x01000000, 0x00000001}, + {0x50563443, 0x01000000, 0x00000001}, + {0x50563643, 0x02000000, 0x00000001}, + {0x50563743, 0x00800000, 0x00000001}, + {0x50564143, 0x02000000, 0x00000002}, + {0x50564159, 0x04000000, 0x00000002}, + {0x50564242, 0x00800000, 0x00000001}, + {0x50564243, 0x04000000, 0x00000002}, + {0x50564341, 0x04000000, 0x00000002}, + {0x50564359, 0x01000000, 0x00000003}, + {0x50564441, 0x01000000, 0x00000001}, + {0x50564442, 0x00000000, 0x00000001}, + {0x50564443, 0x01000000, 0x00000001}, + {0x50564454, 0x07FFEC70, 0x00000003}, + {0x50564641, 0x04000000, 0x00000001}, + {0x50564642, 0x00800000, 0x00000001}, + {0x50564741, 0x02000000, 0x00000002}, + {0x50564841, 0x01000000, 0x00000001}, + {0x50564842, 0x02000000, 0x00000001}, + {0x50564843, 0x02000000, 0x00000003}, + {0x50564854, 0x04000000, 0x00000001}, + {0x50564942, 0x00800000, 0x00000001}, + {0x50564959, 0x08000000, 0x00000003}, + {0x50564A56, 0x04000000, 0x00000001}, + {0x50564C41, 0x01000000, 0x00000002}, + {0x50564C43, 0x04000000, 0x00000001}, + {0x50564C54, 0x02000000, 0x00000002}, + {0x50564D41, 0x04000000, 0x00000001}, + {0x50564D42, 0x00800000, 0x00000001}, + {0x50564D43, 0x00800000, 0x00000001}, + {0x50564D54, 0x04000000, 0x00000002}, + {0x50564E42, 0x02000000, 0x00000001}, + {0x50564E43, 0x10000000, 0x00000005}, + {0x50565042, 0x00800000, 0x00000002}, + {0x50565043, 0x04000000, 0x00000002}, + {0x50565059, 0x04000000, 0x00000001}, + {0x50565141, 0x01000000, 0x00000002}, + {0x50565143, 0x04000000, 0x00000001}, + {0x50565159, 0x01000000, 0x00000001}, + {0x50565243, 0x02000000, 0x00000001}, + {0x50565259, 0x02000000, 0x00000005}, + {0x50565341, 0x00800000, 0x00000001}, + {0x50565342, 0x02000000, 0x00000001}, + {0x50565343, 0x02000000, 0x00000005}, + {0x50565441, 0x02000000, 0x00000001}, + {0x50565442, 0x02000000, 0x00000002}, + {0x50565443, 0x04000000, 0x00000003}, + {0x50565459, 0x08000000, 0x00000003}, + {0x50565542, 0x02000000, 0x00000002}, + {0x50565642, 0x01000000, 0x00000002}, + {0x50565741, 0x01000000, 0x00000001}, + {0x50565742, 0x02000000, 0x00000001}, + {0x50565756, 0x04000000, 0x00000001}, + {0x50565841, 0x04000000, 0x00000003}, + {0x50565842, 0x02000000, 0x00000001}, + {0x50565859, 0x00800000, 0x00000001}, + {0x50565A41, 0x00800000, 0x00000001}, + {0x50565A43, 0x02000000, 0x00000001}, + {0x50573259, 0x04000000, 0x00000008}, + {0x50573341, 0x04000000, 0x00000002}, + {0x50573641, 0x02000000, 0x00000002}, + {0x50573643, 0x02000000, 0x00000002}, + {0x50573742, 0x01000000, 0x00000002}, + {0x50573759, 0x01000000, 0x00000001}, + {0x50574142, 0x02000000, 0x00000001}, + {0x50574159, 0x04000000, 0x00000002}, + {0x50574259, 0x01000000, 0x00000002}, + {0x50574343, 0x02000000, 0x00000001}, + {0x50574354, 0x02000000, 0x00000001}, + {0x50574442, 0x02000000, 0x00000001}, + {0x50574443, 0x00800000, 0x00000001}, + {0x50574459, 0x02000000, 0x00000005}, + {0x50574542, 0x04000000, 0x00000002}, + {0x50574641, 0x01000000, 0x00000001}, + {0x50574741, 0x01000000, 0x00000002}, + {0x50574759, 0x00800000, 0x00000001}, + {0x50574843, 0x02000000, 0x00000002}, + {0x50574859, 0x02000000, 0x00000001}, + {0x50574942, 0x04000000, 0x00000002}, + {0x50574A43, 0x00800000, 0x00000001}, + {0x50574A59, 0x00800000, 0x00000001}, + {0x50574B41, 0x04000000, 0x00000002}, + {0x50574B42, 0x00800000, 0x00000002}, + {0x50574B59, 0x08000000, 0x00000003}, + {0x50574C41, 0x02000000, 0x00000001}, + {0x50574C43, 0x10000000, 0x00000002}, + {0x50574C54, 0x02000000, 0x00000002}, + {0x50574C59, 0x02000000, 0x00000001}, + {0x50574D41, 0x04000000, 0x00000002}, + {0x50574D43, 0x02000000, 0x00000002}, + {0x50574D49, 0x04000000, 0x00000007}, + {0x50574D54, 0x01000000, 0x00000001}, + {0x50574D59, 0x01000000, 0x00000002}, + {0x50574E41, 0x02000000, 0x00000002}, + {0x50574E42, 0x02000000, 0x00000001}, + {0x50574E59, 0x02000000, 0x00000001}, + {0x50574F41, 0x00800000, 0x00000001}, + {0x50575041, 0x02000000, 0x00000001}, + {0x50575042, 0x01000000, 0x00000001}, + {0x50575043, 0x04000000, 0x00000002}, + {0x50575054, 0x00800000, 0x00000002}, + {0x50575141, 0x01000000, 0x00000001}, + {0x50575159, 0x00800000, 0x00000001}, + {0x50575243, 0x02000000, 0x00000002}, + {0x50575254, 0x04000000, 0x00000002}, + {0x50575259, 0x02000000, 0x00000005}, + {0x50575343, 0x04000000, 0x00000001}, + {0x50575442, 0x02000000, 0x00000001}, + {0x50575443, 0x08000000, 0x00000001}, + {0x50575542, 0x02000000, 0x00000001}, + {0x50575559, 0x02000000, 0x00000002}, + {0x50575641, 0x02000000, 0x00000002}, + {0x50575643, 0x01000000, 0x00000002}, + {0x50575941, 0x02000000, 0x00000002}, + {0x50575942, 0x00800000, 0x00000001}, + {0x50575A41, 0x02000000, 0x00000002}, + {0x50583242, 0x02000000, 0x00000002}, + {0x50583341, 0x04000000, 0x00000001}, + {0x50583542, 0x02000000, 0x00000003}, + {0x50583559, 0x00800000, 0x00000008}, + {0x50583659, 0x00800000, 0x00000008}, + {0x50584142, 0x04000000, 0x00000001}, + {0x50584143, 0x02000000, 0x00000003}, + {0x50584154, 0x00800000, 0x00000001}, + {0x50584159, 0x02000000, 0x00000002}, + {0x50584241, 0x04000000, 0x00000002}, + {0x50584242, 0x00800000, 0x00000001}, + {0x50584259, 0x00800000, 0x00000001}, + {0x50584341, 0x01000000, 0x00000003}, + {0x50584343, 0x01000000, 0x00000003}, + {0x50584354, 0x00800000, 0x00000001}, + {0x50584443, 0x02000000, 0x00000001}, + {0x50584459, 0x04000000, 0x00000001}, + {0x50584559, 0x02000000, 0x00000002}, + {0x50584641, 0x08000000, 0x00000003}, + {0x50584642, 0x04000000, 0x00000002}, + {0x50584741, 0x08000000, 0x00000003}, + {0x50584742, 0x02000000, 0x00000002}, + {0x50584759, 0x08000000, 0x00000002}, + {0x50584841, 0x00800000, 0x00000001}, + {0x50584843, 0x02000000, 0x00000003}, + {0x50584859, 0x01000000, 0x00000001}, + {0x50584943, 0x00800000, 0x00000001}, + {0x50584A43, 0x01000000, 0x00000001}, + {0x50584A59, 0x00800000, 0x00000001}, + {0x50584C41, 0x02000000, 0x00000001}, + {0x50584C43, 0x02000000, 0x00000002}, + {0x50584C59, 0x00800000, 0x00000001}, + {0x50584D41, 0x02000000, 0x00000001}, + {0x50584D42, 0x02000000, 0x00000001}, + {0x50584D59, 0x00800000, 0x00000001}, + {0x50584E41, 0x02000000, 0x00000001}, + {0x50584F41, 0x02000000, 0x00000001}, + {0x50585043, 0x01000000, 0x00000005}, + {0x50585054, 0x00800000, 0x00000002}, + {0x50585059, 0x00800000, 0x00000003}, + {0x50585143, 0x04000000, 0x00000001}, + {0x50585159, 0x01000000, 0x00000001}, + {0x50585342, 0x02000000, 0x00000001}, + {0x50585359, 0x01000000, 0x00000001}, + {0x50585441, 0x01000000, 0x00000002}, + {0x50585543, 0x04000000, 0x00000001}, + {0x50585559, 0x04000000, 0x00000003}, + {0x50585641, 0x01000000, 0x00000001}, + {0x50585741, 0x01000000, 0x00000002}, + {0x50585742, 0x02000000, 0x00000001}, + {0x50585759, 0x01000000, 0x00000002}, + {0x50585859, 0x04000000, 0x00000002}, + {0x50585941, 0x08000000, 0x00000005}, + {0x50585942, 0x10000000, 0x00000003}, + {0x50585A42, 0x02000000, 0x00000001}, + {0x50585A59, 0x04000000, 0x00000002}, + {0x50593259, 0x00800000, 0x00000008}, + {0x50593341, 0x04000000, 0x00000003}, + {0x50593342, 0x02000000, 0x00000001}, + {0x50593443, 0x02000000, 0x00000001}, + {0x50593542, 0x01000000, 0x00000001}, + {0x50593641, 0x01000000, 0x00000002}, + {0x50593842, 0x02000000, 0x00000001}, + {0x50594143, 0x02000000, 0x00000001}, + {0x50594159, 0x02000000, 0x00000001}, + {0x50594242, 0x00800000, 0x00000001}, + {0x50594243, 0x02000000, 0x00000001}, + {0x50594259, 0x02000000, 0x00000001}, + {0x50594343, 0x01000000, 0x00000001}, + {0x50594359, 0x00800000, 0x00000001}, + {0x50594442, 0x04000000, 0x00000002}, + {0x50594443, 0x02000000, 0x00000002}, + {0x50594459, 0x00800000, 0x00000001}, + {0x50594542, 0x00800000, 0x00000001}, + {0x50594641, 0x04000000, 0x00000001}, + {0x50594659, 0x08000000, 0x00000005}, + {0x50594741, 0x04000000, 0x00000005}, + {0x50594742, 0x01000000, 0x00000001}, + {0x50594842, 0x02000000, 0x00000001}, + {0x50594843, 0x00000000, 0x00000001}, + {0x50594859, 0x01000000, 0x00000001}, + {0x50594943, 0x04000000, 0x00000002}, + {0x50594959, 0x01000000, 0x00000001}, + {0x50594A42, 0x04000000, 0x00000001}, + {0x50594A59, 0x00800000, 0x00000001}, + {0x50594B41, 0x02000000, 0x00000003}, + {0x50594B42, 0x02000000, 0x00000002}, + {0x50594C41, 0x04000000, 0x00000001}, + {0x50594C43, 0x02000000, 0x00000002}, + {0x50594C59, 0x02000000, 0x00000002}, + {0x50594D54, 0x00800000, 0x00000001}, + {0x50594D59, 0x08000000, 0x00000005}, + {0x50594E41, 0x04000000, 0x00000003}, + {0x50594E42, 0x04000000, 0x00000001}, + {0x50594E43, 0x08000000, 0x00000002}, + {0x50594E59, 0x00800000, 0x00000001}, + {0x50594F41, 0x02000000, 0x00000002}, + {0x50594F43, 0x00000000, 0x00000002}, + {0x50595041, 0x02000000, 0x00000002}, + {0x50595042, 0x00800000, 0x00000001}, + {0x50595056, 0x10000000, 0x00000005}, + {0x50595241, 0x02000000, 0x00000002}, + {0x50595243, 0x01000000, 0x00000001}, + {0x50595254, 0x02000000, 0x00000001}, + {0x50595342, 0x02000000, 0x00000002}, + {0x50595344, 0x02000000, 0x00000001}, + {0x50595359, 0x01000000, 0x00000001}, + {0x50595442, 0x01000000, 0x00000002}, + {0x50595443, 0x01000000, 0x00000002}, + {0x50595543, 0x02000000, 0x00000001}, + {0x50595642, 0x08000000, 0x00000001}, + {0x50595743, 0x02000000, 0x00000003}, + {0x50595842, 0x04000000, 0x00000002}, + {0x50595941, 0x01000000, 0x00000002}, + {0x50595942, 0x08000000, 0x00000003}, + {0x50595943, 0x00800000, 0x00000001}, + {0x50595A41, 0x04000000, 0x00000002}, + {0x505A3243, 0x00800000, 0x00000002}, + {0x505A3441, 0x00800000, 0x00000001}, + {0x505A3442, 0x08000000, 0x00000002}, + {0x505A3443, 0x04000000, 0x00000002}, + {0x505A3542, 0x01000000, 0x00000001}, + {0x505A3642, 0x04000000, 0x00000003}, + {0x505A3659, 0x08000000, 0x00000000}, + {0x505A3742, 0x04000000, 0x00000001}, + {0x505A3842, 0x01000000, 0x00000001}, + {0x505A4159, 0x01000000, 0x00000001}, + {0x505A4241, 0x08000000, 0x00000003}, + {0x505A4243, 0x01000000, 0x00000003}, + {0x505A4259, 0x01000000, 0x00000001}, + {0x505A4341, 0x01000000, 0x00000001}, + {0x505A4342, 0x01000000, 0x00000002}, + {0x505A4343, 0x00800000, 0x00000001}, + {0x505A4359, 0x00800000, 0x00000001}, + {0x505A4441, 0x02000000, 0x00000002}, + {0x505A4442, 0x04000000, 0x00000003}, + {0x505A4443, 0x04000000, 0x00000002}, + {0x505A4459, 0x01000000, 0x00000002}, + {0x505A4641, 0x04000000, 0x00000001}, + {0x505A4642, 0x00800000, 0x00000001}, + {0x505A4742, 0x01000000, 0x00000002}, + {0x505A4743, 0x00000000, 0x00000001}, + {0x505A4759, 0x04000000, 0x00000001}, + {0x505A4841, 0x04000000, 0x00000001}, + {0x505A4842, 0x02000000, 0x00000003}, + {0x505A4859, 0x04000000, 0x00000002}, + {0x505A4941, 0x02000000, 0x00000002}, + {0x505A4943, 0x02000000, 0x00000001}, + {0x505A4A59, 0x04000000, 0x00000005}, + {0x505A4C42, 0x02000000, 0x00000001}, + {0x505A4C43, 0x04000000, 0x00000001}, + {0x505A4C59, 0x10000000, 0x00000002}, + {0x505A4D42, 0x00800000, 0x00000002}, + {0x505A4D54, 0x01000000, 0x00000002}, + {0x505A4D56, 0x04000000, 0x00000001}, + {0x505A4E41, 0x01000000, 0x00000001}, + {0x505A4E42, 0x01000000, 0x00000001}, + {0x505A4E59, 0x04000000, 0x00000002}, + {0x505A4F41, 0x01000000, 0x00000002}, + {0x505A4F42, 0x02000000, 0x00000001}, + {0x505A4F59, 0x00000000, 0x00000002}, + {0x505A5042, 0x00000000, 0x00000001}, + {0x505A5059, 0x01000000, 0x00000001}, + {0x505A5143, 0x02000000, 0x00000001}, + {0x505A5241, 0x04000000, 0x00000002}, + {0x505A5242, 0x04000000, 0x00000003}, + {0x505A5243, 0x00800000, 0x00000002}, + {0x505A5259, 0x01000000, 0x00000002}, + {0x505A5359, 0x08000000, 0x00000001}, + {0x505A5442, 0x02000000, 0x00000001}, + {0x505A5459, 0x04000000, 0x00000001}, + {0x505A5541, 0x04000000, 0x00000005}, + {0x505A5542, 0x00800000, 0x00000002}, + {0x505A5543, 0x04000000, 0x00000001}, + {0x505A5759, 0x04000000, 0x00000001}, + {0x505A5A42, 0x01000000, 0x00000001}, + {0x51374C42, 0x04000000, 0x00000001}, + {0x51375042, 0x02000000, 0x00000001}, + {0x51375142, 0x02000000, 0x00000001}, + {0x51385042, 0x04000000, 0x00000001}, + {0x51435143, 0x02000000, 0x00000001}, + {0x51454642, 0x04000000, 0x00000001}, + {0x514C5542, 0x02000000, 0x00000001}, + {0x514F5542, 0x01000000, 0x00000001}, + {0x51503642, 0x02000000, 0x00000001}, + {0x51573542, 0x02000000, 0x00000001}, + {0x51584C42, 0x04000000, 0x00000008}, + {0x51585042, 0x04000000, 0x00000003}, + {0x51594C42, 0x04000000, 0x00000008}, + {0x52335741, 0x04000000, 0x00000001}, + {0x52464443, 0x04000000, 0x00000002}, + {0x53323643, 0x04000000, 0x00000001}, + {0x53335141, 0x04000000, 0x00000002}, + {0x53335159, 0x04000000, 0x00000002}, + {0x53344259, 0x02000000, 0x00000001}, + {0x53344C43, 0x04000000, 0x00000002}, + {0x53354841, 0x02000000, 0x00000002}, + {0x53394341, 0x04000000, 0x00000001}, + {0x53414441, 0x04000000, 0x00000006}, + {0x53415041, 0x04000000, 0x00000006}, + {0x53415249, 0x10000000, 0x00000006}, + {0x53424542, 0x10000000, 0x00000003}, + {0x53425249, 0x10000000, 0x00000006}, + {0x53434A42, 0x04000000, 0x00000002}, + {0x53434D43, 0x02000000, 0x00000002}, + {0x53435141, 0x04000000, 0x00000002}, + {0x53435259, 0x08000000, 0x00000002}, + {0x53435943, 0x02000000, 0x00000002}, + {0x53445249, 0x20000000, 0x00000006}, + {0x53445641, 0x01000000, 0x00000002}, + {0x53453231, 0x02000000, 0x00000003}, + {0x53453443, 0x04000000, 0x00000001}, + {0x53454343, 0x01000000, 0x00000005}, + {0x53454542, 0x10000000, 0x00000003}, + {0x53454559, 0x10000000, 0x00000003}, + {0x53454959, 0x02000000, 0x00000002}, + {0x53454C43, 0x04000000, 0x00000001}, + {0x53455249, 0x20000000, 0x00000006}, + {0x53464959, 0x02000000, 0x00000002}, + {0x53464B59, 0x02000000, 0x00000001}, + {0x53464C42, 0x10000000, 0x00000003}, + {0x53465359, 0x04000000, 0x00000001}, + {0x53474D41, 0x01000000, 0x00000001}, + {0x53474D43, 0x04000000, 0x00000001}, + {0x53475049, 0x08000000, 0x00000006}, + {0x534A3343, 0x10000000, 0x00000003}, + {0x534A5641, 0x04000000, 0x00000002}, + {0x534B4356, 0x08000000, 0x00000002}, + {0x534B5049, 0x08000000, 0x00000006}, + {0x534C4443, 0x02000000, 0x00000004}, + {0x534C4C43, 0x01000000, 0x00000002}, + {0x534D4359, 0x02000000, 0x00000001}, + {0x534F4359, 0x04000000, 0x00000001}, + {0x534F5342, 0x02000000, 0x00000001}, + {0x53504A59, 0x01000000, 0x00000001}, + {0x53505A55, 0x08000000, 0xFFFFFFFF}, + {0x53514142, 0x08000000, 0x00000002}, + {0x53525359, 0x01000000, 0x00000005}, + {0x53533341, 0x02000000, 0x00000001}, + {0x53534F41, 0x08000000, 0x00000005}, + {0x53535541, 0x04000000, 0x00000001}, + {0x53544C59, 0x08000000, 0x00000002}, + {0x53554259, 0x08000000, 0x00000003}, + {0x53555043, 0x08000000, 0x00000006}, + {0x53563543, 0x01000000, 0x00000001}, + {0x53564256, 0x02000000, 0x00000001}, + {0x53564E43, 0x10000000, 0x00000005}, + {0x53565841, 0x04000000, 0x00000003}, + {0x53574143, 0x04000000, 0x00000001}, + {0x53594641, 0x04000000, 0x00000001}, + {0x53594C41, 0x04000000, 0x00000001}, + {0x53595543, 0x02000000, 0x00000001}, + {0x53595A41, 0x04000000, 0x00000002}, + {0x535A4641, 0x04000000, 0x00000001}, + {0x535A5359, 0x08000000, 0x00000001}, + {0x54595056, 0x10000000, 0x00000005}, + {0x55414C59, 0x00800000, 0x00000002}, + {0x55425742, 0x04000000, 0x00000002}, + {0x55434956, 0x04000000, 0x00000002}, + {0x55435243, 0x02000000, 0x00000001}, + {0x55444E41, 0x00800000, 0x00000008}, + {0x55454342, 0x02000000, 0x00000002}, + {0x55463343, 0x02000000, 0x00000002}, + {0x554A5243, 0x02000000, 0x00000001}, + {0x55504A59, 0x01000000, 0x00000001}, + {0x55515243, 0x02000000, 0x00000001}, + {0x55524542, 0x02000000, 0x00000001}, + {0x55525342, 0x01000000, 0x00000001}, + {0x55544256, 0x02000000, 0x00000002}, + {0x55545942, 0x04000000, 0x00000002}, + {0x55573341, 0x04000000, 0x00000002}, + {0x55574C41, 0x02000000, 0x00000001}, + {0x56324356, 0x02000000, 0x00000001}, + {0x56324456, 0x04000000, 0x00000001}, + {0x56324D56, 0x04000000, 0x00000002}, + {0x56335356, 0x08000000, 0x00000005}, + {0x56335456, 0x04000000, 0x00000001}, + {0x56345456, 0x04000000, 0x00000003}, + {0x56364356, 0x02000000, 0x00000002}, + {0x56394856, 0x04000000, 0x00000002}, + {0x56395056, 0x04000000, 0x00000001}, + {0x56413956, 0x02000000, 0x00000000}, + {0x56414156, 0x02000000, 0x00000008}, + {0x56414256, 0x02000000, 0x00000001}, + {0x56414356, 0x04000000, 0x00000001}, + {0x56414C56, 0x04000000, 0x00000002}, + {0x56434156, 0x04000000, 0x00000002}, + {0x56434D56, 0x02000000, 0x00000001}, + {0x56444356, 0x04000000, 0x00000002}, + {0x56444956, 0x02000000, 0x00000002}, + {0x56455056, 0x04000000, 0x00000001}, + {0x56455456, 0x04000000, 0x00000002}, + {0x56464956, 0x02000000, 0x00000002}, + {0x56465056, 0x04000000, 0x00000001}, + {0x56473256, 0x02000000, 0x00000006}, + {0x56475256, 0x02000000, 0x00000002}, + {0x56494C56, 0x02000000, 0x00000001}, + {0x56495256, 0x02000000, 0x00000001}, + {0x564A4956, 0x08000000, 0x00000003}, + {0x564B4356, 0x08000000, 0x00000002}, + {0x564B4D56, 0x02000000, 0x00000003}, + {0x564B5355, 0x08000000, 0xFFFFFFFF}, + {0x564B5356, 0x04000000, 0x00000001}, + {0x564C4156, 0x04000000, 0x00000002}, + {0x564C4256, 0x02000000, 0x00000002}, + {0x564C4556, 0x02000000, 0x00000003}, + {0x564D4356, 0x04000000, 0x00000002}, + {0x564E5356, 0x04000000, 0x00000002}, + {0x564F4156, 0x04000000, 0x00000001}, + {0x564F5356, 0x04000000, 0x00000003}, + {0x56505056, 0x02000000, 0x00000001}, + {0x56505256, 0x02000000, 0x00000001}, + {0x56505456, 0x08000000, 0x00000002}, + {0x56524756, 0x04000000, 0x00000001}, + {0x56534256, 0x02000000, 0x00000001}, + {0x56534556, 0x04000000, 0x00000001}, + {0x56534656, 0x08000000, 0x00000003}, + {0x56534844, 0x02000000, 0xFFFFFFFF}, + {0x56544156, 0x02000000, 0x00000001}, + {0x56554B56, 0x04000000, 0x00000001}, + {0x56555A56, 0x02000000, 0x00000002}, + {0x56564156, 0x04000000, 0x00000001}, + {0x56564256, 0x02000000, 0x00000001}, + {0x56564A56, 0x04000000, 0x00000001}, + {0x56565056, 0x04000000, 0x00000002}, + {0x56565756, 0x04000000, 0x00000001}, + {0x56574356, 0x02000000, 0x00000002}, + {0x56574856, 0x04000000, 0x00000002}, + {0x56574A56, 0x02000000, 0x00000003}, + {0x56594D56, 0x04000000, 0x00000001}, + {0x565A4656, 0x02000000, 0x00000001}, + {0x565A4D56, 0x04000000, 0x00000001}, + {0x57325141, 0x02000000, 0x00000002}, + {0x57334941, 0x01000000, 0x00000002}, + {0x57414356, 0x04000000, 0x00000001}, + {0x57414E43, 0x04000000, 0x00000001}, + {0x57445759, 0x01000000, 0x00000002}, + {0x57474C43, 0x04000000, 0x00000001}, + {0x574C5759, 0x02000000, 0x00000001}, + {0x57565141, 0x01000000, 0x00000002}, + {0x575A5242, 0x04000000, 0x00000003}, + {0x58324354, 0x00800000, 0x00000001}, + {0x58324842, 0x02000000, 0x00000003}, + {0x58324859, 0x02000000, 0x00000003}, + {0x58324B41, 0x04000000, 0x00000001}, + {0x58324D56, 0x04000000, 0x00000002}, + {0x58325141, 0x02000000, 0x00000002}, + {0x58325241, 0x02000000, 0x00000003}, + {0x58325341, 0x01000000, 0x00000001}, + {0x58334242, 0x00000000, 0x00000001}, + {0x58334542, 0x04000000, 0x00000001}, + {0x58334759, 0x02000000, 0x00000003}, + {0x58334841, 0x04000000, 0x00000003}, + {0x58334941, 0x01000000, 0x00000002}, + {0x58334943, 0x04000000, 0x00000001}, + {0x58334C41, 0x02000000, 0x00000001}, + {0x58335456, 0x04000000, 0x00000001}, + {0x58343242, 0x00800000, 0x00000001}, + {0x58344A43, 0x01000000, 0x00000001}, + {0x58345442, 0x01000000, 0x00000008}, + {0x58345741, 0x02000000, 0x00000002}, + {0x58354259, 0x02000000, 0x00000002}, + {0x58354A42, 0x02000000, 0x00000001}, + {0x58354D54, 0x04000000, 0x00000003}, + {0x58355059, 0x10000000, 0x00000001}, + {0x58355142, 0x04000000, 0x00000001}, + {0x58355243, 0x10000000, 0x00000001}, + {0x58355259, 0x02000000, 0x00000002}, + {0x58355343, 0x04000000, 0x00000001}, + {0x58363559, 0x04000000, 0x00000008}, + {0x58364254, 0x02000000, 0x00000001}, + {0x58364341, 0x01000000, 0x00000002}, + {0x58365259, 0x00000000, 0x00000002}, + {0x58374943, 0x04000000, 0x00000002}, + {0x58374A42, 0x00800000, 0x00000001}, + {0x58374C42, 0x04000000, 0x00000001}, + {0x58375042, 0x02000000, 0x00000001}, + {0x58384442, 0x04000000, 0x00000001}, + {0x58384843, 0x02000000, 0x00000001}, + {0x58384D41, 0x01000000, 0x00000001}, + {0x58385741, 0x04000000, 0x00000001}, + {0x58385742, 0x01000000, 0x00000001}, + {0x58385859, 0x08000000, 0x00000001}, + {0x58394259, 0x02000000, 0x00000003}, + {0x58394943, 0x01000000, 0x00000002}, + {0x58394D59, 0x01000000, 0x00000001}, + {0x58395056, 0x04000000, 0x00000001}, + {0x58395141, 0x04000000, 0x00000001}, + {0x58395341, 0x02000000, 0x00000001}, + {0x58395759, 0x08000000, 0x00000001}, + {0x58413541, 0x04000000, 0x00000001}, + {0x58414243, 0x02000000, 0x00000001}, + {0x58414356, 0x04000000, 0x00000001}, + {0x58414643, 0x08000000, 0x00000002}, + {0x58414E43, 0x04000000, 0x00000001}, + {0x58415141, 0x02000000, 0x00000001}, + {0x58415243, 0x00800000, 0x00000001}, + {0x58415359, 0x01000000, 0x00000002}, + {0x58415459, 0x04000000, 0x00000001}, + {0x58415A43, 0x02000000, 0x00000002}, + {0x58423242, 0x08000000, 0x00000002}, + {0x58423542, 0x08000000, 0x00000002}, + {0x58424254, 0x02000000, 0x00000001}, + {0x58424654, 0x01000000, 0x00000001}, + {0x58424743, 0x02000000, 0x00000001}, + {0x58424A43, 0x01000000, 0x00000001}, + {0x58424B43, 0x02000000, 0x00000002}, + {0x58425342, 0x04000000, 0x00000003}, + {0x58425442, 0x04000000, 0x00000002}, + {0x58425742, 0x04000000, 0x00000002}, + {0x58433342, 0x04000000, 0x00000002}, + {0x58433441, 0x02000000, 0x00000003}, + {0x58434341, 0x02000000, 0x00000001}, + {0x58434542, 0x01000000, 0x00000003}, + {0x58434642, 0x02000000, 0x00000001}, + {0x58434741, 0x04000000, 0x00000003}, + {0x58434941, 0x01000000, 0x00000001}, + {0x58435043, 0x01000000, 0x00000002}, + {0x58435143, 0x02000000, 0x00000001}, + {0x58435359, 0x02000000, 0x00000001}, + {0x58435842, 0x01000000, 0x00000001}, + {0x58443743, 0x04000000, 0x00000001}, + {0x58444359, 0x01000000, 0x00000001}, + {0x58444642, 0x00000000, 0x00000001}, + {0x58444842, 0x04000000, 0x00000001}, + {0x58444A54, 0x01000000, 0x00000001}, + {0x58444B42, 0x00800000, 0x00000001}, + {0x58445054, 0x08000000, 0x00000001}, + {0x58445759, 0x01000000, 0x00000002}, + {0x58453242, 0x00800000, 0x00000001}, + {0x58453442, 0x01000000, 0x00000001}, + {0x58454543, 0x00800000, 0x00000001}, + {0x58454C43, 0x04000000, 0x00000001}, + {0x58455056, 0x04000000, 0x00000001}, + {0x58455141, 0x00800000, 0x00000002}, + {0x58455143, 0x04000000, 0x00000002}, + {0x58455456, 0x04000000, 0x00000002}, + {0x58455542, 0x02000000, 0x00000001}, + {0x58463642, 0x08000000, 0x00000001}, + {0x58464143, 0x01000000, 0x00000001}, + {0x58464243, 0x08000000, 0x00000003}, + {0x58464541, 0x00800000, 0x00000001}, + {0x58464A42, 0x08000000, 0x00000003}, + {0x58465956, 0x02000000, 0x00000001}, + {0x58465A42, 0x04000000, 0x00000001}, + {0x58473241, 0x02000000, 0x00000003}, + {0x58474142, 0x01000000, 0x00000001}, + {0x58474143, 0x02000000, 0x00000001}, + {0x58474342, 0x04000000, 0x00000002}, + {0x58474354, 0x04000000, 0x00000001}, + {0x58474542, 0x00800000, 0x00000001}, + {0x58475742, 0x04000000, 0x00000001}, + {0x58475956, 0x04000000, 0x00000001}, + {0x58483343, 0x00800000, 0x00000001}, + {0x58483842, 0x04000000, 0x00000002}, + {0x58484759, 0x08000000, 0x00000001}, + {0x58484A42, 0x01000000, 0x00000001}, + {0x58484C41, 0x02000000, 0x00000001}, + {0x58485243, 0x00000000, 0x00000002}, + {0x58485254, 0x02000000, 0x00000001}, + {0x58485641, 0x04000000, 0x00000002}, + {0x58485A59, 0x04000000, 0x00000001}, + {0x58493642, 0x04000000, 0x00000002}, + {0x58494442, 0x04000000, 0x00000001}, + {0x58494641, 0x02000000, 0x00000002}, + {0x58494942, 0x00800000, 0x00000001}, + {0x58494C43, 0x04000000, 0x00000001}, + {0x58495259, 0x04000000, 0x00000002}, + {0x58495442, 0x01000000, 0x00000001}, + {0x584A4841, 0x01000000, 0x00000002}, + {0x584A4D54, 0x02000000, 0x00000001}, + {0x584A5143, 0x00800000, 0x00000001}, + {0x584B3443, 0x00800000, 0x00000001}, + {0x584B3842, 0x02000000, 0x00000002}, + {0x584B4143, 0x04000000, 0x00000002}, + {0x584B4243, 0x04000000, 0x00000002}, + {0x584B4541, 0x04000000, 0x00000002}, + {0x584B4642, 0x04000000, 0x00000001}, + {0x584B4B41, 0x02000000, 0x00000003}, + {0x584B4C42, 0x04000000, 0x00000001}, + {0x584B5356, 0x04000000, 0x00000001}, + {0x584B5559, 0x04000000, 0x00000001}, + {0x584C4643, 0x02000000, 0x00000002}, + {0x584C4A59, 0x01000000, 0x00000002}, + {0x584C4E59, 0x04000000, 0x00000001}, + {0x584C5059, 0x00800000, 0x00000001}, + {0x584C5242, 0x02000000, 0x00000001}, + {0x584C5342, 0x02000000, 0x00000003}, + {0x584C5543, 0x04000000, 0x00000001}, + {0x584C5759, 0x02000000, 0x00000001}, + {0x584C5941, 0x02000000, 0x00000002}, + {0x584C5959, 0x04000000, 0x00000002}, + {0x584D3243, 0x02000000, 0x00000002}, + {0x584D3442, 0x02000000, 0x00000001}, + {0x584D4359, 0x02000000, 0x00000001}, + {0x584D4842, 0x02000000, 0x00000001}, + {0x584D4A54, 0x00800000, 0x00000001}, + {0x584D4C42, 0x01000000, 0x00000001}, + {0x584D4E42, 0x04000000, 0x00000001}, + {0x584D5642, 0x02000000, 0x00000001}, + {0x584D5842, 0x04000000, 0x00000002}, + {0x584E3743, 0x04000000, 0x00000001}, + {0x584E4354, 0x01000000, 0x00000001}, + {0x584E4559, 0x00800000, 0x00000001}, + {0x584E4641, 0x02000000, 0x00000002}, + {0x584E5159, 0x04000000, 0x00000002}, + {0x584F3543, 0x01000000, 0x00000001}, + {0x584F3642, 0x02000000, 0x00000001}, + {0x584F3743, 0x04000000, 0x00000002}, + {0x584F4142, 0x04000000, 0x00000001}, + {0x584F4156, 0x04000000, 0x00000001}, + {0x584F4442, 0x01000000, 0x00000001}, + {0x584F4D59, 0x04000000, 0x00000001}, + {0x584F5542, 0x02000000, 0x00000001}, + {0x584F5741, 0x02000000, 0x00000002}, + {0x584F5841, 0x01000000, 0x00000002}, + {0x584F5843, 0x04000000, 0x00000001}, + {0x58503541, 0x04000000, 0x00000001}, + {0x58504259, 0x02000000, 0x00000001}, + {0x58504342, 0x04000000, 0x00000002}, + {0x58504442, 0x02000000, 0x00000001}, + {0x58504B59, 0x01000000, 0x00000001}, + {0x58504F43, 0x01000000, 0x00000003}, + {0x58505343, 0x02000000, 0x00000003}, + {0x58513543, 0x01000000, 0x00000002}, + {0x58513643, 0x08000000, 0x00000001}, + {0x58514559, 0x01000000, 0x00000001}, + {0x58514A59, 0x01000000, 0x00000001}, + {0x58514C42, 0x02000000, 0x00000001}, + {0x58514D43, 0x02000000, 0x00000001}, + {0x58514D59, 0x02000000, 0x00000001}, + {0x58515459, 0x01000000, 0x00000001}, + {0x58523559, 0x04000000, 0x00000008}, + {0x58523743, 0x00800000, 0x00000001}, + {0x58524354, 0x00800000, 0x00000001}, + {0x58524459, 0x01000000, 0x00000001}, + {0x58524842, 0x02000000, 0x00000001}, + {0x58524943, 0x04000000, 0x00000002}, + {0x58524A42, 0x01000000, 0x00000001}, + {0x58524C54, 0x08000000, 0x00000001}, + {0x58524D42, 0x02000000, 0x00000001}, + {0x58525042, 0x00800000, 0x00000001}, + {0x58525141, 0x01000000, 0x00000002}, + {0x58525642, 0x04000000, 0x00000001}, + {0x58525843, 0x04000000, 0x00000001}, + {0x58533841, 0x00800000, 0x00000002}, + {0x58534342, 0x04000000, 0x00000002}, + {0x58534556, 0x04000000, 0x00000001}, + {0x58534642, 0x04000000, 0x00000001}, + {0x58534643, 0x02000000, 0x00000001}, + {0x58534743, 0x08000000, 0x00000001}, + {0x58534A54, 0x00800000, 0x00000001}, + {0x58534E43, 0x04000000, 0x00000002}, + {0x58535143, 0x02000000, 0x00000001}, + {0x58543341, 0x02000000, 0x00000002}, + {0x58543642, 0x04000000, 0x00000001}, + {0x58543743, 0x01000000, 0x00000002}, + {0x58544256, 0x02000000, 0x00000002}, + {0x58544D59, 0x02000000, 0x00000002}, + {0x58545054, 0x08000000, 0x00000001}, + {0x58545259, 0x02000000, 0x00000002}, + {0x58545A41, 0x01000000, 0x00000005}, + {0x58554159, 0x04000000, 0x00000003}, + {0x58554242, 0x04000000, 0x00000003}, + {0x58554341, 0x08000000, 0x00000005}, + {0x58554454, 0x01000000, 0x00000001}, + {0x58554643, 0x00000000, 0x00000002}, + {0x58554E42, 0x01000000, 0x00000001}, + {0x58555442, 0x04000000, 0x00000002}, + {0x58555841, 0x02000000, 0x00000001}, + {0x58564142, 0x04000000, 0x00000001}, + {0x58564159, 0x04000000, 0x00000002}, + {0x58564343, 0x01000000, 0x00000001}, + {0x58564854, 0x04000000, 0x00000001}, + {0x58564B42, 0x00800000, 0x00000001}, + {0x58564D42, 0x00800000, 0x00000001}, + {0x58565141, 0x01000000, 0x00000002}, + {0x58573241, 0x04000000, 0x00000001}, + {0x58573341, 0x04000000, 0x00000002}, + {0x58573742, 0x01000000, 0x00000002}, + {0x58574443, 0x01000000, 0x00000001}, + {0x58574859, 0x02000000, 0x00000001}, + {0x58574942, 0x04000000, 0x00000002}, + {0x58574C41, 0x02000000, 0x00000001}, + {0x58574D42, 0x04000000, 0x00000002}, + {0x58575141, 0x02000000, 0x00000001}, + {0x58575343, 0x04000000, 0x00000001}, + {0x58575942, 0x00800000, 0x00000001}, + {0x58584254, 0x04000000, 0x00000002}, + {0x58584C41, 0x02000000, 0x00000001}, + {0x58584D59, 0x00800000, 0x00000001}, + {0x58585043, 0x01000000, 0x00000005}, + {0x58594159, 0x02000000, 0x00000001}, + {0x58594259, 0x02000000, 0x00000001}, + {0x58594443, 0x02000000, 0x00000002}, + {0x58594741, 0x04000000, 0x00000003}, + {0x58594842, 0x02000000, 0x00000001}, + {0x58594943, 0x04000000, 0x00000002}, + {0x58594A42, 0x04000000, 0x00000001}, + {0x58594E42, 0x04000000, 0x00000001}, + {0x58595543, 0x02000000, 0x00000001}, + {0x585A3242, 0x00800000, 0x00000001}, + {0x585A3742, 0x04000000, 0x00000001}, + {0x585A4341, 0x01000000, 0x00000001}, + {0x585A4A59, 0x04000000, 0x00000005}, + {0x585A4C59, 0x10000000, 0x00000002}, + {0x585A4D56, 0x04000000, 0x00000001}, + {0x585A5059, 0x01000000, 0x00000001}, + {0x585A5242, 0x04000000, 0x00000003}, + {0x585A5243, 0x00800000, 0x00000002}, + {0x585A5442, 0x04000000, 0x00000001}, + {0x59325141, 0x02000000, 0x00000002}, + {0x59334242, 0x08000000, 0x00000001}, + {0x59334759, 0x02000000, 0x00000003}, + {0x59334941, 0x01000000, 0x00000002}, + {0x59334943, 0x04000000, 0x00000001}, + {0x59334C41, 0x02000000, 0x00000001}, + {0x59345741, 0x02000000, 0x00000002}, + {0x59354A42, 0x02000000, 0x00000001}, + {0x59355142, 0x08000000, 0x00000001}, + {0x59364341, 0x01000000, 0x00000002}, + {0x59374943, 0x00000000, 0x00000002}, + {0x59394259, 0x02000000, 0x00000003}, + {0x59395056, 0x04000000, 0x00000001}, + {0x59414356, 0x04000000, 0x00000001}, + {0x59414643, 0x08000000, 0x00000002}, + {0x59414E43, 0x04000000, 0x00000001}, + {0x59415359, 0x01000000, 0x00000002}, + {0x59415459, 0x04000000, 0x00000001}, + {0x59425442, 0x04000000, 0x00000002}, + {0x59425742, 0x04000000, 0x00000002}, + {0x59434741, 0x04000000, 0x00000003}, + {0x59443442, 0x01000000, 0x00000001}, + {0x59444642, 0x00800000, 0x00000001}, + {0x59445054, 0x08000000, 0x00000001}, + {0x59453442, 0x01000000, 0x00000001}, + {0x59454259, 0x08000000, 0x00000003}, + {0x59454543, 0x00800000, 0x00000001}, + {0x59454C43, 0x04000000, 0x00000001}, + {0x59455056, 0x04000000, 0x00000001}, + {0x59455143, 0x04000000, 0x00000002}, + {0x59455542, 0x02000000, 0x00000001}, + {0x59463642, 0x08000000, 0x00000001}, + {0x59465042, 0x04000000, 0x00000002}, + {0x59474354, 0x04000000, 0x00000001}, + {0x59474C43, 0x04000000, 0x00000001}, + {0x59484A42, 0x01000000, 0x00000001}, + {0x59484C41, 0x02000000, 0x00000001}, + {0x59495443, 0x02000000, 0x00000002}, + {0x594A4841, 0x01000000, 0x00000002}, + {0x594A4D54, 0x02000000, 0x00000001}, + {0x594B5356, 0x04000000, 0x00000001}, + {0x594C4A59, 0x01000000, 0x00000002}, + {0x594C4E59, 0x04000000, 0x00000001}, + {0x594C5759, 0x02000000, 0x00000001}, + {0x594E4641, 0x02000000, 0x00000002}, + {0x594E4654, 0x04000000, 0x00000002}, + {0x594E5159, 0x04000000, 0x00000002}, + {0x594F5841, 0x01000000, 0x00000002}, + {0x59504442, 0x02000000, 0x00000001}, + {0x59513642, 0x00800000, 0x00000001}, + {0x59514559, 0x01000000, 0x00000001}, + {0x59514D59, 0x02000000, 0x00000001}, + {0x59524254, 0x04000000, 0x00000001}, + {0x59524459, 0x01000000, 0x00000001}, + {0x59524842, 0x02000000, 0x00000001}, + {0x59524C54, 0x08000000, 0x00000001}, + {0x59533841, 0x00800000, 0x00000002}, + {0x59545054, 0x08000000, 0x00000001}, + {0x59545259, 0x02000000, 0x00000002}, + {0x59545A41, 0x01000000, 0x00000005}, + {0x59554242, 0x04000000, 0x00000003}, + {0x59554341, 0x08000000, 0x00000005}, + {0x59554B56, 0x04000000, 0x00000001}, + {0x59554D42, 0x04000000, 0x00000001}, + {0x59555154, 0x00800000, 0x00000001}, + {0x59555442, 0x04000000, 0x00000002}, + {0x59564854, 0x04000000, 0x00000001}, + {0x59565141, 0x01000000, 0x00000002}, + {0x59573241, 0x04000000, 0x00000001}, + {0x59574443, 0x01000000, 0x00000001}, + {0x59574C41, 0x02000000, 0x00000001}, + {0x59574D42, 0x04000000, 0x00000002}, + {0x59594159, 0x02000000, 0x00000001}, + {0x59594254, 0x04000000, 0x00000002}, + {0x59594442, 0x08000000, 0x00000002}, + {0x59594E42, 0x04000000, 0x00000001}, + {0x595A4341, 0x01000000, 0x00000001}, + {0x595A4A59, 0x04000000, 0x00000005}, + {0x595A5059, 0x01000000, 0x00000001}, + {0x595A5242, 0x04000000, 0x00000003}, + {0x595A5442, 0x04000000, 0x00000001}, + {0x595A5443, 0x02000000, 0x00000003}, + {0x5A325141, 0x02000000, 0x00000002}, + {0x5A334941, 0x01000000, 0x00000002}, + {0x5A335456, 0x04000000, 0x00000001}, + {0x5A345741, 0x02000000, 0x00000002}, + {0x5A353859, 0x00800000, 0x00000008}, + {0x5A374943, 0x04000000, 0x00000002}, + {0x5A414356, 0x04000000, 0x00000001}, + {0x5A424259, 0x02000000, 0x00000001}, + {0x5A445759, 0x01000000, 0x00000002}, + {0x5A454259, 0x08000000, 0x00000003}, + {0x5A475956, 0x04000000, 0x00000001}, + {0x5A4A3642, 0x00800000, 0x00000001}, + {0x5A4A3959, 0x00800000, 0x00000008}, + {0x5A4C4E59, 0x04000000, 0x00000001}, + {0x5A4C5759, 0x02000000, 0x00000001}, + {0x5A4C5959, 0x04000000, 0x00000002}, + {0x5A4D4842, 0x02000000, 0x00000001}, + {0x5A4F3959, 0x00800000, 0x00000000}, + {0x5A513642, 0x00800000, 0x00000001}, + {0x5A523642, 0x08000000, 0x00000002}, + {0x5A544D59, 0x02000000, 0x00000002}, + {0x5A545054, 0x08000000, 0x00000001}, + {0x5A554242, 0x04000000, 0x00000003}, + {0x5A565141, 0x01000000, 0x00000002}, + {0x5A574C41, 0x02000000, 0x00000001}, + {0x5A595543, 0x02000000, 0x00000001}, + {0x5A5A4254, 0x04000000, 0x00000002}, + {0x5A5A4341, 0x01000000, 0x00000001}, + {0x5A5A5242, 0x04000000, 0x00000003}, +}; + +#endif // ROMLIST_H diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8df6ec8..a3207c7 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -1900,39 +1900,6 @@ int main(int argc, char** argv) SANITIZE(Config::ScreenSizing, 0, 3); #undef SANITIZE - // TODO: this should be checked before running anything -#if 0 - { - const char* romlist_missing = "Save memory type detection will not work correctly.\n\n" - "You should use the latest version of romlist.bin (provided in melonDS release packages)."; -#if !defined(UNIX_PORTABLE) && !defined(__WIN32__) - std::string missingstr = std::string(romlist_missing) + - "\n\nThe ROM list should be placed in " + g_get_user_data_dir() + "/melonds/, otherwise " - "melonDS will search for it in the current working directory."; - const char* romlist_missing_text = missingstr.c_str(); -#else - const char* romlist_missing_text = romlist_missing; -#endif - - FILE* f = Platform::OpenDataFile("romlist.bin"); - if (f) - { - u32 data; - fread(&data, 4, 1, f); - fclose(f); - - if ((data >> 24) == 0) // old CRC-based list - { - uiMsgBoxError(NULL, "Your version of romlist.bin is outdated.", romlist_missing_text); - } - } - else - { - uiMsgBoxError(NULL, "romlist.bin not found.", romlist_missing_text); - } - } -#endif - QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); -- cgit v1.2.3