From de405ce8922713b78fe30c7612cbfc610578a474 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 Apr 2020 23:17:16 +0200 Subject: so, this is it this was a glorious fight, but I admit defeat --- src/frontend/qt/main.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt/main.h | 24 ++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/frontend/qt/main.cpp create mode 100644 src/frontend/qt/main.h (limited to 'src/frontend') diff --git a/src/frontend/qt/main.cpp b/src/frontend/qt/main.cpp new file mode 100644 index 0000000..3f61ec6 --- /dev/null +++ b/src/frontend/qt/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; +} diff --git a/src/frontend/qt/main.h b/src/frontend/qt/main.h new file mode 100644 index 0000000..65d6518 --- /dev/null +++ b/src/frontend/qt/main.h @@ -0,0 +1,24 @@ +/* + 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_H +#define MAIN_H + +// put the class shit here + +#endif // MAIN_H -- cgit v1.2.3 From 231f0fc2e5e22b2d4907341cc191cfc9215556fb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 14 Apr 2020 23:38:48 +0200 Subject: welp --- melonDS.cbp | 4 ++-- src/frontend/qt/main.cpp | 45 -------------------------------------------- src/frontend/qt/main.h | 24 ----------------------- src/frontend/qt_sdl/main.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/frontend/qt_sdl/main.h | 24 +++++++++++++++++++++++ 5 files changed, 71 insertions(+), 71 deletions(-) delete mode 100644 src/frontend/qt/main.cpp delete mode 100644 src/frontend/qt/main.h create mode 100644 src/frontend/qt_sdl/main.cpp create mode 100644 src/frontend/qt_sdl/main.h (limited to 'src/frontend') diff --git a/melonDS.cbp b/melonDS.cbp index 7305ee5..2a33978 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -153,8 +153,8 @@ - - + + diff --git a/src/frontend/qt/main.cpp b/src/frontend/qt/main.cpp deleted file mode 100644 index 3f61ec6..0000000 --- a/src/frontend/qt/main.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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; -} diff --git a/src/frontend/qt/main.h b/src/frontend/qt/main.h deleted file mode 100644 index 65d6518..0000000 --- a/src/frontend/qt/main.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - 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_H -#define MAIN_H - -// put the class shit here - -#endif // MAIN_H 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; +} diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h new file mode 100644 index 0000000..65d6518 --- /dev/null +++ b/src/frontend/qt_sdl/main.h @@ -0,0 +1,24 @@ +/* + 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_H +#define MAIN_H + +// put the class shit here + +#endif // MAIN_H -- cgit v1.2.3 From d58c9d4b53162c0e41fb084d7d8218f6672cc8ab Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 Apr 2020 18:56:39 +0200 Subject: blarg --- CMakeLists.txt | 6 ---- src/frontend/qt_sdl/CMakeLists.txt | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 src/frontend/qt_sdl/CMakeLists.txt (limited to 'src/frontend') diff --git a/CMakeLists.txt b/CMakeLists.txt index 048dd44..98c653a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,14 +32,8 @@ endif() add_compile_options(-fno-pic) add_link_options(-no-pie) -option(BUILD_LIBUI "Build libui frontend" ON) - add_subdirectory(src) -if (BUILD_LIBUI) - add_subdirectory(src/libui_sdl) -endif() - configure_file( ${CMAKE_SOURCE_DIR}/romlist.bin ${CMAKE_BINARY_DIR}/romlist.bin COPYONLY) diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt new file mode 100644 index 0000000..e95d24b --- /dev/null +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -0,0 +1,73 @@ +project(qt_sdl) + +SET(SOURCES_LIBUI + main.cpp + Platform.cpp + PlatformConfig.cpp + LAN_Socket.cpp + LAN_PCap.cpp + DlgAudioSettings.cpp + DlgEmuSettings.cpp + DlgInputConfig.cpp + DlgVideoSettings.cpp + DlgWifiSettings.cpp + OSD.cpp +) + +if (WIN32) + set(CMAKE_RC_COMPILE_OBJECT " -i -o ") +endif() + +option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) +set(BUILD_SHARED_LIBS OFF) +add_subdirectory(libui) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(SDL2 REQUIRED sdl2) + +add_executable(melonDS ${SOURCES_LIBUI}) +target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS}) +target_link_libraries(melonDS core libui ${SDL2_LIBRARIES}) + +if (UNIX) + option(UNIX_PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) + if (UNIX_PORTABLE) + add_definitions(-DUNIX_PORTABLE) + endif() + + find_package(PkgConfig REQUIRED) + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + + target_include_directories(melonDS PRIVATE ${GTK3_INCLUDE_DIRS}) + target_link_libraries(melonDS ${GTK3_LIBRARIES}) + + ADD_DEFINITIONS(${GTK3_CFLAGS_OTHER}) + + add_custom_command(OUTPUT melon_grc.c + COMMAND glib-compile-resources --sourcedir=${CMAKE_SOURCE_DIR} + --target=${CMAKE_CURRENT_BINARY_DIR}/melon_grc.c + --generate-source "${CMAKE_SOURCE_DIR}/melon_grc.xml" + COMMAND glib-compile-resources --sourcedir=${CMAKE_SOURCE_DIR} + --target=${CMAKE_CURRENT_BINARY_DIR}/melon_grc.h + --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") + + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_link_libraries(melonDS dl) + 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) +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(TARGETS melonDS RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -- cgit v1.2.3 From 0bdafb62951234eab93ea46ba82ea9e2a0fc1277 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 Apr 2020 19:31:19 +0200 Subject: finally get this going, I guess --- CMakeLists.txt | 6 ++++++ src/frontend/qt_sdl/CMakeLists.txt | 27 ++++++++------------------- 2 files changed, 14 insertions(+), 19 deletions(-) (limited to 'src/frontend') diff --git a/CMakeLists.txt b/CMakeLists.txt index 98c653a..488da81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,14 @@ endif() add_compile_options(-fno-pic) add_link_options(-no-pie) +option(BUILD_QT_SDL "Build Qt/SDL frontend" ON) + 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/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index e95d24b..ff2ed09 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -1,33 +1,22 @@ project(qt_sdl) -SET(SOURCES_LIBUI +SET(SOURCES_QT_SDL main.cpp - Platform.cpp - PlatformConfig.cpp - LAN_Socket.cpp - LAN_PCap.cpp - DlgAudioSettings.cpp - DlgEmuSettings.cpp - DlgInputConfig.cpp - DlgVideoSettings.cpp - DlgWifiSettings.cpp - OSD.cpp ) if (WIN32) set(CMAKE_RC_COMPILE_OBJECT " -i -o ") endif() -option(BUILD_SHARED_LIBS "Whether to build libui as a shared library or a static library" ON) -set(BUILD_SHARED_LIBS OFF) -add_subdirectory(libui) +find_package(Qt5 COMPONENTS Core REQUIRED) +find_package(Qt5 COMPONENTS Widgets REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2) -add_executable(melonDS ${SOURCES_LIBUI}) +add_executable(melonDS ${SOURCES_QT_SDL}) target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS}) -target_link_libraries(melonDS core libui ${SDL2_LIBRARIES}) +target_link_libraries(melonDS core ${SDL2_LIBRARIES}) if (UNIX) option(UNIX_PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) @@ -52,14 +41,14 @@ if (UNIX) --generate-header "${CMAKE_SOURCE_DIR}/melon_grc.xml") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(melonDS dl) + target_link_libraries(melonDS dl Qt5::Core 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) + 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) endif () install(FILES ../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) -- 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') 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') 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') 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 d6efb03248e3c7751b0c7e5d3b6398ea671325b0 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Mon, 27 Apr 2020 20:59:11 +0200 Subject: HARK HARK HARK --- src/frontend/FrontendUtil.h | 31 +++++++++++++++++++++++++++++++ src/frontend/Util_ROM.cpp | 17 +++++++++++++++++ src/frontend/qt_sdl/CMakeLists.txt | 4 ++++ 3 files changed, 52 insertions(+) create mode 100644 src/frontend/FrontendUtil.h create mode 100644 src/frontend/Util_ROM.cpp (limited to 'src/frontend') diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h new file mode 100644 index 0000000..6a199b7 --- /dev/null +++ b/src/frontend/FrontendUtil.h @@ -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/. +*/ + +#ifndef FRONTENDUTIL_H +#define FRONTENDUTIL_H + +#include "types.h" + +namespace FrontendUtil +{ + +// + +} + +#endif // FRONTENDUTIL_H diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp new file mode 100644 index 0000000..b3077f7 --- /dev/null +++ b/src/frontend/Util_ROM.cpp @@ -0,0 +1,17 @@ +/* + 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/. +*/ diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index baa4be2..fb9f547 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -4,6 +4,9 @@ SET(SOURCES_QT_SDL main.cpp Platform.cpp PlatformConfig.cpp + + ../Util_ROM.cpp + ../FrontendUtil.h ) if (WIN32) @@ -21,6 +24,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_link_libraries(melonDS core ${SDL2_LIBRARIES}) -- 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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 492a4b4b464b4b48bd821c126475c791e66b5c6d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 03:02:42 +0200 Subject: add config entries for BIOS/firmware paths --- src/frontend/qt_sdl/PlatformConfig.cpp | 16 ++++++++++++---- src/frontend/qt_sdl/PlatformConfig.h | 8 ++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index f78b195..fba649c 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -60,9 +60,13 @@ int SavestateRelocSRAM; int AudioVolume; int MicInputType; -char MicWavPath[512]; +char MicWavPath[1024]; -char LastROMFolder[512]; +char LastROMFolder[1024]; + +char BIOS9Path[1024]; +char BIOS7Path[1024]; +char FirmwarePath[1024]; ConfigEntry PlatformConfigFile[] = @@ -141,9 +145,13 @@ ConfigEntry PlatformConfigFile[] = {"AudioVolume", 0, &AudioVolume, 256, NULL, 0}, {"MicInputType", 0, &MicInputType, 1, NULL, 0}, - {"MicWavPath", 1, MicWavPath, 0, "", 511}, + {"MicWavPath", 1, MicWavPath, 0, "", 1023}, + + {"LastROMFolder", 1, LastROMFolder, 0, "", 1023}, - {"LastROMFolder", 1, LastROMFolder, 0, "", 511}, + {"BIOS9Path", 1, BIOS9Path, 0, "", 1023}, + {"BIOS7Path", 1, BIOS7Path, 0, "", 1023}, + {"FirmwarePath", 1, FirmwarePath, 0, "", 1023}, {"", -1, NULL, 0, NULL, 0} }; diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h index d0f765b..e104015 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -73,9 +73,13 @@ extern int SavestateRelocSRAM; extern int AudioVolume; extern int MicInputType; -extern char MicWavPath[512]; +extern char MicWavPath[1024]; -extern char LastROMFolder[512]; +extern char LastROMFolder[1024]; + +extern char BIOS9Path[1024]; +extern char BIOS7Path[1024]; +extern char FirmwarePath[1024]; } -- 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') 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 17d30e91f01ea015caf5e28afe8ddca4aede45b1 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 04:37:44 +0200 Subject: actually hook this up --- src/Config.cpp | 8 +++++ src/Config.h | 4 +++ src/NDS.cpp | 4 +-- src/SPI.cpp | 16 +++++++--- src/frontend/qt_sdl/EmuSettingsDialog.cpp | 49 +++++++++++++++++++++++++++++-- src/frontend/qt_sdl/EmuSettingsDialog.h | 2 ++ src/frontend/qt_sdl/PlatformConfig.cpp | 8 ----- src/frontend/qt_sdl/PlatformConfig.h | 4 --- 8 files changed, 75 insertions(+), 20 deletions(-) (limited to 'src/frontend') diff --git a/src/Config.cpp b/src/Config.cpp index f558ef6..7604785 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -28,6 +28,10 @@ namespace Config const char* kConfigFile = "melonDS.ini"; +char BIOS9Path[1024]; +char BIOS7Path[1024]; +char FirmwarePath[1024]; + int _3DRenderer; int Threaded3D; @@ -36,6 +40,10 @@ int GL_Antialias; ConfigEntry ConfigFile[] = { + {"BIOS9Path", 1, BIOS9Path, 0, "", 1023}, + {"BIOS7Path", 1, BIOS7Path, 0, "", 1023}, + {"FirmwarePath", 1, FirmwarePath, 0, "", 1023}, + {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0}, {"Threaded3D", 0, &Threaded3D, 1, NULL, 0}, diff --git a/src/Config.h b/src/Config.h index 0aeab85..05b9b8b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -42,6 +42,10 @@ bool HasConfigFile(const char* fileName); void Load(); void Save(); +extern char BIOS9Path[1024]; +extern char BIOS7Path[1024]; +extern char FirmwarePath[1024]; + extern int _3DRenderer; extern int Threaded3D; diff --git a/src/NDS.cpp b/src/NDS.cpp index a2ab6ce..1d425a8 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -416,7 +416,7 @@ void Reset() RunningGame = false; LastSysClockCycles = 0; - f = Platform::OpenLocalFile("bios9.bin", "rb"); + f = Platform::OpenLocalFile(Config::BIOS9Path, "rb"); if (!f) { printf("ARM9 BIOS not found\n"); @@ -433,7 +433,7 @@ void Reset() fclose(f); } - f = Platform::OpenLocalFile("bios7.bin", "rb"); + f = Platform::OpenLocalFile(Config::BIOS7Path, "rb"); if (!f) { printf("ARM7 BIOS not found\n"); diff --git a/src/SPI.cpp b/src/SPI.cpp index 1a5873e..056e8d5 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -28,6 +28,7 @@ namespace SPI_Firmware { +char FirmwarePath[1024]; u8* Firmware; u32 FirmwareLength; u32 FirmwareMask; @@ -76,6 +77,7 @@ bool VerifyCRC16(u32 start, u32 offset, u32 len, u32 crcoffset) bool Init() { + memset(FirmwarePath, 0, sizeof(FirmwarePath)); Firmware = NULL; return true; } @@ -90,10 +92,12 @@ void Reset() if (Firmware) delete[] Firmware; Firmware = NULL; - FILE* f = Platform::OpenLocalFile("firmware.bin", "rb"); + strncpy(FirmwarePath, Config::FirmwarePath, 1023); + + FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb"); if (!f) { - printf("firmware.bin not found\n"); + printf("Firmware not found\n"); // TODO: generate default firmware return; @@ -129,7 +133,11 @@ void Reset() fclose(f); // take a backup - const char* firmbkp = "firmware.bin.bak"; + char firmbkp[1028]; + int fplen = strlen(FirmwarePath); + strncpy(&firmbkp[0], FirmwarePath, fplen); + strncpy(&firmbkp[fplen], ".bak", 1028-fplen); + firmbkp[fplen+4] = '\0'; f = Platform::OpenLocalFile(firmbkp, "rb"); if (f) fclose(f); else @@ -325,7 +333,7 @@ void Write(u8 val, u32 hold) if (!hold && (CurCmd == 0x02 || CurCmd == 0x0A)) { - FILE* f = Platform::OpenLocalFile("firmware.bin", "r+b"); + FILE* f = Platform::OpenLocalFile(FirmwarePath, "r+b"); if (f) { u32 cutoff = 0x7FA00 & FirmwareMask; diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 34cafb5..bce5513 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -16,9 +16,12 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ +#include #include +#include #include "types.h" +#include "Platform.h" #include "Config.h" #include "PlatformConfig.h" @@ -47,8 +50,52 @@ EmuSettingsDialog::~EmuSettingsDialog() delete ui; } +void EmuSettingsDialog::verifyFirmware() +{ + // 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. + + char filename[1024]; + strncpy(filename, ui->txtFirmwarePath->text().toStdString().c_str(), 1023); filename[1023] = '\0'; + FILE* f = Platform::OpenLocalFile(filename, "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)) + { + QMessageBox::warning(this, + "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."); + } +} + void EmuSettingsDialog::on_EmuSettingsDialog_accepted() { + verifyFirmware(); + 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'; @@ -95,7 +142,5 @@ void EmuSettingsDialog::on_btnFirmwareBrowse_clicked() 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 471e0fb..ce64145 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.h +++ b/src/frontend/qt_sdl/EmuSettingsDialog.h @@ -58,6 +58,8 @@ private slots: void on_btnFirmwareBrowse_clicked(); private: + void verifyFirmware(); + Ui::EmuSettingsDialog* ui; }; diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index fba649c..1f6a873 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -64,10 +64,6 @@ char MicWavPath[1024]; char LastROMFolder[1024]; -char BIOS9Path[1024]; -char BIOS7Path[1024]; -char FirmwarePath[1024]; - ConfigEntry PlatformConfigFile[] = { @@ -149,10 +145,6 @@ ConfigEntry PlatformConfigFile[] = {"LastROMFolder", 1, LastROMFolder, 0, "", 1023}, - {"BIOS9Path", 1, BIOS9Path, 0, "", 1023}, - {"BIOS7Path", 1, BIOS7Path, 0, "", 1023}, - {"FirmwarePath", 1, FirmwarePath, 0, "", 1023}, - {"", -1, NULL, 0, NULL, 0} }; diff --git a/src/frontend/qt_sdl/PlatformConfig.h b/src/frontend/qt_sdl/PlatformConfig.h index e104015..3704d14 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -77,10 +77,6 @@ extern char MicWavPath[1024]; extern char LastROMFolder[1024]; -extern char BIOS9Path[1024]; -extern char BIOS7Path[1024]; -extern char FirmwarePath[1024]; - } #endif // PLATFORMCONFIG_H -- cgit v1.2.3 From 49b24ea2b3b730b2d4acb20231989d1ace84a59b Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 17 May 2020 04:42:15 +0200 Subject: this might be betterer --- src/frontend/qt_sdl/EmuSettingsDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index bce5513..6264d91 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -84,7 +84,7 @@ void EmuSettingsDialog::verifyFirmware() if (!memcmp(chk1, chk2, 0x180)) { - QMessageBox::warning(this, + QMessageBox::warning((QWidget*)this->parent(), "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" -- 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') 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') 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') 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') 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') 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') 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') 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 2a7027f794267effe651b242956ed669c242e9ca Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 19 May 2020 13:46:31 +0200 Subject: add AltGr, weak attempt at blocking garbage key names --- src/frontend/qt_sdl/InputConfigDialog.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 3b006fd..54251a1 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -235,6 +235,7 @@ printf("KEY PRESSED = %08X %08X | %08X %08X %08X | %08X\n", event->key(), event- int key = event->key(); bool ismod = (key == Qt::Key_Control || key == Qt::Key_Alt || + key == Qt::Key_AltGr || key == Qt::Key_Shift || key == Qt::Key_Meta); @@ -284,11 +285,17 @@ QString KeyMapButton::mappingText() case Qt::Key_Control: return "Ctrl"; case Qt::Key_Alt: return "Alt"; + case Qt::Key_AltGr: return "AltGr"; case Qt::Key_Shift: return "Shift"; case Qt::Key_Meta: return "Meta"; } QKeySequence seq(key); QString ret = seq.toString(); + + // weak attempt at detecting garbage key names + if (ret.length() == 2 && ret[0].unicode() > 0xFF) + return QString("[%1]").arg(key, 8, 16); + return ret.replace("&", "&&"); } -- cgit v1.2.3 From 23cc8c71a2c0ab3389b5208f49a25df0efc05a2e Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 14:15:11 +0200 Subject: distinguish left/right Ctrl and Shift --- src/frontend/qt_sdl/InputConfigDialog.cpp | 22 +++++++++++++++------- src/frontend/qt_sdl/main.h | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 54251a1..0ef29bb 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -24,6 +24,7 @@ #include "Config.h" #include "PlatformConfig.h" +#include "main.h" #include "InputConfigDialog.h" #include "ui_InputConfigDialog.h" @@ -231,7 +232,9 @@ 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); + + printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode()); + int key = event->key(); bool ismod = (key == Qt::Key_Control || key == Qt::Key_Alt || @@ -247,6 +250,8 @@ printf("KEY PRESSED = %08X %08X | %08X %08X %08X | %08X\n", event->key(), event- if (!ismod) key |= event->modifiers(); + else if (IsRightModKey(event)) + key |= (1<<31); *mapping = key; click(); @@ -279,23 +284,26 @@ QString KeyMapButton::mappingText() { int key = *mapping; + if (key == -1) return "None"; + + QString isright = (key & (1<<31)) ? "Right " : "Left "; + key &= ~(1<<31); + switch (key) { - case -1: return "None"; - - case Qt::Key_Control: return "Ctrl"; + case Qt::Key_Control: return isright + "Ctrl"; case Qt::Key_Alt: return "Alt"; case Qt::Key_AltGr: return "AltGr"; - case Qt::Key_Shift: return "Shift"; + case Qt::Key_Shift: return isright + "Shift"; case Qt::Key_Meta: return "Meta"; } QKeySequence seq(key); QString ret = seq.toString(); - + // weak attempt at detecting garbage key names if (ret.length() == 2 && ret[0].unicode() > 0xFF) return QString("[%1]").arg(key, 8, 16); - + return ret.replace("&", "&&"); } diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 4553875..5d6638c 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 @@ -131,4 +132,24 @@ 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 04d38e5e66cee768e32864b37a5cf37d8109d481 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 14:16:35 +0200 Subject: axe the default key mappings (not too cross-platform and blargy) --- src/frontend/qt_sdl/PlatformConfig.cpp | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 1f6a873..3b4b4aa 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -67,18 +67,18 @@ char LastROMFolder[1024]; 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}, + {"Key_A", 0, &KeyMapping[0], -1, NULL, 0}, + {"Key_B", 0, &KeyMapping[1], -1, NULL, 0}, + {"Key_Select", 0, &KeyMapping[2], -1, NULL, 0}, + {"Key_Start", 0, &KeyMapping[3], -1, NULL, 0}, + {"Key_Right", 0, &KeyMapping[4], -1, NULL, 0}, + {"Key_Left", 0, &KeyMapping[5], -1, NULL, 0}, + {"Key_Up", 0, &KeyMapping[6], -1, NULL, 0}, + {"Key_Down", 0, &KeyMapping[7], -1, NULL, 0}, + {"Key_R", 0, &KeyMapping[8], -1, NULL, 0}, + {"Key_L", 0, &KeyMapping[9], -1, NULL, 0}, + {"Key_X", 0, &KeyMapping[10], -1, NULL, 0}, + {"Key_Y", 0, &KeyMapping[11], -1, NULL, 0}, {"Joy_A", 0, &JoyMapping[0], -1, NULL, 0}, {"Joy_B", 0, &JoyMapping[1], -1, NULL, 0}, @@ -93,14 +93,14 @@ ConfigEntry PlatformConfigFile[] = {"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}, + {"HKKey_Lid", 0, &HKKeyMapping[HK_Lid], -1, NULL, 0}, + {"HKKey_Mic", 0, &HKKeyMapping[HK_Mic], -1, 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], -1, NULL, 0}, + {"HKKey_FastForwardToggle", 0, &HKKeyMapping[HK_FastForwardToggle], -1, NULL, 0}, + {"HKKey_SolarSensorDecrease", 0, &HKKeyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, + {"HKKey_SolarSensorIncrease", 0, &HKKeyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, {"HKJoy_Lid", 0, &HKJoyMapping[HK_Lid], -1, NULL, 0}, {"HKJoy_Mic", 0, &HKJoyMapping[HK_Mic], -1, NULL, 0}, -- cgit v1.2.3 From 4b038f5d370c961803666f418ebfeb775cfa2d2a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Tue, 19 May 2020 14:24:57 +0200 Subject: re-add old special keys for mapping (Esc=cancel, Backspace=clear) --- src/frontend/qt_sdl/InputConfigDialog.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 0ef29bb..93204aa 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -236,12 +236,19 @@ void KeyMapButton::keyPressEvent(QKeyEvent* event) printf("KEY PRESSED = %08X %08X | %08X %08X %08X\n", event->key(), event->modifiers(), event->nativeVirtualKey(), event->nativeModifiers(), event->nativeScanCode()); 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 (!mod) + { + if (key == Qt::Key_Escape) { click(); return; } + if (key == Qt::Key_Backspace) { *mapping = -1; click(); return; } + } + if (isHotkey) { if (ismod) @@ -249,7 +256,7 @@ void KeyMapButton::keyPressEvent(QKeyEvent* event) } if (!ismod) - key |= event->modifiers(); + key |= mod; else if (IsRightModKey(event)) key |= (1<<31); -- 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') 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') 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') 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') 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') 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 34133ef75c8f6f735604d7368a79a54724f06b99 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 20 May 2020 01:09:58 +0200 Subject: make it able to map the Tab key --- src/NDSCart.cpp | 1 + src/frontend/qt_sdl/InputConfigDialog.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src/frontend') diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 585eadf..8ced842 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -903,6 +903,7 @@ bool LoadROM(const char* path, const char* sram, bool direct) { // TODO: streaming mode? for really big ROMs or systems with limited RAM // for now we're lazy + // also TODO: validate what we're loading!! FILE* f = Platform::OpenFile(path, "rb"); if (!f) diff --git a/src/frontend/qt_sdl/InputConfigDialog.h b/src/frontend/qt_sdl/InputConfigDialog.h index 82e37bc..de57414 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.h +++ b/src/frontend/qt_sdl/InputConfigDialog.h @@ -80,6 +80,8 @@ protected: void keyPressEvent(QKeyEvent* event) override; void focusOutEvent(QFocusEvent* event) override; + bool focusNextPrevChild(bool next) override { return false; } + private slots: void onClick(); @@ -103,6 +105,8 @@ protected: void focusOutEvent(QFocusEvent* event) override; void timerEvent(QTimerEvent* event) override; + bool focusNextPrevChild(bool next) override { return false; } + private slots: void onClick(); -- 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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') 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 f79583bf1697b4c6a5b40c1e727e2a40c789757d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 21 May 2020 02:33:48 +0200 Subject: add actual blow-into-mic sample that actually works --- src/frontend/Util_Audio.cpp | 15 +- src/frontend/mic_blow.h | 5539 ++++++++++++++++++++++++++++ src/frontend/qt_sdl/AudioSettingsDialog.ui | 2 +- src/frontend/qt_sdl/CMakeLists.txt | 1 + 4 files changed, 5548 insertions(+), 9 deletions(-) create mode 100644 src/frontend/mic_blow.h (limited to 'src/frontend') diff --git a/src/frontend/Util_Audio.cpp b/src/frontend/Util_Audio.cpp index 3f03810..d4c3333 100644 --- a/src/frontend/Util_Audio.cpp +++ b/src/frontend/Util_Audio.cpp @@ -28,6 +28,8 @@ #include "NDS.h" +#include "mic_blow.h" + namespace Frontend { @@ -92,19 +94,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; + int sample_len = sizeof(mic_blow) / sizeof(u16); + static int sample_pos = 0; s16 tmp[735]; for (int i = 0; i < 735; i++) { - int val = noisesample[j]; - j++; - if (j >= 8) j = rand() & 7; - - tmp[i] = val; + tmp[i] = mic_blow[sample_pos]; + sample_pos++; + if (sample_pos >= sample_len) sample_pos = 0; } NDS::MicInputFrame(tmp, 735); diff --git a/src/frontend/mic_blow.h b/src/frontend/mic_blow.h new file mode 100644 index 0000000..cee92fe --- /dev/null +++ b/src/frontend/mic_blow.h @@ -0,0 +1,5539 @@ +/* + 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 MIC_BLOW_H +#define MIC_BLOW_H + +const u16 mic_blow[] = +{ + 0x1840, 0x1EF0, 0x24F0, 0x2A60, 0x2F60, 0x33F0, 0x3800, 0x3BC0, 0x3FB0, 0x43E0, 0x48A0, 0x4EC0, 0x5490, 0x5A30, 0x6040, 0x6490, + 0x6960, 0x6E40, 0x7220, 0x76B0, 0x79B0, 0x7CA0, 0x7E60, 0x7F00, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F30, + 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F30, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, + 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F50, 0x7EF0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, + 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7EB0, 0x7F20, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F80, 0x7EB0, 0x7220, 0x66D0, 0x5BD0, 0x5190, 0x4680, + 0x3D70, 0x3470, 0x2C70, 0x2640, 0x2090, 0x1D00, 0x1A40, 0x1910, 0x1810, 0x17A0, 0x1860, 0x19C0, 0x1C10, 0x1F30, 0x22E0, 0x2930, + 0x2FA0, 0x3720, 0x3EC0, 0x46B0, 0x4E80, 0x5660, 0x5ED0, 0x6710, 0x7000, 0x7720, 0x7D10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7E80, 0x7D30, 0x7C00, 0x7AA0, 0x7890, + 0x7610, 0x73F0, 0x71A0, 0x6F60, 0x6CD0, 0x6970, 0x6670, 0x6310, 0x5F90, 0x5D10, 0x5A20, 0x5720, 0x5410, 0x4FB0, 0x4AC0, 0x4670, + 0x4250, 0x3E40, 0x39F0, 0x3540, 0x2FB0, 0x28E0, 0x2260, 0x1BB0, 0x15F0, 0x10B0, 0x0C60, 0x08B0, 0x05B0, 0x0300, 0x00F0, 0xFEB0, + 0xFC00, 0xF8E0, 0xF570, 0xF170, 0xED60, 0xE8E0, 0xE4C0, 0xDFF0, 0xDB90, 0xD650, 0xD090, 0xCAB0, 0xC570, 0xC0C0, 0xBD00, 0xBA30, + 0xB790, 0xB4C0, 0xB1B0, 0xAF40, 0xAD00, 0xAC10, 0xAB70, 0xAA70, 0xA9C0, 0xA800, 0xA640, 0xA520, 0xA420, 0xA2C0, 0xA1D0, 0xA000, + 0x9E60, 0x9CF0, 0x9B80, 0x9A10, 0x97F0, 0x9550, 0x9340, 0x9170, 0x8F80, 0x8DA0, 0x8C40, 0x8B10, 0x89E0, 0x8890, 0x87B0, 0x86F0, + 0x8660, 0x8640, 0x8600, 0x85F0, 0x85D0, 0x85B0, 0x8580, 0x8560, 0x8550, 0x8550, 0x8540, 0x8530, 0x8530, 0x8520, 0x8510, 0x8510, + 0x8500, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x8510, 0x84E0, 0x84E0, 0x8500, 0x84F0, + 0x84F0, 0x84C0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8530, 0x8550, 0x8580, 0x8590, 0x85D0, 0x8610, 0x8690, 0x8730, 0x8820, + 0x8970, 0x8BC0, 0x8E40, 0x9190, 0x9560, 0x9990, 0x9E30, 0xA1E0, 0xA540, 0xA890, 0xAAB0, 0xADB0, 0xB0E0, 0xB370, 0xB5E0, 0xB860, + 0xBB30, 0xBEB0, 0xC230, 0xC5E0, 0xC930, 0xCD20, 0xCFA0, 0xD130, 0xD310, 0xD530, 0xD8C0, 0xDC80, 0xE0D0, 0xE520, 0xE880, 0xEBF0, + 0xEEB0, 0xF160, 0xF460, 0xF6F0, 0xF970, 0xFBC0, 0xFE90, 0x0250, 0x04C0, 0x06E0, 0x0910, 0x0AB0, 0x0C90, 0x0DA0, 0x0F80, 0x1210, + 0x1400, 0x1550, 0x1680, 0x1770, 0x18A0, 0x1A10, 0x1C90, 0x1E80, 0x2060, 0x22B0, 0x2360, 0x2540, 0x2600, 0x26C0, 0x2920, 0x2B40, + 0x2D50, 0x2EF0, 0x30C0, 0x31D0, 0x3210, 0x3330, 0x33E0, 0x35C0, 0x36F0, 0x37D0, 0x38A0, 0x3990, 0x39F0, 0x39C0, 0x39C0, 0x3950, + 0x3820, 0x3730, 0x36A0, 0x3610, 0x35A0, 0x3490, 0x3270, 0x30B0, 0x2E20, 0x2C60, 0x2A90, 0x2890, 0x2760, 0x2490, 0x2330, 0x20C0, + 0x1F20, 0x1E10, 0x1D30, 0x1D70, 0x1D20, 0x1D10, 0x1E40, 0x1F00, 0x2010, 0x2110, 0x21B0, 0x23C0, 0x25E0, 0x2810, 0x2A20, 0x2C10, + 0x2DF0, 0x2E20, 0x2E60, 0x2F10, 0x2FB0, 0x30F0, 0x3200, 0x31F0, 0x31B0, 0x3070, 0x2F50, 0x2DC0, 0x2BD0, 0x29F0, 0x27C0, 0x2650, + 0x2470, 0x2290, 0x2090, 0x1DF0, 0x1B60, 0x18C0, 0x1670, 0x1490, 0x1220, 0x10E0, 0x0EA0, 0x0D60, 0x0C90, 0x0B10, 0x09B0, 0x0860, + 0x06C0, 0x0630, 0x0520, 0x0520, 0x04F0, 0x0430, 0x0340, 0x0180, 0x0150, 0x0100, 0xFFE0, 0x00A0, 0xFFC0, 0xFFF0, 0xFFF0, 0xFFF0, + 0x00B0, 0x00C0, 0x0150, 0x0190, 0x00D0, 0x0170, 0x01F0, 0x0330, 0x03F0, 0x0480, 0x0510, 0x0580, 0x0570, 0x05C0, 0x0630, 0x06E0, + 0x0810, 0x0910, 0x0A50, 0x0B20, 0x0BD0, 0x0CD0, 0x0E70, 0x1070, 0x1280, 0x1520, 0x17B0, 0x18F0, 0x2120, 0x2240, 0x2340, 0x23B0, + 0x2560, 0x2640, 0x27F0, 0x29F0, 0x2AB0, 0x2BC0, 0x2C50, 0x2CE0, 0x2E20, 0x2F50, 0x3150, 0x3360, 0x33E0, 0x3510, 0x3500, 0x3520, + 0x34F0, 0x33B0, 0x3320, 0x3200, 0x3210, 0x3150, 0x30E0, 0x3010, 0x2ED0, 0x2DE0, 0x2D20, 0x2AF0, 0x2A50, 0x28D0, 0x2760, 0x26C0, + 0x2560, 0x2540, 0x2460, 0x2350, 0x2290, 0x2170, 0x21A0, 0x2110, 0x2090, 0x2000, 0x1F50, 0x1F80, 0x1F40, 0x21A0, 0x21D0, 0x21B0, + 0x21E0, 0x21C0, 0x2260, 0x2370, 0x24F0, 0x2630, 0x2700, 0x2760, 0x2810, 0x2930, 0x2AE0, 0x2C40, 0x2D20, 0x2D80, 0x2DF0, 0x2F00, + 0x30A0, 0x31F0, 0x3510, 0x36B0, 0x3950, 0x3AB0, 0x3B70, 0x3DA0, 0x3F90, 0x4310, 0x4640, 0x4840, 0x4B10, 0x4D20, 0x4FE0, 0x5270, + 0x5590, 0x5900, 0x5C00, 0x5ED0, 0x6110, 0x63A0, 0x66F0, 0x69A0, 0x6CA0, 0x6F40, 0x7090, 0x7290, 0x7440, 0x75F0, 0x7800, 0x79C0, + 0x7BA0, 0x7C90, 0x7D90, 0x7E00, 0x7E70, 0x7ED0, 0x7EF0, 0x7F70, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EA0, + 0x7E40, 0x7C70, 0x7AA0, 0x7890, 0x76F0, 0x74E0, 0x71F0, 0x6EC0, 0x6A00, 0x6630, 0x61E0, 0x5D10, 0x5A30, 0x5560, 0x5160, 0x4D50, + 0x4990, 0x46E0, 0x4400, 0x4130, 0x3DE0, 0x3A00, 0x3790, 0x3480, 0x31E0, 0x2F80, 0x2CD0, 0x2B30, 0x27C0, 0x24D0, 0x2220, 0x2020, + 0x1F00, 0x1D10, 0x1B10, 0x1830, 0x1520, 0x12F0, 0x1160, 0x10A0, 0x0FC0, 0x0E30, 0x0BB0, 0x0900, 0x05F0, 0x0350, 0x00E0, 0xFF50, + 0xFD70, 0xFA30, 0xF600, 0xF1C0, 0xEE10, 0xEA30, 0xE5E0, 0xE1F0, 0xDDB0, 0xD8C0, 0xD3C0, 0xCE10, 0xC850, 0xC2C0, 0xBD40, 0xB720, + 0xAFF0, 0xA880, 0xA0D0, 0x99A0, 0x9250, 0x8C50, 0x88B0, 0x86A0, 0x85B0, 0x8540, 0x8510, 0x84F0, 0x84E0, 0x84D0, 0x84D0, 0x84C0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84F0, 0x84F0, + 0x84D0, 0x84D0, 0x8490, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8540, 0x8560, 0x8590, 0x85E0, 0x8630, 0x8680, 0x8700, + 0x87C0, 0x88C0, 0x89D0, 0x8BA0, 0x8DF0, 0x9050, 0x9320, 0x9620, 0x9930, 0x9BE0, 0x9E30, 0xA0F0, 0xA300, 0xA5B0, 0xA8C0, 0xABC0, + 0xAE30, 0xB140, 0xB3E0, 0xB660, 0xB7B0, 0xB990, 0xBB30, 0xBDC0, 0xBF70, 0xC0A0, 0xC200, 0xC310, 0xC410, 0xC5A0, 0xC710, 0xC7F0, + 0xC910, 0xC960, 0xCA30, 0xCA70, 0xCB70, 0xCB90, 0xCBF0, 0xCCB0, 0xCD00, 0xCE40, 0xCEA0, 0xCEF0, 0xD010, 0xD0F0, 0xD2F0, 0xD360, + 0xD470, 0xD570, 0xD660, 0xD740, 0xD7B0, 0xD820, 0xD820, 0xD880, 0xD810, 0xD910, 0xDA60, 0xDB80, 0xDC90, 0xDD20, 0xDD40, 0xDDA0, + 0xDE00, 0xDE90, 0xDF60, 0xDFD0, 0xE030, 0xE070, 0xE010, 0xE070, 0xE130, 0xE1F0, 0xE240, 0xE1C0, 0xE1A0, 0xE1C0, 0xE1C0, 0xE210, + 0xE270, 0xE1E0, 0xE1D0, 0xE1A0, 0xE0E0, 0xE0A0, 0xDFF0, 0xE010, 0xDFC0, 0xDF60, 0xDEB0, 0xDDB0, 0xDC70, 0xDC10, 0xDB70, 0xDA80, + 0xD990, 0xD8B0, 0xD790, 0xD7E0, 0xD860, 0xD800, 0xD7B0, 0xD650, 0xD580, 0xD470, 0xD3F0, 0xD380, 0xD3D0, 0xD3D0, 0xD300, 0xD1B0, + 0xD030, 0xCFA0, 0xCF60, 0xCF10, 0xCF30, 0xCEE0, 0xCEE0, 0xCEA0, 0xCEF0, 0xCEE0, 0xCF10, 0xCF80, 0xD030, 0xD0A0, 0xD150, 0xD230, + 0xD2A0, 0xD3E0, 0xD4F0, 0xD5E0, 0xD6C0, 0xD7C0, 0xD9C0, 0xDC50, 0xDDE0, 0xDF70, 0xDFD0, 0xDFF0, 0xDFB0, 0xE020, 0xE070, 0xE130, + 0xE280, 0xE3B0, 0xE480, 0xE530, 0xE500, 0xE4D0, 0xE3F0, 0xE370, 0xE270, 0xE1C0, 0xE110, 0xE170, 0xE240, 0xE2F0, 0xE310, 0xE260, + 0xE0C0, 0xDF00, 0xDCB0, 0xDB60, 0xDA20, 0xD950, 0xD730, 0xD550, 0xD290, 0xCE90, 0xCBB0, 0xC980, 0xC750, 0xC4E0, 0xC210, 0xBED0, + 0xBC10, 0xBA10, 0xB8A0, 0xB780, 0xB690, 0xB520, 0xB410, 0xB240, 0xB110, 0xB100, 0xB0D0, 0xB140, 0xB180, 0xB290, 0xB320, 0xB460, + 0xB680, 0xB8C0, 0xBB70, 0xBCE0, 0xBF30, 0xC140, 0xC3D0, 0xC750, 0xCA50, 0xCD20, 0xCFA0, 0xD1A0, 0xD370, 0xD530, 0xD710, 0xD930, + 0xDB50, 0xDCA0, 0xDD30, 0xDCF0, 0xDD00, 0xDDF0, 0xDE50, 0xDDB0, 0xDC70, 0xD9E0, 0xD660, 0xD250, 0xCDB0, 0xC8D0, 0xC410, 0xBE00, + 0xB810, 0xB180, 0xAB00, 0xA410, 0x9DB0, 0x9650, 0x8FB0, 0x8AE0, 0x87D0, 0x8670, 0x85D0, 0x8590, 0x8580, 0x8580, 0x85A0, 0x85D0, + 0x8640, 0x8730, 0x8950, 0x8E80, 0x9630, 0x9E10, 0xA5B0, 0xAD40, 0xB370, 0xB8D0, 0xBE30, 0xC2E0, 0xC740, 0xCBF0, 0xD040, 0xD470, + 0xDA20, 0xDEE0, 0xE3C0, 0xE770, 0xEA30, 0xED30, 0xEFC0, 0xF250, 0xF480, 0xF720, 0xF9F0, 0xFC00, 0xFE60, 0x0060, 0x0210, 0x03B0, + 0x04E0, 0x0600, 0x0790, 0x07B0, 0x08A0, 0x08E0, 0x08D0, 0x08E0, 0x0940, 0x0950, 0x08B0, 0x0780, 0x0700, 0x05D0, 0x0590, 0x05E0, + 0x05C0, 0x0640, 0x0580, 0x0540, 0x0490, 0x0490, 0x0420, 0x0410, 0x0510, 0x0550, 0x05F0, 0x06F0, 0x0730, 0x07A0, 0x0700, 0x0630, + 0x0580, 0x03C0, 0x0350, 0x0290, 0x0160, 0x00B0, 0x0010, 0xFF60, 0xFDC0, 0xFC40, 0xFA80, 0xF880, 0xF740, 0xF5F0, 0xF450, 0xF270, + 0xF090, 0xEEF0, 0xEDE0, 0xEC60, 0xEC20, 0xEAF0, 0xE8E0, 0xE720, 0xE450, 0xE290, 0xDFE0, 0xDDC0, 0xDA50, 0xD710, 0xD330, 0xCEE0, + 0xCA80, 0xC640, 0xC1C0, 0xBCD0, 0xB7D0, 0xB240, 0xAC90, 0xA620, 0xA0B0, 0x9AE0, 0x93F0, 0x8EA0, 0x8A40, 0x87A0, 0x8610, 0x8560, + 0x8510, 0x84F0, 0x84E0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x84B0, + 0x8490, 0x8470, 0x8470, 0x8450, 0x8470, 0x8470, 0x84A0, 0x8480, 0x84B0, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x8510, 0x8530, 0x8530, 0x8550, + 0x8560, 0x8570, 0x8590, 0x8590, 0x8590, 0x85B0, 0x85C0, 0x85E0, 0x85F0, 0x8660, 0x86D0, 0x8750, 0x87C0, 0x8800, 0x8860, 0x88C0, + 0x88E0, 0x88F0, 0x8940, 0x8920, 0x88C0, 0x8800, 0x8740, 0x86A0, 0x8600, 0x8580, 0x8550, 0x8500, 0x84E0, 0x84F0, 0x84B0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8470, + 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83C0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x83C0, 0x83A0, 0x83C0, 0x83C0, 0x83F0, + 0x83F0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x8490, + 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x84F0, 0x8510, 0x8540, 0x85B0, 0x8680, 0x88E0, 0x8F80, 0x9A70, 0xA590, + 0xB2D0, 0xC030, 0xCE40, 0xDD10, 0xEAF0, 0xF910, 0x0560, 0x1130, 0x1B90, 0x2650, 0x2F70, 0x3730, 0x3E60, 0x4460, 0x49D0, 0x4EF0, + 0x5380, 0x5800, 0x5CB0, 0x6030, 0x6400, 0x6740, 0x6AC0, 0x6EB0, 0x7280, 0x7710, 0x7B10, 0x7E40, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, + 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, + 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F20, + 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F80, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, + 0x7F80, 0x7EF0, 0x7F20, 0x7ED0, 0x7F10, 0x7F70, 0x7F20, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, + 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F30, 0x7F10, 0x7E90, 0x7EB0, 0x7EA0, 0x7EF0, 0x7F10, 0x7EB0, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, + 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F30, 0x7EF0, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, + 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F00, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7C80, 0x70C0, 0x65B0, 0x5AD0, 0x5000, 0x4640, 0x3E30, 0x3790, + 0x3330, 0x2FB0, 0x2D80, 0x2B70, 0x2980, 0x2A40, 0x2D00, 0x3230, 0x39A0, 0x43C0, 0x5030, 0x5BE0, 0x66C0, 0x7150, 0x7A30, 0x7EF0, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F90, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7E80, + 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, + 0x7F00, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, + 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F20, 0x7F30, 0x7F00, 0x7F30, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F30, 0x7EE0, 0x7ED0, + 0x7EF0, 0x7F20, 0x7F60, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7F30, 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, + 0x7F00, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EF0, + 0x7F10, 0x7EF0, 0x7EF0, 0x7F70, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, + 0x7EF0, 0x7F00, 0x7F40, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7F10, 0x7F20, 0x7EF0, 0x7E90, 0x7F00, + 0x7F20, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F40, + 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F70, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EC0, + 0x7F10, 0x7EF0, 0x7F70, 0x7EF0, 0x7EC0, 0x7F00, 0x7ED0, 0x7F10, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F10, + 0x7F10, 0x7F20, 0x7EE0, 0x7F70, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7F10, 0x7EF0, + 0x7EF0, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, + 0x7EC0, 0x7ED0, 0x7EF0, 0x7F30, 0x7EF0, 0x7ED0, 0x7F00, 0x7EE0, 0x7F30, 0x7F10, 0x7E90, 0x7EC0, 0x7EF0, 0x7F30, 0x7EE0, 0x7E90, + 0x7ED0, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, + 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x75F0, 0x6B10, 0x60B0, 0x5570, + 0x4AC0, 0x3EF0, 0x33B0, 0x29C0, 0x2050, 0x1890, 0x1230, 0x0B40, 0x03D0, 0xFC70, 0xF320, 0xEB50, 0xE4B0, 0xDF20, 0xDA40, 0xD4D0, + 0xCFB0, 0xC940, 0xC240, 0xB9A0, 0xB050, 0xA640, 0x9B60, 0x90F0, 0x89C0, 0x8690, 0x8560, 0x8510, 0x84E0, 0x84D0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x8460, 0x84D0, 0x84E0, + 0x8500, 0x8510, 0x8530, 0x8580, 0x8600, 0x86F0, 0x8850, 0x8A40, 0x8CC0, 0x9010, 0x9360, 0x9730, 0x9B10, 0xA020, 0xA4A0, 0xA7D0, + 0xAA70, 0xAC90, 0xAFD0, 0xB350, 0xB710, 0xBB50, 0xBEA0, 0xC240, 0xC4A0, 0xC7C0, 0xCA60, 0xCD30, 0xD0D0, 0xD4C0, 0xD7F0, 0xDAD0, + 0xDD30, 0xDFA0, 0xE250, 0xE4F0, 0xE860, 0xEAE0, 0xECF0, 0xEF70, 0xF130, 0xF3A0, 0xF450, 0xF5B0, 0xF560, 0xF3F0, 0xF310, 0xF170, + 0xF120, 0xF190, 0xF1B0, 0xF1E0, 0xF1C0, 0xF0C0, 0xEEA0, 0xEC10, 0xE950, 0xE680, 0xE360, 0xDFA0, 0xDA40, 0xD500, 0xCF20, 0xC8C0, + 0xC250, 0xBB70, 0xB440, 0xAC40, 0xA3E0, 0x9C10, 0x94D0, 0x8ED0, 0x89D0, 0x8710, 0x85E0, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84D0, + 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, + 0x84E0, 0x84F0, 0x84F0, 0x8510, 0x8500, 0x8510, 0x8520, 0x8570, 0x8550, 0x8570, 0x8590, 0x85B0, 0x85E0, 0x8600, 0x8650, 0x86C0, + 0x8730, 0x87C0, 0x8850, 0x88A0, 0x88F0, 0x89C0, 0x8A70, 0x8B80, 0x8C20, 0x8D00, 0x8DC0, 0x8E60, 0x8F80, 0x9080, 0x9240, 0x9400, + 0x9530, 0x96C0, 0x97A0, 0x9980, 0x9BA0, 0x9ED0, 0xA240, 0xA600, 0xA920, 0xACC0, 0xAFE0, 0xB370, 0xB650, 0xB8C0, 0xBA90, 0xBB80, + 0xBBD0, 0xBBD0, 0xBB80, 0xBBE0, 0xBB10, 0xBA40, 0xB960, 0xB8B0, 0xB710, 0xB5D0, 0xB400, 0xB1C0, 0xAEF0, 0xABC0, 0xA930, 0xA7A0, + 0xA6E0, 0xA610, 0xA440, 0xA230, 0xA080, 0x9EC0, 0x9CE0, 0x9C00, 0x9AB0, 0x9A30, 0x9A40, 0x9A90, 0x9A80, 0x9A50, 0x9A60, 0x9A50, + 0x9AE0, 0x9C10, 0x9D60, 0x9E30, 0x9EF0, 0x9F50, 0x9FA0, 0x9FF0, 0xA000, 0xA030, 0xA140, 0xA210, 0xA260, 0xA260, 0xA250, 0xA1F0, + 0xA190, 0xA1B0, 0xA260, 0xA290, 0xA310, 0xA2D0, 0xA2F0, 0xA200, 0xA1A0, 0xA210, 0xA1B0, 0xA190, 0xA110, 0xA050, 0x9FE0, 0x9FF0, + 0xA0C0, 0xA200, 0xA310, 0xA330, 0xA340, 0xA330, 0xA370, 0xA500, 0xA730, 0xA930, 0xABB0, 0xADF0, 0xB030, 0xB2D0, 0xB560, 0xB7E0, + 0xBA50, 0xBC50, 0xBDC0, 0xBFE0, 0xC310, 0xC5E0, 0xC900, 0xCC50, 0xCF60, 0xD1D0, 0xD4E0, 0xD780, 0xDAA0, 0xDE10, 0xE0E0, 0xE3F0, + 0xE630, 0xE910, 0xEC00, 0xEF10, 0xF270, 0xF580, 0xF800, 0xFA70, 0xFB90, 0xFD30, 0xFF20, 0x01E0, 0x04F0, 0x07F0, 0x09C0, 0x0B50, + 0x0B90, 0x0C50, 0x0DA0, 0x0F90, 0x11D0, 0x1400, 0x1610, 0x17B0, 0x18F0, 0x1A60, 0x1BC0, 0x1D00, 0x1EA0, 0x2000, 0x2120, 0x2200, + 0x22D0, 0x2360, 0x23D0, 0x22B0, 0x2120, 0x1FD0, 0x1DF0, 0x1C80, 0x1AA0, 0x18D0, 0x16D0, 0x1430, 0x1170, 0x0DF0, 0x0AB0, 0x0860, + 0x0680, 0x0500, 0x0380, 0x01B0, 0x0060, 0xFF40, 0xFF70, 0x00A0, 0x02A0, 0x0600, 0x0AD0, 0x1100, 0x1820, 0x20D0, 0x2A10, 0x34C0, + 0x3FF0, 0x4BD0, 0x5830, 0x64A0, 0x7140, 0x7C80, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7EE0, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F70, 0x7EF0, 0x7EB0, 0x7F20, 0x7F40, 0x7F40, + 0x7ED0, 0x7E70, 0x7EF0, 0x7F10, 0x7EF0, 0x7E70, 0x7E60, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7BF0, + 0x6A00, 0x5660, 0x3CF0, 0x1E60, 0xFDE0, 0xDB20, 0xC030, 0xACE0, 0xA1C0, 0xA010, 0xA950, 0xBD40, 0xDC30, 0x0280, 0x32B0, 0x5F20, + 0x7ED0, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F10, + 0x7F00, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F10, 0x7EF0, 0x7E90, 0x7EF0, 0x7F20, 0x7E50, 0x7A90, 0x7900, 0x79A0, 0x7B90, 0x7C90, 0x7DA0, + 0x7E00, 0x7EE0, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7EF0, 0x7F40, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, + 0x7F50, 0x7F00, 0x7F20, 0x74D0, 0x6630, 0x5CA0, 0x5540, 0x4F50, 0x4970, 0x41E0, 0x3950, 0x2E50, 0x2180, 0x12F0, 0x0550, 0xF8E0, + 0xF020, 0xEAC0, 0xE880, 0xE6D0, 0xE3A0, 0xDE80, 0xD430, 0xC620, 0xB530, 0xA1C0, 0x8E40, 0x8600, 0x84E0, 0x84B0, 0x8480, 0x8470, + 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x8410, + 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x8400, 0x8430, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8480, 0x8460, 0x8470, 0x8480, 0x8490, + 0x8490, 0x84B0, 0x84D0, 0x84E0, 0x8520, 0x85C0, 0x8800, 0x8E80, 0x98F0, 0xA360, 0xAC50, 0xB560, 0xBD90, 0xC520, 0xCBB0, 0xCFE0, + 0xD3C0, 0xD570, 0xD5D0, 0xD670, 0xD6A0, 0xD650, 0xD550, 0xD320, 0xD060, 0xCCD0, 0xC9E0, 0xC680, 0xC2F0, 0xBF70, 0xBA80, 0xB400, + 0xAD50, 0xA690, 0xA050, 0x88A0, 0x8670, 0x8590, 0x8530, 0x8510, 0x8500, 0x8510, 0x84F0, 0x84F0, 0x84E0, 0x84F0, 0x8510, 0x8530, + 0x8560, 0x85B0, 0x8640, 0x8750, 0x88F0, 0x8BA0, 0x9020, 0x9490, 0x9740, 0x9920, 0x99E0, 0x9B50, 0x9C60, 0x9E30, 0xA040, 0xA1E0, + 0xA340, 0xA3B0, 0xA3A0, 0xA3B0, 0xA4F0, 0xA620, 0xA790, 0xA870, 0xAA50, 0xAC90, 0xB120, 0xB720, 0xBEF0, 0xC790, 0xD030, 0xDAC0, + 0xE540, 0xF220, 0xFE50, 0x0A30, 0x1590, 0x1E70, 0x2510, 0x2A80, 0x2E70, 0x3130, 0x31D0, 0x2FB0, 0x2B60, 0x2470, 0x1CF0, 0x14E0, + 0x0C40, 0x05A0, 0xFEF0, 0xF860, 0xF0E0, 0xE870, 0xE050, 0xD7E0, 0xCF90, 0xC7B0, 0xBF90, 0xB770, 0xAEF0, 0xA800, 0xA1B0, 0x9C00, + 0x9720, 0x92B0, 0x8E60, 0x8AB0, 0x8800, 0x8680, 0x85C0, 0x85A0, 0x8550, 0x8540, 0x8550, 0x8590, 0x85B0, 0x8620, 0x8730, 0x8930, + 0x8CA0, 0x90C0, 0x9610, 0x9BD0, 0xA290, 0xAA90, 0xB2D0, 0xBC70, 0xC500, 0xCE90, 0xD810, 0xE260, 0xEC00, 0xF5F0, 0xFFD0, 0x0900, + 0x12D0, 0x1C10, 0x24D0, 0x2E60, 0x37B0, 0x4070, 0x4970, 0x5160, 0x59D0, 0x6230, 0x68E0, 0x6F50, 0x7430, 0x79A0, 0x7D60, 0x7EF0, + 0x7F10, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, + 0x7F00, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7D30, 0x78B0, 0x7360, 0x6CC0, 0x64D0, 0x5C00, 0x50E0, 0x4520, 0x3830, 0x2D40, 0x22A0, + 0x1950, 0x1100, 0x09E0, 0x0410, 0xFEB0, 0xF8F0, 0xF250, 0xE970, 0xDF70, 0xD250, 0xC330, 0xB1D0, 0x9E20, 0x8B50, 0x8580, 0x84E0, + 0x84C0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, + 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8530, 0x8650, 0x8DA0, 0xA210, 0xB6B0, 0xCBF0, 0xDF70, 0xF270, 0x0360, 0x13F0, 0x22D0, + 0x3130, 0x3E60, 0x4960, 0x5470, 0x5C70, 0x62F0, 0x6850, 0x6B10, 0x6DB0, 0x6F10, 0x6F50, 0x6F90, 0x6EC0, 0x6E80, 0x6DA0, 0x6C60, + 0x6BE0, 0x6AD0, 0x6990, 0x6720, 0x6320, 0x5D70, 0x55C0, 0x4E10, 0x4600, 0x3EB0, 0x3920, 0x3540, 0x33D0, 0x33B0, 0x3400, 0x35F0, + 0x3860, 0x3CB0, 0x4240, 0x4890, 0x5030, 0x5700, 0x5D60, 0x6410, 0x68C0, 0x6D20, 0x6F90, 0x70B0, 0x7160, 0x70C0, 0x6F50, 0x6DE0, + 0x6AF0, 0x6880, 0x6530, 0x6260, 0x5FE0, 0x5ED0, 0x6210, 0x6800, 0x7370, 0x7E70, 0x7F30, 0x7EF0, 0x7E90, 0x7ED0, 0x7F00, 0x7F00, + 0x7F10, 0x7E90, 0x7ED0, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x1390, 0xF4A0, 0xD8C0, 0xC0E0, 0xACE0, 0x9B10, + 0x8CE0, 0x86C0, 0x8530, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, + 0x8420, 0x8430, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, + 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8470, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x84B0, 0x84A0, 0x84C0, 0x84F0, 0x8580, 0x88C0, 0x9930, 0xAA80, 0xB8D0, 0xC600, 0xD160, + 0xDA50, 0xE3B0, 0xEC10, 0xF470, 0xFD80, 0x0600, 0x0EB0, 0x1890, 0x2130, 0x2930, 0x30A0, 0x3620, 0x3AF0, 0x3E30, 0x4100, 0x4360, + 0x4630, 0x4900, 0x4A60, 0x4A70, 0x49F0, 0x4870, 0x4640, 0x4390, 0x4030, 0x3CE0, 0x3890, 0x33F0, 0x2F50, 0x2AE0, 0x26E0, 0x2290, + 0x1E70, 0x1A50, 0x14D0, 0x0F50, 0x0960, 0x03F0, 0xFE10, 0xF890, 0xF2E0, 0xECE0, 0xE670, 0xDEE0, 0xD780, 0xCFF0, 0xC7D0, 0xC070, + 0xBA50, 0xB580, 0xB1F0, 0xB0D0, 0xB0F0, 0xB290, 0xB5C0, 0xB9E0, 0xBDF0, 0xC1D0, 0xC5C0, 0xCA60, 0xCFA0, 0xD650, 0xDC60, 0xE2E0, + 0xE950, 0xEE50, 0xF370, 0xF7C0, 0xFB40, 0xFE10, 0xFFF0, 0x0250, 0x0540, 0x0710, 0x08A0, 0x0A00, 0x0AD0, 0x0A70, 0x0960, 0x07B0, + 0x0630, 0x0620, 0x05C0, 0x0610, 0x06D0, 0x0720, 0x0940, 0x0C50, 0x11A0, 0x17C0, 0x1F90, 0x2870, 0x3240, 0x3C90, 0x4780, 0x5170, + 0x5BA0, 0x64F0, 0x6BB0, 0x70A0, 0x73C0, 0x75D0, 0x77F0, 0x7A20, 0x7CA0, 0x7E40, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7EA0, 0x7F20, + 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F80, 0x7F10, + 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F00, 0x7EE0, + 0x7ED0, 0x7EF0, 0x7F60, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7F30, 0x7F10, 0x7E70, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, + 0x7F00, 0x7F00, 0x7F10, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7F10, + 0x7F20, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F80, 0x7EF0, 0x7EE0, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7ED0, + 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F30, 0x7ED0, 0x7E90, 0x7F10, + 0x7F20, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x6610, 0x45A0, 0x2240, 0xFEF0, 0xDFA0, 0xC6D0, 0xB8F0, 0xB570, 0xBD60, 0xCD60, + 0xDF10, 0xEEF0, 0xF900, 0xFD00, 0xFBF0, 0xF830, 0xF470, 0xF300, 0xF530, 0xFAB0, 0x0180, 0x0940, 0x0F10, 0x1270, 0x1400, 0x1290, + 0x10F0, 0x0EC0, 0x0D50, 0x0C90, 0x0CD0, 0x0E40, 0x0E90, 0x0DD0, 0x0CB0, 0x0B00, 0x0980, 0x08E0, 0x0920, 0x0A40, 0x0C30, 0x1060, + 0x1520, 0x1BC0, 0x24B0, 0x3000, 0x3B40, 0x6860, 0x70C0, 0x7760, 0x7C40, 0x7ED0, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, + 0x7ED0, 0x7F00, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7EB0, 0x7CE0, 0x79C0, + 0x7780, 0x7590, 0x7370, 0x72E0, 0x7100, 0x6F10, 0x6C20, 0x6910, 0x6730, 0x6460, 0x61C0, 0x5E80, 0x5AF0, 0x5860, 0x55A0, 0x51D0, + 0x4E60, 0x49A0, 0x4510, 0x3F10, 0x38B0, 0x31A0, 0x29F0, 0x22F0, 0x1B20, 0x1380, 0x0C90, 0x0540, 0xFEE0, 0xF850, 0xF1B0, 0xEB00, + 0xE4E0, 0xDEF0, 0xD930, 0xD340, 0xCCC0, 0xC5D0, 0xBF30, 0xB740, 0xAEF0, 0xA670, 0x9CD0, 0x9460, 0x8D20, 0x8850, 0x8620, 0x8550, + 0x8500, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84F0, 0x8540, 0x8660, 0x8B40, + 0x98D0, 0xA700, 0xB570, 0xC2F0, 0xCFC0, 0xDC10, 0xE730, 0xF1F0, 0xFAF0, 0x0250, 0x0740, 0x0A40, 0x0B10, 0x0870, 0x0400, 0xFCC0, + 0xF260, 0xE690, 0xD980, 0xCC80, 0xBFD0, 0xB5E0, 0xAF70, 0xAC90, 0xAEE0, 0xB5D0, 0xBFF0, 0xCC60, 0xDB00, 0xEBA0, 0xFC80, 0x0DF0, + 0x2000, 0x30D0, 0x4280, 0x51E0, 0x6140, 0x6EF0, 0x7AB0, 0x7EF0, 0x7EF0, 0x7F90, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F70, 0x7F10, + 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F00, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F50, 0x7F10, 0x7EB0, + 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F00, + 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EE0, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, + 0x7EF0, 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7EF0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, + 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7EC0, 0x7F40, + 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F80, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, + 0x7590, 0x6980, 0x5C20, 0x4D80, 0x3DC0, 0x2DD0, 0x1DA0, 0x0BF0, 0xFCB0, 0xEDA0, 0xDE80, 0xD010, 0xC190, 0xB440, 0xA720, 0x9AF0, + 0x8F40, 0x88D0, 0x8630, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84F0, 0x8500, 0x8520, 0x8560, 0x85D0, + 0x8670, 0x8770, 0x8900, 0x8B20, 0x8E20, 0x90C0, 0x9330, 0x94C0, 0x94E0, 0x92B0, 0x91E0, 0x90D0, 0x8FF0, 0x8E10, 0x8BD0, 0x8A20, + 0x8890, 0x8750, 0x8680, 0x85D0, 0x8590, 0x8550, 0x8530, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84F0, 0x84E0, 0x8510, 0x84E0, 0x84F0, + 0x8520, 0x8520, 0x8540, 0x8570, 0x85B0, 0x8610, 0x86C0, 0x8780, 0x8870, 0x8930, 0x8990, 0x8970, 0x8890, 0x87B0, 0x8720, 0x86E0, + 0x86D0, 0x8720, 0x87F0, 0x8940, 0x8BB0, 0x8F70, 0x9520, 0x9BA0, 0xA230, 0xA950, 0xB130, 0xB840, 0xBF40, 0xC630, 0xCDC0, 0xD540, + 0xDDC0, 0xE690, 0xF000, 0xFB50, 0x0670, 0x1290, 0x1F50, 0x2C30, 0x3980, 0x4700, 0x5460, 0x6200, 0x6F70, 0x7A70, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7FA0, 0x7F10, 0x7F20, 0x7F30, + 0x7EF0, 0x7F50, 0x7F20, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F00, + 0x7F10, 0x7F00, 0x7EE0, 0x7ED0, 0x7EB0, 0x7F20, 0x7F40, 0x7E80, 0x7EF0, 0x7F00, 0x7F00, 0x7F30, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, + 0x7EF0, 0x7E80, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7EB0, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F50, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7F00, 0x7F00, 0x7B90, + 0x62B0, 0x59F0, 0x5C90, 0x64D0, 0x6C30, 0x6EF0, 0x6CC0, 0x6580, 0x5E20, 0x5B70, 0x5FB0, 0x6BB0, 0x7A70, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F30, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F80, 0x7F00, 0x7EF0, 0x7F30, 0x7F20, 0x7F80, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, + 0x7F60, 0x7F00, 0x7E10, 0x7D10, 0x7BB0, 0x7B50, 0x7B10, 0x79B0, 0x77A0, 0x71F0, 0x6530, 0x5240, 0x36A0, 0x14D0, 0xED70, 0xC8C0, + 0xA790, 0x8D80, 0x85F0, 0x8510, 0x84F0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84E0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84D0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8550, 0x85F0, 0x8720, 0x89C0, 0x8FA0, 0x9730, 0x9F70, + 0xA670, 0xACF0, 0xB380, 0xB9C0, 0xC0B0, 0xC710, 0xCE90, 0xE950, 0xF110, 0xF940, 0x01A0, 0x0B00, 0x13C0, 0x1CD0, 0x2630, 0x2EE0, + 0x38E0, 0x4190, 0x48B0, 0x4ED0, 0x52B0, 0x5570, 0x5720, 0x56F0, 0x5710, 0x55E0, 0x54E0, 0x5200, 0x4F00, 0x4C00, 0x4740, 0x41F0, + 0x3B30, 0x33C0, 0x2BB0, 0x22D0, 0x1A90, 0x10C0, 0x0750, 0xFE00, 0xF460, 0xEA50, 0xDF90, 0xD410, 0xC7F0, 0xBB80, 0xADC0, 0xA0A0, + 0x9390, 0x89F0, 0x8620, 0x8530, 0x84F0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84A0, 0x84B0, + 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x8500, 0x84E0, 0x84F0, 0x84E0, 0x8510, 0x8520, 0x8530, 0x8540, 0x8540, 0x8550, 0x8550, 0x8570, + 0x8580, 0x85B0, 0x85E0, 0x8630, 0x8670, 0x8700, 0x8780, 0x8860, 0x89B0, 0x8BB0, 0x8EF0, 0x9320, 0x9900, 0x9F60, 0xA590, 0xAC70, + 0xB2C0, 0xB830, 0xBDA0, 0xC210, 0xC5D0, 0xC950, 0xCD50, 0xD0F0, 0xD490, 0xD780, 0xD9C0, 0xDAC0, 0xDBF0, 0xDC30, 0xDC60, 0xDBB0, + 0xD9F0, 0xD7E0, 0xD560, 0xD1F0, 0xCDA0, 0xC7E0, 0xC1A0, 0xBA50, 0xB280, 0xA9A0, 0xA070, 0x97F0, 0x8FB0, 0x8A00, 0x86F0, 0x85C0, + 0x8550, 0x8510, 0x8500, 0x84E0, 0x84D0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, + 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x8520, 0x8530, 0x8540, 0x8560, 0x8580, + 0x85B0, 0x85F0, 0x8630, 0x8670, 0x86D0, 0x8700, 0x8720, 0x8710, 0x8780, 0x87A0, 0x87D0, 0x8790, 0x8770, 0x8730, 0x8720, 0x86B0, + 0x8680, 0x8670, 0x8660, 0x8640, 0x8630, 0x8620, 0x8620, 0x8600, 0x8610, 0x8620, 0x8630, 0x8620, 0x8660, 0x8630, 0x8660, 0x8690, + 0x86E0, 0x8740, 0x87A0, 0x87F0, 0x8840, 0x8850, 0x8880, 0x88C0, 0x8970, 0x8A80, 0x8BA0, 0x8C50, 0x8C90, 0x8C10, 0x8B10, 0x8990, + 0x8880, 0x87A0, 0x86E0, 0x8650, 0x85D0, 0x8590, 0x8560, 0x8540, 0x8530, 0x8530, 0x8530, 0x8530, 0x8530, 0x8540, 0x8560, 0x85A0, + 0x85D0, 0x85F0, 0x85F0, 0x85E0, 0x85D0, 0x85D0, 0x85D0, 0x85F0, 0x8610, 0x8610, 0x8600, 0x85F0, 0x85C0, 0x8590, 0x8560, 0x8530, + 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84E0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, + 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8530, + 0x8530, 0x8540, 0x8550, 0x8550, 0x8550, 0x8560, 0x8580, 0x85C0, 0x8600, 0x8640, 0x8670, 0x86B0, 0x86D0, 0x8730, 0x87D0, 0x88C0, + 0x89F0, 0x8B40, 0x8CE0, 0x8E30, 0x9010, 0x9190, 0x9350, 0x9420, 0x9550, 0x96B0, 0x9850, 0x9A40, 0x9BD0, 0x9D30, 0x9E40, 0x9E50, + 0x9D70, 0x9D10, 0x9CF0, 0x9DE0, 0x9F80, 0xA0F0, 0xA270, 0xA2D0, 0xA310, 0xA330, 0xA3D0, 0xA4A0, 0xA4E0, 0xA4C0, 0xA3A0, 0xA2D0, + 0xA260, 0xA250, 0xA320, 0xA460, 0xA4E0, 0xA480, 0xA3E0, 0xA310, 0xA2B0, 0xA210, 0xA250, 0xA290, 0xA180, 0xA0B0, 0xA000, 0x9F90, + 0xA040, 0xA130, 0xA220, 0xA2C0, 0xA2E0, 0xA260, 0xA220, 0xA240, 0xA340, 0xA3A0, 0xA330, 0xA2C0, 0xA1D0, 0xA110, 0xA110, 0xA0A0, + 0x9FD0, 0x9EC0, 0x9DB0, 0x9C40, 0x9AC0, 0x9900, 0x97C0, 0x9740, 0x97B0, 0x9850, 0x98F0, 0x9960, 0x9A30, 0x9B60, 0x9D70, 0x9F40, + 0xA120, 0xA3D0, 0xA650, 0xAAB0, 0xB070, 0xB650, 0xBC50, 0xC1F0, 0xD5D0, 0xDB30, 0xE040, 0xE450, 0xE7E0, 0xEA00, 0xEC30, 0xEDD0, + 0xEEB0, 0xEFA0, 0xEF70, 0xEF20, 0xEE50, 0xED40, 0xEBC0, 0xE8F0, 0xE550, 0xE090, 0xDB20, 0xD480, 0xCDE0, 0xC6B0, 0xBF70, 0xB700, + 0xAD50, 0xA270, 0x9690, 0x8BE0, 0x86B0, 0x8550, 0x8500, 0x84D0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, + 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x8500, 0x8560, 0x8660, + 0x8870, 0x8B90, 0x8DF0, 0x8EF0, 0x8E00, 0x8C40, 0x8A70, 0x88C0, 0x8780, 0x8670, 0x85D0, 0x8570, 0x8540, 0x8520, 0x8500, 0x84F0, + 0x84E0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8480, 0x8480, 0x8490, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8500, + 0x8540, 0x85E0, 0x8790, 0x8D30, 0x96C0, 0xA0B0, 0xAA10, 0xB380, 0xBC30, 0xC440, 0xC9C0, 0xCEB0, 0xD3E0, 0xD950, 0xDFF0, 0xE7C0, + 0xF080, 0xF880, 0xFFC0, 0x0460, 0x0680, 0x06C0, 0x0490, 0x0230, 0xFE70, 0xF9E0, 0xF5A0, 0xF0D0, 0xEDC0, 0xEA90, 0xE890, 0xE830, + 0xE8A0, 0xE9D0, 0xEBF0, 0xEDE0, 0xF0F0, 0xF3D0, 0xF720, 0xFAE0, 0xFE90, 0x02D0, 0x06B0, 0x0AA0, 0x0EA0, 0x1280, 0x1620, 0x17B0, + 0x1830, 0x1730, 0x14E0, 0x11C0, 0x0C90, 0x07C0, 0x0210, 0xFB90, 0xF630, 0xF140, 0xECE0, 0xE950, 0xE520, 0xE180, 0xDDE0, 0xD9B0, + 0xD6B0, 0xD2D0, 0xD000, 0xCD00, 0xCA80, 0xC890, 0xC750, 0xC720, 0xC6F0, 0xC710, 0xC790, 0xC840, 0xCA50, 0xCC70, 0xCFA0, 0xD3E0, + 0xD820, 0xDF00, 0xE5F0, 0xEDF0, 0xF600, 0xFD70, 0x03E0, 0x0840, 0x0B90, 0x15A0, 0x1850, 0x1B70, 0x1EB0, 0x2140, 0x2350, 0x2520, + 0x26C0, 0x2750, 0x2890, 0x2930, 0x2A40, 0x2C10, 0x2D30, 0x2F20, 0x30D0, 0x3160, 0x3220, 0x3240, 0x31D0, 0x3230, 0x3320, 0x35E0, + 0x37F0, 0x3960, 0x3A80, 0x3AD0, 0x3BB0, 0x3C20, 0x3CE0, 0x3D90, 0x3E30, 0x3F70, 0x4050, 0x4110, 0x4170, 0x4170, 0x4180, 0x3FF0, + 0x3EA0, 0x3CC0, 0x3A90, 0x3900, 0x3780, 0x3590, 0x3330, 0x30A0, 0x2E20, 0x2AF0, 0x27D0, 0x24E0, 0x20D0, 0x1CC0, 0x17E0, 0x1240, + 0x0D90, 0x09D0, 0x06E0, 0x04C0, 0x0240, 0x0170, 0x00E0, 0x02C0, 0x06D0, 0x0CA0, 0x1460, 0x1C10, 0x2230, 0x2590, 0x24A0, 0x21B0, + 0x1C00, 0x1400, 0x0B90, 0x02F0, 0xFCF0, 0xF990, 0xF9B0, 0xFDE0, 0x0460, 0x0EA0, 0x1A30, 0x26B0, 0x3320, 0x4070, 0x4DF0, 0x5B30, + 0x6870, 0x7350, 0x7BF0, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, + 0x7ED0, 0x7E90, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7EF0, 0x7F50, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7F10, 0x7F10, 0x7EE0, + 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F50, 0x7F20, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7ED0, 0x7F00, 0x7F50, + 0x7F20, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F00, 0x7EF0, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F40, 0x7F10, 0x7F10, + 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, + 0x7F50, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7F00, 0x7EF0, 0x7F50, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F30, + 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7ED0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, + 0x7F00, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, + 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F30, + 0x7F20, 0x7E90, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7E60, 0x7D90, 0x7C10, 0x7AE0, 0x7800, 0x75B0, 0x7260, 0x6E00, 0x6A50, + 0x6600, 0x61E0, 0x5E40, 0x59D0, 0x55B0, 0x5240, 0x4ED0, 0x4BF0, 0x48A0, 0x4570, 0x4290, 0x4130, 0x4060, 0x3ED0, 0x3E90, 0x3EE0, + 0x3F70, 0x4260, 0x4520, 0x4830, 0x4BE0, 0x4F20, 0x5240, 0x55B0, 0x59E0, 0x5E20, 0x6120, 0x6410, 0x66C0, 0x6850, 0x69D0, 0x6A90, + 0x6B40, 0x6B40, 0x6B10, 0x6A70, 0x69E0, 0x6850, 0x6710, 0x6620, 0x64E0, 0x6390, 0x61D0, 0x5FF0, 0x5D80, 0x5B50, 0x5860, 0x5560, + 0x51D0, 0x4D60, 0x48A0, 0x4400, 0x3E70, 0x37F0, 0x30B0, 0x27B0, 0x1E70, 0x1420, 0x0A60, 0x00D0, 0xF710, 0xEEA0, 0xE630, 0xDD50, + 0xD400, 0xCB40, 0xC260, 0xB980, 0xB0B0, 0xA8B0, 0xA120, 0x9A50, 0x93C0, 0x8D90, 0x89F0, 0x87D0, 0x86A0, 0x85E0, 0x8580, 0x8540, + 0x8520, 0x84F0, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8510, 0x8520, 0x8520, 0x8560, 0x8540, 0x8550, 0x8570, 0x8580, 0x8590, + 0x85A0, 0x85B0, 0x85D0, 0x85F0, 0x8600, 0x8620, 0x8620, 0x8620, 0x8630, 0x8640, 0x8640, 0x8650, 0x8660, 0x8680, 0x86A0, 0x86A0, + 0x86C0, 0x86C0, 0x86D0, 0x86F0, 0x8700, 0x8730, 0x8770, 0x8790, 0x87F0, 0x8880, 0x8940, 0x89B0, 0x8A60, 0x8B70, 0x8C90, 0x8E40, + 0x8FB0, 0x9170, 0x93F0, 0x9680, 0x9930, 0x9C70, 0xA030, 0xA3B0, 0xA780, 0xAB70, 0xAF50, 0xB2B0, 0xB6E0, 0xBAF0, 0xBEC0, 0xC2F0, + 0xC650, 0xC9F0, 0xCD60, 0xD0E0, 0xD3B0, 0xD660, 0xD8C0, 0xDAC0, 0xDCE0, 0xDE70, 0xE000, 0xE130, 0xE1E0, 0xE1B0, 0xE080, 0xDE60, + 0xDC70, 0xDA00, 0xD810, 0xD620, 0xD470, 0xD2E0, 0xD090, 0xCE40, 0xCBC0, 0xC990, 0xC800, 0xC6D0, 0xC6B0, 0xC700, 0xC850, 0xCAA0, + 0xCCA0, 0xCF90, 0xD220, 0xD510, 0xD840, 0xDB60, 0xDF00, 0xE340, 0xE7B0, 0xEC30, 0xF0E0, 0xF4B0, 0xF840, 0xFC30, 0x0050, 0x03F0, + 0x06B0, 0x0930, 0x0BC0, 0x0EF0, 0x1280, 0x1570, 0x18C0, 0x1BE0, 0x1DF0, 0x2120, 0x2300, 0x2530, 0x27F0, 0x2A70, 0x2E20, 0x3050, + 0x33A0, 0x35C0, 0x3870, 0x3AF0, 0x3C80, 0x3F00, 0x4090, 0x4230, 0x44A0, 0x4690, 0x49B0, 0x4D00, 0x4FE0, 0x5390, 0x56A0, 0x59C0, + 0x5C90, 0x5E90, 0x61A0, 0x6500, 0x6840, 0x6BB0, 0x6F20, 0x7340, 0x7680, 0x79B0, 0x7C60, 0x7E50, 0x7F10, 0x7F20, 0x7F60, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F50, 0x7EF0, 0x7F00, 0x7F40, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, + 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, + 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F00, 0x7F20, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, + 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7F20, + 0x7F00, 0x7EF0, 0x7F50, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F00, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F50, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, + 0x7F20, 0x7F10, 0x7EB0, 0x7F10, 0x7EF0, 0x7460, 0x63F0, 0x4FC0, 0x3C70, 0x2950, 0x1710, 0x06A0, 0xF600, 0xE5D0, 0xD510, 0xC3C0, + 0xB160, 0xA000, 0x8F40, 0x86F0, 0x8520, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x84A0, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8460, 0x84C0, 0x84F0, 0x8500, 0x8540, 0x85B0, 0x8700, 0x8A40, + 0x90B0, 0x97F0, 0x9F90, 0xA5A0, 0xAB80, 0xAF30, 0xB2C0, 0xB420, 0xB5B0, 0xB600, 0xB580, 0xB7C0, 0xB990, 0xBB40, 0xBCC0, 0xBE80, + 0xC100, 0xC410, 0xC7E0, 0xCB60, 0xCE90, 0xD1D0, 0xD410, 0xD710, 0xDA40, 0xDDB0, 0xE1A0, 0xE4D0, 0xE830, 0xEAC0, 0xED70, 0xF090, + 0xF330, 0xF6C0, 0xF9C0, 0xFB50, 0xFD40, 0xFDE0, 0xFED0, 0xFFD0, 0x00D0, 0x01C0, 0x0250, 0x0280, 0x01C0, 0x00F0, 0x01C0, 0x02C0, + 0x04E0, 0x0690, 0x0830, 0x09B0, 0x0AF0, 0x0D10, 0x1020, 0x1360, 0x16F0, 0x1A00, 0x1C80, 0x1F80, 0x22D0, 0x2770, 0x2B60, 0x3000, + 0x33D0, 0x36A0, 0x3960, 0x3AD0, 0x3B50, 0x3BA0, 0x3A90, 0x3A10, 0x38E0, 0x3760, 0x3710, 0x3710, 0x38F0, 0x3990, 0x3990, 0x3A20, + 0x39A0, 0x38B0, 0x3750, 0x3560, 0x3390, 0x30B0, 0x2D50, 0x2920, 0x2440, 0x1EB0, 0x1820, 0x1160, 0x0A30, 0x0260, 0xFAA0, 0xF2C0, + 0xEBB0, 0xE490, 0xDC00, 0xD1D0, 0xC630, 0xB920, 0xA8D0, 0x95B0, 0x8830, 0x8520, 0x84D0, 0x84A0, 0x8480, 0x8470, 0x8470, 0x8450, + 0x8440, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, + 0x83F0, 0x8400, 0x8440, 0x8440, 0x8430, 0x8440, 0x8460, 0x8450, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x84D0, 0x84C0, 0x84B0, + 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8540, 0x8610, 0x8890, 0x91B0, 0x9E60, 0xA910, 0xB1B0, 0xB760, 0xBC40, 0xC060, 0xC400, 0xC7C0, + 0xCBD0, 0xD010, 0xD560, 0xDA20, 0xDF60, 0xE580, 0xEAE0, 0xEFD0, 0xF430, 0xF8B0, 0xFDE0, 0x0370, 0x0960, 0x0F00, 0x1440, 0x19B0, + 0x1F00, 0x2620, 0x2DD0, 0x35F0, 0x3E80, 0x4640, 0x4E90, 0x55B0, 0x5BF0, 0x62D0, 0x68B0, 0x6F00, 0x7440, 0x78B0, 0x7BA0, 0x7CE0, + 0x7D90, 0x7DB0, 0x7D70, 0x7CE0, 0x7B50, 0x7980, 0x76F0, 0x73D0, 0x71B0, 0x6E40, 0x6B60, 0x6680, 0x6030, 0x5960, 0x5180, 0x49D0, + 0x4320, 0x3C10, 0x3610, 0x2EA0, 0x26A0, 0x1DC0, 0x13D0, 0x0A00, 0xFE40, 0xF3F0, 0xE9E0, 0xE040, 0xD8A0, 0xD290, 0xCDF0, 0xCAA0, + 0xC870, 0xC6B0, 0xC520, 0xC3E0, 0xC290, 0xC2B0, 0xC350, 0xC3A0, 0xC420, 0xC530, 0xC600, 0xC800, 0xCB30, 0xCF70, 0xD500, 0xDA90, + 0xE050, 0xE640, 0xECC0, 0xF4F0, 0xFC60, 0x04F0, 0x0D90, 0x1630, 0x1F40, 0x2780, 0x3090, 0x39B0, 0x4350, 0x4C50, 0x5470, 0x5CE0, + 0x6480, 0x6B80, 0x7360, 0x7A80, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F50, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, + 0x7EF0, 0x7ED0, 0x7F10, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7DD0, 0x7080, 0x6040, 0x4E90, 0x3C70, 0x2B20, 0x1D10, 0x1450, 0x1270, 0x1700, 0x2120, + 0x2FA0, 0x3F80, 0x4F20, 0x5DD0, 0x6A90, 0x74A0, 0x7B60, 0x7E90, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7E60, 0x6A60, 0x5640, 0x4150, 0x2AE0, 0x16F0, 0x0280, 0xED80, 0xD8F0, 0xC560, 0xB460, 0xA5A0, 0x9B00, 0x92D0, + 0x8E00, 0x8A70, 0x8800, 0x8660, 0x8570, 0x8510, 0x84E0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, + 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84A0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84D0, 0x84D0, + 0x84E0, 0x8480, 0x84F0, 0x8500, 0x8530, 0x8520, 0x8530, 0x8560, 0x8520, 0x85D0, 0x8630, 0x86C0, 0x8790, 0x8870, 0x89B0, 0x8B30, + 0x8D70, 0x8F50, 0x9210, 0x94D0, 0x97D0, 0x9A90, 0x9E30, 0xA2C0, 0xA770, 0xABF0, 0xB160, 0xB5F0, 0xBAD0, 0xBF60, 0xC370, 0xC670, + 0xC8D0, 0xCB80, 0xCC90, 0xCDB0, 0xCDD0, 0xCD40, 0xCD70, 0xCC60, 0xCBA0, 0xCA90, 0xC8A0, 0xC770, 0xC690, 0xC4C0, 0xC2D0, 0xC030, + 0xBEF0, 0xBDB0, 0xBCE0, 0xBCC0, 0xBC50, 0xBC90, 0xBC30, 0xBC20, 0xBC40, 0xBB20, 0xBAA0, 0xB8A0, 0xB730, 0xB570, 0xB3E0, 0xB1D0, + 0xAFE0, 0xAE70, 0xABF0, 0xA940, 0xA730, 0xA580, 0xA440, 0xA2D0, 0xA230, 0xA220, 0xA250, 0xA3B0, 0xA560, 0xA7D0, 0xAB70, 0xAEF0, + 0xB320, 0xB760, 0xBC10, 0xC270, 0xCA20, 0xD1B0, 0xD9D0, 0xE1E0, 0xEA20, 0xF190, 0xF8B0, 0x00A0, 0x06F0, 0x0D00, 0x1120, 0x1370, + 0x1510, 0x14B0, 0x1420, 0x1280, 0x0EF0, 0x0B20, 0x0500, 0xFE90, 0xF730, 0xEF00, 0xE740, 0xDEA0, 0xD5B0, 0xCD60, 0xC3C0, 0xBA00, + 0xB120, 0xA880, 0xA010, 0x9880, 0x9240, 0x8D10, 0x85C0, 0x8560, 0x8530, 0x8560, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8510, + 0x8520, 0x8530, 0x8550, 0x8570, 0x85B0, 0x8610, 0x86B0, 0x87C0, 0x8910, 0x8AF0, 0x8DE0, 0x9200, 0x95A0, 0x9990, 0x9C50, 0x9E60, + 0xA110, 0xA310, 0xA4E0, 0xA6C0, 0xA8C0, 0xAAC0, 0xACC0, 0xAEC0, 0xB0A0, 0xB1B0, 0xB370, 0xB460, 0xB590, 0xB750, 0xB840, 0xBA60, + 0xBB50, 0xBC70, 0xBD40, 0xBD60, 0xBDD0, 0xBCC0, 0xBB00, 0xB9B0, 0xB830, 0xB6A0, 0xB480, 0xB150, 0xADF0, 0xA9F0, 0xA5E0, 0xA110, + 0x9D70, 0x99E0, 0x95D0, 0x9260, 0x8F30, 0x8C80, 0x8A70, 0x88B0, 0x8780, 0x86C0, 0x8640, 0x85F0, 0x85A0, 0x8570, 0x8530, 0x8510, + 0x8510, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, + 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8530, 0x8540, + 0x8550, 0x8570, 0x8590, 0x85D0, 0x8610, 0x8680, 0x86F0, 0x8790, 0x8850, 0x8950, 0x8A60, 0x8BC0, 0x8DD0, 0x9080, 0x9340, 0x95A0, + 0x97D0, 0x9A60, 0x9CB0, 0x9F20, 0xA200, 0xA4A0, 0xA7C0, 0xAA00, 0xAC40, 0xAE70, 0xB070, 0xB2C0, 0xB580, 0xB840, 0xBB30, 0xBC60, + 0xBDA0, 0xBF20, 0xC0B0, 0xC250, 0xC370, 0xC4B0, 0xC550, 0xC5C0, 0xC5C0, 0xC4F0, 0xC4E0, 0xC450, 0xC380, 0xC200, 0xC070, 0xBE60, + 0xBBF0, 0xBA20, 0xB8E0, 0xB690, 0xB3A0, 0xB080, 0xADA0, 0xAB00, 0xA770, 0xA3C0, 0xA090, 0x9CE0, 0x98F0, 0x94F0, 0x91E0, 0x8EB0, + 0x8C30, 0x8A00, 0x8840, 0x8700, 0x8630, 0x85B0, 0x8580, 0x8550, 0x8530, 0x8530, 0x8500, 0x8510, 0x8500, 0x8500, 0x8500, 0x8500, + 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8510, 0x8510, 0x8520, 0x8520, 0x8530, 0x8550, 0x8570, 0x8580, 0x85C0, 0x8610, 0x8650, + 0x86A0, 0x86F0, 0x8750, 0x8770, 0x87F0, 0x8820, 0x87E0, 0x8760, 0x86E0, 0x8670, 0x8610, 0x85C0, 0x8580, 0x8560, 0x8530, 0x8520, + 0x8500, 0x8500, 0x8510, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8520, 0x8580, + 0x86C0, 0x8D60, 0x9D40, 0xAE70, 0xC1B0, 0xD710, 0xEE00, 0x06C0, 0x20E0, 0x3B20, 0x5790, 0x6FA0, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, + 0x7EE0, 0x7F60, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7EA0, 0x7EC0, 0x7EC0, + 0x7F10, 0x7F20, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7930, 0x6C80, + 0x5F20, 0x4F40, 0x3ED0, 0x2EB0, 0x1E70, 0x1060, 0x02F0, 0xF860, 0xF120, 0xEBF0, 0xEAB0, 0xEA60, 0xEA50, 0xEA10, 0xE7F0, 0xE340, + 0xDB80, 0xD290, 0xC800, 0xBE60, 0xB4D0, 0xAB60, 0xA0E0, 0x9680, 0x8D60, 0x8820, 0x8630, 0x8590, 0x8560, 0x8570, 0x85E0, 0x8730, + 0x8CC0, 0x9A90, 0xA8C0, 0xB550, 0xC060, 0xC9F0, 0xD310, 0xDC00, 0xE660, 0xF0E0, 0xFB50, 0x0670, 0x0F00, 0x1710, 0x1E30, 0x23C0, + 0x29E0, 0x2E50, 0x3310, 0x3770, 0x3C80, 0x42E0, 0x4780, 0x4BD0, 0x4FA0, 0x5340, 0x5690, 0x5960, 0x5C80, 0x6050, 0x63F0, 0x67A0, + 0x6B20, 0x6D50, 0x6F90, 0x7160, 0x72D0, 0x7510, 0x76F0, 0x78A0, 0x7A00, 0x7B50, 0x7C90, 0x7D30, 0x7E00, 0x7E30, 0x7EA0, 0x7EC0, + 0x7E90, 0x7E90, 0x7E60, 0x7E40, 0x7E70, 0x7EA0, 0x7ED0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F10, 0x7F30, 0x7F30, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, + 0x7EF0, 0x7F30, 0x7F20, 0x7F10, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F70, 0x7F30, 0x7F00, 0x7F00, 0x7F10, 0x7F30, + 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7F00, 0x7EE0, 0x7EC0, 0x7EC0, 0x7EF0, 0x7F50, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, + 0x7ED0, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7EB0, 0x7F30, 0x7F00, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7F00, 0x7EC0, + 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, 0x7F50, 0x7F10, 0x7F60, + 0x7F20, 0x7F10, 0x7EF0, 0x7EF0, 0x7F90, 0x7F10, 0x7F00, 0x7EE0, 0x7EE0, 0x7F70, 0x7730, 0x6AA0, 0x5F60, 0x5280, 0x4660, 0x3B50, + 0x30D0, 0x2850, 0x2130, 0x1B90, 0x1790, 0x13D0, 0x1140, 0x0EF0, 0x0DD0, 0x0E60, 0x0F20, 0x1230, 0x1620, 0x1AA0, 0x1FC0, 0x2530, + 0x2AC0, 0x3070, 0x3550, 0x3A50, 0x3EE0, 0x4380, 0x4810, 0x4CF0, 0x53C0, 0x59D0, 0x6010, 0x66B0, 0x6CF0, 0x73D0, 0x79D0, 0x7E30, + 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, + 0x7E90, 0x7EF0, 0x7EE0, 0x7F30, 0x7EB0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F60, + 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F00, 0x7EE0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7F00, 0x7300, 0x46D0, 0x2030, + 0xFC80, 0xE380, 0xD1B0, 0xC5B0, 0xBF00, 0xB9A0, 0xB4C0, 0xAF40, 0xA8B0, 0xA1D0, 0x9A40, 0x92B0, 0x8BB0, 0x8760, 0x85A0, 0x8510, + 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8410, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, + 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, + 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8530, 0x8560, 0x85B0, 0x8630, 0x86E0, 0x87B0, 0x88F0, 0x89F0, 0x8AB0, 0x8B90, 0x8C10, 0x8DC0, + 0x9020, 0x9350, 0x9820, 0x9E50, 0xA5B0, 0xADC0, 0xB5C0, 0xBD80, 0xC3D0, 0xCA60, 0xD020, 0xD5F0, 0xDBF0, 0xE130, 0xE680, 0xEB40, + 0xEF70, 0xF300, 0xF580, 0xF910, 0xFBE0, 0xFE90, 0x0170, 0x0250, 0x0260, 0x0010, 0xFD90, 0xFA20, 0xF5C0, 0xF090, 0xEA20, 0xE370, + 0xDC90, 0xD670, 0xCFE0, 0xC950, 0xC290, 0xBCD0, 0xB650, 0xAFC0, 0xAA30, 0xA500, 0xA0D0, 0x9C90, 0x9A10, 0x9810, 0x95F0, 0x9450, + 0x9270, 0x9140, 0x8F50, 0x8D60, 0x8BD0, 0x8A20, 0x8930, 0x8910, 0x8950, 0x8AA0, 0x8CF0, 0x90E0, 0x95A0, 0x9A30, 0x9E90, 0xA300, + 0xA7A0, 0xAB70, 0xAF60, 0xB2E0, 0xB4A0, 0xB650, 0xB7A0, 0xB8E0, 0xBAD0, 0xBD00, 0xBFD0, 0xC380, 0xC750, 0xCD20, 0xD2E0, 0xD8F0, + 0xDEF0, 0xE460, 0xE900, 0xECD0, 0xEFD0, 0xF240, 0xF420, 0xF610, 0xF8A0, 0xFA70, 0xFBE0, 0xFCF0, 0xFE60, 0xFFF0, 0x0170, 0x0310, + 0x04C0, 0x06E0, 0x0990, 0x0B00, 0x0DE0, 0x0F30, 0x1160, 0x13C0, 0x15B0, 0x18B0, 0x1B60, 0x1E70, 0x2140, 0x2380, 0x2620, 0x2800, + 0x2900, 0x2A20, 0x2B60, 0x2E00, 0x3090, 0x32E0, 0x34C0, 0x3580, 0x3660, 0x3670, 0x3710, 0x38B0, 0x3A40, 0x3D70, 0x3FD0, 0x41D0, + 0x4400, 0x46D0, 0x4AB0, 0x4E70, 0x5160, 0x5410, 0x55D0, 0x5780, 0x5840, 0x5890, 0x5A20, 0x5BA0, 0x5D90, 0x5FB0, 0x61F0, 0x65C0, + 0x68F0, 0x6E30, 0x7460, 0x7A50, 0x7EB0, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, + 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7D30, 0x6E40, 0x5DF0, 0x4B70, 0x3AC0, + 0x2A60, 0x1B80, 0x0EA0, 0x03E0, 0xFBA0, 0xF810, 0xF920, 0xFE60, 0x04C0, 0x09D0, 0x0C60, 0x0B40, 0x05F0, 0xFBD0, 0xED90, 0xDC80, + 0xC800, 0xB130, 0x9860, 0x87C0, 0x8500, 0x84D0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, + 0x8460, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8470, 0x8470, 0x84A0, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, + 0x8450, 0x8450, 0x8430, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8560, 0x88B0, + 0x9A10, 0xADA0, 0xBDF0, 0xCC40, 0xD8C0, 0xE430, 0xEF00, 0xF970, 0x0310, 0x0B30, 0x1200, 0x1660, 0x17F0, 0x1870, 0x17A0, 0x1670, + 0x1510, 0x1380, 0x1180, 0x0E10, 0x0980, 0x03E0, 0xFDA0, 0xF7B0, 0xF180, 0xEBA0, 0xE580, 0xDF40, 0xD970, 0xD3C0, 0xCF00, 0xCB40, + 0xC800, 0xC510, 0xC2E0, 0xC170, 0xBFD0, 0xBEF0, 0xBF80, 0xC030, 0xC1B0, 0xC450, 0xC6C0, 0xC9B0, 0xCE00, 0xD360, 0xD940, 0xDF30, + 0xE650, 0xEEE0, 0xF850, 0x0250, 0x0D70, 0x18C0, 0x2230, 0x2C60, 0x3560, 0x3E10, 0x4610, 0x4D90, 0x5520, 0x5C80, 0x6380, 0x6A90, + 0x71F0, 0x7880, 0x7D60, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, + 0x7EF0, 0x7EF0, 0x7EF0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F00, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EB0, 0x7F40, 0x7F10, 0x7EC0, 0x7F40, 0x7EF0, + 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F00, + 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7EF0, 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F20, 0x7F00, 0x7F40, 0x7ED0, 0x7EA0, 0x7F10, + 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, + 0x7F20, 0x7F40, 0x7F00, 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F90, 0x7F10, 0x7F00, + 0x7F00, 0x7ED0, 0x7F30, 0x7F00, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F00, 0x7F30, 0x7F20, 0x7EC0, 0x7C90, + 0x7650, 0x6EE0, 0x6920, 0x6410, 0x61B0, 0x60C0, 0x6050, 0x6210, 0x6480, 0x6800, 0x6A50, 0x6C30, 0x6DB0, 0x6DE0, 0x6BD0, 0x68B0, + 0x63A0, 0x5E00, 0x5750, 0x5010, 0x47C0, 0x3E40, 0x3470, 0x28C0, 0x1DC0, 0x1270, 0x0670, 0xFAA0, 0xEED0, 0xE3D0, 0xDA30, 0xD270, + 0xCC10, 0xC7A0, 0xC540, 0xC390, 0xC1F0, 0xC070, 0xBFC0, 0xC020, 0xC140, 0xC300, 0xC560, 0xC800, 0xCAF0, 0xCEE0, 0xD3B0, 0xD9C0, + 0xE050, 0xE660, 0xEDB0, 0xF300, 0xF820, 0xFCA0, 0x0090, 0x0590, 0x0880, 0x09F0, 0x0A50, 0x0900, 0x07A0, 0x0590, 0x0310, 0xFF20, + 0xFA70, 0xF440, 0xED20, 0xE5E0, 0xDDE0, 0xD5D0, 0xCE40, 0xC660, 0xBD80, 0xB380, 0xA7E0, 0x9B80, 0x8FA0, 0x8810, 0x85A0, 0x8510, + 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x8500, + 0x8580, 0x87C0, 0x92F0, 0xA430, 0xB5A0, 0xC5F0, 0xD6B0, 0xE400, 0xEF00, 0xF590, 0xF830, 0xF5E0, 0xEF50, 0xE5B0, 0xD9C0, 0xCB70, + 0xBFB0, 0xB590, 0xAFB0, 0xAD40, 0xAF10, 0xB3B0, 0xB930, 0xBE70, 0xC370, 0xC6B0, 0xC890, 0xC910, 0xC9B0, 0xC960, 0xC8D0, 0xC950, + 0xC9F0, 0xCBA0, 0xCB50, 0xC8B0, 0xC300, 0xB870, 0xAB30, 0x9A80, 0x8BD0, 0x8630, 0x8510, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, + 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8470, + 0x8490, 0x8480, 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8470, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, + 0x8460, 0x8460, 0x84A0, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x8530, 0x85C0, 0x87C0, 0x8C90, 0x9270, + 0x9750, 0x9BE0, 0xA060, 0xA4F0, 0xA830, 0xA8A0, 0xA350, 0x9560, 0x87A0, 0x8510, 0x84D0, 0x8480, 0x8460, 0x8480, 0x8440, 0x8430, + 0x8430, 0x8450, 0x8420, 0x8410, 0x8420, 0x8400, 0x83F0, 0x83F0, 0x83D0, 0x83D0, 0x83D0, 0x83F0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83F0, 0x83C0, 0x83D0, 0x83D0, 0x83F0, 0x83E0, 0x8400, 0x8400, 0x8420, 0x8430, 0x8440, 0x8410, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8470, 0x84A0, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84A0, 0x84A0, 0x84A0, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8520, 0x8620, 0x8C10, 0x9DB0, 0xB020, 0xBEF0, 0xCC10, + 0xD700, 0xE0A0, 0xEA10, 0xF470, 0x0070, 0x0D20, 0x1AD0, 0x2790, 0x31E0, 0x3810, 0x39D0, 0x36A0, 0x2E30, 0x1FE0, 0x0CB0, 0xF400, + 0xDB90, 0xC530, 0xB1D0, 0xA370, 0x9970, 0x9280, 0x8DB0, 0x8AE0, 0x88A0, 0x8780, 0x86C0, 0x8630, 0x85E0, 0x85C0, 0x85D0, 0x85E0, + 0x85F0, 0x8610, 0x8640, 0x8690, 0x8760, 0x8930, 0x8DE0, 0x9600, 0xA080, 0xAB00, 0xB5D0, 0xBE20, 0xC4C0, 0xC9E0, 0xCE10, 0xD1E0, + 0xD5E0, 0xDAA0, 0xE0F0, 0xE840, 0xEF50, 0xF680, 0xFC60, 0x0160, 0x04C0, 0x0600, 0x03A0, 0xFE90, 0xF750, 0xED60, 0xE220, 0xD5D0, + 0xC890, 0xBB00, 0xACE0, 0x9C40, 0x8CF0, 0x8610, 0x84E0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, + 0x8420, 0x8430, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8460, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x84F0, 0x8520, 0x85A0, 0x86F0, 0x8B10, 0x9640, 0xA3A0, 0xB1D0, + 0xBFD0, 0xCDB0, 0xDBB0, 0xE8E0, 0xF6E0, 0x0240, 0x0B90, 0x13E0, 0x1A40, 0x1FF0, 0x2420, 0x2880, 0x2C40, 0x2F10, 0x3110, 0x3260, + 0x33A0, 0x3590, 0x3930, 0x3F30, 0x4900, 0x5650, 0x6770, 0x7810, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x66D0, 0x4E00, 0x36C0, 0x21C0, 0x1030, 0x00E0, 0xF090, 0xDED0, 0xC7D0, 0xAB10, 0x8C00, 0x84F0, + 0x84A0, 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84F0, 0x84E0, 0x8520, 0x85F0, + 0x8990, 0x96D0, 0xA570, 0xB2B0, 0xBEA0, 0xCA80, 0xD410, 0xDC70, 0xE500, 0xEE10, 0xF790, 0x01B0, 0x0B50, 0x14D0, 0x1D60, 0x2500, + 0x2B10, 0x3050, 0x3690, 0x3BA0, 0x41C0, 0x4840, 0x4E30, 0x5620, 0x5C90, 0x6300, 0x6820, 0x6BC0, 0x6ED0, 0x7070, 0x72A0, 0x74F0, + 0x7770, 0x7AA0, 0x7D00, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F00, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7EB0, 0x7EE0, + 0x7F10, 0x7EA0, 0x7EA0, 0x7ED0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, + 0x7F00, 0x7F10, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, + 0x7F70, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F80, 0x7EF0, 0x7EB0, 0x7F00, 0x7EF0, 0x7F50, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F40, + 0x7EE0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7E70, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, + 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F50, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, + 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, + 0x7F10, 0x7E90, 0x7EB0, 0x7ED0, 0x7F10, 0x7F00, 0x7E80, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F10, 0x7F10, + 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7EE0, + 0x7F50, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7EB0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7EB0, 0x7F10, 0x7F20, 0x7F40, + 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, + 0x7F00, 0x7F40, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F60, 0x7E90, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, + 0x7F20, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7EE0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, + 0x7EE0, 0x7F50, 0x7F00, 0x7EE0, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, 0x7E90, 0x7ED0, 0x7F00, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, + 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, + 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7EF0, 0x7F20, 0x7ED0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, + 0x7EF0, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F00, 0x7F00, + 0x7EF0, 0x7F10, 0x7F80, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EC0, 0x7ED0, 0x7F00, 0x7F20, 0x7F10, 0x7E90, 0x7EE0, 0x7EE0, + 0x7F10, 0x7F10, 0x7E90, 0x7E60, 0x7EF0, 0x7F10, 0x7F20, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7EF0, + 0x7F00, 0x7EE0, 0x7F40, 0x7EF0, 0x7F20, 0x7F40, 0x7EC0, 0x7F10, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, + 0x7F00, 0x7F30, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, + 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7E90, 0x7EE0, 0x7EE0, 0x7F10, + 0x7F10, 0x7E70, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7E90, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, + 0x7EC0, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7F10, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7A60, + 0x7140, 0x67E0, 0x5F90, 0x57B0, 0x4FF0, 0x47C0, 0x4070, 0x3830, 0x3160, 0x29E0, 0x21E0, 0x1A40, 0x1190, 0x0890, 0xFE70, 0xF3D0, + 0xEA50, 0xE040, 0xD6C0, 0xCD30, 0xC470, 0xBC40, 0xB410, 0xACF0, 0xA6E0, 0xA110, 0x9D60, 0x99F0, 0x9830, 0x9720, 0x96D0, 0x97E0, + 0x9960, 0x9BC0, 0x9ED0, 0xA200, 0xA520, 0xA8C0, 0xAC90, 0xB100, 0xB500, 0xB950, 0xBD30, 0xC080, 0xC550, 0xC900, 0xCBD0, 0xCE10, + 0xD090, 0xD240, 0xD3F0, 0xD5D0, 0xD750, 0xD8C0, 0xD9F0, 0xDAD0, 0xDBC0, 0xDC40, 0xDD00, 0xDDD0, 0xDF10, 0xE080, 0xE210, 0xE380, + 0xE5B0, 0xE760, 0xE8C0, 0xEAF0, 0xED60, 0xF140, 0xF540, 0xF990, 0xFDC0, 0x0110, 0x0480, 0x0820, 0x0B40, 0x0E30, 0x1090, 0x12A0, + 0x15C0, 0x1800, 0x1990, 0x1BA0, 0x1D80, 0x1E90, 0x1F50, 0x2000, 0x20F0, 0x2180, 0x2240, 0x2370, 0x23A0, 0x23B0, 0x2400, 0x24C0, + 0x24D0, 0x2470, 0x24C0, 0x2490, 0x2430, 0x2490, 0x2340, 0x21E0, 0x1FD0, 0x1CD0, 0x19E0, 0x1650, 0x1290, 0x0EE0, 0x0980, 0x0310, + 0xFBF0, 0xF3C0, 0xEAC0, 0xE0E0, 0xD820, 0xD050, 0xC900, 0xC2A0, 0xBCA0, 0xB6E0, 0xB110, 0xABB0, 0xA700, 0xA250, 0x9E40, 0x9950, + 0x94E0, 0x90C0, 0x8D70, 0x8AE0, 0x88B0, 0x8790, 0x8680, 0x85E0, 0x8590, 0x8540, 0x8520, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84D0, + 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, + 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8450, 0x8460, + 0x8450, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8470, 0x8430, 0x8430, 0x8430, 0x8470, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8460, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, + 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x8400, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x8410, 0x83C0, 0x83C0, + 0x83C0, 0x83A0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x84F0, 0x8520, 0x85A0, 0x86E0, + 0x8A40, 0x93B0, 0x9F50, 0xA8D0, 0xB1D0, 0xBA40, 0xC200, 0xC8F0, 0xD020, 0xD5A0, 0xD980, 0xDD20, 0xDF70, 0xE190, 0xE240, 0xE120, + 0xDE30, 0xD7A0, 0xD050, 0xC480, 0xB4B0, 0xA1F0, 0x8D30, 0x8580, 0x84D0, 0x84A0, 0x8480, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8460, 0x8460, 0x8480, 0x8490, 0x84C0, 0x8530, 0x89C0, + 0xA990, 0xC7D0, 0xE3D0, 0xFDF0, 0x12E0, 0x2440, 0x3190, 0x3D00, 0x4470, 0x48F0, 0x4BF0, 0x4D30, 0x4DF0, 0x4E10, 0x4DD0, 0x4EC0, + 0x4F40, 0x5150, 0x5490, 0x5760, 0x5C00, 0x60A0, 0x65F0, 0x6BA0, 0x7180, 0x7880, 0x7DA0, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F00, + 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F70, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, + 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F20, 0x7E90, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, + 0x7E90, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, + 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F80, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EF0, + 0x7EA0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F40, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F70, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, + 0x7F10, 0x7F00, 0x7F00, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, + 0x7EC0, 0x7ED0, 0x7EF0, 0x7F00, 0x7EF0, 0x7E90, 0x7EB0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7340, + 0x5A80, 0x4030, 0x2540, 0x0B50, 0xF2D0, 0xDC30, 0xC6C0, 0xB1A0, 0xA050, 0x91F0, 0x8990, 0x86B0, 0x85D0, 0x85A0, 0x85C0, 0x8650, + 0x88E0, 0x91F0, 0xA270, 0xB5A0, 0xCB70, 0xE250, 0xF9B0, 0x1150, 0x26A0, 0x3BB0, 0x4C10, 0x5960, 0x63D0, 0x6AD0, 0x6FF0, 0x7340, + 0x73D0, 0x7390, 0x71C0, 0x6DD0, 0x69B0, 0x6400, 0x5DF0, 0x5680, 0x4DB0, 0x4520, 0x3C00, 0x3350, 0x2BA0, 0x2460, 0x1ED0, 0x1900, + 0x1420, 0x0E70, 0xF610, 0xEF50, 0xE8A0, 0xE400, 0xE090, 0xDFB0, 0xE2E0, 0xE820, 0xEF40, 0xF720, 0xFD40, 0x0190, 0x0380, 0x0390, + 0x02F0, 0x0240, 0x02D0, 0x0450, 0x06F0, 0x0B40, 0x11C0, 0x19D0, 0x2160, 0x29E0, 0x3140, 0x3830, 0x3FE0, 0x4820, 0x4F90, 0x5770, + 0x60B0, 0x6990, 0x7170, 0x7840, 0x7D40, 0x7EB0, 0x7F00, 0x7F00, 0x7F40, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F00, + 0x7F00, 0x7EF0, 0x7ED0, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F50, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7ED0, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7EF0, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F20, + 0x7EC0, 0x7EF0, 0x65D0, 0x4360, 0x1E80, 0xF5A0, 0xCFE0, 0xA960, 0x8A20, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8490, 0x8460, 0x8460, + 0x8470, 0x8460, 0x8450, 0x8460, 0x8490, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x8500, 0x85F0, 0x8E80, 0xA650, 0xBBF0, 0xCF30, + 0xE1B0, 0xF1B0, 0xFFB0, 0x0CE0, 0x1A00, 0x25B0, 0x3120, 0x3B80, 0x4450, 0x4CB0, 0x52C0, 0x5800, 0x5B40, 0x5DB0, 0x5F30, 0x5FE0, + 0x6090, 0x6110, 0x60F0, 0x6130, 0x6120, 0x61C0, 0x60F0, 0x6050, 0x6030, 0x5F70, 0x5FD0, 0x5EB0, 0x5CE0, 0x5A90, 0x5710, 0x5360, + 0x4EA0, 0x4950, 0x4350, 0x3CE0, 0x36C0, 0x3050, 0x2A30, 0x2440, 0x1CE0, 0x1650, 0x0F30, 0x0780, 0x00F0, 0xF9A0, 0xF420, 0xEEA0, + 0xEA10, 0xE6B0, 0xE2A0, 0xDF60, 0xDB30, 0xD670, 0xD200, 0xCD80, 0xC9A0, 0xC670, 0xC320, 0xC030, 0xBC80, 0xB960, 0xB6D0, 0xB380, + 0xB170, 0xAF00, 0xAC00, 0xA950, 0xA580, 0xA280, 0x9FE0, 0x9DC0, 0x9B10, 0x98A0, 0x9670, 0x9450, 0x9240, 0x90E0, 0x8F90, 0x8E60, + 0x8D20, 0x8BF0, 0x8BA0, 0x8B10, 0x8B30, 0x8B50, 0x8B50, 0x8BB0, 0x8BB0, 0x8B90, 0x8BB0, 0x8C10, 0x8D20, 0x8EA0, 0x8FD0, 0x9050, + 0x90A0, 0x91C0, 0x9270, 0x9470, 0x9630, 0x97A0, 0x9980, 0x9AF0, 0x9D00, 0x9FB0, 0xA210, 0xA510, 0xA880, 0xABC0, 0xAE40, 0xB160, + 0xB580, 0xB9C0, 0xBE70, 0xC2B0, 0xC670, 0xCB20, 0xCFB0, 0xD410, 0xD8F0, 0xDD80, 0xE230, 0xE690, 0xEA90, 0xEF20, 0xF3D0, 0xF830, + 0xFBE0, 0xFF60, 0x0350, 0x0770, 0x0B20, 0x0E70, 0x11F0, 0x15B0, 0x18E0, 0x1C30, 0x1EF0, 0x2170, 0x24C0, 0x2790, 0x2C50, 0x3100, + 0x3610, 0x3A70, 0x3D60, 0x4150, 0x4510, 0x4900, 0x4E20, 0x5380, 0x58D0, 0x5D70, 0x60A0, 0x6C80, 0x6F70, 0x71F0, 0x7360, 0x7550, + 0x7690, 0x7730, 0x7840, 0x7880, 0x7890, 0x78A0, 0x77B0, 0x7800, 0x7740, 0x7750, 0x7710, 0x75F0, 0x7520, 0x73C0, 0x7300, 0x7240, + 0x70C0, 0x6F30, 0x6D20, 0x6B80, 0x69E0, 0x67D0, 0x66F0, 0x6520, 0x6350, 0x6130, 0x5F60, 0x5D80, 0x5B80, 0x59B0, 0x5840, 0x5740, + 0x56D0, 0x5560, 0x53F0, 0x5310, 0x52B0, 0x5300, 0x5260, 0x51D0, 0x50F0, 0x4F70, 0x4DF0, 0x4D00, 0x4B70, 0x4B10, 0x4A10, 0x49B0, + 0x4960, 0x47E0, 0x46F0, 0x4540, 0x4490, 0x43A0, 0x4180, 0x4010, 0x3D90, 0x3B20, 0x3800, 0x3570, 0x32F0, 0x2FB0, 0x2C30, 0x2820, + 0x23C0, 0x1FF0, 0x1BC0, 0x1780, 0x1390, 0x0EA0, 0x0AA0, 0x0690, 0x0350, 0x0020, 0xFD40, 0xFB90, 0xF9E0, 0xF860, 0xF770, 0xF730, + 0xF7F0, 0xF940, 0xFB30, 0xFE90, 0x01E0, 0x0620, 0x0AF0, 0x10C0, 0x1680, 0x1B10, 0x2100, 0x26E0, 0x2BF0, 0x31F0, 0x3730, 0x3E00, + 0x43F0, 0x49B0, 0x4FA0, 0x5400, 0x5810, 0x5BB0, 0x5F60, 0x6380, 0x6680, 0x6960, 0x6B80, 0x6CD0, 0x6F10, 0x6FA0, 0x70C0, 0x7190, + 0x7230, 0x72C0, 0x7280, 0x7380, 0x7420, 0x7500, 0x76F0, 0x7890, 0x7930, 0x7940, 0x78D0, 0x7870, 0x7800, 0x7610, 0x7270, 0x6C60, + 0x65A0, 0x5D90, 0x5690, 0x4F60, 0x4770, 0x40A0, 0x38E0, 0x3070, 0x27E0, 0x2060, 0x1B70, 0x1910, 0x19F0, 0x1D60, 0x21D0, 0x2630, + 0x28B0, 0x2970, 0x2950, 0x2790, 0x25E0, 0x2320, 0x20B0, 0x1F60, 0x1D20, 0x1AD0, 0x1690, 0x10F0, 0x0960, 0xFF80, 0xF410, 0xE570, + 0xD570, 0xC510, 0xB380, 0xA140, 0x8F50, 0x86D0, 0x8510, 0x84D0, 0x84B0, 0x8490, 0x84B0, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, + 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8470, 0x8430, 0x8430, 0x8430, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8430, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8410, 0x8450, 0x8450, 0x8460, + 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, + 0x8530, 0x8590, 0x8640, 0x8890, 0x8C90, 0x9340, 0x9AC0, 0xA190, 0xA8C0, 0xAFA0, 0xB5C0, 0xBCA0, 0xC2B0, 0xC870, 0xCDA0, 0xD1E0, + 0xD5C0, 0xD9A0, 0xDDE0, 0xE230, 0xE6B0, 0xEAA0, 0xED70, 0xF010, 0xF1F0, 0xF3D0, 0xF520, 0xF6A0, 0xF780, 0xF830, 0xF8A0, 0xF8F0, + 0xF960, 0xFA60, 0xF990, 0xF7F0, 0xF760, 0xF6F0, 0xF6C0, 0xF7F0, 0xFA30, 0xFBF0, 0xFEA0, 0x0030, 0x01C0, 0x0320, 0x03D0, 0x03E0, + 0x0300, 0x0240, 0x00D0, 0xFF70, 0xFEA0, 0xFDC0, 0xFCD0, 0xFBA0, 0xFA90, 0xFAA0, 0xFB60, 0xFBE0, 0xFCF0, 0xFDD0, 0xFEB0, 0xFEE0, + 0xFF80, 0xFF70, 0xFF10, 0xFF40, 0xFFD0, 0x01D0, 0x05B0, 0x0BE0, 0x1360, 0x1C10, 0x24A0, 0x2B70, 0x3050, 0x3400, 0x37B0, 0x3AD0, + 0x3E90, 0x4380, 0x48C0, 0x4E90, 0x53B0, 0x5760, 0x5B10, 0x5F50, 0x62B0, 0x6620, 0x69F0, 0x6E70, 0x7270, 0x75C0, 0x7870, 0x7AB0, + 0x7CE0, 0x7E60, 0x7F10, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7BE0, 0x7320, 0x6A60, 0x5FF0, 0x53F0, 0x44C0, 0x3470, 0x2150, 0x0B50, 0xF260, 0xD6C0, 0xB8F0, 0x99E0, 0x86E0, + 0x84E0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, + 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8540, 0x8580, + 0x85E0, 0x8660, 0x8750, 0x8820, 0x8990, 0x8B10, 0x8C40, 0x8CC0, 0x8D20, 0x8CD0, 0x8B70, 0x8A00, 0x8850, 0x86E0, 0x85E0, 0x8540, + 0x8500, 0x84D0, 0x84D0, 0x84A0, 0x8490, 0x8480, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, + 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8480, 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, + 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8480, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, + 0x8490, 0x8490, 0x84B0, 0x84B0, 0x84C0, 0x84E0, 0x8510, 0x8570, 0x8690, 0x8A20, 0x9430, 0x9F80, 0xAA10, 0xB350, 0xBCA0, 0xC500, + 0xCC40, 0xD430, 0xDC00, 0xE300, 0xEB20, 0xF220, 0xFA30, 0x01D0, 0x0930, 0x11C0, 0x1A00, 0x21B0, 0x29C0, 0x3270, 0x3BF0, 0x4480, + 0x4C80, 0x5440, 0x5B10, 0x6210, 0x67B0, 0x6CE0, 0x7270, 0x76A0, 0x7AE0, 0x7E40, 0x7F70, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F60, + 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F00, 0x7F20, 0x7ED0, + 0x7EB0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7E90, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, + 0x7F40, 0x7ED0, 0x7F10, 0x7F40, 0x7F00, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7F00, 0x7F10, 0x7F10, + 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F00, 0x7F60, 0x7EE0, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, + 0x7F70, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7C90, 0x5530, 0x33E0, 0x16D0, + 0xFE10, 0xE650, 0xCDA0, 0xB100, 0x8E60, 0x8510, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84E0, + 0x8510, 0x8580, 0x8660, 0x8850, 0x8D90, 0x97C0, 0xA3F0, 0xAF10, 0xB760, 0xBB10, 0xB740, 0xAE30, 0xA000, 0x8FA0, 0x8700, 0x8520, + 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x84A0, 0x84B0, 0x84C0, 0x84F0, 0x8510, 0x8550, 0x85F0, 0x8760, 0x8B70, 0x9400, 0x9F80, 0xAB40, 0xB780, 0xC370, 0xCF90, 0xDD00, + 0xEB40, 0xFB50, 0x0CD0, 0x1DF0, 0x2D50, 0x3A80, 0x4600, 0x4F70, 0x5800, 0x60C0, 0x68D0, 0x70B0, 0x7880, 0x7DA0, 0x7F20, 0x7F20, + 0x7F50, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F00, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EF0, 0x7F30, + 0x7F00, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, 0x7E90, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E80, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, + 0x7E90, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F30, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F70, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F20, 0x7F50, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F60, 0x7F00, 0x7F40, 0x7F10, 0x7F20, + 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, + 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EA0, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F50, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F70, + 0x7EE0, 0x7ED0, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7340, + 0x56F0, 0x3D50, 0x2850, 0x1980, 0x0FE0, 0x0AF0, 0x0A60, 0x0C10, 0x0FC0, 0x14F0, 0x1B80, 0x2360, 0x2C50, 0x35F0, 0x3FF0, 0x4A40, + 0x5500, 0x5DA0, 0x65A0, 0x6B30, 0x70B0, 0x75B0, 0x79D0, 0x7C90, 0x7E80, 0x7F10, 0x7F30, 0x7F00, 0x7E40, 0x7BB0, 0x77B0, 0x7300, + 0x6EA0, 0x6AC0, 0x6710, 0x62B0, 0x5D00, 0x5510, 0x4A90, 0x3C70, 0x2B20, 0x1760, 0x02F0, 0xECA0, 0xD880, 0xC530, 0xB3F0, 0xA430, + 0x95C0, 0x8B80, 0x8710, 0x8590, 0x8520, 0x84F0, 0x84E0, 0x8460, 0x84D0, 0x84D0, 0x84D0, 0x84F0, 0x8520, 0x85C0, 0x87F0, 0x9090, + 0x9D60, 0xA950, 0xB470, 0xBF80, 0xCA00, 0xD3B0, 0xDC90, 0xE300, 0xE860, 0xEC90, 0xF000, 0xF0F0, 0xF040, 0xEDF0, 0xE930, 0xE180, + 0xD8F0, 0xD020, 0xC780, 0xBFF0, 0xB980, 0xB450, 0xB060, 0xAE50, 0xAE20, 0xAF90, 0xB230, 0xB510, 0xB8F0, 0xBD70, 0xC350, 0xC940, + 0xE1A0, 0xE850, 0xEEB0, 0xF530, 0xFC00, 0x0240, 0x0830, 0x0E00, 0x12E0, 0x1710, 0x1B20, 0x1FA0, 0x23E0, 0x2730, 0x29F0, 0x2CA0, + 0x2EE0, 0x3110, 0x3270, 0x3370, 0x3570, 0x3620, 0x3740, 0x3930, 0x3BD0, 0x3F70, 0x43A0, 0x48B0, 0x4E20, 0x53C0, 0x5910, 0x5EB0, + 0x6570, 0x6B70, 0x7140, 0x76D0, 0x7AF0, 0x7DA0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7E70, 0x7D30, 0x7A30, 0x7620, 0x7110, 0x6AD0, 0x6300, + 0x5A20, 0x50D0, 0x4730, 0x3DE0, 0x3500, 0x2D60, 0x2680, 0x20B0, 0x1C60, 0x18D0, 0x1590, 0x12A0, 0x1070, 0x0F50, 0x1020, 0x11A0, + 0x1400, 0x1710, 0x1B30, 0x2000, 0x2670, 0x2DB0, 0x3570, 0x3C20, 0x4340, 0x49C0, 0x5170, 0x58E0, 0x5F50, 0x6610, 0x6C20, 0x7240, + 0x7740, 0x7AD0, 0x7DB0, 0x7E50, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F50, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7D80, 0x7A40, 0x7710, 0x7330, 0x6F40, 0x6BD0, 0x6730, 0x6330, 0x5F00, 0x5AE0, 0x5770, 0x5440, + 0x5200, 0x5090, 0x4F30, 0x4EC0, 0x4D40, 0x4CB0, 0x4BB0, 0x4A50, 0x4A10, 0x49A0, 0x49E0, 0x4990, 0x48C0, 0x49E0, 0x4AC0, 0x4CC0, + 0x4E40, 0x4ED0, 0x4FD0, 0x5000, 0x5120, 0x5150, 0x5290, 0x5590, 0x5800, 0x5A10, 0x5B90, 0x5C80, 0x5DE0, 0x5F40, 0x6080, 0x62A0, + 0x63C0, 0x64F0, 0x66A0, 0x6840, 0x69C0, 0x6AD0, 0x6CB0, 0x6DF0, 0x6E60, 0x6E90, 0x6E70, 0x6F80, 0x70F0, 0x72B0, 0x7420, 0x7520, + 0x7650, 0x7650, 0x7670, 0x76C0, 0x7730, 0x7860, 0x7940, 0x79D0, 0x7AF0, 0x7B70, 0x7CC0, 0x7DD0, 0x7E80, 0x7EA0, 0x7E90, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7ED0, 0x7F20, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F20, + 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, + 0x7ED0, 0x7EE0, 0x7F80, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7E70, 0x7ED0, 0x7EB0, 0x7F10, 0x7F00, 0x7E90, 0x7EF0, + 0x7F20, 0x7F20, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, + 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7EF0, 0x7F10, + 0x7EE0, 0x7EF0, 0x7F90, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7EF0, 0x7F00, 0x7F40, 0x7ED0, 0x7EB0, 0x7F10, + 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EC0, 0x7EF0, 0x7F00, 0x7F20, 0x7EE0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7E90, + 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F70, + 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F70, 0x7F20, 0x7ED0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7A60, 0x72C0, 0x6BA0, 0x65E0, 0x6050, 0x5C90, 0x5920, + 0x5740, 0x5580, 0x53B0, 0x52F0, 0x5130, 0x51B0, 0x51E0, 0x5210, 0x5310, 0x5400, 0x5440, 0x5490, 0x5410, 0x53E0, 0x5360, 0x5270, + 0x5130, 0x4E00, 0x4970, 0x42C0, 0x3A90, 0x3160, 0x25B0, 0x1990, 0x0BE0, 0xFD60, 0xED90, 0xDCF0, 0xCB60, 0xB800, 0xA2C0, 0x8D00, + 0x85B0, 0x84E0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, + 0x8410, 0x8420, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84C0, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84E0, + 0x84F0, 0x84F0, 0x8510, 0x8560, 0x8560, 0x85D0, 0x85F0, 0x8670, 0x8750, 0x88F0, 0x8B90, 0x8EC0, 0x91B0, 0x94F0, 0x9890, 0x9CA0, + 0xA170, 0xA6D0, 0xAC20, 0xAFF0, 0xB450, 0xB880, 0xBD00, 0xC1F0, 0xC740, 0xCD30, 0xD300, 0xD8D0, 0xDD70, 0xE1E0, 0xE700, 0xEAC0, + 0xEE00, 0xF0D0, 0xF270, 0xF3F0, 0xF500, 0xF6D0, 0xF840, 0xF920, 0xF8F0, 0xF830, 0xF6C0, 0xF5D0, 0xF490, 0xF390, 0xF140, 0xEE40, + 0xEAD0, 0xE710, 0xE400, 0xE140, 0xDEB0, 0xDCB0, 0xDA00, 0xD7F0, 0xD660, 0xD4C0, 0xD310, 0xD210, 0xD0B0, 0xCFE0, 0xCDB0, 0xCC70, + 0xCB00, 0xCB40, 0xCC20, 0xCD30, 0xCF20, 0xD010, 0xD170, 0xD390, 0xD660, 0xD950, 0xDBE0, 0xDE60, 0xE0C0, 0xE350, 0xE660, 0xE940, + 0xEC50, 0xEFC0, 0xF2E0, 0xF5E0, 0xF7B0, 0xF920, 0xF9A0, 0xF910, 0xF8F0, 0xF7D0, 0xF600, 0xF3C0, 0xF0C0, 0xEEC0, 0xEC60, 0xEA90, + 0xE930, 0xE7B0, 0xE710, 0xE5F0, 0xE560, 0xE570, 0xE5F0, 0xE7B0, 0xE9D0, 0xEB80, 0xEE40, 0xF110, 0xF430, 0xF770, 0xFB00, 0xFD90, + 0xFFF0, 0x0230, 0x0540, 0x08D0, 0x0CC0, 0x1140, 0x1580, 0x19D0, 0x1E60, 0x2350, 0x2910, 0x30E0, 0x38E0, 0x4180, 0x4B10, 0x5590, + 0x6020, 0x6BC0, 0x76D0, 0x7E90, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7B70, 0x74B0, 0x6D30, + 0x6560, 0x5CF0, 0x5490, 0x4C60, 0x44C0, 0x3E30, 0x3880, 0x3330, 0x2E70, 0x2AD0, 0x26F0, 0x2440, 0x2200, 0x2070, 0x2010, 0x2100, + 0x2250, 0x24D0, 0x28F0, 0x2E30, 0x3390, 0x3940, 0x3E90, 0x4370, 0x45E0, 0x46C0, 0x4540, 0x4240, 0x3D90, 0x3830, 0x32E0, 0x2DD0, + 0x28A0, 0x2440, 0x2000, 0x1C60, 0x1920, 0x15E0, 0x1320, 0x1080, 0x0DF0, 0x0AE0, 0x0830, 0x0530, 0x02F0, 0x0080, 0xFDF0, 0xFA50, + 0xF690, 0xF230, 0xEDE0, 0xE950, 0xE550, 0xE120, 0xDD80, 0xD9F0, 0xD7A0, 0xD5D0, 0xD480, 0xD350, 0xD260, 0xD1A0, 0xD0D0, 0xD030, + 0xCFA0, 0xCF20, 0xCDD0, 0xCC80, 0xCA40, 0xC750, 0xC450, 0xC000, 0xBBC0, 0xB6F0, 0xB250, 0xAD00, 0xA800, 0xA280, 0x9D70, 0x98B0, + 0x94F0, 0x91E0, 0x8FC0, 0x8E00, 0x8CC0, 0x8BF0, 0x8BF0, 0x8C10, 0x8C90, 0x8DF0, 0x8EB0, 0x8F90, 0x9040, 0x90F0, 0x90E0, 0x90D0, + 0x8FC0, 0x8E60, 0x8D50, 0x8C00, 0x8A80, 0x8940, 0x8820, 0x8720, 0x8640, 0x85A0, 0x8540, 0x8540, 0x84F0, 0x84E0, 0x84D0, 0x84B0, + 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8430, 0x8430, 0x8430, 0x8420, 0x8430, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8440, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, + 0x8500, 0x8540, 0x85B0, 0x8670, 0x8750, 0x8800, 0x88A0, 0x89F0, 0x8C00, 0x9010, 0x9400, 0x96E0, 0x9880, 0x9810, 0x95F0, 0x91A0, + 0x8C20, 0x87F0, 0x8600, 0x8530, 0x84F0, 0x8500, 0x84F0, 0x84B0, 0x84B0, 0x84D0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x84A0, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8490, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, + 0x84F0, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84E0, 0x84C0, 0x84D0, 0x84B0, 0x84A0, 0x84A0, + 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x84C0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84E0, 0x8500, 0x8510, 0x8530, 0x8570, 0x85C0, 0x8670, 0x8760, + 0x88A0, 0x8A90, 0x8D00, 0x8FC0, 0x92D0, 0x95D0, 0x9980, 0x9CD0, 0x9FF0, 0xA2E0, 0xA620, 0xA960, 0xAC70, 0xAF40, 0xB1D0, 0xB3B0, + 0xB5B0, 0xB7A0, 0xB970, 0xBC30, 0xBEB0, 0xC1A0, 0xC430, 0xC6B0, 0xC8C0, 0xCA30, 0xCBD0, 0xCD70, 0xCE40, 0xCF00, 0xCFD0, 0xD130, + 0xD270, 0xD330, 0xD460, 0xD540, 0xD640, 0xD750, 0xD730, 0xD820, 0xD780, 0xD7F0, 0xD820, 0xD8A0, 0xD8F0, 0xD860, 0xD760, 0xD670, + 0xD510, 0xD430, 0xD2C0, 0xD150, 0xCFE0, 0xCD70, 0xCB70, 0xC910, 0xC680, 0xC430, 0xC1C0, 0xC010, 0xBEC0, 0xBD10, 0xBBF0, 0xBB30, + 0xBB10, 0xB9F0, 0xB930, 0xB8A0, 0xB8E0, 0xB9E0, 0xBAC0, 0xBC20, 0xBDF0, 0xBE80, 0xBF40, 0xBF30, 0xBF30, 0xBFB0, 0xC010, 0xC180, + 0xC170, 0xC130, 0xBFB0, 0xBDD0, 0xBBE0, 0xB8F0, 0xB610, 0xB3B0, 0xB110, 0xAE20, 0xAAF0, 0xA8D0, 0xA730, 0xA560, 0xA3D0, 0xA2E0, + 0xA270, 0xA2C0, 0xA2B0, 0xA380, 0xA4C0, 0xA620, 0xA780, 0xA940, 0xABB0, 0xAD00, 0xAF10, 0xB1C0, 0xB460, 0xB710, 0xBA50, 0xBDB0, + 0xC160, 0xC5B0, 0xC970, 0xCE60, 0xD2E0, 0xD7B0, 0xDCA0, 0xE160, 0xE640, 0xEAD0, 0xF070, 0xF5D0, 0xFB30, 0x0060, 0x0520, 0x09C0, + 0x0E80, 0x1390, 0x18E0, 0x1DE0, 0x2340, 0x2800, 0x2D30, 0x3270, 0x3800, 0x3E10, 0x4350, 0x47F0, 0x4D80, 0x5190, 0x5630, 0x59A0, + 0x5D40, 0x6150, 0x6500, 0x6800, 0x6AC0, 0x6CB0, 0x6FA0, 0x7220, 0x7540, 0x7790, 0x79E0, 0x7C20, 0x7DF0, 0x7ED0, 0x7F20, 0x7F40, + 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F70, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7F20, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, 0x7F10, 0x7F10, 0x7F30, 0x7EC0, 0x7EC0, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F30, 0x7F20, 0x7F10, + 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, + 0x7EE0, 0x7F60, 0x7F10, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EF0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F20, 0x7F20, 0x7580, 0x65B0, 0x5630, 0x4680, 0x3910, 0x2D30, 0x2230, 0x18B0, 0x10B0, 0x0A00, 0x0470, 0xFFC0, 0xFBB0, 0xF860, + 0xF550, 0xF250, 0xEFA0, 0xECB0, 0xEA20, 0xE6D0, 0xE380, 0xE050, 0xDD30, 0xDAB0, 0xD940, 0xD810, 0xD820, 0xD840, 0xD890, 0xD950, + 0xD970, 0xD840, 0xD6A0, 0xD370, 0xCF40, 0xCB10, 0xC630, 0xC160, 0xBCB0, 0xB9E0, 0xB8A0, 0xBA30, 0xBEF0, 0xC620, 0xCF90, 0xDAB0, + 0xE660, 0xF390, 0x0200, 0x0FB0, 0x1D80, 0x2B40, 0x38B0, 0x4730, 0x5670, 0x6620, 0x7660, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x6EA0, 0x3E70, 0x0940, 0xD030, 0x95D0, 0x84E0, 0x8490, 0x8470, 0x8450, 0x8440, + 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x83E0, + 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8490, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84F0, 0x8500, + 0x8500, 0x8510, 0x8510, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84F0, 0x8500, 0x8530, 0x8570, 0x85F0, + 0x86F0, 0x8870, 0x8B30, 0x8DF0, 0x9050, 0x91F0, 0x9200, 0x90D0, 0x8E90, 0x8BD0, 0x8930, 0x8760, 0x8660, 0x85B0, 0x8570, 0x8530, + 0x8510, 0x84F0, 0x84E0, 0x84C0, 0x84F0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84F0, + 0x8570, 0x8780, 0x9360, 0xA3A0, 0xB000, 0xB7C0, 0xB9F0, 0xB630, 0xAD40, 0xA080, 0x93D0, 0x8A70, 0x8690, 0x8560, 0x8500, 0x84E0, + 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, + 0x84C0, 0x84B0, 0x8480, 0x8480, 0x84A0, 0x8460, 0x8460, 0x8410, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8440, + 0x8410, 0x8400, 0x8400, 0x83A0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x83C0, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8470, 0x8490, 0x84A0, 0x84C0, 0x84E0, 0x8510, 0x8660, 0x8F50, 0xA5B0, 0xBB30, 0xD020, 0xE410, 0xF770, 0x0710, 0x14E0, + 0x2140, 0x2BC0, 0x3350, 0x3940, 0x3D00, 0x3F90, 0x41A0, 0x42E0, 0x4450, 0x44B0, 0x44E0, 0x4470, 0x4480, 0x4650, 0x4900, 0x4C50, + 0x4FA0, 0x5240, 0x55D0, 0x5930, 0x5CB0, 0x5FE0, 0x61D0, 0x62B0, 0x60F0, 0x5C40, 0x5540, 0x4A90, 0x3D20, 0x2C20, 0x17F0, 0x0280, + 0xEC60, 0xD680, 0xC5B0, 0xB8D0, 0xB220, 0xAE90, 0xAE60, 0xAE50, 0xAB20, 0xA3D0, 0x95D0, 0x8900, 0x8530, 0x84D0, 0x84B0, 0x84A0, + 0x8490, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84E0, 0x8530, 0x87C0, 0x9CA0, 0xB6E0, 0xCCA0, 0xDF40, 0xF040, + 0x0040, 0x10B0, 0x21F0, 0x3340, 0x4560, 0x5910, 0x69B0, 0x7860, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, + 0x7ED0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F70, + 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7EA0, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, + 0x7ED0, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, + 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, + 0x7EE0, 0x7E90, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7F00, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, + 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F10, 0x7EF0, 0x7F10, + 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7EB0, 0x7EB0, 0x7F50, + 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EB0, 0x7700, 0x70C0, 0x6B80, 0x68B0, 0x6760, 0x6740, 0x6980, + 0x6D20, 0x7260, 0x7810, 0x7D60, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, + 0x7F60, 0x7F10, 0x7EF0, 0x7F10, 0x7F10, 0x7F40, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F50, + 0x7C30, 0x7670, 0x7160, 0x6C50, 0x66F0, 0x62C0, 0x5E90, 0x5CA0, 0x5A70, 0x58E0, 0x58D0, 0x5930, 0x5AB0, 0x5BE0, 0x5CF0, 0x5EE0, + 0x6000, 0x6250, 0x6390, 0x6360, 0x6300, 0x6200, 0x5FF0, 0x5D20, 0x5940, 0x55B0, 0x5030, 0x49C0, 0x42C0, 0x3AE0, 0x3330, 0x2B60, + 0x23A0, 0x1C90, 0x1490, 0x0D70, 0x06E0, 0x00D0, 0xFB10, 0xF4E0, 0xEF00, 0xE7F0, 0xE110, 0xDA80, 0xD480, 0xCF70, 0xCAD0, 0xC5F0, + 0xC220, 0xBD70, 0xB860, 0xB3A0, 0xAEB0, 0xAA10, 0xA4E0, 0x9FC0, 0x9B00, 0x9630, 0x9290, 0x8F10, 0x8C50, 0x8A50, 0x88F0, 0x8820, + 0x8770, 0x8700, 0x86D0, 0x86C0, 0x86D0, 0x86F0, 0x8730, 0x8790, 0x8840, 0x8990, 0x8BA0, 0x8F10, 0x9480, 0x9A30, 0x9F90, 0xA680, + 0xAD50, 0xB560, 0xBCF0, 0xC590, 0xCD70, 0xD570, 0xDE90, 0xE790, 0xF0C0, 0xFAC0, 0x04B0, 0x0F70, 0x19E0, 0x24C0, 0x2EF0, 0x39F0, + 0x44C0, 0x4ED0, 0x59B0, 0x6360, 0x6C40, 0x7510, 0x7B80, 0x7F00, 0x7F10, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, + 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, + 0x7F10, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7B70, 0x6A40, 0x5870, 0x4380, 0x3080, 0x1EC0, + 0x0E50, 0x0090, 0xF4D0, 0xEBE0, 0xE6A0, 0xE450, 0xE4F0, 0xE7A0, 0xEBF0, 0xF0C0, 0xF4D0, 0xF7D0, 0xF9E0, 0xFAB0, 0xFC40, 0xFD50, + 0xFFB0, 0x01A0, 0x0380, 0x0410, 0x0480, 0x03B0, 0x02A0, 0x0200, 0x01A0, 0x0300, 0x0480, 0x0730, 0x0B20, 0x0FE0, 0x1520, 0x1A00, + 0x1E10, 0x21D0, 0x2500, 0x2950, 0x2D80, 0x3270, 0x36E0, 0x3BC0, 0x4010, 0x44D0, 0x49F0, 0x4E40, 0x52C0, 0x56D0, 0x5AB0, 0x5E20, + 0x6120, 0x6410, 0x6730, 0x69C0, 0x6BD0, 0x6D30, 0x6E40, 0x6E60, 0x6E90, 0x6E90, 0x6E00, 0x6D20, 0x6B90, 0x6A00, 0x67B0, 0x65E0, + 0x63C0, 0x61B0, 0x5F30, 0x5CC0, 0x59A0, 0x55C0, 0x51A0, 0x4DB0, 0x4A10, 0x4660, 0x4340, 0x4040, 0x3D10, 0x3A60, 0x3710, 0x3490, + 0x31E0, 0x2F30, 0x2CC0, 0x2B10, 0x29D0, 0x2920, 0x2860, 0x2730, 0x2610, 0x2520, 0x2440, 0x2410, 0x24F0, 0x25A0, 0x26C0, 0x2770, + 0x2800, 0x2870, 0x28D0, 0x2960, 0x29C0, 0x2AC0, 0x2A50, 0x29B0, 0x2890, 0x2730, 0x2510, 0x2360, 0x21A0, 0x1FD0, 0x1DD0, 0x1C00, + 0x19A0, 0x1760, 0x1420, 0x10F0, 0x0D10, 0x08B0, 0x03C0, 0xFF00, 0xF8F0, 0xF2D0, 0xECC0, 0xE6A0, 0xE110, 0xDC00, 0xD7D0, 0xD420, + 0xD0C0, 0xCE30, 0xCC30, 0xCA00, 0xC7D0, 0xC5B0, 0xC460, 0xC330, 0xC240, 0xC210, 0xC190, 0xC130, 0xC100, 0xC160, 0xC240, 0xC360, + 0xC550, 0xC760, 0xC9B0, 0xCCC0, 0xD000, 0xD430, 0xD980, 0xDDD0, 0xE210, 0xE600, 0xE980, 0xEC90, 0xEF30, 0xF2E0, 0xF550, 0xF8E0, + 0xFB90, 0xFF70, 0x0450, 0x0900, 0x0EB0, 0x1480, 0x1A60, 0x2140, 0x2880, 0x2ED0, 0x3560, 0x3B20, 0x4200, 0x4990, 0x5070, 0x5820, + 0x5ED0, 0x65F0, 0x6BA0, 0x70F0, 0x7680, 0x7A80, 0x7E40, 0x7EF0, 0x7F70, 0x7F00, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, + 0x7EF0, 0x7F00, 0x7F20, 0x7F20, 0x7EC0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7E90, 0x7ED0, 0x7F10, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F40, 0x7F40, + 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7ED0, + 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7EF0, 0x7EE0, 0x7DC0, 0x79B0, 0x7430, 0x6E20, + 0x6700, 0x5E50, 0x5540, 0x4C40, 0x43F0, 0x3CB0, 0x35E0, 0x3160, 0x2D00, 0x2A80, 0x2820, 0x26F0, 0x2750, 0x27C0, 0x2940, 0x2A80, + 0x2AF0, 0x2C10, 0x2C40, 0x2CD0, 0x2E20, 0x2EE0, 0x3090, 0x3280, 0x34E0, 0x36E0, 0x3940, 0x3C90, 0x3EA0, 0x4040, 0x3E50, 0x3BD0, + 0x3900, 0x3610, 0x3390, 0x3020, 0x2C40, 0x2A10, 0x26E0, 0x2330, 0x1FF0, 0x1C40, 0x1950, 0x1630, 0x13A0, 0x11F0, 0x1030, 0x0F10, + 0x0DC0, 0x0BF0, 0x0A10, 0x07B0, 0x0530, 0x0240, 0xFE50, 0xF920, 0xF280, 0xEAB0, 0xE2E0, 0xDAD0, 0xD3C0, 0xCCE0, 0xC670, 0xBFA0, + 0xB840, 0xB0D0, 0xA7E0, 0xA000, 0x9790, 0x8F90, 0x8520, 0x84F0, 0x84E0, 0x84C0, 0x84C0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x84B0, 0x8490, 0x8490, 0x8490, 0x8490, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, + 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84F0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, + 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83D0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x8360, 0x83B0, 0x83A0, 0x83A0, 0x8360, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8380, + 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8370, 0x8380, 0x83A0, 0x8370, 0x8370, 0x8370, 0x8380, 0x8380, 0x8390, + 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, + 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83D0, 0x8360, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84D0, + 0x84E0, 0x8530, 0x8610, 0x87A0, 0x89A0, 0x8A70, 0x8A00, 0x8900, 0x8770, 0x8660, 0x8590, 0x84E0, 0x8500, 0x84E0, 0x84E0, 0x84D0, + 0x8500, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x8510, 0x8580, 0x8900, 0xA060, 0xBBC0, 0xD580, 0xEB70, 0xFB20, 0x0860, + 0x1400, 0x2100, 0x3210, 0x4300, 0x5360, 0x6140, 0x69D0, 0x6E30, 0x6D00, 0x6780, 0x5DD0, 0x4F20, 0x3EC0, 0x2B80, 0x15D0, 0xFFE0, + 0xEA00, 0xD620, 0xC240, 0xAD20, 0x93C0, 0x8690, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x84C0, 0x8490, + 0x84A0, 0x84B0, 0x84D0, 0x8500, 0x8600, 0x8DC0, 0xAAA0, 0xC790, 0xE670, 0x06B0, 0x27B0, 0x4900, 0x6820, 0x7ED0, 0x7F30, 0x7F30, + 0x7F50, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7ED0, 0x73F0, 0x6920, 0x5CF0, 0x5190, 0x46A0, 0x3CE0, 0x3450, 0x2D90, 0x2840, 0x24E0, 0x2290, + 0x2260, 0x2340, 0x2490, 0x2660, 0x2860, 0x2A10, 0x2B50, 0x2CD0, 0x2DA0, 0x2E50, 0x2E40, 0x2E50, 0x2D40, 0x2C60, 0x2BD0, 0x2C00, + 0x2C60, 0x2DE0, 0x2F30, 0x3030, 0x30C0, 0x3090, 0x3020, 0x2FE0, 0x30E0, 0x32A0, 0x3510, 0x39A0, 0x3FE0, 0x46D0, 0x4F60, 0x57A0, + 0x6040, 0x68C0, 0x7090, 0x7740, 0x7D40, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7E40, 0x7530, 0x6C70, 0x62F0, 0x5990, 0x4F40, 0x4640, 0x3E80, 0x3630, + 0x2F20, 0x2840, 0x2300, 0x1DA0, 0x18C0, 0x1590, 0x1290, 0x0FF0, 0x0F10, 0x0F10, 0x1160, 0x1560, 0x1A60, 0x2130, 0x2A10, 0x3550, + 0x4360, 0x5340, 0x6530, 0x7860, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7EF0, 0x7F30, 0x7EF0, 0x7EA0, 0x7F20, 0x7EF0, + 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F10, 0x7F40, 0x7ED0, 0x7E90, 0x7F20, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F20, + 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, 0x7EF0, 0x7F30, 0x7F30, 0x7F00, 0x7F80, 0x7F10, 0x7F00, 0x7F00, + 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, 0x7E70, 0x7EC0, 0x7ED0, + 0x7F20, 0x7F20, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E90, 0x7E60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, + 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, + 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F50, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7EE0, + 0x7F50, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7E70, 0x7F10, 0x7EF0, 0x7EF0, 0x7EF0, 0x7E80, 0x7F10, 0x7F00, 0x7F20, + 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, + 0x7EF0, 0x7F60, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F80, 0x7F20, 0x7F00, 0x7ED0, 0x7ED0, 0x7F30, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, + 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7E90, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, + 0x7EC0, 0x7EF0, 0x7F10, 0x7E90, 0x7ED0, 0x7F00, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F40, + 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7F10, + 0x7F30, 0x7F00, 0x7F80, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7ED0, 0x7EB0, + 0x7EE0, 0x7F60, 0x7F00, 0x7E90, 0x7EB0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, + 0x7F10, 0x7F00, 0x7EE0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F80, 0x7F10, 0x7F20, + 0x7EF0, 0x7EF0, 0x7F50, 0x7F00, 0x7F00, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, + 0x7ED0, 0x7D10, 0x7AA0, 0x79C0, 0x78C0, 0x77B0, 0x7860, 0x7900, 0x7A50, 0x7BD0, 0x7D60, 0x7EC0, 0x7F10, 0x7F80, 0x7F00, 0x7F00, + 0x7EF0, 0x7F10, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F80, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7ED0, 0x7EF0, + 0x7F00, 0x7F40, 0x7F10, 0x7E90, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7F10, 0x7F20, 0x7F40, 0x7EA0, 0x7ED0, 0x7F10, + 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7480, 0x4BE0, 0x28C0, 0x0B60, 0xF590, 0xE570, 0xD9E0, 0xD300, 0xD000, + 0xD120, 0xD710, 0xE290, 0xF480, 0x0D80, 0x2C80, 0x4F90, 0x71B0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, + 0x7F00, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x71A0, 0x34A0, 0xF7D0, + 0xBB00, 0x88A0, 0x84B0, 0x8480, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, + 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8500, + 0x8580, 0x8690, 0x8950, 0x8FD0, 0x98C0, 0xA070, 0xA7D0, 0xAF10, 0xB710, 0xBFE0, 0xC6D0, 0xCD40, 0xD390, 0xD900, 0xDDC0, 0xE290, + 0xE7F0, 0xECD0, 0xF1B0, 0xF570, 0xF970, 0xFC60, 0xFF10, 0x01D0, 0x0410, 0x05F0, 0x0780, 0x0890, 0x0920, 0x0A40, 0x0A50, 0x0A10, + 0x0970, 0x0850, 0x06F0, 0x04B0, 0x0280, 0x0080, 0xFE30, 0xFB40, 0xF900, 0xF5B0, 0xF2B0, 0xEFF0, 0xEE10, 0xED10, 0xEC60, 0xEBE0, + 0xEC50, 0xED30, 0xEE80, 0xF020, 0xF230, 0xF4A0, 0xF780, 0xFA90, 0xFDF0, 0x0220, 0x0620, 0x0A10, 0x0D90, 0x11E0, 0x16E0, 0x1D70, + 0x2500, 0x2EC0, 0x3970, 0x44F0, 0x5060, 0x5B40, 0x6550, 0x6F10, 0x7730, 0x7CE0, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7E00, 0x7550, 0x6A60, 0x5CF0, 0x4D10, 0x3B00, 0x2620, 0x0CA0, 0xF2B0, 0xD690, 0xBA90, 0x9FA0, 0x8AF0, + 0x8590, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x8500, 0x8570, 0x87A0, 0x9AA0, 0xB2C0, 0xCB10, 0xE070, + 0xF170, 0xFB60, 0xFD30, 0xF5F0, 0xE5F0, 0xCDA0, 0xB200, 0x9550, 0x86B0, 0x8500, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, + 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8490, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, + 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8520, 0x8550, 0x8590, 0x85E0, 0x8620, 0x86D0, 0x8770, 0x8870, 0x8A90, 0x8D80, + 0x9150, 0x95B0, 0x99E0, 0x9E50, 0xA410, 0xAA80, 0xB280, 0xBB00, 0xC3E0, 0xCD50, 0xD610, 0xDFA0, 0xE8E0, 0xF3A0, 0xFDA0, 0x0650, + 0x0FB0, 0x17E0, 0x2040, 0x2810, 0x2F80, 0x3760, 0x3E10, 0x4490, 0x49B0, 0x4E70, 0x5400, 0x5880, 0x5D80, 0x61E0, 0x6680, 0x6AB0, + 0x6E80, 0x7260, 0x7600, 0x7970, 0x7CA0, 0x7EC0, 0x7F40, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7EF0, + 0x7F40, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7F30, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F50, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F30, + 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, + 0x7F00, 0x7F10, 0x7EF0, 0x7F00, 0x7F20, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F80, 0x4240, 0xED50, 0x9040, 0x84A0, + 0x8470, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8460, 0x8460, 0x8450, 0x8460, 0x8490, 0x8480, 0x84C0, + 0x84B0, 0x84D0, 0x8500, 0x85F0, 0x8A50, 0x97D0, 0xA3A0, 0xACF0, 0xB460, 0xBA50, 0xBED0, 0xC180, 0xC1F0, 0xC0B0, 0xBEB0, 0xBD40, + 0xBC60, 0xBD90, 0xC0D0, 0xC5E0, 0xCCD0, 0xD500, 0xDE60, 0xE8C0, 0xF470, 0x0200, 0x1060, 0x2180, 0x30E0, 0x3E90, 0x4AD0, 0x53A0, + 0x58E0, 0x5AE0, 0x5B90, 0x5D70, 0x60E0, 0x66C0, 0x6EF0, 0x77D0, 0x7EA0, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7F10, 0x7F00, 0x7F60, + 0x7ED0, 0x7EB0, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7EA0, 0x7F10, 0x7F10, 0x7F20, 0x7E70, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, + 0x7F80, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F00, 0x7EF0, 0x7ED0, 0x7F60, 0x7F10, 0x7ED0, 0x7EF0, 0x7F20, 0x7F40, + 0x7F10, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7EC0, + 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, + 0x7F20, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7390, 0x6630, 0x5CA0, 0x5480, 0x4F00, 0x4BA0, 0x48C0, 0x4690, + 0x4470, 0x41B0, 0x3E70, 0x3A50, 0x36E0, 0x3370, 0x30C0, 0x2E90, 0x2DB0, 0x2EC0, 0x3080, 0x3330, 0x3760, 0x3B50, 0x4030, 0x4530, + 0x4A60, 0x4F40, 0x52D0, 0x54A0, 0x5460, 0x51F0, 0x4F70, 0x4B80, 0x4800, 0x4490, 0x4120, 0x3EE0, 0x3CF0, 0x3CF0, 0x3DB0, 0x3F90, + 0x4360, 0x46C0, 0x4BD0, 0x50F0, 0x55A0, 0x5B20, 0x6040, 0x6520, 0x6A30, 0x6DE0, 0x7240, 0x7580, 0x78B0, 0x7BA0, 0x7D70, 0x7EF0, + 0x7F10, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F30, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, + 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7F10, 0x7F00, 0x7EF0, 0x7F90, + 0x7F00, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7F00, + 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7F30, 0x7F00, 0x7F00, 0x7F00, 0x7F00, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F50, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, + 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7E70, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, + 0x7EC0, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F00, 0x7EF0, 0x7F30, + 0x74C0, 0x4FC0, 0x29C0, 0x0160, 0xD6F0, 0xABE0, 0x88C0, 0x84E0, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8410, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84C0, 0x84E0, + 0x8500, 0x8540, 0x8670, 0x8930, 0x8FA0, 0x9770, 0x9EE0, 0xA590, 0xABE0, 0xB280, 0xBAE0, 0xC380, 0xCC90, 0xD410, 0xDB20, 0xE040, + 0xE350, 0xE480, 0xE420, 0xE240, 0xDF30, 0xD9B0, 0xD340, 0xCCE0, 0xC7A0, 0xC3B0, 0xC240, 0xC320, 0xC4A0, 0xC5B0, 0xC530, 0xC230, + 0xBBF0, 0xB1A0, 0xA570, 0x98D0, 0x8DB0, 0x87C0, 0x85B0, 0x8510, 0x84E0, 0x84C0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8440, 0x8440, + 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83F0, 0x83D0, 0x83D0, 0x8410, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83B0, + 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x8400, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, + 0x8410, 0x8430, 0x8430, 0x8430, 0x8470, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8470, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8460, 0x8460, 0x8470, 0x8450, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8540, + 0x85C0, 0x8710, 0x8BC0, 0x9860, 0xA810, 0xB7C0, 0xC690, 0xD3F0, 0xDF90, 0xE900, 0xEF90, 0xF430, 0xF620, 0xF7B0, 0xF7D0, 0xF920, + 0xFAE0, 0xFD90, 0x02B0, 0x08C0, 0x10C0, 0x1910, 0x2020, 0x26E0, 0x2CC0, 0x31B0, 0x3760, 0x3BA0, 0x4110, 0x4610, 0x4A70, 0x4E90, + 0x50D0, 0x52E0, 0x5340, 0x5390, 0x53B0, 0x53E0, 0x54C0, 0x5510, 0x55D0, 0x5650, 0x56A0, 0x57E0, 0x58E0, 0x5990, 0x5A90, 0x5A70, + 0x5B70, 0x5B10, 0x5A70, 0x5920, 0x5660, 0x5310, 0x4EE0, 0x4AE0, 0x4780, 0x4450, 0x4340, 0x42C0, 0x4330, 0x4530, 0x46E0, 0x49C0, + 0x4C90, 0x4F30, 0x5300, 0x5600, 0x5910, 0x5C00, 0x5EE0, 0x6250, 0x64B0, 0x65A0, 0x64C0, 0x6250, 0x5EE0, 0x59C0, 0x5390, 0x4D50, + 0x46A0, 0x3FA0, 0x3870, 0x3230, 0x2D60, 0x29B0, 0x28B0, 0x2960, 0x2B50, 0x2EA0, 0x3160, 0x3470, 0x34B0, 0x32B0, 0x2F20, 0x2980, + 0x2540, 0x23F0, 0x26E0, 0x2FC0, 0x3C90, 0x4D10, 0x5E40, 0x6EF0, 0x7C50, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, + 0x7F00, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F50, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, + 0x7F10, 0x7F10, 0x7F30, 0x7EC0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F30, 0x7EF0, 0x7EA0, 0x7F20, 0x7F10, 0x7F10, 0x7EE0, 0x7EC0, 0x7F10, + 0x7ED0, 0x7F00, 0x7EF0, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7E90, 0x7F10, 0x7F20, 0x7F40, 0x7ED0, 0x7EA0, + 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EE0, 0x7F00, 0x7F20, 0x7F00, 0x7F50, + 0x7F20, 0x7F40, 0x7EF0, 0x7F10, 0x7F70, 0x7EF0, 0x7F00, 0x7F10, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7F20, + 0x7F00, 0x7EF0, 0x7EB0, 0x7F30, 0x7EF0, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7ED0, 0x7F00, 0x7F00, 0x7EF0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, + 0x7EF0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F50, 0x7EE0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, + 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F30, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, + 0x7EE0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7E70, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, 0x7EC0, + 0x7ED0, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F60, 0x7F00, + 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F50, 0x7F10, 0x7CB0, + 0x6470, 0x4910, 0x2E70, 0x1310, 0xF660, 0xD8B0, 0xB990, 0x9A30, 0x8740, 0x84F0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, + 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8480, 0x8480, 0x8450, 0x8460, 0x8420, 0x8470, 0x8470, 0x84B0, 0x8480, 0x8490, + 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8550, 0x8640, 0x8940, 0x92D0, 0x9F10, 0xAA90, 0xB690, 0xC230, 0xCDF0, 0xD980, 0xE380, + 0xEC50, 0xF590, 0xFE70, 0x0720, 0x0F50, 0x18B0, 0x2040, 0x2810, 0x2F80, 0x34E0, 0x3A20, 0x3ED0, 0x4270, 0x46E0, 0x4B40, 0x4EF0, + 0x5300, 0x55B0, 0x5840, 0x5A00, 0x5BB0, 0x5E00, 0x5F50, 0x6060, 0x6160, 0x62F0, 0x6450, 0x6560, 0x66A0, 0x6780, 0x6790, 0x6750, + 0x66E0, 0x6690, 0x6710, 0x67B0, 0x68C0, 0x69C0, 0x6AD0, 0x6C00, 0x6DA0, 0x7020, 0x7240, 0x7510, 0x7810, 0x7AA0, 0x7D20, 0x7EB0, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F10, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7EF0, 0x7E90, 0x7D10, 0x7B60, 0x79A0, 0x7850, 0x7630, 0x73B0, 0x7260, 0x7150, 0x6F70, 0x6E30, 0x6CA0, 0x6BE0, + 0x6B90, 0x6AA0, 0x6B00, 0x69D0, 0x68C0, 0x6810, 0x6790, 0x67A0, 0x6820, 0x69D0, 0x6B80, 0x6D00, 0x6E00, 0x6E10, 0x6F10, 0x6F80, + 0x7020, 0x7050, 0x7000, 0x6FA0, 0x6EA0, 0x6C90, 0x6BE0, 0x6A40, 0x6910, 0x6830, 0x66A0, 0x6560, 0x6480, 0x6450, 0x64A0, 0x6540, + 0x6730, 0x68A0, 0x6A20, 0x6BE0, 0x6D90, 0x7090, 0x72A0, 0x7480, 0x7720, 0x7880, 0x7A90, 0x7BB0, 0x7CF0, 0x7DE0, 0x7E90, 0x7EF0, + 0x7EE0, 0x7F40, 0x7E80, 0x7E20, 0x7D20, 0x7C20, 0x7A90, 0x7950, 0x7700, 0x7560, 0x7290, 0x6FF0, 0x6D20, 0x6910, 0x65B0, 0x61B0, + 0x5D60, 0x5950, 0x54B0, 0x5060, 0x4B90, 0x45B0, 0x3FE0, 0x3900, 0x32D0, 0x2BB0, 0x2480, 0x1EA0, 0x1730, 0x1020, 0x0940, 0x0240, + 0xFC30, 0xF5D0, 0xEF20, 0xE830, 0xE0B0, 0xD7E0, 0xD040, 0xC930, 0xC2C0, 0xBC40, 0xB5B0, 0xAED0, 0xA8A0, 0xA260, 0x9B80, 0x9660, + 0x91C0, 0x8DE0, 0x8B40, 0x8990, 0x88C0, 0x8850, 0x8830, 0x8850, 0x88C0, 0x8920, 0x8960, 0x89D0, 0x8AE0, 0x8C70, 0x8FA0, 0x9430, + 0x9880, 0x9CE0, 0xA060, 0xA3F0, 0xA730, 0xAA60, 0xAE20, 0xB0C0, 0xB3B0, 0xB820, 0xBB60, 0xBF50, 0xC300, 0xC6C0, 0xCAA0, 0xCD50, + 0xD060, 0xD370, 0xD6F0, 0xDA20, 0xDCC0, 0xDFB0, 0xE300, 0xE5A0, 0xE8F0, 0xEAD0, 0xEDB0, 0xEFC0, 0xF1B0, 0xF430, 0xF5A0, 0xF770, + 0xF870, 0xF960, 0xFB40, 0xFD00, 0xFEE0, 0x00A0, 0x01F0, 0x0350, 0x04F0, 0x05C0, 0x0720, 0x0870, 0x0A60, 0x0B30, 0x0C20, 0x0DD0, + 0x0EB0, 0x1060, 0x1110, 0x1250, 0x1250, 0x1170, 0x1010, 0x0EB0, 0x0E60, 0x0CF0, 0x0B10, 0x08A0, 0x0500, 0x0100, 0xFC30, 0xF670, + 0xF160, 0xEBD0, 0xE630, 0xDFB0, 0xD8B0, 0xD210, 0xCB50, 0xC530, 0xBF00, 0xB8F0, 0xB3E0, 0xAE70, 0xAA10, 0xA700, 0xA530, 0xA4B0, + 0xA480, 0xA530, 0xAE10, 0xB150, 0xB4C0, 0xB8E0, 0xBCA0, 0xC0B0, 0xC4E0, 0xC860, 0xCC30, 0xCF40, 0xD210, 0xD360, 0xD410, 0xD450, + 0xD4A0, 0xD580, 0xD730, 0xD8A0, 0xD890, 0xD760, 0xD430, 0xCE40, 0xC6A0, 0xBCE0, 0xB270, 0xA6D0, 0x9A40, 0x8EC0, 0x87E0, 0x8580, + 0x84F0, 0x84C0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8440, 0x8430, 0x8430, 0x8420, + 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8430, 0x8420, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, + 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8420, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8460, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84E0, 0x84C0, 0x84B0, 0x84B0, 0x84D0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, + 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, + 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x8480, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8530, 0x8550, 0x8580, 0x8600, 0x86E0, + 0x8870, 0x8BD0, 0x91C0, 0x9860, 0x9FB0, 0xA6F0, 0xAE90, 0xB6A0, 0xBDF0, 0xC5B0, 0xCDB0, 0xD520, 0xDC90, 0xE4E0, 0xECC0, 0xF410, + 0xFAF0, 0x00F0, 0x0700, 0x0C70, 0x1250, 0x1920, 0x1FF0, 0x2660, 0x2C10, 0x3280, 0x38F0, 0x3F70, 0x4620, 0x4BD0, 0x5130, 0x5670, + 0x5B40, 0x6090, 0x6600, 0x6B00, 0x6FF0, 0x72F0, 0x7710, 0x79E0, 0x7CF0, 0x7ED0, 0x7F20, 0x7F40, 0x7F10, 0x7F50, 0x7F00, 0x7F20, + 0x7EF0, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F40, 0x7F30, 0x5F70, 0x3700, 0x11C0, 0xF510, 0xDC00, 0xC420, 0xAB50, 0x9200, 0x8630, 0x84E0, 0x84B0, 0x8490, 0x8490, + 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, + 0x8440, 0x8430, 0x8440, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8440, 0x8400, 0x8400, 0x8410, 0x8410, 0x8400, + 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8480, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8440, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, + 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x8640, 0x90E0, 0xA7F0, 0xBEE0, 0xD580, 0xEA70, 0xFD30, 0x0CA0, 0x1A50, 0x2530, 0x2EF0, 0x3760, + 0x3D50, 0x4210, 0x4480, 0x42C0, 0x3ED0, 0x3690, 0x2C30, 0x1DD0, 0x0EE0, 0x0030, 0xF160, 0xE2D0, 0xD430, 0xC3F0, 0xB180, 0x99A0, + 0x8660, 0x84C0, 0x8480, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8530, 0x8690, 0x8DC0, 0x9EC0, + 0xAE70, 0xBE00, 0xCC20, 0xD9C0, 0xE930, 0xF6E0, 0x0390, 0x1030, 0x1B70, 0x26D0, 0x3200, 0x3DE0, 0x49A0, 0x5490, 0x5ED0, 0x6800, + 0x70E0, 0x7880, 0x7DD0, 0x7F10, 0x7F00, 0x7F50, 0x7F00, 0x7F00, 0x7F20, 0x7EF0, 0x7F80, 0x7F20, 0x7F40, 0x7F10, 0x7EF0, 0x7F80, + 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, 0x7F10, 0x7EE0, 0x7F00, 0x7F00, 0x7F60, 0x7F00, 0x7ED0, 0x7ED0, 0x7EB0, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7ED0, 0x7EF0, 0x7F30, 0x7F20, 0x7E90, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7E70, 0x7D20, 0x7B60, 0x78F0, 0x7730, 0x7500, + 0x7340, 0x7210, 0x7090, 0x6FC0, 0x6F10, 0x6E30, 0x6DE0, 0x6C40, 0x6B40, 0x6990, 0x68A0, 0x6800, 0x6750, 0x6820, 0x6AA0, 0x6E60, + 0x7390, 0x79F0, 0x7EA0, 0x7EE0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7ED0, 0x7F00, 0x7EE0, 0x7F70, 0x7ED0, + 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7E90, 0x7F00, 0x7EE0, 0x7DC0, 0x7230, 0x64A0, + 0x54E0, 0x45B0, 0x35C0, 0x26C0, 0x1700, 0x0590, 0xF3B0, 0xDFF0, 0xCC00, 0xB5E0, 0xA2B0, 0x9110, 0x87D0, 0x8580, 0x8500, 0x84E0, + 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8540, 0x8590, 0x8630, 0x8790, 0x8A90, 0x9050, 0x9790, + 0x9E90, 0xA570, 0xAC60, 0xB330, 0xBA70, 0xC170, 0xC870, 0xCF00, 0xD540, 0xDA90, 0xDFA0, 0xE470, 0xE8F0, 0xED60, 0xF240, 0xF690, + 0xFA50, 0xFD90, 0x0040, 0x0210, 0x02F0, 0x0290, 0x0050, 0xFD00, 0xF9E0, 0xF630, 0xF2F0, 0xF100, 0xF090, 0xF2B0, 0xF6F0, 0xFE20, + 0x0620, 0x0E90, 0x17D0, 0x1FB0, 0x2520, 0x2970, 0x2B40, 0x2B20, 0x28F0, 0x2410, 0x1EC0, 0x18C0, 0x1410, 0x1150, 0x1040, 0x1160, + 0x12D0, 0x14E0, 0x1500, 0x13D0, 0x11D0, 0x0E30, 0x09E0, 0x0440, 0xFED0, 0xF960, 0xF350, 0xEDC0, 0xE630, 0xDB70, 0xCCC0, 0xB8D0, + 0xA170, 0x8BA0, 0x8560, 0x84D0, 0x84B0, 0x84A0, 0x84A0, 0x8470, 0x8470, 0x8460, 0x8470, 0x8470, 0x8420, 0x8470, 0x8470, 0x8470, + 0x8480, 0x8490, 0x84A0, 0x84E0, 0x85C0, 0x9BC0, 0xBD20, 0xDBE0, 0xF830, 0x1220, 0x2C40, 0x4440, 0x5B90, 0x6F80, 0x7DE0, 0x7EF0, + 0x7F00, 0x7F30, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7EE0, 0x7EF0, 0x7F50, 0x7F00, 0x7F20, 0x7F10, 0x4A50, + 0x01E0, 0xBD80, 0x8700, 0x8490, 0x8460, 0x8440, 0x8420, 0x83F0, 0x83E0, 0x83D0, 0x83C0, 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8380, + 0x8380, 0x8370, 0x8370, 0x8370, 0x8360, 0x8360, 0x8360, 0x8320, 0x8370, 0x8360, 0x8370, 0x8390, 0x8370, 0x8370, 0x8310, 0x8380, + 0x8380, 0x8380, 0x8390, 0x8390, 0x8390, 0x8350, 0x83A0, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8400, 0x8420, 0x8420, + 0x8420, 0x8400, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x84F0, 0x8520, 0x8580, 0x86D0, 0x8FF0, 0xA1F0, 0xB4E0, 0xCB10, + 0xE2A0, 0xFB90, 0x1550, 0x2F30, 0x47A0, 0x5EF0, 0x7560, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F40, 0x7F20, 0x7F10, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F00, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F30, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F90, 0x7F30, + 0x7F00, 0x7F00, 0x7EF0, 0x7F50, 0x7F20, 0x7F00, 0x7F00, 0x7EB0, 0x7F20, 0x7EE0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F30, 0x7F30, 0x7EA0, 0x7F00, 0x7ED0, 0x7AB0, 0x70A0, 0x6840, 0x62D0, + 0x5E30, 0x5B20, 0x5960, 0x5880, 0x5840, 0x5830, 0x56D0, 0x5580, 0x51A0, 0x4D00, 0x4790, 0x4130, 0x3A60, 0x32C0, 0x2A70, 0x2200, + 0x1BA0, 0x1870, 0x18B0, 0x1BA0, 0x21F0, 0x2800, 0x2D90, 0x3130, 0x3330, 0x34F0, 0x3690, 0x38E0, 0x3AF0, 0x3E30, 0x4230, 0x4760, + 0x4DF0, 0x5700, 0x5FD0, 0x6890, 0x7120, 0x7970, 0x7E90, 0x7F30, 0x7F00, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, + 0x7EF0, 0x7EF0, 0x7F10, 0x7E70, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F30, 0x7EF0, + 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F90, 0x7F00, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7F30, 0x7F00, 0x7E70, 0x7ED0, 0x7ED0, 0x7F20, 0x7F40, 0x7E90, 0x7ED0, + 0x7EE0, 0x7F10, 0x7F10, 0x7E90, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F20, + 0x7EF0, 0x7F10, 0x7ED0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, + 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7F40, 0x7ED0, 0x7EB0, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7EF0, 0x7F20, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, + 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F10, 0x7F10, 0x7F00, 0x76A0, 0x66D0, 0x57E0, 0x4740, 0x3840, 0x29D0, 0x1C90, 0x0EB0, + 0x01F0, 0xF6A0, 0xEB90, 0xE090, 0xD660, 0xCC10, 0xC310, 0xB9F0, 0xB110, 0xA8F0, 0xA0B0, 0x98A0, 0x9250, 0x8DD0, 0x8B50, 0x8970, + 0x8850, 0x87F0, 0x87D0, 0x8800, 0x88A0, 0x89F0, 0x8CC0, 0x9160, 0x9740, 0x9D60, 0xA440, 0xAB90, 0xB370, 0xBB80, 0xC3B0, 0xCBE0, + 0xD350, 0xDB10, 0xE300, 0xEBE0, 0xF400, 0xFB80, 0x0350, 0x0B20, 0x11F0, 0x1860, 0x1E10, 0x23F0, 0x2A40, 0x2EF0, 0x33D0, 0x3870, + 0x3C60, 0x4150, 0x4630, 0x4A70, 0x4F20, 0x5320, 0x5740, 0x5A90, 0x5DB0, 0x6140, 0x6400, 0x67B0, 0x6AA0, 0x6DF0, 0x71D0, 0x7490, + 0x7830, 0x7B60, 0x7DD0, 0x7EF0, 0x7F00, 0x7F40, 0x7F00, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, 0x7F90, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F70, 0x7F20, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7ED0, 0x7EF0, 0x7F20, 0x7F20, 0x7EC0, + 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F30, + 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, + 0x7EF0, 0x7F00, 0x7F00, 0x7F70, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EA0, 0x7AC0, 0x7610, 0x6FA0, 0x6820, 0x5FD0, 0x5590, + 0x4A90, 0x3CD0, 0x2EB0, 0x2030, 0x1060, 0xFFC0, 0xEDD0, 0xDBA0, 0xC980, 0xB560, 0x9E60, 0x8B50, 0x8570, 0x84E0, 0x84B0, 0x8490, + 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x84A0, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, + 0x84D0, 0x8510, 0x85C0, 0x8940, 0x99C0, 0xAB80, 0xBE30, 0xCFE0, 0xE090, 0xF170, 0x0060, 0x0FC0, 0x1AF0, 0x2330, 0x2B10, 0x2F10, + 0x30E0, 0x3040, 0x2E10, 0x2AF0, 0x2640, 0x2190, 0x1CC0, 0x1730, 0x10C0, 0x0950, 0x0040, 0xF6E0, 0xED30, 0xE4D0, 0xDC20, 0xD3C0, + 0xCBB0, 0xC400, 0xBD00, 0xB590, 0xAFA0, 0xAB00, 0xA7A0, 0xA610, 0xA570, 0xA530, 0xA580, 0xA660, 0xA7A0, 0xAAD0, 0xB0F0, 0xBB10, + 0xCA10, 0xDEE0, 0xF8E0, 0x1650, 0x3490, 0x5400, 0x6D50, 0x7E30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, + 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7EF0, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7DB0, 0x6EF0, + 0x6280, 0x57C0, 0x4E70, 0x4680, 0x3E40, 0x3640, 0x2EE0, 0x2A20, 0x2740, 0x26D0, 0x2810, 0x2B70, 0x2FC0, 0x33D0, 0x3650, 0x37E0, + 0x39A0, 0x3AD0, 0x3B90, 0x3D30, 0x4040, 0x43F0, 0x48D0, 0x5930, 0x5BE0, 0x5CF0, 0x5D90, 0x5D30, 0x5C40, 0x5AF0, 0x58D0, 0x5620, + 0x52C0, 0x4DC0, 0x47A0, 0x4130, 0x39F0, 0x31E0, 0x2980, 0x2040, 0x1690, 0x0CA0, 0x0260, 0xF6D0, 0xEBB0, 0xE010, 0xD400, 0xC800, + 0xBC00, 0xB130, 0xA620, 0x9C20, 0x91F0, 0x8BC0, 0x8840, 0x86A0, 0x85E0, 0x85D0, 0x8580, 0x8590, 0x85D0, 0x8660, 0x8780, 0x89B0, + 0x8D40, 0x9260, 0x9690, 0x9A90, 0x9DA0, 0x9F90, 0xA270, 0xA500, 0xA850, 0xACE0, 0xB1C0, 0xB760, 0xBC90, 0xC2E0, 0xC8B0, 0xCDB0, + 0xD1F0, 0xD550, 0xD900, 0xDCE0, 0xDF60, 0xE160, 0xE2C0, 0xE3B0, 0xE430, 0xE350, 0xE1A0, 0xDDE0, 0xD930, 0xD310, 0xCBE0, 0xC420, + 0xBCA0, 0xB3C0, 0xAB90, 0xA330, 0x9A50, 0x9040, 0x88D0, 0x8600, 0x8520, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x84C0, 0x8480, + 0x8470, 0x8460, 0x8490, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8410, 0x8430, 0x8430, 0x8430, + 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84F0, 0x84D0, 0x84F0, 0x8510, 0x8570, 0x8670, + 0x89B0, 0x9250, 0x9DE0, 0xA830, 0xB1F0, 0xBC00, 0xC610, 0xD060, 0xDB80, 0xE650, 0xF150, 0xFBC0, 0x05A0, 0x1000, 0x19D0, 0x24B0, + 0x2F60, 0x39C0, 0x43B0, 0x4D80, 0x58D0, 0x62D0, 0x6BB0, 0x7440, 0x7B40, 0x7ED0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EE0, + 0x7F50, 0x7F20, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F10, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F20, 0x7F20, + 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7F30, 0x7EF0, 0x7F20, 0x7ED0, 0x7BF0, 0x77F0, 0x73C0, 0x6F50, 0x6BB0, 0x6800, 0x6510, 0x61B0, 0x5EB0, 0x5C60, 0x5990, + 0x56A0, 0x5420, 0x5100, 0x4F30, 0x4D30, 0x4C40, 0x4BD0, 0x4B90, 0x4BC0, 0x4850, 0x4740, 0x45E0, 0x44D0, 0x4430, 0x4320, 0x4240, + 0x4150, 0x3FF0, 0x3F80, 0x3E10, 0x3D00, 0x3B70, 0x3940, 0x36F0, 0x3400, 0x3260, 0x3040, 0x2EF0, 0x2E00, 0x2D00, 0x2C30, 0x2A30, + 0x2740, 0x24E0, 0x2140, 0x1D90, 0x1A50, 0x1770, 0x1560, 0x12F0, 0x1090, 0x0E00, 0x0B60, 0x0840, 0x0480, 0x00B0, 0xFD80, 0xFB00, + 0xF870, 0xF580, 0xF250, 0xEF50, 0xEAA0, 0xE760, 0xE490, 0xE1B0, 0xDF30, 0xDC70, 0xDA30, 0xD6F0, 0xD3D0, 0xD0A0, 0xCC40, 0xC8A0, + 0xC5C0, 0xC2E0, 0xC0B0, 0xBEB0, 0xBCB0, 0xBA60, 0xB790, 0xB4F0, 0xB180, 0xAEB0, 0xAC10, 0xA870, 0xA620, 0xA420, 0xA270, 0x9FF0, + 0x9CE0, 0x9A10, 0x96E0, 0x9330, 0x9060, 0x8DD0, 0x8BB0, 0x89F0, 0x8890, 0x8760, 0x86A0, 0x8610, 0x85D0, 0x8590, 0x8570, 0x8550, + 0x8530, 0x8520, 0x8510, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x84C0, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8430, 0x8480, 0x8470, 0x8470, 0x8430, 0x8480, 0x8480, 0x8470, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x84B0, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84B0, 0x84B0, 0x84C0, 0x8510, 0x8500, + 0x8530, 0x85C0, 0x8750, 0x8D40, 0x9980, 0xA690, 0xB4A0, 0xC1C0, 0xCEE0, 0xDC90, 0xE9B0, 0xF720, 0x0590, 0x12D0, 0x1F30, 0x2A60, + 0x34D0, 0x3D90, 0x4460, 0x48C0, 0x4AD0, 0x4AB0, 0x4540, 0x3CD0, 0x2F10, 0x1D20, 0x07E0, 0xEDD0, 0xD030, 0xB0B0, 0x8E10, 0x8530, + 0x84C0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8440, 0x8450, 0x8450, + 0x8460, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84C0, 0x8590, 0xA040, 0xD550, 0x0E70, 0x4100, 0x6BB0, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7E90, 0x4DE0, 0x11C0, 0xBDE0, 0x84B0, + 0x8440, 0x8410, 0x8410, 0x83C0, 0x83B0, 0x83A0, 0x8390, 0x83C0, 0x83A0, 0x83C0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x8380, 0x83B0, + 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x8430, 0x83F0, 0x83F0, 0x8400, 0x8400, + 0x8430, 0x8400, 0x8400, 0x83E0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, + 0x8490, 0x84B0, 0x8510, 0x88C0, 0xA830, 0xC6F0, 0xE3D0, 0xFDE0, 0x1810, 0x2EB0, 0x4380, 0x5800, 0x6C40, 0x7DB0, 0x7F20, 0x7F40, + 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F30, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7EF0, 0x7F20, 0x7F10, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, + 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7E90, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7ED0, 0x7EF0, + 0x7EE0, 0x7E80, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F00, + 0x7F00, 0x7F10, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7F00, 0x7F40, 0x7F00, + 0x7F10, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F90, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, + 0x7EA0, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7E90, 0x7E70, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, + 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x6B50, 0x5A00, 0x4B00, 0x3FF0, 0x3770, 0x31A0, 0x2FB0, 0x3110, 0x3640, + 0x3E90, 0x49A0, 0x57D0, 0x66C0, 0x75F0, 0x7ED0, 0x7F00, 0x7F00, 0x7F10, 0x7F50, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, 0x7ED0, + 0x7EB0, 0x7F00, 0x7F20, 0x7F40, 0x7EF0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7F00, + 0x7F30, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F70, + 0x7EE0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F70, 0x6E00, 0x54F0, 0x3DE0, 0x26A0, 0x0EF0, 0xF730, 0xDD70, 0xC1D0, 0xA950, 0x9450, 0x8960, + 0x8670, 0x85E0, 0x85E0, 0x8640, 0x8710, 0x8840, 0x8A10, 0x8D30, 0x95F0, 0xA610, 0xBC40, 0xD9A0, 0xFAB0, 0x1A60, 0x3630, 0x4160, + 0x3D20, 0x2A50, 0x0CB0, 0xECC0, 0xCF00, 0xB840, 0xA9E0, 0xA1F0, 0x9EF0, 0x9CE0, 0x9850, 0x8510, 0x84E0, 0x84D0, 0x84C0, 0x84A0, + 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, + 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8470, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x83E0, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8460, 0x8440, 0x8440, 0x8440, 0x8400, 0x8430, 0x8430, 0x8430, 0x83D0, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8420, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8440, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8420, 0x83C0, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x8410, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, + 0x8460, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8530, 0x86C0, 0x9120, 0xA2F0, 0xB150, 0xBBF0, 0xC300, 0xC5B0, 0xC3A0, 0xBC00, 0xAFC0, + 0x9F00, 0x8C10, 0x8590, 0x84E0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8460, + 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8540, 0x8720, 0x92D0, 0xA470, 0xB540, 0xC4C0, 0xD330, + 0xE170, 0xECF0, 0xF770, 0x0120, 0x0A20, 0x1340, 0x1AF0, 0x2140, 0x2690, 0x2B30, 0x2EA0, 0x3280, 0x35F0, 0x38D0, 0x3B70, 0x3C40, + 0x3C60, 0x3B90, 0x38A0, 0x33D0, 0x2DB0, 0x26B0, 0x2060, 0x1A50, 0x1650, 0x1430, 0x13E0, 0x1560, 0x1750, 0x1870, 0x19C0, 0x1A80, + 0x1B50, 0x1C60, 0x1F00, 0x2300, 0x27E0, 0x2E20, 0x3590, 0x3E30, 0x4710, 0x5050, 0x5970, 0x6270, 0x6B30, 0x7420, 0x7C40, 0x7F10, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F20, + 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7EF0, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, + 0x7EF0, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F40, 0x7F50, + 0x7EF0, 0x7EF0, 0x7EB0, 0x7F60, 0x7F40, 0x7E90, 0x7EC0, 0x7F00, 0x7F10, 0x7F30, 0x7EA0, 0x7EE0, 0x7F00, 0x7F10, 0x7F00, 0x7EA0, + 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, + 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7ED0, 0x7EF0, 0x7F00, 0x7F10, 0x7F60, 0x7F00, + 0x7ED0, 0x7F00, 0x7EF0, 0x7F50, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7E90, + 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, + 0x7F10, 0x7EF0, 0x7F30, 0x7F20, 0x7F80, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7F40, + 0x7F10, 0x7F10, 0x7EE0, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, + 0x7F10, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7EE0, 0x7F40, 0x7EF0, 0x7E90, 0x7F10, + 0x7EF0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F10, + 0x7F00, 0x7F10, 0x7F10, 0x7F80, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7830, 0x6D70, 0x6360, 0x5810, 0x4C50, 0x4120, 0x35C0, + 0x2B60, 0x2230, 0x18A0, 0x1150, 0x0990, 0x02D0, 0xFCC0, 0xF790, 0xF490, 0xF310, 0xF310, 0xF510, 0xF910, 0x26A0, 0x36F0, 0x4800, + 0x57E0, 0x67E0, 0x7580, 0x7ED0, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, + 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, + 0x7EF0, 0x7F30, 0x7F20, 0x7EF0, 0x7F50, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, + 0x7F00, 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7EF0, 0x7F00, 0x7EE0, 0x7F50, 0x7BB0, 0x7230, 0x6780, 0x5B90, 0x4E90, 0x4100, 0x3320, + 0x2550, 0x16F0, 0x0730, 0xF800, 0xE890, 0xD920, 0xCA50, 0xB970, 0xA960, 0x9970, 0x8BF0, 0x8660, 0x8520, 0x84E0, 0x84D0, 0x84B0, + 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x83F0, 0x8440, 0x8430, 0x8440, + 0x8430, 0x8430, 0x8440, 0x8420, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x84A0, 0x8450, 0x8450, 0x8450, + 0x8460, 0x8450, 0x8450, 0x8480, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8470, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8450, 0x8470, 0x8470, 0x8480, 0x84C0, 0x8490, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8460, 0x8460, 0x8450, 0x8440, 0x8420, 0x8420, + 0x8410, 0x8400, 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x8390, + 0x8390, 0x8390, 0x8390, 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83C0, 0x8390, + 0x8390, 0x8350, 0x83A0, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83D0, 0x83A0, 0x83D0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, + 0x83E0, 0x83A0, 0x83B0, 0x8360, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8470, 0x8480, 0x8490, 0x8490, + 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8480, 0x8470, + 0x8460, 0x8450, 0x8440, 0x8430, 0x8470, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, + 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8470, 0x8490, 0x8560, 0xB1A0, 0xF1A0, 0x29D0, 0x58D0, 0x7A70, + 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F90, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F40, 0x7EB0, 0x7EB0, + 0x7EF0, 0x7F30, 0x7EE0, 0x7E90, 0x7EB0, 0x7F10, 0x7F20, 0x7EF0, 0x7E90, 0x7EB0, 0x7F20, 0x7F40, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F30, 0x7F00, 0x7F30, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EC0, 0x7F40, 0x7EF0, 0x7F20, + 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F10, + 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F30, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EC0, 0x7EF0, + 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7F20, + 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, 0x7F00, + 0x7F10, 0x7F50, 0x7EE0, 0x7E70, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F40, 0x7EF0, 0x7EC0, 0x7F10, 0x7F10, + 0x7F20, 0x7F20, 0x7E90, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, + 0x7F30, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7F10, 0x7F00, 0x7EE0, + 0x7ED0, 0x7F60, 0x7F00, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EF0, + 0x7F00, 0x7EE0, 0x7E90, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, + 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F10, 0x7ED0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7F10, 0x7EB0, 0x7F20, 0x7EE0, 0x7EF0, + 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7F80, 0x7EF0, 0x7F20, 0x7F10, + 0x7F00, 0x7F90, 0x7F10, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F40, 0x7F10, 0x7E90, 0x7EB0, 0x7ED0, + 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, + 0x7F20, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F00, + 0x7EF0, 0x7F50, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7D10, 0x7190, 0x65B0, 0x5960, 0x4B80, 0x3A50, + 0x26B0, 0x1160, 0xFA80, 0xE550, 0xD510, 0xCCA0, 0xCE00, 0xD850, 0xE920, 0xFDD0, 0x12B0, 0x2690, 0x37A0, 0x4600, 0x54B0, 0x61A0, + 0x6F10, 0x7B00, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F20, 0x7EF0, + 0x7F10, 0x7F90, 0x6F70, 0x54E0, 0x3800, 0x1850, 0xF6B0, 0xD480, 0xB160, 0x8E50, 0x8530, 0x84C0, 0x84B0, 0x8490, 0x8490, 0x8490, + 0x84A0, 0x8490, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84B0, 0x8470, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83D0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x83D0, 0x8420, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x84E0, 0x8510, + 0x8510, 0x8520, 0x8550, 0x8550, 0x8530, 0x8540, 0x8530, 0x85A0, 0x8610, 0x8700, 0x88F0, 0x8D80, 0x94C0, 0x9D80, 0xA630, 0xAEF0, + 0xB880, 0xC250, 0xCC70, 0xD6F0, 0xE130, 0xEBE0, 0xF510, 0xFFA0, 0x07A0, 0x0F50, 0x1710, 0x2060, 0x2A80, 0x35C0, 0x40B0, 0x4AB0, + 0x5520, 0x5D70, 0x6520, 0x6BE0, 0x71C0, 0x7600, 0x79D0, 0x7CB0, 0x7E70, 0x7F10, 0x7EF0, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, + 0x7F40, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7E10, 0x7CD0, 0x7BC0, 0x7AF0, 0x7AA0, + 0x7AA0, 0x7B20, 0x7BF0, 0x7C90, 0x7CE0, 0x7D40, 0x7DD0, 0x7E20, 0x7E40, 0x7E90, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, + 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7EE0, 0x7E00, 0x7CD0, 0x7B30, 0x7970, 0x7840, 0x77B0, 0x77B0, 0x77D0, 0x7770, 0x7750, 0x7780, 0x7770, 0x77C0, 0x7850, + 0x7890, 0x7830, 0x77A0, 0x7730, 0x7720, 0x7750, 0x7890, 0x7A30, 0x7B20, 0x7BD0, 0x7BF0, 0x7C10, 0x7C60, 0x7CC0, 0x7D10, 0x7D70, + 0x7D60, 0x7D20, 0x7CF0, 0x7D10, 0x7D60, 0x7D30, 0x7CB0, 0x7B60, 0x7A20, 0x78C0, 0x7790, 0x76E0, 0x7620, 0x75E0, 0x75E0, 0x75E0, + 0x7610, 0x7650, 0x7610, 0x7560, 0x7490, 0x72D0, 0x7030, 0x6DD0, 0x6C30, 0x6A90, 0x68B0, 0x6640, 0x6310, 0x5F10, 0x5A20, 0x5500, + 0x4EE0, 0x49E0, 0x4430, 0x3DF0, 0x3680, 0x2EC0, 0x26C0, 0x1F30, 0x1890, 0x11C0, 0x0B10, 0x0580, 0x00A0, 0xFC70, 0xFA50, 0xF980, + 0xFA10, 0xFC20, 0x0050, 0x0510, 0x0A80, 0x1060, 0x16C0, 0x1CA0, 0x20B0, 0x2320, 0x2460, 0x2310, 0x2000, 0x1AE0, 0x12D0, 0x0930, + 0xFD30, 0xEFC0, 0xE1F0, 0xD490, 0xC7D0, 0xBC90, 0xB200, 0xA7F0, 0x9E80, 0x9540, 0x8D50, 0x8830, 0x85F0, 0x8520, 0x84E0, 0x84D0, + 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, + 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, + 0x83D0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x8400, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8460, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, + 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8550, 0x85B0, 0x8660, 0x87A0, 0x8970, 0x8BA0, 0x8E60, 0x9190, 0x9440, 0x9730, + 0x9A80, 0x9D50, 0xA0A0, 0xA430, 0xA7F0, 0xAC10, 0xB110, 0xB4B0, 0xB9D0, 0xBE00, 0xC1E0, 0xC680, 0xCAE0, 0xCFB0, 0xD460, 0xD8B0, + 0xDCC0, 0xE060, 0xE4F0, 0xEA50, 0xF060, 0xF670, 0xFCD0, 0x0410, 0x0B00, 0x1190, 0x1880, 0x1F80, 0x2760, 0x2ED0, 0x35B0, 0x3CB0, + 0x4170, 0x4690, 0x4B00, 0x4F60, 0x6430, 0x69F0, 0x6FE0, 0x7610, 0x7BF0, 0x7ED0, 0x7F70, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7F50, + 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F40, 0x7F10, 0x7E90, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, + 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, + 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F50, + 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F60, 0x7ED0, 0x7F10, 0x7F00, 0x7F00, 0x7F50, 0x7F00, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F50, 0x7F00, + 0x7EA0, 0x7ED0, 0x7ED0, 0x7F20, 0x7F00, 0x7E90, 0x7ED0, 0x7EE0, 0x7F00, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7E90, + 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, + 0x7EF0, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F00, 0x7F00, 0x7F00, 0x7F50, 0x7EB0, + 0x7E70, 0x7EE0, 0x7EF0, 0x7F40, 0x7ED0, 0x7E90, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7EA0, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, + 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, + 0x7F00, 0x7F20, 0x7F10, 0x7EF0, 0x7F70, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, + 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, + 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F70, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F20, 0x7F70, 0x7EF0, + 0x7EB0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7E90, + 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F00, 0x7F20, 0x7DE0, 0x6980, 0x5530, + 0x4040, 0x2930, 0x15E0, 0x0370, 0xF150, 0xE030, 0xCEE0, 0xBDC0, 0xABC0, 0x9800, 0x88C0, 0x8540, 0x84E0, 0x84B0, 0x84D0, 0x8480, + 0x8470, 0x8460, 0x8450, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8440, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8470, 0x8450, 0x8490, 0x8470, 0x8480, 0x84B0, 0x84E0, 0x8610, 0x9C90, 0xBD70, 0xDEE0, 0xFFF0, + 0x2040, 0x3F30, 0x5B20, 0x72A0, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x6AB0, 0x4970, + 0x26C0, 0x0890, 0xED60, 0xD580, 0xC1C0, 0xB1A0, 0xA530, 0x9C30, 0x95C0, 0x92D0, 0x92B0, 0x9600, 0x9D60, 0xA840, 0xB590, 0xC5C0, + 0xD6E0, 0xE880, 0xFA10, 0x0800, 0x12F0, 0x1B80, 0x21B0, 0x25A0, 0x2890, 0x2930, 0x27B0, 0x23B0, 0x1C60, 0x1290, 0x06B0, 0xF9F0, + 0xEBF0, 0xDBE0, 0xCA30, 0xB610, 0x9D50, 0x89D0, 0x8520, 0x84C0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, + 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8460, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84D0, 0x8520, 0x86A0, 0x8FE0, 0xA240, 0xB2D0, 0xC2D0, + 0xD250, 0xE1D0, 0xEF90, 0xFC80, 0x07E0, 0x11F0, 0x19B0, 0x1FD0, 0x2480, 0x2740, 0x29B0, 0x2B60, 0x2D50, 0x2F10, 0x3150, 0x33A0, + 0x3680, 0x3990, 0x3C00, 0x3DF0, 0x3F90, 0x4030, 0x3FE0, 0x3EC0, 0x3AF0, 0x35D0, 0x2EC0, 0x26A0, 0x1B70, 0x0EC0, 0xFFE0, 0xEE70, + 0xDC10, 0xC840, 0xB430, 0x9F70, 0x8DC0, 0x8630, 0x8510, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, + 0x8510, 0x8580, 0x86B0, 0x8A70, 0x92F0, 0x9D70, 0xA750, 0xB010, 0xB8C0, 0xC140, 0xC840, 0xCDC0, 0xD290, 0xD700, 0xDAF0, 0xDF10, + 0xE250, 0xE4C0, 0xE720, 0xE890, 0xE9D0, 0xEA70, 0xEAC0, 0xEA80, 0xE9D0, 0xE950, 0xE8E0, 0xE790, 0xE5F0, 0xE3A0, 0xE180, 0xDF10, + 0xDCD0, 0xDB80, 0xD9E0, 0xD8F0, 0xD7A0, 0xD650, 0xD520, 0xD330, 0xD110, 0xCFC0, 0xCD90, 0xCBB0, 0xC9E0, 0xC860, 0xC710, 0xC610, + 0xC530, 0xC3A0, 0xC250, 0xC160, 0xBFF0, 0xBF10, 0xBE20, 0xBD40, 0xBCD0, 0xBC10, 0xBC00, 0xBB70, 0xBB30, 0xBBD0, 0xBC00, 0xBD90, + 0xBF00, 0xC030, 0xC280, 0xC490, 0xC730, 0xC9A0, 0xCD60, 0xD220, 0xD8C0, 0xDEE0, 0xE4B0, 0xEA90, 0xF0A0, 0xF680, 0xFDD0, 0x0590, + 0x0DE0, 0x16D0, 0x1F10, 0x2720, 0x2F00, 0x3640, 0x3E90, 0x4620, 0x4D00, 0x5390, 0x5A80, 0x6090, 0x6630, 0x6C20, 0x71C0, 0x7680, + 0x7AB0, 0x7DA0, 0x7F50, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, + 0x7EE0, 0x7F20, 0x7F10, 0x7E90, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F00, 0x7F20, + 0x7F10, 0x7F10, 0x7EC0, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F20, + 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7ED0, 0x7F00, 0x7ED0, 0x7F10, 0x7F60, 0x7EE0, 0x7EC0, 0x7F10, + 0x7F20, 0x7F40, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7EA0, 0x7EF0, 0x7D10, 0x7750, 0x7320, 0x6E20, 0x6960, 0x6510, + 0x5FF0, 0x5B70, 0x5660, 0x51D0, 0x4D50, 0x49E0, 0x4190, 0x40F0, 0x41B0, 0x42C0, 0x4500, 0x4730, 0x4950, 0x4BC0, 0x4EA0, 0x5280, + 0x5650, 0x5A90, 0x5E30, 0x6100, 0x63C0, 0x6640, 0x6810, 0x6AC0, 0x6CE0, 0x6ED0, 0x70B0, 0x7120, 0x71F0, 0x7380, 0x74B0, 0x75B0, + 0x76A0, 0x7790, 0x7780, 0x7740, 0x7650, 0x7500, 0x7380, 0x7140, 0x6D90, 0x6910, 0x6230, 0x5AA0, 0x5110, 0x46B0, 0x3B00, 0x2CF0, + 0x1E50, 0x0E50, 0xFE60, 0xEE60, 0xDF10, 0xCEE0, 0xC090, 0xB210, 0xA450, 0x97A0, 0x8CC0, 0x8790, 0x85B0, 0x8520, 0x84F0, 0x84D0, + 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x84B0, 0x8490, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, 0x84A0, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, + 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8530, 0x85B0, 0x8690, 0x8880, 0x8DD0, 0x94F0, 0x9D30, 0xA4D0, 0xACB0, + 0xB470, 0xBA50, 0xC140, 0xC700, 0xCE10, 0xD550, 0xDC30, 0xE380, 0xE950, 0xEDD0, 0xF260, 0xF6E0, 0xFAC0, 0xFF80, 0x03C0, 0x0880, + 0x0B80, 0x0F30, 0x1320, 0x17E0, 0x1D30, 0x22B0, 0x2990, 0x3030, 0x3670, 0x3D00, 0x4440, 0x4C10, 0x53B0, 0x5AE0, 0x6240, 0x6850, + 0x6E90, 0x74B0, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F80, 0x7F00, 0x7F00, 0x7F10, + 0x7F10, 0x7F80, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F20, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, + 0x7EF0, 0x7F10, 0x7EA0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, + 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F10, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x6F60, 0x5750, + 0x3B50, 0x2290, 0x0A60, 0xF3C0, 0xDF20, 0xCBD0, 0xBCF0, 0xB120, 0xA8C0, 0xA240, 0x9E20, 0x9C10, 0x99F0, 0x9800, 0x9630, 0x9490, + 0x9370, 0x9240, 0x91E0, 0x92C0, 0x94F0, 0x98F0, 0x9E00, 0xA340, 0xA980, 0xAEA0, 0xB420, 0xBA10, 0xC0B0, 0xC830, 0xD060, 0xD980, + 0xE230, 0xEAB0, 0xF2C0, 0xFA70, 0x0300, 0x0A00, 0x10F0, 0x1880, 0x1FE0, 0x2800, 0x2F50, 0x3610, 0x3D60, 0x4440, 0x4A10, 0x4E90, + 0x51F0, 0x5700, 0x5A50, 0x5F70, 0x6420, 0x6840, 0x6DB0, 0x7260, 0x77A0, 0x7D50, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F40, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7350, 0x64B0, 0x5360, 0x4020, 0x29E0, + 0x13E0, 0xFC60, 0xE380, 0xC950, 0xAED0, 0x9550, 0x8780, 0x8550, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8500, + 0x8500, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x84E0, 0x84E0, 0x84E0, 0x84F0, + 0x84F0, 0x8510, 0x8530, 0x8570, 0x85F0, 0x8690, 0x8790, 0x88C0, 0x8AA0, 0x8CF0, 0x90E0, 0x9500, 0x98B0, 0x9B80, 0x9D70, 0x9E60, + 0x9E70, 0x9D10, 0x9C20, 0x9AF0, 0x9930, 0x97A0, 0x9680, 0x9710, 0x9A60, 0xA080, 0xA810, 0xB0F0, 0xBA00, 0xC360, 0xCCC0, 0xD490, + 0xDAD0, 0xDF80, 0xE0F0, 0xDE50, 0xD6B0, 0xCAD0, 0xBBE0, 0xA9F0, 0x99F0, 0x8CB0, 0x86D0, 0x8580, 0x84F0, 0x84D0, 0x84C0, 0x84B0, + 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x84B0, 0x8490, 0x84C0, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, + 0x8500, 0x8510, 0x8550, 0x85F0, 0x8850, 0x90E0, 0x9E20, 0xABF0, 0xB9F0, 0xC880, 0xD7D0, 0xE6C0, 0xF4D0, 0x02A0, 0x0DA0, 0x16F0, + 0x1F90, 0x27B0, 0x2EE0, 0x34F0, 0x3970, 0x3BB0, 0x3B40, 0x3890, 0x3360, 0x2D00, 0x25A0, 0x1D50, 0x1500, 0x0CD0, 0x0560, 0xFE30, + 0xF880, 0xF570, 0xF3F0, 0xF3A0, 0xF520, 0xF780, 0xFB80, 0x0140, 0x0870, 0x1080, 0x1930, 0x2300, 0x2D80, 0x3850, 0x44D0, 0x5190, + 0x5D70, 0x6A30, 0x74B0, 0x7D60, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7ED0, 0x7F10, 0x7F30, + 0x7EE0, 0x7E90, 0x7EF0, 0x7EF0, 0x7C50, 0x6A00, 0x50C0, 0x31D0, 0x0EF0, 0xEBB0, 0xCC50, 0xB220, 0x9D00, 0x8F80, 0x8880, 0x8600, + 0x8530, 0x84F0, 0x84F0, 0x84F0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84F0, 0x84D0, 0x84E0, 0x8500, 0x8530, 0x85C0, + 0x8720, 0x8AE0, 0x9370, 0x9D90, 0xA810, 0xB2C0, 0xBE80, 0xCBB0, 0xD8F0, 0xE730, 0xF630, 0x0580, 0x1410, 0x2250, 0x3030, 0x3E10, + 0x4F30, 0x5EE0, 0x6DF0, 0x7AD0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F40, 0x7F10, 0x7E90, 0x7E90, 0x7F00, 0x7EF0, 0x7F10, + 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7220, 0x5A40, 0x3A00, 0x1510, 0xEC80, + 0xC3F0, 0x9D90, 0x8740, 0x84F0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8490, 0x8460, 0x8460, 0x8410, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8480, 0x8460, 0x8480, 0x8440, + 0x8460, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84D0, + 0x84B0, 0x84D0, 0x84E0, 0x8510, 0x8550, 0x8600, 0x8810, 0x8E50, 0x9A10, 0xA590, 0xB260, 0xBDB0, 0xC830, 0xD160, 0xD9B0, 0xE1F0, + 0xEA30, 0xF160, 0xF870, 0xFF30, 0x0540, 0x0AD0, 0x0F10, 0x1330, 0x1760, 0x1B60, 0x1F90, 0x2290, 0x25B0, 0x2790, 0x2930, 0x2B70, + 0x2D00, 0x2ED0, 0x3020, 0x3120, 0x3250, 0x3300, 0x3360, 0x33A0, 0x3310, 0x33B0, 0x3370, 0x33C0, 0x3410, 0x34B0, 0x3630, 0x3710, + 0x37C0, 0x3800, 0x37B0, 0x37B0, 0x3800, 0x37C0, 0x36F0, 0x3690, 0x31C0, 0x2F60, 0x2E60, 0x2C80, 0x2B00, 0x29F0, 0x2970, 0x2B80, + 0x2EC0, 0x3430, 0x3A50, 0x4210, 0x4BB0, 0x5460, 0x5BE0, 0x6210, 0x6680, 0x6AA0, 0x6D20, 0x6F10, 0x70B0, 0x7230, 0x73A0, 0x7440, + 0x73C0, 0x7230, 0x6F00, 0x6AE0, 0x64D0, 0x5EF0, 0x5850, 0x5150, 0x4A70, 0x43C0, 0x3CD0, 0x3730, 0x31D0, 0x2EC0, 0x2CC0, 0x2A70, + 0x28B0, 0x2700, 0x2690, 0x26D0, 0x27A0, 0x2A80, 0x2E40, 0x3310, 0x3880, 0x3C80, 0x4130, 0x44B0, 0x4720, 0x48D0, 0x4850, 0x4550, + 0x3EE0, 0x3490, 0x27E0, 0x1920, 0x0980, 0xF910, 0xE960, 0xDB80, 0xCF30, 0xC5D0, 0xBDE0, 0xB7F0, 0xB470, 0xB280, 0xB300, 0xB3B0, + 0xB4B0, 0xB5E0, 0xB640, 0xB470, 0xB1B0, 0xAD10, 0xA830, 0xA1D0, 0x9B60, 0x9470, 0x8EA0, 0x8AA0, 0x8810, 0x86E0, 0x8640, 0x85F0, + 0x85B0, 0x8570, 0x8560, 0x8540, 0x8530, 0x8520, 0x8510, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x8530, 0x84E0, 0x84E0, 0x84F0, + 0x8500, 0x8510, 0x8540, 0x8590, 0x8630, 0x8770, 0x89E0, 0x90E0, 0x99C0, 0xA390, 0xAE00, 0xB8E0, 0xC420, 0xCF50, 0xDAF0, 0xE760, + 0xF470, 0x00C0, 0x0BD0, 0x1730, 0x20B0, 0x2970, 0x3180, 0x37B0, 0x3E20, 0x43C0, 0x48B0, 0x4E20, 0x51E0, 0x5650, 0x5A10, 0x5C70, + 0x5EA0, 0x5F80, 0x60C0, 0x60E0, 0x6090, 0x6030, 0x5E60, 0x5D40, 0x5B50, 0x59B0, 0x5920, 0x5940, 0x5B90, 0x5EB0, 0x6260, 0x66F0, + 0x69F0, 0x6B60, 0x6960, 0x63F0, 0x5B00, 0x4F50, 0x4150, 0x3270, 0x23C0, 0x1710, 0x0BB0, 0x01F0, 0xF8C0, 0xEEA0, 0xE510, 0xDB00, + 0xD020, 0xC480, 0xB8E0, 0xAD40, 0xA110, 0x9580, 0x8C60, 0x8810, 0x86A0, 0x85E0, 0x8590, 0x8580, 0x8590, 0x8580, 0x85A0, 0x85F0, + 0x8680, 0x87D0, 0x8A80, 0x9020, 0x9850, 0xA280, 0xAC20, 0xB650, 0xC180, 0xCB80, 0xD550, 0xDD90, 0xE570, 0xEC70, 0xF210, 0xF790, + 0xFBE0, 0x0020, 0x02C0, 0x04C0, 0x0750, 0x0980, 0x0B70, 0x0CA0, 0x0CB0, 0x0D00, 0x0CE0, 0x0B70, 0x0930, 0x05B0, 0x0120, 0xF9D0, + 0xEFD0, 0xBD00, 0xAFC0, 0xA3C0, 0x9AB0, 0x9310, 0x8D50, 0x8980, 0x8740, 0x85F0, 0x8550, 0x8510, 0x84E0, 0x84D0, 0x84C0, 0x84B0, + 0x84D0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8490, 0x8490, 0x8450, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84C0, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, + 0x8500, 0x8500, 0x8520, 0x8550, 0x85B0, 0x8640, 0x8750, 0x8950, 0x8D10, 0x92C0, 0x9920, 0x9DE0, 0xA1C0, 0xA5E0, 0xA9D0, 0xAC90, + 0xAFB0, 0xB2D0, 0xB5F0, 0xB8B0, 0xBAC0, 0xBCD0, 0xBDE0, 0xBF30, 0xBFD0, 0xBF80, 0xBEE0, 0xBE30, 0xBD50, 0xBC30, 0xBAA0, 0xB940, + 0xB760, 0xB5B0, 0xB440, 0xB3D0, 0xB270, 0xB1D0, 0xB1C0, 0xB1B0, 0xB0D0, 0xB020, 0xAFC0, 0xAED0, 0xAE80, 0xAEE0, 0xAF00, 0xAEE0, + 0xAE10, 0xAC80, 0xAA70, 0xA890, 0xA780, 0xA720, 0xA6F0, 0xA630, 0xA620, 0xA6C0, 0xA740, 0xA7A0, 0xA7F0, 0xA7E0, 0xA820, 0xA870, + 0xA9D0, 0xABA0, 0xADF0, 0xB030, 0xB200, 0xB330, 0xB440, 0xB540, 0xB6B0, 0xB940, 0xBBC0, 0xBE30, 0xBFF0, 0xC100, 0xC210, 0xC310, + 0xC3F0, 0xC580, 0xC760, 0xC940, 0xCAC0, 0xCBC0, 0xCCF0, 0xCE80, 0xD000, 0xD250, 0xD450, 0xD760, 0xD9D0, 0xDBF0, 0xDEB0, 0xE160, + 0xE460, 0xE6F0, 0xE990, 0xEC60, 0xEFD0, 0xF380, 0xF760, 0xFAE0, 0xFDD0, 0x0030, 0x01C0, 0x02F0, 0x04B0, 0x0730, 0x0900, 0x0AD0, + 0x0C10, 0x0C90, 0x0C00, 0x0B40, 0x0950, 0x0850, 0x0710, 0x0600, 0x0560, 0x0580, 0x05D0, 0x06A0, 0x0750, 0x08D0, 0x0B00, 0x0E20, + 0x1330, 0x1960, 0x2100, 0x2A10, 0x3410, 0x3EA0, 0x49E0, 0x54F0, 0x6090, 0x6BE0, 0x76F0, 0x7E90, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F60, 0x7F40, 0x7F70, 0x7F20, 0x7EE0, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7E80, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7E90, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7EE0, 0x79E0, 0x7040, 0x6430, 0x5700, 0x4820, 0x3900, 0x2B30, 0x1E40, 0x1240, 0x0890, + 0xFF30, 0xF660, 0xEDA0, 0xE450, 0xDCA0, 0xD4A0, 0xCC80, 0xC3C0, 0xBB80, 0xB2F0, 0xAA00, 0xA110, 0x9800, 0x8FC0, 0x8A80, 0x8780, + 0x8630, 0x85A0, 0x8550, 0x8530, 0x8510, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84F0, 0x84D0, 0x84D0, + 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x8460, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, + 0x84F0, 0x8500, 0x8510, 0x8510, 0x8520, 0x8530, 0x8530, 0x8540, 0x8550, 0x8550, 0x8580, 0x8590, 0x85B0, 0x85C0, 0x85E0, 0x85F0, + 0x85D0, 0x85B0, 0x85D0, 0x8590, 0x85B0, 0x8580, 0x8580, 0x8580, 0x8560, 0x8550, 0x8540, 0x8530, 0x8530, 0x8530, 0x8540, 0x8540, + 0x8550, 0x8580, 0x85C0, 0x8650, 0x8780, 0x8A70, 0x91D0, 0x9C50, 0xA6E0, 0xB220, 0xBD60, 0xC8F0, 0xD440, 0xDE60, 0xE690, 0xEDF0, + 0xF480, 0xF880, 0xFBF0, 0xFD80, 0xFD70, 0xF890, 0xF180, 0xE6E0, 0xDA50, 0xCC40, 0xBE60, 0xB150, 0xA5F0, 0x9C00, 0x9300, 0x8CC0, + 0x88D0, 0x86F0, 0x8600, 0x8580, 0x8540, 0x8520, 0x8500, 0x8500, 0x8500, 0x8530, 0x8500, 0x8500, 0x8500, 0x84E0, 0x8510, 0x8510, + 0x8530, 0x8530, 0x8550, 0x8570, 0x85A0, 0x85F0, 0x86A0, 0x8810, 0x8AE0, 0x8F50, 0xA150, 0xA4A0, 0xA7A0, 0xA9C0, 0xAA50, 0xA920, + 0xA4E0, 0x9F10, 0x9740, 0x8DC0, 0x87E0, 0x8580, 0x84F0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8460, 0x8470, 0x8470, 0x8480, 0x84A0, 0x8480, 0x8490, + 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x84D0, 0x84E0, 0x84E0, 0x8500, 0x84F0, + 0x84F0, 0x8500, 0x84B0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8530, 0x8550, 0x8570, 0x8590, 0x85B0, 0x85E0, 0x8630, 0x86B0, 0x8790, + 0x8920, 0x8B10, 0x8DE0, 0x9280, 0x9820, 0x9F60, 0xA640, 0xAD80, 0xB6B0, 0xC020, 0xCA30, 0xD4D0, 0xDFB0, 0xEB90, 0xF780, 0x02B0, + 0x0CD0, 0x1470, 0x1B60, 0x2080, 0x23B0, 0x2520, 0x2440, 0x2380, 0x2200, 0x2180, 0x2110, 0x2030, 0x2020, 0x1E90, 0x1CC0, 0x1B90, + 0x1BC0, 0x1E80, 0x21F0, 0x2680, 0x2BA0, 0x30E0, 0x3610, 0x3BB0, 0x41A0, 0x4890, 0x4EC0, 0x54C0, 0x59C0, 0x5EB0, 0x6440, 0x69C0, + 0x6F90, 0x7530, 0x79F0, 0x7D90, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F00, 0x7ED0, 0x7ED0, 0x76C0, 0x6A40, 0x5BD0, + 0x4A00, 0x34E0, 0x1EE0, 0x06C0, 0xECA0, 0xD490, 0xBDF0, 0xA9C0, 0x9840, 0x8C50, 0x87B0, 0x8650, 0x85E0, 0x85B0, 0x85B0, 0x8590, + 0x8560, 0x8530, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x8500, 0x84E0, 0x84F0, 0x8500, 0x8520, 0x8550, 0x85E0, 0x8780, 0x8CD0, + 0x97E0, 0xA3C0, 0xAFD0, 0xBB80, 0xC570, 0xCD30, 0xD1C0, 0xD2B0, 0xD140, 0xCC80, 0xC580, 0xBCF0, 0xB3C0, 0xA980, 0x9F90, 0x9540, + 0x8D30, 0x88B0, 0x86D0, 0x8600, 0x85B0, 0x8580, 0x8580, 0x85B0, 0x85F0, 0x8670, 0x8780, 0x8890, 0x89D0, 0x8AC0, 0x8BA0, 0x8CC0, + 0x8DC0, 0x8E60, 0x8DA0, 0x8C00, 0x8A40, 0x88A0, 0x8780, 0x8690, 0x8600, 0x8590, 0x8550, 0x8520, 0x8510, 0x8500, 0x84F0, 0x84F0, + 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x8500, 0x8520, 0x8530, 0x8550, 0x8590, 0x85F0, 0x8690, 0x87E0, 0x8A60, + 0x8F70, 0x9680, 0x9E70, 0xA5E0, 0xADC0, 0xB580, 0xBD10, 0xC540, 0xCCA0, 0xD3E0, 0xDB50, 0xE310, 0xEAA0, 0xF1A0, 0xF7F0, 0xFDA0, + 0x0320, 0x08A0, 0x0ED0, 0x1510, 0x1AE0, 0x1FE0, 0x2550, 0x29D0, 0x2DE0, 0x31D0, 0x35B0, 0x3A40, 0x3DE0, 0x40D0, 0x4370, 0x4520, + 0x47C0, 0x4A50, 0x4C60, 0x4ED0, 0x50D0, 0x52E0, 0x54A0, 0x5660, 0x5890, 0x5A10, 0x5CA0, 0x5E10, 0x5E80, 0x5F00, 0x5F10, 0x5FD0, + 0x60B0, 0x6200, 0x64D0, 0x6670, 0x67C0, 0x68C0, 0x69B0, 0x6AB0, 0x6C00, 0x6D40, 0x6F50, 0x71B0, 0x7440, 0x7690, 0x78A0, 0x7AC0, + 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7EE0, 0x7E40, 0x7CD0, 0x7A90, 0x7760, 0x73D0, 0x7050, 0x6D40, 0x6A20, + 0x66D0, 0x6260, 0x5E70, 0x5910, 0x5290, 0x4AE0, 0x42C0, 0x3860, 0x2FE0, 0x2910, 0x2250, 0x1C00, 0x16A0, 0x1110, 0x0C90, 0x0960, + 0x0840, 0x0860, 0x0A00, 0x0C40, 0x1020, 0x1550, 0x1C50, 0x2490, 0x2DE0, 0x3830, 0x4090, 0x4880, 0x4FF0, 0x5730, 0x5E90, 0x6660, + 0x6E00, 0x7450, 0x7A30, 0x7D60, 0x7E50, 0x7E30, 0x7B30, 0x7460, 0x6890, 0x5940, 0x45B0, 0x2ED0, 0x1890, 0x02C0, 0xECD0, 0xD7A0, + 0xC3E0, 0xB180, 0xA070, 0x92E0, 0x8A30, 0x8740, 0x8640, 0x8600, 0x8620, 0x8690, 0x88B0, 0x8DC0, 0x95B0, 0x9E60, 0xA470, 0xA9B0, + 0xAD90, 0xB040, 0xB280, 0xB380, 0xB270, 0xAF50, 0xA990, 0xA1B0, 0x97C0, 0x8DB0, 0x8800, 0x85D0, 0x8520, 0x84F0, 0x84D0, 0x84C0, + 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84D0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84F0, 0x84E0, + 0x8530, 0x8550, 0x85F0, 0x8800, 0x8E90, 0x9980, 0xA420, 0xAEA0, 0xB720, 0xBDD0, 0xC2D0, 0xC740, 0xCAB0, 0xCDF0, 0xD010, 0xD2A0, + 0xD430, 0xD4E0, 0xD560, 0xD590, 0xD610, 0xD5C0, 0xD480, 0xD370, 0xD2B0, 0xD2D0, 0xD2D0, 0xD220, 0xD140, 0xCFF0, 0xCDD0, 0xCB90, + 0xC970, 0xC890, 0xC6C0, 0xC5C0, 0xC400, 0xC230, 0xC0E0, 0xBF00, 0xBD40, 0xBAE0, 0xB8F0, 0xB6C0, 0xB4D0, 0xB300, 0xB140, 0xAF80, + 0xAE10, 0xAC80, 0xAB10, 0xA9E0, 0xA920, 0xA8F0, 0xAA00, 0xABA0, 0xAE00, 0xB000, 0xB390, 0xB750, 0xBD00, 0xC2C0, 0xC970, 0xD0B0, + 0xD890, 0xE0F0, 0xE990, 0xF270, 0xFD00, 0x06C0, 0x1230, 0x1DC0, 0x2890, 0x3470, 0x3F70, 0x4B40, 0x55F0, 0x6050, 0x69F0, 0x7240, + 0x77F0, 0x7D00, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F00, 0x7EE0, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, + 0x7F10, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, + 0x7EF0, 0x7F80, 0x7F10, 0x7EF0, 0x7F30, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, + 0x7F70, 0x7F20, 0x7EC0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7C80, 0x7250, 0x68B0, 0x5D60, 0x5280, 0x46D0, 0x3C20, + 0x33A0, 0x2A60, 0x21D0, 0x1900, 0x1120, 0x0B20, 0x0650, 0x0440, 0x0480, 0x06D0, 0x0C70, 0x1320, 0x1B00, 0x21D0, 0x27A0, 0x2B70, + 0x2D30, 0x2E30, 0x2DE0, 0x2B80, 0x2850, 0x22D0, 0x1C70, 0x1590, 0x0F50, 0x0B20, 0x0A60, 0x0B90, 0x0E00, 0x10A0, 0x12E0, 0x1310, + 0x1170, 0x0E60, 0x09B0, 0x04E0, 0xFFC0, 0xFA90, 0xF6B0, 0xF360, 0xF140, 0xEFD0, 0xEF90, 0xF120, 0xF160, 0xF1D0, 0xF0D0, 0xEEE0, + 0xED70, 0xEB30, 0xE9B0, 0xE800, 0xE6F0, 0xE820, 0xE980, 0xEC40, 0xEFF0, 0xF350, 0xF800, 0xFC00, 0x00D0, 0x1EC0, 0x2810, 0x3080, + 0x3860, 0x40C0, 0x4900, 0x50E0, 0x5710, 0x5AB0, 0x5E80, 0x60E0, 0x62F0, 0x64D0, 0x6770, 0x6AD0, 0x6DD0, 0x7030, 0x7340, 0x75E0, + 0x7980, 0x7CB0, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F30, 0x7EF0, 0x7ED0, 0x7EE0, + 0x7F00, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F20, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EE0, + 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7EA0, 0x7BE0, 0x7790, 0x72D0, 0x6D00, 0x66E0, 0x6050, 0x5990, + 0x5310, 0x4C60, 0x4680, 0x4080, 0x3AA0, 0x34C0, 0x2F10, 0x2A70, 0x2730, 0x24A0, 0x2370, 0x2300, 0x22F0, 0x2400, 0x2550, 0x2700, + 0x2960, 0x2B90, 0x2F10, 0x3260, 0x3640, 0x3910, 0x3A90, 0x3C00, 0x3B80, 0x3AF0, 0x39B0, 0x37A0, 0x3630, 0x3400, 0x3140, 0x2E10, + 0x29F0, 0x2680, 0x2240, 0x1EE0, 0x1B80, 0x1890, 0x1710, 0x15A0, 0x15C0, 0x16D0, 0x1880, 0x1BF0, 0x2020, 0x25D0, 0x2D10, 0x33B0, + 0x3BC0, 0x42F0, 0x4B30, 0x5280, 0x5940, 0x5FD0, 0x6550, 0x6AC0, 0x6E10, 0x6FB0, 0x70F0, 0x7040, 0x6D90, 0x69B0, 0x6520, 0x6000, + 0x5890, 0x4FF0, 0x4740, 0x3DC0, 0x33D0, 0x28F0, 0x1DA0, 0x12E0, 0x0730, 0xFB00, 0xEF50, 0xE3D0, 0xD980, 0xCE50, 0xC490, 0xBB10, + 0xB2A0, 0xAB00, 0xA320, 0x9D70, 0x98B0, 0x9580, 0x9410, 0x9480, 0x9670, 0x9830, 0x9A50, 0x9BF0, 0x9DF0, 0xA000, 0xA2F0, 0xA620, + 0xA9A0, 0xAC90, 0xAF80, 0xB1A0, 0xB3E0, 0xB690, 0xB830, 0xB920, 0xBA10, 0xBA90, 0xBB60, 0xBC10, 0xBCA0, 0xBE70, 0xBFB0, 0xC0D0, + 0xC230, 0xC310, 0xC480, 0xC590, 0xC790, 0xC9E0, 0xCC30, 0xCE60, 0xCFC0, 0xD0E0, 0xD220, 0xD330, 0xD3C0, 0xD460, 0xD4F0, 0xD4E0, + 0xD4B0, 0xD4D0, 0xD450, 0xD480, 0xD440, 0xD3B0, 0xD3D0, 0xD460, 0xD480, 0xD510, 0xD580, 0xD680, 0xD6B0, 0xD690, 0xD560, 0xD420, + 0xD3D0, 0xD3C0, 0xD470, 0xD470, 0xD4C0, 0xD530, 0xD580, 0xD550, 0xD5D0, 0xD680, 0xD710, 0xD6F0, 0xD630, 0xD640, 0xD5D0, 0xD630, + 0xD6F0, 0xD700, 0xD740, 0xD700, 0xD750, 0xD710, 0xD7E0, 0xD960, 0xDA80, 0xDB20, 0xDB70, 0xDB00, 0xDB80, 0xDBE0, 0xDCA0, 0xDD40, + 0xDDF0, 0xDEF0, 0xDEA0, 0xDE70, 0xDDE0, 0xDDB0, 0xDDD0, 0xDD60, 0xDD40, 0xDCD0, 0xDC20, 0xDC90, 0xDCD0, 0xDCD0, 0xDCC0, 0xDD30, + 0xDDB0, 0xDE30, 0xE020, 0xE350, 0xE6D0, 0xEB00, 0xEE60, 0xF170, 0xF3A0, 0xF670, 0xFA90, 0xFF10, 0x03F0, 0x0940, 0x0D90, 0x11F0, + 0x13A0, 0x1540, 0x1610, 0x16A0, 0x1680, 0x16B0, 0x1670, 0x1560, 0x13C0, 0x11F0, 0x0F60, 0x0CC0, 0x0900, 0x0550, 0x0160, 0xFE40, + 0xFA90, 0xF720, 0xF2E0, 0xEE00, 0xE8D0, 0xE310, 0xDDA0, 0xD890, 0xD340, 0xCE20, 0xC960, 0xC460, 0xBEF0, 0xB9E0, 0xB5A0, 0xB1E0, + 0xAE90, 0xAB70, 0xA860, 0xA5B0, 0xA450, 0xA3F0, 0xA3A0, 0xA4A0, 0xA5B0, 0xA770, 0xA940, 0xAB40, 0xADB0, 0xB080, 0xB470, 0xB8F0, + 0xBE00, 0xC320, 0xC840, 0xCD90, 0xD410, 0xDA30, 0xDFB0, 0xE580, 0xEAD0, 0xF010, 0xF4C0, 0xF960, 0xFF40, 0x04D0, 0x0950, 0x0CE0, + 0x1050, 0x12F0, 0x1530, 0x17A0, 0x1AC0, 0x1DD0, 0x20B0, 0x2310, 0x24C0, 0x2650, 0x2770, 0x2820, 0x2810, 0x2780, 0x26B0, 0x2500, + 0x22F0, 0x20F0, 0x1EA0, 0x1AE0, 0x1710, 0x1280, 0x0E50, 0x0A00, 0x05B0, 0x01E0, 0xFEE0, 0xFC70, 0xFB30, 0xFA10, 0xF9A0, 0xFA70, + 0xFBD0, 0xFD90, 0x0060, 0x03A0, 0x0730, 0x0B30, 0x0F00, 0x12C0, 0x15D0, 0x17F0, 0x19E0, 0x1BE0, 0x1E40, 0x20F0, 0x23B0, 0x2760, + 0x2AE0, 0x2D80, 0x2FB0, 0x31D0, 0x3490, 0x3790, 0x3B60, 0x3EB0, 0x4240, 0x4540, 0x4890, 0x4D20, 0x52A0, 0x5A50, 0x6290, 0x6B30, + 0x7440, 0x7C10, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7EE0, 0x7100, 0x6210, 0x5390, 0x4560, + 0x3910, 0x2D70, 0x2000, 0x11A0, 0x0050, 0xED50, 0xD8B0, 0xC460, 0xAFD0, 0xA070, 0x9500, 0x8EC0, 0x8C30, 0x8C60, 0x9060, 0x9A40, + 0xA690, 0xB780, 0xC7C0, 0xD760, 0xE5F0, 0xF1C0, 0xFC40, 0x0380, 0x0890, 0x0BF0, 0x0E80, 0x1010, 0x1160, 0x12E0, 0x1580, 0x17A0, + 0x1A30, 0x1CC0, 0x1F90, 0x2300, 0x2660, 0x2AC0, 0x2FC0, 0x3610, 0x3CF0, 0x4360, 0x4A80, 0x5180, 0x5830, 0x5DE0, 0x61D0, 0x6590, + 0x6800, 0x69A0, 0x6AF0, 0x6BB0, 0x6BB0, 0x6A50, 0x6860, 0x6400, 0x5DC0, 0x5650, 0x4CC0, 0x43A0, 0x3B00, 0x3230, 0x2960, 0x2060, + 0x1680, 0x0D10, 0x0310, 0xFA40, 0xF1F0, 0xE9D0, 0xE330, 0xDD60, 0xDA50, 0xD920, 0xD9C0, 0xDC40, 0xDEF0, 0xE2B0, 0xE530, 0xE7C0, + 0xEAB0, 0xED60, 0xF050, 0xF2F0, 0xF550, 0xF7A0, 0xFA40, 0xFCD0, 0x0070, 0x0540, 0x0B10, 0x10D0, 0x1700, 0x1DC0, 0x2550, 0x2E50, + 0x3820, 0x4300, 0x4E60, 0x5840, 0x6290, 0x6C30, 0x7600, 0x7D40, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F00, 0x7EF0, 0x7EB0, 0x73E0, 0x6660, 0x56F0, 0x47B0, 0x37F0, 0x2940, 0x1C50, 0x1070, 0x0570, 0xFC50, 0xF480, + 0xEE10, 0xE920, 0xE570, 0xE2B0, 0xE1B0, 0xE1A0, 0xE210, 0xE2F0, 0xE460, 0xE5D0, 0xE790, 0xE950, 0xEB60, 0xECA0, 0xECA0, 0xECA0, + 0xEBD0, 0xEAD0, 0xE9A0, 0xE7F0, 0xE6D0, 0xE520, 0xE360, 0xE0F0, 0xDE80, 0xDBF0, 0xD9A0, 0xD710, 0xD500, 0xD3A0, 0xD360, 0xD390, + 0xD510, 0xD870, 0xDB90, 0xE090, 0xE5C0, 0xEB10, 0xF050, 0xF5A0, 0xFB90, 0x00E0, 0x0670, 0x0B30, 0x0F00, 0x1280, 0x1590, 0x1830, + 0x1A40, 0x1AF0, 0x1BD0, 0x1B50, 0x19D0, 0x1830, 0x1600, 0x1480, 0x1290, 0x11B0, 0x1160, 0x1220, 0x1450, 0x17B0, 0x1C00, 0x2210, + 0x28B0, 0x30B0, 0x3920, 0x4220, 0x4C90, 0x5800, 0x6280, 0x6C90, 0x74B0, 0x7BB0, 0x7EC0, 0x7F40, 0x7F30, 0x7F20, 0x7F10, 0x7F00, + 0x7F40, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7D80, 0x78E0, 0x74F0, 0x7080, 0x6C90, 0x67F0, 0x6380, 0x5FD0, 0x5B90, 0x56F0, + 0x5290, 0x4DF0, 0x49E0, 0x44D0, 0x3FF0, 0x3AA0, 0x3570, 0x30D0, 0x2CD0, 0x28F0, 0x2610, 0x22D0, 0x2000, 0x1C30, 0x1820, 0x0EC0, + 0x0D80, 0x0D10, 0x0C90, 0x0CB0, 0x0CE0, 0x0CD0, 0x0D10, 0x0D30, 0x0DB0, 0x0E00, 0x0EA0, 0x1000, 0x1060, 0x11C0, 0x11E0, 0x1090, + 0x0FB0, 0x0E00, 0x0C20, 0x0AD0, 0x0890, 0x05E0, 0x0300, 0xFFF0, 0xFBB0, 0xF660, 0xF1D0, 0xEC80, 0xE750, 0xE1E0, 0xDC90, 0xD6F0, + 0xD0E0, 0xCA70, 0xC330, 0xBC30, 0xB5E0, 0xAF90, 0xAA60, 0xA5D0, 0xA1E0, 0x9F30, 0x9CA0, 0x9B20, 0x9AA0, 0x9B50, 0x9D00, 0x9F30, + 0xA2F0, 0xA6C0, 0xAAC0, 0xAF10, 0xB4B0, 0xBA20, 0xC0D0, 0xC730, 0xCE20, 0xD430, 0xD930, 0xDF90, 0xE490, 0xEB00, 0xF090, 0xF570, + 0xFAE0, 0xFF90, 0x0480, 0x0990, 0x0EA0, 0x1400, 0x1900, 0x1D80, 0x2210, 0x2650, 0x2BD0, 0x3170, 0x37A0, 0x3D50, 0x4310, 0x49C0, + 0x50E0, 0x57D0, 0x5EF0, 0x6630, 0x6DE0, 0x74D0, 0x7B70, 0x7EE0, 0x7F30, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, + 0x7F30, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7910, 0x6860, 0x54D0, 0x4210, 0x2F60, 0x1E00, 0x0D50, 0xFE30, + 0xF0B0, 0xE520, 0xDAB0, 0xD170, 0xCAC0, 0xC690, 0xC380, 0xC1F0, 0xC2A0, 0xC4F0, 0xC980, 0xCF70, 0xD810, 0xE1F0, 0xED70, 0xFAB0, + 0x07D0, 0x1530, 0x2230, 0x2DF0, 0x38F0, 0x41F0, 0x4840, 0x4D10, 0x5040, 0x52A0, 0x54D0, 0x5770, 0x59A0, 0x5AC0, 0x5A90, 0x56F0, + 0x4FF0, 0x4740, 0x3BB0, 0x3030, 0x2400, 0x1770, 0x0C50, 0x00A0, 0xF7C0, 0xEF40, 0xE750, 0xE070, 0xD900, 0xD140, 0xC980, 0xC1C0, + 0xB9E0, 0xB200, 0xAA90, 0xA370, 0x9BF0, 0x9530, 0x8EE0, 0x8A80, 0x87E0, 0x8650, 0x85E0, 0x8550, 0x8550, 0x8500, 0x84F0, 0x84F0, + 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84E0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84D0, 0x84F0, 0x8500, + 0x8510, 0x8530, 0x8540, 0x8580, 0x85E0, 0x8660, 0x8770, 0x8970, 0x8D10, 0x92C0, 0x9890, 0x9E80, 0xA4A0, 0xAB40, 0xB100, 0xB710, + 0xBD80, 0xC410, 0xCAA0, 0xD150, 0xD850, 0xDF50, 0xE5D0, 0xEB70, 0xF0B0, 0xF4E0, 0xF980, 0xFDE0, 0x02B0, 0x06E0, 0x0A40, 0x0E60, + 0x10A0, 0x1280, 0x1490, 0x1610, 0x1930, 0x1BA0, 0x1CD0, 0x1E50, 0x1EF0, 0x2090, 0x22B0, 0x2560, 0x2840, 0x2BB0, 0x2EF0, 0x3220, + 0x35F0, 0x3A70, 0x3F70, 0x4590, 0x4C50, 0x53B0, 0x5C20, 0x6410, 0x6CB0, 0x74F0, 0x7C70, 0x7F10, 0x7EA0, 0x7EC0, 0x7E80, 0x7F10, + 0x7F20, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7E30, 0x7150, 0x6500, + 0x5800, 0x4A90, 0x3CF0, 0x2EA0, 0x2190, 0x1370, 0x07A0, 0xFB10, 0xF250, 0xEB00, 0xE4D0, 0xDFB0, 0xDB50, 0xD6B0, 0xD220, 0xCC80, + 0xC5D0, 0xBFC0, 0xB990, 0xB390, 0xAD40, 0xA7C0, 0xA300, 0x9EC0, 0x9C60, 0x9AB0, 0x9B10, 0x9C60, 0x9DC0, 0x9F00, 0x9F30, 0x9F80, + 0x9FB0, 0x9F10, 0x9DD0, 0x9B60, 0x98F0, 0x9520, 0x9040, 0x8C20, 0x8910, 0x8720, 0x8630, 0x85A0, 0x8550, 0x8530, 0x8510, 0x8500, + 0x84F0, 0x8500, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, + 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8500, 0x8510, 0x8510, 0x8520, 0x8530, 0x8550, 0x8560, 0x8580, 0x85B0, 0x8610, + 0x86A0, 0x8790, 0x88D0, 0x8AC0, 0x8C30, 0x8D20, 0x8D40, 0x8C70, 0x8B30, 0x8980, 0x8810, 0x86E0, 0x8600, 0x8580, 0x8540, 0x8510, + 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84A0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8520, 0x8530, 0x8540, + 0x8550, 0x8570, 0x8590, 0x85B0, 0x85D0, 0x85E0, 0x85E0, 0x85E0, 0x85E0, 0x8600, 0x85E0, 0x85D0, 0x85C0, 0x85B0, 0x8590, 0x8570, + 0x8560, 0x8550, 0x8540, 0x8530, 0x8530, 0x8530, 0x8520, 0x8550, 0x8520, 0x8520, 0x8520, 0x8510, 0x8510, 0x8510, 0x8510, 0x8510, + 0x8520, 0x8520, 0x8520, 0x8530, 0x8530, 0x8550, 0x8560, 0x8580, 0x85B0, 0x85F0, 0x8640, 0x86C0, 0x8780, 0x88F0, 0x9320, 0x96C0, + 0x9A90, 0x9EB0, 0xA3C0, 0xA970, 0xAF20, 0xB4B0, 0xBA70, 0xBFB0, 0xC480, 0xC940, 0xCEC0, 0xD390, 0xD910, 0xDDE0, 0xE310, 0xE8F0, + 0xEE30, 0xF300, 0xF680, 0xF990, 0xFC50, 0xFF30, 0x0270, 0x0580, 0x08E0, 0x0BB0, 0x0EB0, 0x11F0, 0x13E0, 0x15F0, 0x1950, 0x1C30, + 0x1F30, 0x2190, 0x2490, 0x27F0, 0x2AE0, 0x2DD0, 0x3210, 0x3530, 0x3970, 0x3C50, 0x3FB0, 0x41F0, 0x4370, 0x4690, 0x4870, 0x4B70, + 0x4E00, 0x4FD0, 0x5280, 0x5410, 0x5610, 0x5780, 0x57C0, 0x5860, 0x5840, 0x5830, 0x58C0, 0x5890, 0x5860, 0x5780, 0x5660, 0x5550, + 0x53B0, 0x52C0, 0x51E0, 0x5140, 0x5130, 0x5090, 0x50E0, 0x5160, 0x51C0, 0x53D0, 0x56B0, 0x5B20, 0x5FC0, 0x6490, 0x6A30, 0x6FA0, + 0x75E0, 0x7B10, 0x7EF0, 0x7F00, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F10, 0x7E70, 0x7EC0, + 0x7ED0, 0x7F10, 0x7EE0, 0x7E90, 0x7F00, 0x7EA0, 0x75C0, 0x6D90, 0x64C0, 0x5C00, 0x5410, 0x4C50, 0x45E0, 0x4040, 0x3C80, 0x3AD0, + 0x3B90, 0x3EC0, 0x4380, 0x4840, 0x4C90, 0x5110, 0x5620, 0x59E0, 0x5C80, 0x5DB0, 0x5D20, 0x5BA0, 0x5840, 0x5330, 0x4C20, 0x44E0, + 0x3DF0, 0x37B0, 0x3320, 0x3240, 0x3510, 0x3C30, 0x4640, 0x5240, 0x5FB0, 0x6C20, 0x77C0, 0x7E80, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7F00, 0x7F20, 0x7EE0, 0x7E90, 0x7E30, 0x7B20, 0x7990, 0x7AE0, 0x7D60, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7ED0, 0x7F50, 0x7F00, + 0x7F00, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, + 0x7D50, 0x7400, 0x6860, 0x5AC0, 0x4C50, 0x4170, 0x39C0, 0x3670, 0x3690, 0x3820, 0x3A50, 0x3A70, 0x3760, 0x31C0, 0x2850, 0x1D90, + 0x1070, 0x0240, 0xF5D0, 0xE9C0, 0xE1D0, 0xDC90, 0xDAA0, 0xDBE0, 0xDE90, 0xE2F0, 0xE8A0, 0xEEA0, 0xF610, 0xFD10, 0x0460, 0x0A20, + 0x0E40, 0x01E0, 0xF810, 0xEB50, 0xDA00, 0xC400, 0xA930, 0x8C50, 0x8500, 0x84A0, 0x8480, 0x8460, 0x8450, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, 0x8460, 0x8470, 0x8450, + 0x8440, 0x8430, 0x8440, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, + 0x8470, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8450, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8530, 0x8550, 0x8580, 0x85B0, 0x85F0, 0x8630, 0x86C0, + 0x87B0, 0x8910, 0x8B50, 0x8DF0, 0x9090, 0x9290, 0x9580, 0x9870, 0x9B50, 0x9F70, 0xA2D0, 0xA650, 0xA9E0, 0xAC90, 0xB090, 0xB430, + 0xB860, 0xBC80, 0xBFA0, 0xC260, 0xC490, 0xC630, 0xC900, 0xCBC0, 0xCFD0, 0xD260, 0xD480, 0xD620, 0xD7C0, 0xDA20, 0xDBE0, 0xDDD0, + 0xDFF0, 0xE130, 0xE360, 0xE590, 0xE850, 0xEB60, 0xEE10, 0xF0A0, 0xF200, 0xF2F0, 0xF330, 0xF3A0, 0xF500, 0xF690, 0xF7F0, 0xF940, + 0xF9A0, 0xFA10, 0xFAA0, 0xFA70, 0xFA40, 0xFAB0, 0xFB90, 0xFB20, 0xFA70, 0xFB10, 0xFBC0, 0xFCE0, 0xFE90, 0xFF90, 0x00C0, 0x00C0, + 0x00B0, 0x00A0, 0x0060, 0x00F0, 0x00C0, 0x00D0, 0x0160, 0x0040, 0x0010, 0xFF80, 0xFE30, 0xFCD0, 0xFAA0, 0xF8A0, 0xF610, 0xF350, + 0xF0E0, 0xEED0, 0xED70, 0xEB80, 0xE9E0, 0xE850, 0xE710, 0xE550, 0xE350, 0xE0C0, 0xDF80, 0xDCE0, 0xDB40, 0xD980, 0xD860, 0xD7E0, + 0xD690, 0xD550, 0xD380, 0xD120, 0xCF40, 0xCDB0, 0xCC60, 0xCA90, 0xC8B0, 0xC6B0, 0xC420, 0xC280, 0xC0E0, 0xBEE0, 0xBE10, 0xBCC0, + 0xBB90, 0xB9B0, 0xB870, 0xB710, 0xB5B0, 0xB560, 0xB5A0, 0xB610, 0xB6C0, 0xB7D0, 0xB8F0, 0xBB00, 0xBDC0, 0xC1B0, 0xC580, 0xC9D0, + 0xCE80, 0xD310, 0xD890, 0xDDA0, 0xE270, 0xE850, 0xEE40, 0xF4A0, 0xFAF0, 0x00A0, 0x05C0, 0x0AB0, 0x0FD0, 0x14C0, 0x1960, 0x1D50, + 0x2170, 0x2570, 0x2890, 0x2B90, 0x2E40, 0x3060, 0x32D0, 0x3470, 0x35B0, 0x3860, 0x39B0, 0x3BA0, 0x3C80, 0x3C50, 0x3D10, 0x3C70, + 0x3C60, 0x3C80, 0x3BB0, 0x3C60, 0x3D00, 0x3DC0, 0x3DC0, 0x3CD0, 0x3C70, 0x3C00, 0x3C60, 0x3DD0, 0x4080, 0x4520, 0x4980, 0x5010, + 0x57E0, 0x5FA0, 0x6880, 0x7110, 0x7990, 0x7E70, 0x7F10, 0x7F30, 0x7F00, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F90, 0x7F10, + 0x7F20, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EB0, 0x7C90, 0x7A60, 0x7980, 0x7990, 0x7B00, 0x7D20, 0x7ED0, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7EF0, 0x7F50, 0x7730, 0x67E0, 0x5840, 0x4850, 0x3840, 0x2860, 0x1A90, 0x0DB0, 0x03A0, 0xFB90, 0xF610, 0xF2A0, + 0xF010, 0xEE00, 0xEC50, 0xEAD0, 0xE950, 0xE840, 0xE6F0, 0xE620, 0xE540, 0xE4D0, 0xE400, 0xE450, 0xE520, 0xE650, 0xE7B0, 0xE830, + 0xE920, 0xEA00, 0xEA90, 0xEB50, 0xECE0, 0xEF10, 0xF0C0, 0xF220, 0xF3A0, 0xF4E0, 0xF680, 0xF7E0, 0xF9D0, 0xFBD0, 0xFD00, 0xFE80, + 0x0000, 0x01F0, 0x03E0, 0x0590, 0x0690, 0x07E0, 0x08B0, 0x09A0, 0x0B10, 0x0C70, 0x0DD0, 0x0F60, 0x1050, 0x1110, 0x11C0, 0x1200, + 0x12B0, 0x12B0, 0x1340, 0x1370, 0x1390, 0x12C0, 0x11C0, 0x1110, 0x1020, 0x0F20, 0x0E20, 0x0C90, 0x0B00, 0x08C0, 0x07C0, 0x0720, + 0x06E0, 0x05C0, 0x04C0, 0x0320, 0x01B0, 0x0050, 0xFF80, 0xFF00, 0xFEB0, 0xFE50, 0xFD60, 0xFD00, 0xFC40, 0xFC40, 0xFBB0, 0xFB20, + 0xFA40, 0xF950, 0xF830, 0xF740, 0xF660, 0xF600, 0xF5D0, 0xF5C0, 0xF510, 0xF430, 0xF390, 0xF360, 0xF2C0, 0xF1C0, 0xF0D0, 0xEFE0, + 0xEEF0, 0xEE90, 0xEE90, 0xEE40, 0xEDA0, 0xED50, 0xEC30, 0xEAC0, 0xE900, 0xE5B0, 0xE2E0, 0xDFF0, 0xDCB0, 0xD880, 0xD4C0, 0xD1B0, + 0xCDF0, 0xCB10, 0xC760, 0xC420, 0xC0F0, 0xBD30, 0xBA70, 0xB740, 0xB5C0, 0xB340, 0xB160, 0xB030, 0xAF50, 0xAE30, 0xAD10, 0xABF0, + 0xAB10, 0xAA90, 0xA960, 0xA850, 0xA6E0, 0xA6C0, 0xA620, 0xA540, 0xA4B0, 0xA460, 0xA450, 0xA4D0, 0xA530, 0xA620, 0xA670, 0xA690, + 0xA6A0, 0xA740, 0xA7B0, 0xA7D0, 0xA8A0, 0xA920, 0xAA20, 0xAB70, 0xACE0, 0xAE30, 0xAF70, 0xB0C0, 0xB1B0, 0xB2D0, 0xB4C0, 0xB5A0, + 0xB690, 0xB880, 0xBA40, 0xBC70, 0xBE50, 0xBFB0, 0xC1F0, 0xC380, 0xC4E0, 0xC690, 0xC7E0, 0xC980, 0xCB20, 0xD360, 0xD530, 0xD610, + 0xD7E0, 0xD910, 0xDB10, 0xDC30, 0xDC60, 0xDD30, 0xDD90, 0xDE40, 0xDEF0, 0xDFB0, 0xE080, 0xE160, 0xE260, 0xE2C0, 0xE350, 0xE4A0, + 0xE560, 0xE670, 0xE750, 0xE7A0, 0xE8D0, 0xEA30, 0xEBC0, 0xED60, 0xEF50, 0xF170, 0xF320, 0xF440, 0xF5D0, 0xF760, 0xF9C0, 0xFC60, + 0xFF10, 0x0180, 0x0360, 0x0590, 0x06D0, 0x08C0, 0x0B10, 0x0D30, 0x0FE0, 0x11D0, 0x12D0, 0x1560, 0x16A0, 0x1840, 0x1A30, 0x1BB0, + 0x1D80, 0x1E80, 0x1FD0, 0x20E0, 0x2220, 0x2450, 0x2580, 0x26A0, 0x2740, 0x27B0, 0x28B0, 0x2940, 0x2A90, 0x2BB0, 0x2BE0, 0x2CA0, + 0x2D10, 0x2E70, 0x2FE0, 0x3160, 0x3370, 0x3470, 0x35C0, 0x3610, 0x36F0, 0x37C0, 0x3A40, 0x3C90, 0x3F50, 0x41A0, 0x4510, 0x4830, + 0x4AA0, 0x4D00, 0x4F40, 0x5180, 0x5350, 0x5630, 0x5870, 0x5B60, 0x5EC0, 0x6200, 0x6430, 0x66C0, 0x6850, 0x6A10, 0x6B40, 0x6C60, + 0x6E50, 0x6FB0, 0x71E0, 0x7360, 0x74B0, 0x7640, 0x76E0, 0x7810, 0x7980, 0x79E0, 0x79E0, 0x7940, 0x7930, 0x7940, 0x7990, 0x7A70, + 0x7A60, 0x7AA0, 0x7A40, 0x7930, 0x7900, 0x7840, 0x7830, 0x77E0, 0x7700, 0x7680, 0x7590, 0x7470, 0x7400, 0x7340, 0x7330, 0x7280, + 0x71A0, 0x7040, 0x6EC0, 0x6EA0, 0x6EC0, 0x6F90, 0x7060, 0x7100, 0x7240, 0x7310, 0x74B0, 0x7560, 0x75E0, 0x76D0, 0x7880, 0x7AC0, + 0x7C60, 0x7D90, 0x7E30, 0x7E60, 0x7EC0, 0x7ED0, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7E70, 0x7ED0, 0x7ED0, + 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F40, 0x7F30, 0x7F20, + 0x7F20, 0x7EF0, 0x7F50, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7E60, 0x7B10, 0x76B0, 0x7260, 0x6D50, 0x6850, 0x63D0, 0x6100, + 0x5F50, 0x5EB0, 0x5EF0, 0x5FD0, 0x6210, 0x6470, 0x6770, 0x6BD0, 0x7000, 0x7500, 0x79A0, 0x7CC0, 0x7EA0, 0x7EA0, 0x7F10, 0x7F10, + 0x7F20, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7F30, 0x7F00, 0x7EF0, + 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, 0x7EF0, + 0x7F00, 0x7F60, 0x7F10, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7ED0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7EB0, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F00, + 0x7EF0, 0x7F10, 0x7F60, 0x7F20, 0x7F20, 0x7F20, 0x7F00, 0x7A40, 0x7190, 0x6860, 0x5F40, 0x55D0, 0x4C80, 0x4270, 0x3A90, 0x33B0, + 0x2CE0, 0x27C0, 0x22E0, 0x1DB0, 0x19B0, 0x15A0, 0x1190, 0x0F00, 0x0CD0, 0x0BF0, 0x0B70, 0x0BC0, 0x0C40, 0x0D30, 0x0F10, 0x1160, + 0x1440, 0x1810, 0x1B30, 0x2020, 0x24F0, 0x2990, 0x2F90, 0x3500, 0x3B70, 0x4120, 0x4700, 0x4E00, 0x5440, 0x5A10, 0x5F60, 0x63C0, + 0x6850, 0x6CC0, 0x7040, 0x7350, 0x7590, 0x77E0, 0x79C0, 0x7B90, 0x7CF0, 0x7E20, 0x7ED0, 0x7EB0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, + 0x7F00, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EA0, 0x7E60, 0x7E30, 0x7E10, 0x7E10, 0x7EA0, 0x7EE0, + 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7F10, 0x7F00, 0x7EF0, 0x7E90, 0x7E90, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, + 0x7F10, 0x7EE0, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F40, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, + 0x7EF0, 0x7650, 0x6980, 0x5C60, 0x4F40, 0x41B0, 0x3490, 0x28B0, 0x1C80, 0x1110, 0x06F0, 0xFE60, 0xF650, 0xEF10, 0xE880, 0xE280, + 0xDD10, 0xD850, 0xD310, 0xCFA0, 0xCD90, 0xCD20, 0xCEC0, 0xD200, 0xD6B0, 0xDC80, 0xE2A0, 0xEB30, 0xF260, 0xFAB0, 0x03C0, 0x0DF0, + 0x1900, 0x24E0, 0x3210, 0x3E40, 0x49F0, 0x5540, 0x6130, 0x6E00, 0x7A60, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7950, 0x5B30, + 0x3E20, 0x20E0, 0x03F0, 0xE6F0, 0xCA90, 0xAEC0, 0x9210, 0x8660, 0x84F0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, + 0x8450, 0x8440, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8530, 0x85D0, 0x86C0, 0x8740, + 0x86B0, 0x85C0, 0x8530, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x8510, + 0x8520, 0x85C0, 0x87E0, 0x8FB0, 0x9930, 0xA070, 0xA4A0, 0xA630, 0xA440, 0x9F50, 0x9760, 0x8EC0, 0x8840, 0x85F0, 0x8540, 0x8500, + 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84D0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8430, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8440, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84E0, 0x8680, 0x9AA0, 0xAFB0, 0xBB90, 0xBF80, 0xBE00, 0xB9A0, + 0xB400, 0xADD0, 0xA6B0, 0x9F60, 0x9650, 0x8D30, 0x8760, 0x8550, 0x84E0, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8410, 0x8470, 0x8460, + 0x8450, 0x8440, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8410, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8420, 0x8460, 0x8460, 0x8460, 0x8470, 0x8450, 0x8450, 0x8420, 0x8440, + 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8420, 0x8430, 0x8430, + 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8470, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8500, 0x8550, 0x8650, + 0x8970, 0x92B0, 0x9E50, 0xA8B0, 0xB2C0, 0xBC10, 0xC5B0, 0xD070, 0xDA60, 0xE520, 0xF080, 0xFCE0, 0x0980, 0x1710, 0x25E0, 0x3560, + 0x45A0, 0x5380, 0x5ED0, 0x66A0, 0x6960, 0x66C0, 0x5C90, 0x4AB0, 0x3240, 0x1140, 0xEDB0, 0xC7D0, 0xA1F0, 0x87C0, 0x84E0, 0x84B0, + 0x8450, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x84A0, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8530, 0x8590, 0x8650, 0x8780, 0x8920, 0x8AB0, 0x8C90, 0x8E50, 0x90E0, + 0x9410, 0x9680, 0x98C0, 0x9A70, 0x9A80, 0x9930, 0x96E0, 0x9370, 0x8FC0, 0x8C30, 0x8990, 0x87A0, 0x8690, 0x8620, 0x8660, 0x8690, + 0x87F0, 0x8B10, 0x9190, 0x9890, 0x9D10, 0x9E40, 0x9750, 0x99A0, 0x9D40, 0xA1F0, 0xA730, 0xABE0, 0xAF90, 0xB2F0, 0xB520, 0xB870, + 0xBC80, 0xC2D0, 0xCAF0, 0xD4E0, 0xE1C0, 0xF000, 0xFE90, 0x0D70, 0x1A70, 0x2650, 0x2FC0, 0x3760, 0x3D90, 0x42E0, 0x47F0, 0x4CC0, + 0x50C0, 0x53B0, 0x5500, 0x54D0, 0x5210, 0x4E10, 0x4860, 0x40F0, 0x3950, 0x31A0, 0x2A30, 0x22E0, 0x1B30, 0x16A0, 0x1320, 0x1190, + 0x1210, 0x1400, 0x1840, 0x1CD0, 0x2210, 0x2960, 0x3010, 0x3770, 0x3F40, 0x4640, 0x4D90, 0x5400, 0x5970, 0x5E40, 0x62E0, 0x6820, + 0x6C80, 0x71C0, 0x7680, 0x7A60, 0x7DA0, 0x7ED0, 0x7F30, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F80, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F30, + 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7F40, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7EF0, 0x7F00, + 0x7EC0, 0x7F20, 0x7F00, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7F00, 0x7F20, 0x7F40, 0x7F00, + 0x7F30, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F70, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7ED0, 0x7EB0, 0x7F60, + 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EE0, 0x7ED0, 0x7F20, 0x7F20, 0x7E90, 0x7ED0, 0x7F00, 0x7EE0, 0x7EF0, + 0x7EC0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, + 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F80, + 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7F40, 0x7F10, + 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7800, 0x6E70, 0x6520, 0x5B50, 0x52B0, 0x4880, + 0x3BF0, 0x2DB0, 0x1CA0, 0x0A40, 0xF510, 0xDD80, 0xC520, 0xAC00, 0x93D0, 0x86E0, 0x8510, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, + 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84E0, 0x84B0, 0x84B0, 0x84D0, 0x84C0, 0x84D0, 0x84F0, + 0x8500, 0x8550, 0x8640, 0x8BA0, 0xA1F0, 0xC010, 0xE500, 0x10B0, 0x4530, 0x7520, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x58A0, 0xDF50, 0x8790, 0x8490, 0x8470, 0x8460, 0x8470, 0x8470, 0x8480, 0x84A0, 0x84D0, + 0x8500, 0x8520, 0x8510, 0x84E0, 0x84B0, 0x8490, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x84A0, 0x84F0, + 0x9330, 0xD740, 0x10F0, 0x3AA0, 0x4CC0, 0x44B0, 0x2660, 0xF820, 0xC090, 0x8B90, 0x84C0, 0x8490, 0x8470, 0x8450, 0x8450, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84B0, 0x84E0, 0x8580, 0x8A60, + 0xA360, 0xBAC0, 0xD370, 0xECB0, 0x0570, 0x1C70, 0x2EC0, 0x3B10, 0x4190, 0x4260, 0x4040, 0x3CF0, 0x3A80, 0x3A60, 0x3D40, 0x4250, + 0x4AB0, 0x54A0, 0x60A0, 0x6AE0, 0x7270, 0x7650, 0x75B0, 0x6FE0, 0x6420, 0x53F0, 0x4130, 0x2EA0, 0x1FF0, 0x1530, 0x0DB0, 0x0920, + 0x05D0, 0x0400, 0x04B0, 0x07B0, 0x0EC0, 0x1830, 0x23E0, 0x2FA0, 0x3AF0, 0x44B0, 0x4D60, 0x5500, 0x5C00, 0x6150, 0x6330, 0x60A0, + 0x57C0, 0x4890, 0x3480, 0x1EB0, 0x0A30, 0xFA40, 0xF070, 0xEDB0, 0xF030, 0xF630, 0xFDB0, 0x05A0, 0x0CB0, 0x12B0, 0x15E0, 0x1660, + 0x1330, 0x0D00, 0x0470, 0xFAE0, 0xF050, 0xE5D0, 0xDAC0, 0xCF20, 0xC170, 0xB400, 0xA700, 0x9A90, 0x8FD0, 0x8980, 0x86B0, 0x85B0, + 0x8540, 0x8510, 0x8500, 0x8500, 0x8500, 0x8510, 0x8530, 0x8560, 0x85F0, 0x8710, 0x89F0, 0x8EC0, 0x9230, 0x93E0, 0x9380, 0x9190, + 0x8ED0, 0x8C20, 0x8A20, 0x8860, 0x8760, 0x86C0, 0x8660, 0x8640, 0x8650, 0x8690, 0x8700, 0x87C0, 0x8920, 0x8C40, 0x9220, 0x9B50, + 0xA600, 0xB330, 0xC140, 0xD000, 0xE030, 0xF200, 0x0460, 0x1750, 0x2AD0, 0x3EE0, 0x5270, 0x6550, 0x75D0, 0x7F20, 0x7ED0, 0x7EB0, + 0x7F30, 0x7F00, 0x7F10, 0x7EB0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F20, 0x7EC0, 0x7E90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7F20, + 0x7F00, 0x7F00, 0x7F00, 0x7F00, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7F10, + 0x7F20, 0x7F00, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, + 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x78A0, 0x70D0, 0x68B0, 0x60E0, 0x5980, 0x5390, + 0x4F70, 0x4CA0, 0x4C20, 0x4C80, 0x4D30, 0x4EE0, 0x50D0, 0x5490, 0x5880, 0x5CC0, 0x60B0, 0x6390, 0x6660, 0x67A0, 0x68F0, 0x6A30, + 0x6AF0, 0x6C50, 0x6D90, 0x6E80, 0x7020, 0x7140, 0x7230, 0x7330, 0x73D0, 0x7510, 0x75B0, 0x7740, 0x7890, 0x7A30, 0x7C00, 0x7D20, + 0x7DD0, 0x7E40, 0x7ED0, 0x7E90, 0x7E30, 0x7EC0, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, + 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F80, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7EE0, + 0x7EF0, 0x7F20, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F00, + 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7720, 0x6890, 0x5950, 0x4970, 0x3C60, 0x3050, 0x2630, 0x12C0, 0x13B0, 0x1530, 0x1740, 0x19A0, + 0x1C50, 0x1FE0, 0x2360, 0x2690, 0x2A90, 0x2D90, 0x30A0, 0x3260, 0x3360, 0x34D0, 0x34B0, 0x34E0, 0x3640, 0x39F0, 0x4030, 0x46C0, + 0x4DC0, 0x5380, 0x57E0, 0x5B80, 0x5D90, 0x6060, 0x62A0, 0x63E0, 0x6490, 0x6400, 0x6230, 0x6040, 0x5C60, 0x5910, 0x5500, 0x50E0, + 0x4BE0, 0x4650, 0x4190, 0x3C20, 0x3640, 0x30D0, 0x2B80, 0x2730, 0x2340, 0x20A0, 0x1F40, 0x1D50, 0x1D90, 0x1D60, 0x1CA0, 0x1C50, + 0x1BF0, 0x1C00, 0x1C00, 0x1BF0, 0x1CB0, 0x1BF0, 0x1BC0, 0x1A90, 0x1930, 0x1820, 0x1680, 0x1580, 0x1440, 0x12A0, 0x1150, 0x0F30, + 0x0E20, 0x0D40, 0x0BE0, 0x0BB0, 0x0A10, 0x0950, 0x08D0, 0x07D0, 0x07C0, 0x0710, 0x0790, 0x06B0, 0x0640, 0x0710, 0x0800, 0x0940, + 0x0AE0, 0x0C30, 0x0DD0, 0x0EC0, 0x1050, 0x1270, 0x1500, 0x1870, 0x1AE0, 0x1E10, 0x2150, 0x2430, 0x27A0, 0x2AC0, 0x2EF0, 0x33B0, + 0x3780, 0x3BC0, 0x3FF0, 0x43F0, 0x48E0, 0x4DE0, 0x52D0, 0x5730, 0x5BF0, 0x6040, 0x6480, 0x6920, 0x6D00, 0x7090, 0x7430, 0x7760, + 0x7AC0, 0x7D30, 0x7E70, 0x7EC0, 0x7E90, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, + 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, + 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EB0, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F20, 0x7EC0, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7E90, 0x7F00, 0x7F20, 0x7F10, 0x7F20, 0x7EC0, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7F30, + 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F50, 0x7EE0, + 0x7A60, 0x7490, 0x6DF0, 0x6840, 0x62C0, 0x5E10, 0x5AB0, 0x57E0, 0x5570, 0x5410, 0x5360, 0x53D0, 0x5390, 0x52F0, 0x51F0, 0x5010, + 0x4EB0, 0x4CB0, 0x4AF0, 0x49C0, 0x4870, 0x47D0, 0x4700, 0x45C0, 0x4600, 0x45C0, 0x46F0, 0x4820, 0x49A0, 0x4B90, 0x4DA0, 0x5020, + 0x52A0, 0x53D0, 0x55E0, 0x5760, 0x58E0, 0x5990, 0x5B00, 0x5D00, 0x5E00, 0x5E90, 0x5EE0, 0x5EE0, 0x5ED0, 0x5E20, 0x5D20, 0x5C40, + 0x5A90, 0x59E0, 0x58A0, 0x5890, 0x59D0, 0x5CB0, 0x5FE0, 0x6370, 0x6670, 0x6960, 0x6AC0, 0x6BB0, 0x6B60, 0x69F0, 0x6910, 0x6730, + 0x6720, 0x66D0, 0x66F0, 0x67B0, 0x6770, 0x6780, 0x6690, 0x6580, 0x64A0, 0x6280, 0x6180, 0x6000, 0x5D60, 0x5B90, 0x5910, 0x5670, + 0x5280, 0x4EE0, 0x4BA0, 0x4880, 0x45B0, 0x42A0, 0x3FC0, 0x3D50, 0x3A80, 0x37B0, 0x3510, 0x31D0, 0x2F30, 0x2C40, 0x2920, 0x2630, + 0x2390, 0x2230, 0x2140, 0x2230, 0x24A0, 0x27F0, 0x2C90, 0x30B0, 0x33A0, 0x3590, 0x36C0, 0x37B0, 0x3840, 0x3900, 0x38F0, 0x3880, + 0x3870, 0x3840, 0x38B0, 0x3990, 0x3AE0, 0x3CE0, 0x3E50, 0x3F30, 0x3ED0, 0x3D70, 0x3BE0, 0x3A60, 0x3A30, 0x3AF0, 0x3CC0, 0x4070, + 0x45E0, 0x4CB0, 0x5560, 0x5EC0, 0x6910, 0x72B0, 0x7B20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x79E0, 0x6D60, 0x6040, + 0x5370, 0x4AA0, 0x4480, 0x42B0, 0x4490, 0x4A20, 0x5240, 0x5AD0, 0x63B0, 0x6CC0, 0x7350, 0x7910, 0x7DA0, 0x7F10, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7B40, 0x6510, 0x4E50, 0x36A0, 0x1EF0, 0x07F0, 0xF5B0, 0xE6D0, + 0xDB10, 0xD2F0, 0xCDC0, 0xCBA0, 0xCCD0, 0xD090, 0xD850, 0xE250, 0xEE20, 0xFAF0, 0x07D0, 0x1510, 0x20D0, 0x2C40, 0x35C0, 0x3ED0, + 0x46A0, 0x4DA0, 0x5560, 0x5CB0, 0x6290, 0x67B0, 0x6BC0, 0x6E10, 0x6EB0, 0x6D20, 0x6940, 0x6410, 0x5E00, 0x56C0, 0x5010, 0x4A00, + 0x44D0, 0x3F00, 0x3910, 0x32F0, 0x2C00, 0x23C0, 0x1B30, 0x1170, 0x0730, 0xFD70, 0xF290, 0xE940, 0xE100, 0xD9D0, 0xD3A0, 0xCF20, + 0xCC50, 0xCA10, 0xC8C0, 0xC7B0, 0xC780, 0xC8B0, 0xCB10, 0xCE80, 0xD3B0, 0xDA00, 0xE070, 0xE6B0, 0xEBC0, 0xEE30, 0xEF60, 0xEED0, + 0xED60, 0xEAF0, 0xE870, 0xE4A0, 0xDFF0, 0xDCD0, 0xDBE0, 0xDBF0, 0xDF30, 0xE310, 0xE560, 0xE4B0, 0xDE20, 0xD150, 0xBB10, 0x9F60, + 0x87F0, 0x84E0, 0x84D0, 0x8490, 0x8470, 0x8470, 0x84A0, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, + 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x8510, 0x8500, 0x8530, 0x85A0, 0x8630, 0x8730, 0x88D0, 0x8AE0, 0x8D50, 0x8F10, 0x8FC0, + 0x8FB0, 0x8E50, 0x8C30, 0x8A20, 0x8820, 0x86D0, 0x85E0, 0x8560, 0x8520, 0x8500, 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, + 0x8490, 0x84C0, 0x8490, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8490, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, + 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8500, 0x8550, 0x85E0, 0x8710, 0x89C0, 0x8E70, 0x9420, + 0x99B0, 0x9EF0, 0xA490, 0xA9B0, 0xAE10, 0xB120, 0xB270, 0xB2B0, 0xB0B0, 0xAD80, 0xA940, 0xA510, 0xA0C0, 0x9C30, 0x97C0, 0x9310, + 0x8E20, 0x8A70, 0x87E0, 0x8680, 0x85F0, 0x85A0, 0x8590, 0x8590, 0x85C0, 0x8620, 0x86E0, 0x8870, 0x8C10, 0x9250, 0x9930, 0xA190, + 0xAA40, 0xB300, 0xBB10, 0xC320, 0xC9A0, 0xCF80, 0xD380, 0xD6C0, 0xD990, 0xDBE0, 0xDEE0, 0xE080, 0xE190, 0xE1D0, 0xE120, 0xE040, + 0xDF90, 0xDEC0, 0xDE20, 0xDD30, 0xDC90, 0xDBB0, 0xDA60, 0xD950, 0xD990, 0xDA70, 0xDC10, 0xDD70, 0xDF70, 0xE130, 0xE4D0, 0xE810, + 0xECC0, 0xF180, 0xF630, 0xFB00, 0x00A0, 0x04C0, 0x09D0, 0x0E40, 0x1320, 0x1790, 0x1B10, 0x1E80, 0x20D0, 0x2310, 0x2530, 0x2760, + 0x2910, 0x2A50, 0x2B40, 0x2C10, 0x2BE0, 0x2BA0, 0x2AD0, 0x2990, 0x2850, 0x2660, 0x24F0, 0x23F0, 0x2320, 0x1EA0, 0x1D00, 0x1B90, + 0x1970, 0x1860, 0x1640, 0x1470, 0x1380, 0x1260, 0x11B0, 0x10F0, 0x0F50, 0x0EB0, 0x0DA0, 0x0CD0, 0x0B80, 0x0A30, 0x0A40, 0x0A10, + 0x0B50, 0x0CB0, 0x0EA0, 0x1170, 0x1360, 0x1750, 0x1B00, 0x1EA0, 0x2240, 0x24B0, 0x2840, 0x2A60, 0x2CB0, 0x2F00, 0x3050, 0x31B0, + 0x3130, 0x2FA0, 0x2F80, 0x2E90, 0x2E20, 0x2D80, 0x2C90, 0x2C10, 0x2B00, 0x2A00, 0x2990, 0x2A30, 0x2B90, 0x2C90, 0x2DB0, 0x2E20, + 0x2E90, 0x2F30, 0x30E0, 0x33E0, 0x3800, 0x3D10, 0x4260, 0x4800, 0x4D50, 0x5330, 0x5920, 0x5FC0, 0x65D0, 0x6C30, 0x71F0, 0x76F0, + 0x7C20, 0x7EE0, 0x7F70, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F70, 0x7ED0, 0x7EA0, 0x7EE0, + 0x7F10, 0x7F30, 0x7EB0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F20, 0x7F00, 0x7F70, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, + 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7E90, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7F10, + 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, + 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7ED0, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7EC0, 0x7910, 0x7130, 0x68E0, 0x60D0, 0x59B0, 0x5500, 0x5040, 0x4BF0, 0x4710, 0x4100, + 0x3A20, 0x3140, 0x27A0, 0x1C80, 0x1040, 0x0340, 0xF420, 0xE2E0, 0xD050, 0xBCC0, 0xA670, 0x9110, 0x8680, 0x84F0, 0x84C0, 0x8480, + 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8460, 0x8470, 0x84A0, 0x8470, 0x84A0, 0x8470, 0x8470, 0x8480, 0x8470, 0x8480, + 0x84B0, 0x84B0, 0x8480, 0x8480, 0x8440, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8430, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84C0, 0x8490, + 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8510, + 0x8550, 0x8550, 0x85A0, 0x8620, 0x8710, 0x88A0, 0x8B30, 0x8EF0, 0x9390, 0x9820, 0x9C40, 0xA090, 0xA560, 0xA930, 0xACF0, 0xB150, + 0xB530, 0xB8C0, 0xBCE0, 0xC090, 0xC3E0, 0xC640, 0xC860, 0xCA80, 0xCC50, 0xCE90, 0xD160, 0xD320, 0xD530, 0xD6E0, 0xD8A0, 0xD9D0, + 0xDB80, 0xDD80, 0xDEC0, 0xE040, 0xE110, 0xE220, 0xE3B0, 0xE4D0, 0xE6A0, 0xE810, 0xE910, 0xE9E0, 0xEAB0, 0xEBE0, 0xED50, 0xEEF0, + 0xEFA0, 0xF050, 0xF050, 0xF100, 0xF1F0, 0xF2C0, 0xF3D0, 0xF500, 0xF690, 0xF710, 0xF7A0, 0xF7B0, 0xF890, 0xF990, 0xFB10, 0xFCB0, + 0xFE40, 0xFF50, 0xFFB0, 0xFFB0, 0x00A0, 0x0150, 0x0230, 0x02E0, 0x03E0, 0x0450, 0x04C0, 0x0520, 0x0550, 0x0550, 0x04E0, 0x04A0, + 0x04C0, 0x0500, 0x05F0, 0x0720, 0x0790, 0x0870, 0x0860, 0x0820, 0x0850, 0x0810, 0x0860, 0x08E0, 0x0900, 0x0930, 0x0960, 0x0960, + 0x0950, 0x09E0, 0x0AA0, 0x0B00, 0x0B10, 0x0AF0, 0x0AC0, 0x0AD0, 0x0AF0, 0x0AE0, 0x0B60, 0x0B90, 0x0BD0, 0x0C20, 0x0D40, 0x0E70, + 0x0EE0, 0x0F50, 0x0F50, 0x0F90, 0x0F90, 0x0F60, 0x1030, 0x1190, 0x1310, 0x13D0, 0x1460, 0x1500, 0x1680, 0x17F0, 0x1930, 0x1B00, + 0x1BC0, 0x1C10, 0x1C30, 0x1CE0, 0x1E40, 0x1FB0, 0x2130, 0x22C0, 0x23C0, 0x25B0, 0x2620, 0x2710, 0x2810, 0x2930, 0x2B20, 0x2C20, + 0x2DD0, 0x3000, 0x3210, 0x3450, 0x3660, 0x3940, 0x3AB0, 0x3BD0, 0x3D60, 0x3EE0, 0x4080, 0x4250, 0x43E0, 0x4640, 0x4790, 0x4930, + 0x4AE0, 0x4B40, 0x4D70, 0x4F60, 0x5110, 0x5320, 0x5400, 0x5550, 0x5680, 0x5860, 0x5B10, 0x5D80, 0x6020, 0x6220, 0x63C0, 0x65D0, + 0x6790, 0x6A20, 0x6CA0, 0x6EF0, 0x7150, 0x72C0, 0x7580, 0x7730, 0x7870, 0x7A10, 0x7A50, 0x7B20, 0x7B70, 0x7B40, 0x7BD0, 0x7B30, + 0x7C00, 0x7BD0, 0x7B50, 0x7B60, 0x7B00, 0x7B40, 0x7B90, 0x7C10, 0x7CB0, 0x7CB0, 0x7D00, 0x7D40, 0x7D10, 0x7DE0, 0x7E20, 0x7EC0, + 0x7ED0, 0x7EB0, 0x7EC0, 0x7EC0, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F80, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, 0x7F80, 0x7EF0, + 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, 0x7ED0, 0x7E30, 0x7D20, 0x7C00, 0x7AC0, 0x79B0, 0x78C0, 0x7690, 0x74B0, 0x7220, + 0x70C0, 0x6F50, 0x6E00, 0x6DA0, 0x6C80, 0x6C20, 0x6B40, 0x6AD0, 0x6B30, 0x6BA0, 0x6CE0, 0x6E10, 0x6F50, 0x7160, 0x73C0, 0x7640, + 0x7920, 0x7C40, 0x7EC0, 0x7F10, 0x7F70, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F70, 0x7F10, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7E90, 0x7ED0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, + 0x7ED0, 0x7F10, 0x7F10, 0x7F20, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EE0, 0x7F30, + 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7BF0, 0x7390, 0x6BE0, 0x6400, 0x5DC0, 0x57B0, 0x52E0, 0x4F80, 0x4D50, 0x4B60, 0x4F50, + 0x5280, 0x5650, 0x5950, 0x5D70, 0x60E0, 0x6430, 0x6730, 0x6920, 0x6BC0, 0x6D50, 0x6EE0, 0x6FF0, 0x70F0, 0x72B0, 0x7460, 0x7690, + 0x7910, 0x7C10, 0x7E70, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7F30, 0x7EC0, + 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, + 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7F20, 0x7F10, 0x7F30, 0x7EE0, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F70, + 0x7F20, 0x7F10, 0x7EF0, 0x7EF0, 0x7DF0, 0x7090, 0x64D0, 0x5B60, 0x5300, 0x49A0, 0x41C0, 0x3930, 0x3170, 0x2930, 0x20C0, 0x1850, + 0x0EB0, 0x05F0, 0xFBC0, 0xF1E0, 0xE8B0, 0xE010, 0xD710, 0xCEB0, 0xC680, 0xBF50, 0xB820, 0xB130, 0xAC20, 0xA810, 0xA560, 0xA3B0, + 0xA270, 0xA1B0, 0xA030, 0x9E00, 0x9B80, 0x9870, 0x9580, 0x9240, 0x8F30, 0x8BE0, 0x8970, 0x87B0, 0x8680, 0x85E0, 0x8590, 0x8560, + 0x8550, 0x8530, 0x8530, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8510, 0x8510, 0x8510, 0x8500, 0x8500, + 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84D0, 0x84F0, 0x84C0, 0x84D0, 0x84E0, + 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x8510, 0x8510, 0x8520, 0x8530, 0x8530, 0x8520, 0x8510, 0x8530, 0x8520, + 0x8500, 0x84F0, 0x8500, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84F0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x8500, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8500, + 0x8510, 0x8520, 0x8530, 0x8530, 0x8550, 0x8550, 0x8570, 0x8580, 0x85C0, 0x85F0, 0x8610, 0x8650, 0x8680, 0x86F0, 0x8760, 0x8820, + 0x8900, 0x89E0, 0x8AF0, 0x8C10, 0x8D00, 0x8EF0, 0x9160, 0x9470, 0x9720, 0x9980, 0x9C70, 0x9E80, 0xA140, 0xA440, 0xA770, 0xAB20, + 0xADF0, 0xB0F0, 0xB420, 0xB680, 0xB8F0, 0xBB80, 0xBE30, 0xC010, 0xC190, 0xC390, 0xC500, 0xC740, 0xC960, 0xCBC0, 0xCE00, 0xCF60, + 0xD080, 0xD1A0, 0xD2E0, 0xD430, 0xD520, 0xD5A0, 0xD5C0, 0xD5C0, 0xD5F0, 0xD5C0, 0xD610, 0xD600, 0xD550, 0xD430, 0xD320, 0xD280, + 0xD230, 0xD1F0, 0xD1B0, 0xD070, 0xCF10, 0xCDD0, 0xCCA0, 0xCC90, 0xCC80, 0xCD70, 0xCD50, 0xCCC0, 0xCC90, 0xCB90, 0xCAF0, 0xCA50, + 0xCA00, 0xCA20, 0xCA30, 0xC920, 0xC820, 0xC750, 0xC720, 0xC710, 0xC710, 0xC700, 0xC720, 0xC6A0, 0xC630, 0xC600, 0xC5C0, 0xC610, + 0xC750, 0xC840, 0xC8F0, 0xC8F0, 0xC910, 0xC8F0, 0xC8E0, 0xC880, 0xC850, 0xC840, 0xC870, 0xC900, 0xC920, 0xC8C0, 0xC8E0, 0xC910, + 0xC960, 0xC9A0, 0xC9D0, 0xC9E0, 0xCA40, 0xCA70, 0xCB20, 0xCBD0, 0xCCF0, 0xCE20, 0xCF40, 0xD070, 0xD190, 0xD2F0, 0xD440, 0xD570, + 0xD6E0, 0xD8B0, 0xD9C0, 0xDB70, 0xDD80, 0xDF10, 0xE120, 0xE2F0, 0xE510, 0xE730, 0xE990, 0xEC40, 0xEE90, 0xF140, 0xF3F0, 0xF5F0, + 0xF910, 0xFC30, 0xFEA0, 0x0110, 0x03E0, 0x0710, 0x09D0, 0x0CB0, 0x0FA0, 0x12F0, 0x1590, 0x1790, 0x19C0, 0x1C70, 0x1F10, 0x2150, + 0x2370, 0x2560, 0x2760, 0x28F0, 0x2B10, 0x2CC0, 0x2F00, 0x3120, 0x33C0, 0x35D0, 0x37B0, 0x3900, 0x3A40, 0x3B70, 0x3D70, 0x3FB0, + 0x41E0, 0x4410, 0x4610, 0x4740, 0x4920, 0x4A90, 0x4B70, 0x4CB0, 0x4EA0, 0x5000, 0x5150, 0x52C0, 0x54D0, 0x5730, 0x5950, 0x5B20, + 0x5D40, 0x5EC0, 0x5FF0, 0x6120, 0x6330, 0x6530, 0x6690, 0x6800, 0x68A0, 0x6990, 0x6A60, 0x6C40, 0x6E10, 0x6F30, 0x7040, 0x7070, + 0x7050, 0x70D0, 0x7160, 0x71C0, 0x71A0, 0x70F0, 0x7090, 0x6FB0, 0x6E60, 0x6D20, 0x6BF0, 0x69B0, 0x6720, 0x64C0, 0x6250, 0x6030, + 0x5E20, 0x5B40, 0x5800, 0x54D0, 0x5160, 0x4DE0, 0x4A10, 0x46A0, 0x42E0, 0x3F40, 0x3BB0, 0x37B0, 0x3460, 0x31D0, 0x2FF0, 0x2F30, + 0x2DE0, 0x2CD0, 0x2AF0, 0x2A00, 0x29F0, 0x2A60, 0x2C90, 0x2EF0, 0x3240, 0x3580, 0x38D0, 0x3D00, 0x41C0, 0x4690, 0x4C10, 0x51B0, + 0x57A0, 0x5E50, 0x64B0, 0x6AA0, 0x71D0, 0x7850, 0x7D70, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7E90, 0x7EB0, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7E80, 0x7E70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7ED0, 0x7F00, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7ED0, 0x7C30, 0x72E0, 0x6A70, 0x6380, 0x5D90, 0x5860, 0x54A0, 0x51A0, 0x50A0, + 0x4FE0, 0x50D0, 0x5270, 0x54F0, 0x5970, 0x5EF0, 0x6430, 0x6AE0, 0x7000, 0x74F0, 0x79A0, 0x7CC0, 0x7E80, 0x7E90, 0x7F10, 0x7F20, + 0x7F10, 0x7EB0, 0x7C40, 0x78F0, 0x74B0, 0x6F00, 0x69C0, 0x63C0, 0x5E80, 0x5900, 0x5540, 0x53B0, 0x5400, 0x5560, 0x5750, 0x5990, + 0x5CE0, 0x5FC0, 0x6390, 0x67B0, 0x6B60, 0x7040, 0x73D0, 0x7710, 0x7920, 0x7B40, 0x7C80, 0x7CC0, 0x7C60, 0x7B50, 0x7970, 0x77A0, + 0x7600, 0x74D0, 0x7430, 0x7360, 0x7290, 0x71E0, 0x7070, 0x7040, 0x6FD0, 0x7030, 0x7040, 0x6F90, 0x6F10, 0x6E20, 0x6DD0, 0x6CB0, + 0x6BB0, 0x6B70, 0x6A80, 0x6A90, 0x6BA0, 0x6C40, 0x6ED0, 0x7080, 0x7260, 0x7440, 0x7590, 0x77B0, 0x7960, 0x7B40, 0x7D10, 0x7E20, + 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7F10, 0x7EF0, 0x7EB0, 0x7EE0, 0x7E30, 0x7CB0, 0x7A60, 0x7850, 0x75D0, 0x7330, 0x7020, 0x6DC0, + 0x6AD0, 0x6760, 0x63A0, 0x6080, 0x5E30, 0x5C20, 0x59B0, 0x5750, 0x5430, 0x5200, 0x4F80, 0x4D70, 0x4C60, 0x4A90, 0x4950, 0x4720, + 0x44F0, 0x43C0, 0x4110, 0x3F60, 0x3DC0, 0x3A70, 0x3700, 0x3160, 0x2BE0, 0x2610, 0x1F60, 0x18E0, 0x1090, 0x0A10, 0x0360, 0xFD40, + 0xF890, 0xF4E0, 0xF160, 0xEE00, 0xEA70, 0xE6A0, 0xE3E0, 0xE200, 0xE0B0, 0xDF10, 0xDD30, 0xDA10, 0xD620, 0xD1D0, 0xCC50, 0xC810, + 0xC280, 0xBBB0, 0xB380, 0xAA80, 0xA060, 0x95A0, 0x8C80, 0x8790, 0x85C0, 0x8520, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, + 0x84A0, 0x8490, 0x8490, 0x8490, 0x84D0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x8500, 0x8510, 0x8520, 0x8530, 0x8560, 0x8590, 0x85C0, 0x8620, + 0x8680, 0x8710, 0x8790, 0x8830, 0x8960, 0x8AA0, 0x8BD0, 0x8D10, 0x8E20, 0x8FB0, 0x9180, 0x93B0, 0x94F0, 0x95B0, 0x9580, 0x9530, + 0x95C0, 0x9680, 0x9780, 0x98A0, 0x98A0, 0x98D0, 0x9830, 0x9760, 0x9710, 0x96C0, 0x9710, 0x96A0, 0x9610, 0x9580, 0x9500, 0x9480, + 0x9430, 0x9490, 0x94C0, 0x9410, 0x93C0, 0x93C0, 0x9410, 0x94D0, 0x9520, 0x9580, 0x95A0, 0x9580, 0x9600, 0x9600, 0x9680, 0x96F0, + 0x9630, 0x95C0, 0x9460, 0x9390, 0x92F0, 0x9280, 0x9300, 0x92C0, 0x91D0, 0x9060, 0x8F10, 0x8DD0, 0x8D70, 0x8D20, 0x8C80, 0x8BA0, + 0x8AD0, 0x89E0, 0x88D0, 0x8830, 0x87C0, 0x8770, 0x8730, 0x86C0, 0x8660, 0x8620, 0x85E0, 0x85C0, 0x85C0, 0x8570, 0x8570, 0x8560, + 0x8550, 0x8520, 0x8550, 0x8530, 0x8530, 0x8520, 0x8510, 0x8510, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84E0, + 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84D0, 0x8460, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x8450, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84E0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8530, 0x8580, 0x85F0, 0x8710, 0x8930, 0x8CE0, 0x91F0, + 0x9840, 0x9E70, 0xA4D0, 0xAB60, 0xB0C0, 0xB610, 0xBA80, 0xBE00, 0xC1A0, 0xC570, 0xC900, 0xCC90, 0xD010, 0xD260, 0xD440, 0xD5A0, + 0xD690, 0xD830, 0xDA40, 0xDC40, 0xDE70, 0xDFB0, 0xE060, 0xE150, 0xE1C0, 0xE270, 0xE330, 0xE350, 0xE3D0, 0xE450, 0xE500, 0xE630, + 0xE710, 0xE790, 0xE740, 0xE6A0, 0xE630, 0xE590, 0xE530, 0xE5C0, 0xE5E0, 0xE620, 0xE5A0, 0xE4A0, 0xE380, 0xE2A0, 0xE240, 0xE200, + 0xE190, 0xE190, 0xE0B0, 0xE0D0, 0xE160, 0xE1A0, 0xE270, 0xE250, 0xE2B0, 0xE370, 0xE430, 0xE570, 0xE780, 0xE9E0, 0xEC90, 0xEF10, + 0xF1A0, 0xF3B0, 0xF6B0, 0xF980, 0xFD80, 0x0190, 0x0590, 0x09B0, 0x0E40, 0x1300, 0x1790, 0x1C80, 0x2180, 0x2650, 0x2B20, 0x2FA0, + 0x34D0, 0x3980, 0x3EE0, 0x4420, 0x4940, 0x4D90, 0x51E0, 0x5610, 0x5A90, 0x5E80, 0x62A0, 0x65E0, 0x68F0, 0x6BE0, 0x6DE0, 0x6FC0, + 0x71F0, 0x7420, 0x75A0, 0x76D0, 0x7780, 0x77D0, 0x77D0, 0x7850, 0x78D0, 0x7940, 0x7950, 0x78D0, 0x7750, 0x7600, 0x7560, 0x7580, + 0x75A0, 0x75A0, 0x7550, 0x7510, 0x74A0, 0x7520, 0x75F0, 0x76F0, 0x7820, 0x7950, 0x7A10, 0x7B90, 0x7CC0, 0x7E40, 0x7EF0, 0x7F00, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7EE0, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7ED0, 0x7E10, 0x7D30, 0x7C00, 0x7BC0, 0x7B50, 0x7950, 0x7860, 0x77D0, 0x7690, 0x7610, 0x75A0, + 0x75C0, 0x75F0, 0x7630, 0x76A0, 0x7680, 0x75E0, 0x7560, 0x7540, 0x7580, 0x7630, 0x7760, 0x78F0, 0x7A80, 0x7C80, 0x7DE0, 0x7ED0, + 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, + 0x7F00, 0x7F10, 0x7EF0, 0x7F30, 0x7EF0, 0x7E90, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7E80, + 0x7EF0, 0x7F10, 0x7EF0, 0x7ED0, 0x7EB0, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, + 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7F70, 0x7F00, + 0x7ED0, 0x7F10, 0x7F00, 0x7F40, 0x7E90, 0x7C50, 0x7920, 0x7510, 0x70B0, 0x6D10, 0x6940, 0x6680, 0x6350, 0x6030, 0x5DA0, 0x5970, + 0x5660, 0x5370, 0x5090, 0x4F00, 0x4E00, 0x4D60, 0x4C40, 0x4C90, 0x4E00, 0x4F10, 0x5110, 0x5270, 0x5360, 0x5450, 0x5490, 0x5530, + 0x5660, 0x5660, 0x56E0, 0x5720, 0x5670, 0x5600, 0x54A0, 0x5440, 0x5240, 0x4FF0, 0x4D70, 0x4B10, 0x4980, 0x4760, 0x4500, 0x4350, + 0x4150, 0x3FA0, 0x3D60, 0x3B30, 0x3A00, 0x38A0, 0x37C0, 0x36F0, 0x3670, 0x3660, 0x3510, 0x3490, 0x32C0, 0x3090, 0x2F50, 0x2D00, + 0x2C00, 0x2940, 0x26D0, 0x2410, 0x2060, 0x1D80, 0x1A60, 0x16C0, 0x13D0, 0x1050, 0x0C60, 0x08C0, 0x0450, 0x00C0, 0xFCE0, 0xF940, + 0xF610, 0xF230, 0xEF60, 0xEBF0, 0xE830, 0xE490, 0xE070, 0xDC30, 0xD7F0, 0xD470, 0xD140, 0xCEA0, 0xCC60, 0xCA90, 0xC8F0, 0xC7D0, + 0xC600, 0xC4B0, 0xC370, 0xC340, 0xC2A0, 0xC250, 0xC310, 0xC3E0, 0xC540, 0xC700, 0xC9F0, 0xCD20, 0xD030, 0xD290, 0xD580, 0xD780, + 0xDA00, 0xDD00, 0xE040, 0xED40, 0xEFE0, 0xF2D0, 0xF5E0, 0xF8B0, 0xFB50, 0xFD60, 0x0000, 0x0180, 0x03F0, 0x06C0, 0x0950, 0x0BB0, + 0x0D00, 0x0EF0, 0x0FD0, 0x1090, 0x10A0, 0x0F90, 0x0EF0, 0x0D90, 0x0B50, 0x0A30, 0x0860, 0x06E0, 0x0520, 0x0250, 0xFFB0, 0xFC00, + 0xF820, 0xF450, 0xF0C0, 0xEE50, 0xEBF0, 0xEA30, 0xE7E0, 0xE460, 0xE110, 0xDDF0, 0xDB60, 0xD9A0, 0xD7F0, 0xD740, 0xD5D0, 0xD3F0, + 0xD2D0, 0xD1D0, 0xD1F0, 0xD1B0, 0xD230, 0xD330, 0xD3A0, 0xD460, 0xD4D0, 0xD550, 0xD6D0, 0xD800, 0xDA10, 0xDB90, 0xDCF0, 0xDEF0, + 0xE060, 0xE210, 0xE400, 0xE5C0, 0xE7A0, 0xE8E0, 0xEA40, 0xEBC0, 0xEDD0, 0xEFE0, 0xF160, 0xF2A0, 0xF450, 0xF5E0, 0xF910, 0xFBA0, + 0xFED0, 0x0180, 0x0340, 0x0510, 0x06B0, 0x0940, 0x0B70, 0x0E00, 0x10E0, 0x1350, 0x1550, 0x1750, 0x18C0, 0x1B10, 0x1CB0, 0x1E70, + 0x1F40, 0x2090, 0x2230, 0x23E0, 0x2550, 0x2710, 0x2890, 0x2A40, 0x2B80, 0x2B70, 0x2BE0, 0x2C40, 0x2D90, 0x2EA0, 0x2F20, 0x2FC0, + 0x2F50, 0x2EB0, 0x2F50, 0x2FB0, 0x30B0, 0x30C0, 0x30F0, 0x3050, 0x2F20, 0x2FC0, 0x3000, 0x3070, 0x3100, 0x3110, 0x3200, 0x3200, + 0x32C0, 0x32C0, 0x3370, 0x3430, 0x3440, 0x33B0, 0x33D0, 0x3340, 0x33F0, 0x34F0, 0x3500, 0x35C0, 0x3540, 0x3570, 0x34E0, 0x33F0, + 0x33F0, 0x3370, 0x3360, 0x3250, 0x3090, 0x2F30, 0x2D30, 0x2C30, 0x2A30, 0x2950, 0x27C0, 0x24D0, 0x2290, 0x2060, 0x1E00, 0x1C70, + 0x1A40, 0x1940, 0x1770, 0x1540, 0x1460, 0x1290, 0x1130, 0x0F90, 0x0C90, 0x0B10, 0x0900, 0x0740, 0x0590, 0x0490, 0x0420, 0x03A0, + 0x0280, 0x01A0, 0x0020, 0xFFB0, 0xFF50, 0xFF80, 0xFFE0, 0x0040, 0x0130, 0x0130, 0x0190, 0x0180, 0x0190, 0x02C0, 0x03C0, 0x0410, + 0x04A0, 0x0470, 0x04D0, 0x05A0, 0x06C0, 0x0800, 0x08F0, 0x0A40, 0x0A40, 0x0AF0, 0x0C30, 0x0CA0, 0x0E10, 0x0ED0, 0x0EE0, 0x0F40, + 0x0F80, 0x1030, 0x1130, 0x11F0, 0x12D0, 0x1300, 0x1380, 0x1310, 0x1310, 0x13A0, 0x13C0, 0x1450, 0x1450, 0x1520, 0x1530, 0x15B0, + 0x15E0, 0x1640, 0x15D0, 0x1630, 0x1610, 0x1670, 0x1710, 0x17B0, 0x1920, 0x1990, 0x1980, 0x19C0, 0x18E0, 0x1950, 0x19B0, 0x19E0, + 0x1A10, 0x19B0, 0x1960, 0x1900, 0x1840, 0x1820, 0x1740, 0x16A0, 0x15D0, 0x1520, 0x14E0, 0x1430, 0x1470, 0x1400, 0x1420, 0x14F0, + 0x14E0, 0x1590, 0x1550, 0x1530, 0x1560, 0x1520, 0x1590, 0x1510, 0x14E0, 0x1460, 0x1340, 0x12F0, 0x1240, 0x1110, 0x1060, 0x0F80, + 0x0EC0, 0x0DB0, 0x0CB0, 0x0BB0, 0x0980, 0x0860, 0x0640, 0x03A0, 0x0180, 0xFF10, 0xFD00, 0xFA40, 0xF7B0, 0xF450, 0xF180, 0xEEC0, + 0xEC50, 0xE960, 0xE6C0, 0xE490, 0xE2A0, 0xDFE0, 0xDD80, 0xDB20, 0xD930, 0xD750, 0xD620, 0xD530, 0xD490, 0xD3F0, 0xD2F0, 0xD240, + 0xD160, 0xD0C0, 0xD070, 0xD040, 0xD060, 0xD0F0, 0xD150, 0xD1A0, 0xD280, 0xD340, 0xD400, 0xD4A0, 0xD440, 0xD3F0, 0xD390, 0xD3D0, + 0xD480, 0xD520, 0xD620, 0xD680, 0xD6E0, 0xD610, 0xD530, 0xD330, 0xD2F0, 0xD2D0, 0xD290, 0xD2D0, 0xD310, 0xD2F0, 0xD340, 0xD2D0, + 0xD250, 0xD1B0, 0xD170, 0xD190, 0xD1E0, 0xD140, 0xD0D0, 0xD030, 0xCFC0, 0xCF30, 0xCF10, 0xCED0, 0xCED0, 0xCF60, 0xCFE0, 0xD000, + 0xCFF0, 0xD010, 0xD050, 0xD030, 0xD040, 0xD050, 0xD000, 0xD010, 0xD120, 0xD130, 0xD180, 0xD210, 0xD220, 0xD230, 0xD1F0, 0xD1A0, + 0xD1F0, 0xD300, 0xD410, 0xD4C0, 0xD550, 0xD5A0, 0xD600, 0xD5C0, 0xD5B0, 0xD5A0, 0xD560, 0xD5C0, 0xD5C0, 0xD5A0, 0xD580, 0xD550, + 0xD530, 0xD500, 0xD4C0, 0xD450, 0xD450, 0xD400, 0xD440, 0xD4C0, 0xD520, 0xD570, 0xD5D0, 0xD510, 0xD590, 0xD5C0, 0xD650, 0xD710, + 0xD730, 0xD790, 0xD710, 0xD710, 0xD6A0, 0xD6E0, 0xD6B0, 0xD6D0, 0xD730, 0xD7C0, 0xD850, 0xD8C0, 0xD990, 0xDA40, 0xDA70, 0xDAD0, + 0xDB50, 0xDBF0, 0xDC90, 0xDCC0, 0xDDD0, 0xDE70, 0xDED0, 0xDF00, 0xDFA0, 0xDF70, 0xDFF0, 0xE0C0, 0xE130, 0xE1C0, 0xE2B0, 0xE370, + 0xE490, 0xE530, 0xE570, 0xE590, 0xE560, 0xE510, 0xE5C0, 0xE6D0, 0xE7D0, 0xE900, 0xEA60, 0xEB00, 0xEB10, 0xEAF0, 0xEAD0, 0xEAE0, + 0xEC00, 0xECE0, 0xEEE0, 0xF080, 0xF250, 0xF320, 0xF380, 0xF430, 0xF490, 0xF470, 0xF4B0, 0xF610, 0xF750, 0xF870, 0xFA10, 0xFAD0, + 0xFC40, 0xFD70, 0xFE40, 0xFF80, 0xFFF0, 0x0100, 0x0100, 0x0150, 0x0200, 0x02B0, 0x0390, 0x03D0, 0x0440, 0x04C0, 0x04F0, 0x05E0, + 0x0660, 0x0670, 0x06E0, 0x06C0, 0x06C0, 0x0750, 0x0790, 0x0820, 0x0840, 0x0910, 0x0930, 0x0940, 0x09B0, 0x0980, 0x09A0, 0x0A10, + 0x09D0, 0x0A30, 0x0A60, 0x0A40, 0x0AA0, 0x0AA0, 0x0B40, 0x0B50, 0x0AC0, 0x0AC0, 0x0AC0, 0x0AB0, 0x0A70, 0x09B0, 0x09D0, 0x0990, + 0x0970, 0x0990, 0x08F0, 0x0920, 0x08C0, 0x0880, 0x0900, 0x0940, 0x0940, 0x08D0, 0x0830, 0x0800, 0x07F0, 0x07D0, 0x07D0, 0x0810, + 0x07E0, 0x07B0, 0x0870, 0x0840, 0x0910, 0x08B0, 0x07E0, 0x07D0, 0x06E0, 0x0700, 0x06C0, 0x0630, 0x0630, 0x0600, 0x0600, 0x0610, + 0x0570, 0x0640, 0x0600, 0x05A0, 0x05C0, 0x0470, 0x0430, 0x0430, 0x0440, 0x0470, 0x0470, 0x04C0, 0x03E0, 0x0250, 0x01E0, 0x00A0, + 0x0040, 0xFF70, 0xFEE0, 0xFDF0, 0xFD50, 0xFD50, 0xFC60, 0xFBC0, 0xFBB0, 0xFAF0, 0xFAC0, 0xF940, 0xF7F0, 0xF700, 0xF640, 0xF5D0, + 0xF5F0, 0xF5C0, 0xF5D0, 0xF4D0, 0xF430, 0xF3C0, 0xF2B0, 0xF1F0, 0xF140, 0xF090, 0xF000, 0xEF00, 0xEF60, 0xEF80, 0xEF80, 0xEF80, + 0xEEF0, 0xEE50, 0xEDA0, 0xED20, 0xED50, 0xEDB0, 0xEE70, 0xEEE0, 0xEE80, 0xEEA0, 0xEE40, 0xEEB0, 0xEEF0, 0xEF50, 0xF070, 0xF0F0, + 0xF1B0, 0xF2C0, 0xF410, 0xF5E0, 0xF7E0, 0xFAC0, 0xFCC0, 0xFF80, 0x0270, 0x0590, 0x09D0, 0x0E20, 0x12F0, 0x1790, 0x1BA0, 0x2000, + 0x2500, 0x2970, 0x2F60, 0x3460, 0x3A50, 0x3F90, 0x4420, 0x4960, 0x4DC0, 0x5280, 0x5640, 0x5980, 0x5CB0, 0x5E40, 0x6020, 0x6180, + 0x6230, 0x6370, 0x6380, 0x63F0, 0x6460, 0x63A0, 0x6380, 0x6280, 0x60C0, 0x5E60, 0x5B90, 0x58B0, 0x55B0, 0x5280, 0x4F70, 0x4B30, + 0x4780, 0x4310, 0x3DB0, 0x37A0, 0x3100, 0x1400, 0x0B40, 0x0310, 0xFAB0, 0xF360, 0xED00, 0xE750, 0xE270, 0xDD60, 0xD810, 0xD150, + 0xCA70, 0xC340, 0xBB00, 0xB290, 0xA970, 0xA1D0, 0x9D30, 0x9BE0, 0x9EF0, 0xA6C0, 0xB0A0, 0xBB00, 0xC300, 0xC870, 0xC8C0, 0xC4D0, + 0xBCD0, 0xB250, 0xA590, 0x97A0, 0x8AB0, 0x85A0, 0x84E0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, + 0x8520, 0x8550, 0x85B0, 0x8690, 0x8860, 0x8BF0, 0x9130, 0x96C0, 0x9BB0, 0xA150, 0xA620, 0xAA70, 0xADE0, 0xB1F0, 0xB5E0, 0xB8A0, + 0xBC30, 0xC010, 0xC400, 0xC9D0, 0xD000, 0xD740, 0xDFD0, 0xE8B0, 0xF300, 0xFD80, 0x08C0, 0x1450, 0x1E20, 0x27D0, 0x3000, 0x3730, + 0x3D70, 0x42C0, 0x4880, 0x4D00, 0x5160, 0x5590, 0x5860, 0x5B00, 0x5C40, 0x5DB0, 0x5F20, 0x60E0, 0x6310, 0x6490, 0x65E0, 0x6670, + 0x6610, 0x66B0, 0x67E0, 0x6990, 0x6AB0, 0x6B30, 0x6B70, 0x6B10, 0x6A60, 0x69A0, 0x6880, 0x6890, 0x6780, 0x65E0, 0x6550, 0x64D0, + 0x6640, 0x6890, 0x6A90, 0x6E30, 0x7200, 0x7650, 0x7AB0, 0x7DA0, 0x7F00, 0x7EB0, 0x7F20, 0x7F00, 0x7E10, 0x79B0, 0x7440, 0x6EC0, + 0x6990, 0x63B0, 0x5EE0, 0x5980, 0x5510, 0x5180, 0x4E20, 0x4B90, 0x4970, 0x4730, 0x4540, 0x42B0, 0x4220, 0x4260, 0x4250, 0x42D0, + 0x4340, 0x4420, 0x4530, 0x46F0, 0x4A00, 0x4D10, 0x5210, 0x55F0, 0x59F0, 0x5E90, 0x62D0, 0x6900, 0x6EC0, 0x7590, 0x7BA0, 0x7E80, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F10, + 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F60, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F50, 0x7F00, + 0x7F00, 0x7F10, 0x7F20, 0x7F60, 0x7F00, 0x7EF0, 0x7F00, 0x7EE0, 0x7F60, 0x7A90, 0x7120, 0x6CC0, 0x6AF0, 0x6BF0, 0x6FC0, 0x74D0, + 0x7B50, 0x7EF0, 0x7F20, 0x7ED0, 0x7EA0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7EC0, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, + 0x7EE0, 0x7EF0, 0x7F40, 0x7F10, 0x7F60, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, + 0x7F10, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F30, 0x7F20, 0x7E90, + 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7E70, 0x7EC0, 0x6B40, 0x4E30, 0x2F40, 0x0BE0, 0xEB50, 0xC9F0, 0xA7B0, 0x86C0, 0x84C0, 0x8490, + 0x8470, 0x8450, 0x8430, 0x8420, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8460, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, + 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, + 0x8480, 0x8490, 0x8490, 0x84B0, 0x84D0, 0x8500, 0x9B90, 0xA6F0, 0xB010, 0xB8B0, 0xBFF0, 0xC6A0, 0xCD00, 0xD2C0, 0xD640, 0xD870, + 0xD920, 0xD970, 0xD950, 0xD9E0, 0xDAD0, 0xDBD0, 0xDC60, 0xDC00, 0xDAE0, 0xD850, 0xD4F0, 0xD040, 0xCB30, 0xC4D0, 0xBF90, 0xBA60, + 0xB630, 0xB410, 0xB390, 0xB4F0, 0xB740, 0xB9C0, 0xBCF0, 0xC060, 0xC430, 0xC9A0, 0xCF00, 0xD500, 0xDAF0, 0xE210, 0xE9E0, 0xF2D0, + 0xFBF0, 0x05C0, 0x0E70, 0x16B0, 0x1EB0, 0x2600, 0x2C00, 0x30D0, 0x3350, 0x3350, 0x31F0, 0x2F70, 0x2C50, 0x29A0, 0x25A0, 0x20B0, + 0x1B30, 0x1470, 0x0DC0, 0x06D0, 0x00B0, 0xFBE0, 0xF6F0, 0xF350, 0xEF70, 0xEBA0, 0xE840, 0xE4B0, 0xE180, 0xDF10, 0xDC50, 0xD950, + 0xD4E0, 0xD0C0, 0xCB40, 0xC550, 0xC040, 0xB9B0, 0xB230, 0xAAC0, 0xA250, 0x99C0, 0x9140, 0x8AD0, 0x8760, 0x85D0, 0x8540, 0x8500, + 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x8620, 0x8B20, 0x9A70, + 0xAA60, 0xB800, 0xC430, 0xCF10, 0xD920, 0xE270, 0xEB10, 0xF3E0, 0xFB60, 0x02F0, 0x0940, 0x0D60, 0x1050, 0x1200, 0x1350, 0x14C0, + 0x1580, 0x1740, 0x1820, 0x1800, 0x1740, 0x1580, 0x1320, 0x10C0, 0x0DB0, 0x0BF0, 0x0A70, 0x0A70, 0x0BB0, 0x0DB0, 0x11F0, 0x16F0, + 0x1C90, 0x2340, 0x2A50, 0x32B0, 0x3B60, 0x4340, 0x4A10, 0x4FB0, 0x5520, 0x5940, 0x5D50, 0x6120, 0x6420, 0x6810, 0x6AB0, 0x6CF0, + 0x6E90, 0x6F90, 0x70F0, 0x71E0, 0x7240, 0x7350, 0x7320, 0x7400, 0x74D0, 0x74B0, 0x74C0, 0x7400, 0x7350, 0x72B0, 0x71E0, 0x71B0, + 0x7030, 0x6FA0, 0x6E60, 0x6CD0, 0x6C10, 0x6B40, 0x6AE0, 0x6AD0, 0x6A40, 0x6A40, 0x6990, 0x6900, 0x6870, 0x67C0, 0x6890, 0x68E0, + 0x6930, 0x6990, 0x69E0, 0x6AE0, 0x6C40, 0x6DD0, 0x7030, 0x7220, 0x7440, 0x7650, 0x7870, 0x7A60, 0x7C50, 0x7E70, 0x7F00, 0x7F70, + 0x7ED0, 0x7EB0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, + 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7F10, 0x7F20, 0x7EF0, + 0x7F80, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7EE0, 0x7F50, + 0x7F20, 0x7EE0, 0x7ED0, 0x7ED0, 0x7F30, 0x7EF0, 0x7E90, 0x7ED0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, + 0x7F10, 0x77A0, 0x6DA0, 0x64C0, 0x5B90, 0x52A0, 0x4B70, 0x4400, 0x3E70, 0x38E0, 0x33B0, 0x2FD0, 0x2C80, 0x2A80, 0x2950, 0x2950, + 0x2C00, 0x2E40, 0x3290, 0x3880, 0x3E40, 0x4580, 0x4C90, 0x5220, 0x5670, 0x59D0, 0x5C30, 0x5DE0, 0x5F30, 0x5F90, 0x5F70, 0x5FA0, + 0x5EF0, 0x5DF0, 0x5CA0, 0x5B40, 0x5A90, 0x5A30, 0x5A70, 0x5B20, 0x5B90, 0x5D50, 0x5EE0, 0x61F0, 0x66E0, 0x6C60, 0x7350, 0x7A00, + 0x7E70, 0x7EE0, 0x7EC0, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F00, 0x7F00, + 0x7F10, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, + 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EA0, 0x7ED0, 0x7ED0, + 0x7F00, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7ED0, 0x6110, 0x4370, 0x25F0, 0x0830, 0xEEF0, 0xD720, 0xC150, + 0xADF0, 0x9BD0, 0x8E90, 0x88A0, 0x86F0, 0x86C0, 0x8790, 0x8AA0, 0x92B0, 0x9DF0, 0xA910, 0xB410, 0xBE70, 0xC790, 0xD050, 0xD830, + 0xDEE0, 0xE590, 0xEBF0, 0xF220, 0xF780, 0xFB50, 0xFFF0, 0x02C0, 0x0510, 0x06E0, 0x0840, 0x09F0, 0x0AB0, 0x0B50, 0x0BE0, 0x0C60, + 0x0E30, 0x0FA0, 0x11A0, 0x1430, 0x16B0, 0x1AA0, 0x1EC0, 0x23D0, 0x29F0, 0x3020, 0x3650, 0x3B30, 0x3FF0, 0x4420, 0x4790, 0x4B10, + 0x4D20, 0x4DF0, 0x4D90, 0x4B70, 0x4940, 0x4640, 0x43F0, 0x42A0, 0x40E0, 0x40F0, 0x4190, 0x4320, 0x4650, 0x4A90, 0x50C0, 0x57C0, + 0x5F90, 0x68B0, 0x7100, 0x7960, 0x7E90, 0x7F30, 0x7F00, 0x7E90, 0x7ED0, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, + 0x7F10, 0x7EC0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7E10, 0x5E70, 0x3AF0, 0x1490, 0xEAE0, + 0xC400, 0x9D90, 0x8660, 0x84C0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8420, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, + 0x8480, 0x8460, 0x8470, 0x8480, 0x8480, 0x84B0, 0x84E0, 0x8530, 0x86A0, 0x8DB0, 0x9D20, 0xAB40, 0xB7F0, 0xC4C0, 0xD130, 0xDD30, + 0xE8D0, 0xF3B0, 0xFE00, 0x06A0, 0x0E10, 0x1420, 0x19C0, 0x1F30, 0x2310, 0x2570, 0x2790, 0x2830, 0x27F0, 0x2540, 0x2150, 0x1AE0, + 0x12E0, 0x0890, 0xFD50, 0xF0A0, 0xE460, 0xD8B0, 0xCD10, 0xC1D0, 0xB660, 0xAB80, 0xA180, 0x98E0, 0x9180, 0x8BD0, 0x8870, 0x86C0, + 0x85F0, 0x8590, 0x8570, 0x8570, 0x8570, 0x85C0, 0x85E0, 0x8680, 0x8820, 0x8C40, 0x95F0, 0xA030, 0xAAB0, 0xB510, 0xBFB0, 0xCA30, + 0xD440, 0xDCD0, 0xE380, 0xE900, 0xEC90, 0xF030, 0xF390, 0xF7E0, 0xFC70, 0x00D0, 0x04C0, 0x0860, 0x0BD0, 0x0EA0, 0x1170, 0x1430, + 0x1650, 0x18E0, 0x1BD0, 0x1F80, 0x22B0, 0x2640, 0x28C0, 0x2A50, 0x2BA0, 0x2C60, 0x2D70, 0x2E50, 0x30B0, 0x3360, 0x36D0, 0x3990, + 0x3BC0, 0x3E10, 0x3FF0, 0x42B0, 0x4640, 0x4A20, 0x4D80, 0x5160, 0x54E0, 0x58D0, 0x5D30, 0x6120, 0x65A0, 0x69C0, 0x6DF0, 0x71B0, + 0x75F0, 0x78D0, 0x7BD0, 0x7DF0, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F10, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F70, 0x7F20, 0x7EF0, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7EB0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EB0, + 0x7EA0, 0x7ED0, 0x7F30, 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7F40, 0x7ED0, 0x7F00, 0x7EF0, 0x7F30, 0x7F30, 0x7E70, + 0x7ED0, 0x7EE0, 0x7F10, 0x7F30, 0x7E70, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F00, + 0x7F10, 0x7F10, 0x7F30, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, + 0x7F10, 0x7F00, 0x7F20, 0x7F80, 0x7EF0, 0x7EB0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7EB0, + 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F00, 0x7F00, 0x7EE0, 0x7F50, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F70, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F00, 0x7EF0, 0x7EB0, 0x7F60, 0x7EF0, 0x7E90, 0x7EE0, 0x7EE0, 0x7F50, 0x7F20, 0x7EA0, + 0x7ED0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F50, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, + 0x7F10, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F10, 0x7EE0, 0x7F60, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7EC0, + 0x7F10, 0x7F10, 0x7EF0, 0x7E10, 0x7D30, 0x7D20, 0x7CC0, 0x7BF0, 0x7B60, 0x7A00, 0x7880, 0x76B0, 0x7500, 0x73E0, 0x7230, 0x71B0, + 0x7170, 0x7110, 0x7190, 0x7250, 0x7340, 0x74C0, 0x7630, 0x7840, 0x7A40, 0x7BD0, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, + 0x7F30, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F90, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F70, + 0x7F20, 0x7ED0, 0x7EB0, 0x7EE0, 0x7F50, 0x7F10, 0x7E70, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F10, 0x7F10, + 0x7E90, 0x7EB0, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7EE0, + 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, + 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F40, 0x7F10, + 0x7E00, 0x6EE0, 0x5E70, 0x4C30, 0x3BC0, 0x2A90, 0x1AD0, 0x0C00, 0xFDC0, 0xF090, 0xE300, 0xD590, 0xC750, 0xB980, 0xACE0, 0xA110, + 0x9730, 0x8F50, 0x8A50, 0x8800, 0x8720, 0x86E0, 0x8710, 0x8790, 0x8860, 0x89A0, 0x8B10, 0x8D40, 0x9030, 0x9460, 0x9930, 0x9CF0, + 0xA100, 0xA460, 0xA700, 0xA990, 0xAC70, 0xAF40, 0xB1C0, 0xB410, 0xB540, 0xB630, 0xB770, 0xB830, 0xB8C0, 0xB980, 0xBA50, 0xBB00, + 0xBAB0, 0xBAC0, 0xBA80, 0xBAC0, 0xBB40, 0xBB80, 0xBC20, 0xBB80, 0xBAE0, 0xBB40, 0xBC40, 0xBDE0, 0xBFB0, 0xC200, 0xC4E0, 0xC770, + 0xCA80, 0xCDB0, 0xD180, 0xD5E0, 0xDA20, 0xDE40, 0xE340, 0xE830, 0xEE00, 0xF3F0, 0xF9D0, 0xFF90, 0x0370, 0x07A0, 0x0B50, 0x0F30, + 0x1320, 0x1660, 0x1990, 0x1D30, 0x2070, 0x2390, 0x2670, 0x2980, 0x2C00, 0x2DF0, 0x30A0, 0x3260, 0x3440, 0x3710, 0x3830, 0x3A80, + 0x3B50, 0x3AF0, 0x3930, 0x3660, 0x32D0, 0x2F00, 0x2A60, 0x24F0, 0x1ED0, 0x1840, 0x1140, 0x0A10, 0x03F0, 0xFDE0, 0xF840, 0xF120, + 0xEA90, 0xE440, 0xDE80, 0xDB10, 0xD860, 0xD840, 0xD990, 0xDC70, 0xE0E0, 0xE680, 0xED30, 0xF520, 0xFD40, 0x06C0, 0x0FD0, 0x18F0, + 0x2340, 0x2E30, 0x38E0, 0x4440, 0x4F40, 0x5A50, 0x63B0, 0x6D20, 0x7550, 0x7C10, 0x7EE0, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, + 0x7E90, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7F10, 0x7F20, 0x7EA0, 0x7A80, 0x7600, 0x6F60, 0x6880, 0x6180, 0x59A0, + 0x5220, 0x4B70, 0x44D0, 0x3F50, 0x3960, 0x3380, 0x2ED0, 0x2AA0, 0x2840, 0x2510, 0x2270, 0x1FA0, 0x1C00, 0x1880, 0x1330, 0x0E50, + 0x0990, 0x06D0, 0x05E0, 0x0780, 0x0BB0, 0x11B0, 0x1900, 0x20F0, 0x27B0, 0x2CF0, 0x3160, 0x34B0, 0x3890, 0x3C00, 0x3F60, 0x4310, + 0x44A0, 0x4550, 0x4360, 0x3FA0, 0x3AF0, 0x35D0, 0x3040, 0x2B90, 0x2880, 0x2560, 0x22C0, 0x20D0, 0x1F30, 0x1E30, 0x1E80, 0x2030, + 0x2200, 0x2470, 0x2650, 0x2840, 0x29C0, 0x2B00, 0x2B80, 0x2BF0, 0x2BC0, 0x2AD0, 0x2980, 0x2870, 0x2700, 0x25B0, 0x2450, 0x2310, + 0x2230, 0x2160, 0x20E0, 0x2140, 0x2220, 0x2340, 0x2490, 0x25E0, 0x27A0, 0x2970, 0x2BB0, 0x2D40, 0x2F90, 0x3190, 0x3380, 0x35E0, + 0x3800, 0x3A80, 0x3C70, 0x3E90, 0x3FF0, 0x4130, 0x42B0, 0x4480, 0x4680, 0x4890, 0x4A20, 0x4AF0, 0x4B10, 0x4B50, 0x4B20, 0x4B80, + 0x4BF0, 0x4CB0, 0x4D70, 0x4D80, 0x4CD0, 0x4C70, 0x4C80, 0x4C80, 0x4CD0, 0x4C40, 0x4B40, 0x4910, 0x4680, 0x43B0, 0x4150, 0x3EB0, + 0x3C10, 0x3940, 0x3640, 0x32F0, 0x2F30, 0x2B30, 0x27D0, 0x24B0, 0x21A0, 0x1EA0, 0x1C10, 0x1A30, 0x1870, 0x1730, 0x1650, 0x1490, + 0x1270, 0x0F70, 0x0C70, 0x09E0, 0x0760, 0x05D0, 0x03F0, 0x0230, 0xFF20, 0xFC40, 0xF9F0, 0xF730, 0xF580, 0xF390, 0xF180, 0xEF20, + 0xEC20, 0xE9C0, 0xE7A0, 0xE4C0, 0xE230, 0xDE90, 0xDB00, 0xD860, 0xD680, 0xD530, 0xD510, 0xD470, 0xD340, 0xD210, 0xD130, 0xD090, + 0xD0C0, 0xD270, 0xD4A0, 0xD7C0, 0xDB80, 0xDEF0, 0xE140, 0xE3C0, 0xE5F0, 0xE7A0, 0xE870, 0xE8F0, 0xE8B0, 0xE7C0, 0xE800, 0xE890, + 0xE990, 0xEBB0, 0xEDC0, 0xF030, 0xF250, 0xF440, 0xF6D0, 0xF900, 0xFB20, 0xFC80, 0xFD60, 0xFE80, 0xFFF0, 0x0160, 0x02C0, 0x0300, + 0x0230, 0xFFA0, 0xFC10, 0xF7F0, 0xF480, 0xF140, 0xED70, 0xEA30, 0xE6A0, 0xE2C0, 0xDDB0, 0xD910, 0xD4F0, 0xD0A0, 0xCC90, 0xC8F0, + 0xC5E0, 0xC2F0, 0xC0B0, 0xBEA0, 0xBD50, 0xBC20, 0xBA40, 0xB920, 0xB7C0, 0xB780, 0xB850, 0xB880, 0xB8C0, 0xB880, 0xB7C0, 0xB6C0, + 0xB590, 0xB580, 0xB570, 0xB560, 0xB5B0, 0xB520, 0xB4F0, 0xB460, 0xB450, 0xB590, 0xB630, 0xB820, 0xB890, 0xB960, 0xBAA0, 0xBC50, + 0xBEB0, 0xC180, 0xC4C0, 0xC700, 0xC950, 0xCBD0, 0xCDC0, 0xCF30, 0xD100, 0xD1F0, 0xD220, 0xD1B0, 0xD090, 0xCFF0, 0xCF90, 0xD060, + 0xD0E0, 0xD190, 0xD280, 0xD320, 0xD400, 0xD560, 0xD710, 0xDAC0, 0xDE50, 0xE3C0, 0xE9B0, 0xF0E0, 0xF9C0, 0x0340, 0x0DA0, 0x1960, + 0x2600, 0x32B0, 0x3E80, 0x49C0, 0x53D0, 0x5B90, 0x61F0, 0x65C0, 0x6750, 0x6860, 0x6920, 0x6AD0, 0x6BF0, 0x6DC0, 0x6FE0, 0x7150, + 0x73F0, 0x7720, 0x7B90, 0x7EB0, 0x7F00, 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, + 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F20, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F00, 0x78C0, 0x7080, 0x6710, 0x5CB0, 0x5190, + 0x44E0, 0x3890, 0x2B30, 0x1EB0, 0x1280, 0x06F0, 0xFC90, 0xF390, 0xED60, 0xE8F0, 0xE600, 0xE520, 0xE560, 0xE650, 0xE780, 0xE8A0, + 0xEA50, 0xEB10, 0xECB0, 0xEEF0, 0xF180, 0xF470, 0xF670, 0xF8E0, 0xFBF0, 0xFF00, 0x02A0, 0x05D0, 0x0A10, 0x0DD0, 0x10A0, 0x1320, + 0x14B0, 0x1520, 0x1510, 0x1340, 0x1150, 0x0EA0, 0x0A70, 0x0630, 0x00F0, 0xFAE0, 0xF360, 0xE830, 0xDC40, 0xCE30, 0xC080, 0xB3B0, + 0xA830, 0x9EF0, 0x97B0, 0x9410, 0x93E0, 0x9690, 0x9C00, 0xA280, 0xA8E0, 0xAE50, 0xB160, 0xB2F0, 0xB220, 0xB030, 0xAD20, 0xA890, + 0xA250, 0x99F0, 0x8F70, 0x8840, 0x8590, 0x8500, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, + 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, + 0x8470, 0x8470, 0x8470, 0x84A0, 0x8470, 0x8470, 0x84B0, 0x84B0, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8480, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84C0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84D0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84D0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, + 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84E0, 0x84C0, 0x84C0, 0x84F0, 0x84F0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84E0, 0x84D0, 0x84F0, 0x8510, 0x8550, 0x8590, 0x8630, 0x8780, 0x89D0, + 0x8E30, 0x9460, 0x9C00, 0xA330, 0xAAD0, 0xB320, 0xBB50, 0xC270, 0xC9B0, 0xD030, 0xD680, 0xDCB0, 0xE300, 0xE9C0, 0xEF80, 0xF710, + 0xFEC0, 0x0630, 0x0DD0, 0x1480, 0x1B20, 0x21D0, 0x2880, 0x3090, 0x39C0, 0x4240, 0x4B00, 0x52A0, 0x5A10, 0x6010, 0x6670, 0x6C70, + 0x71F0, 0x7870, 0x7CE0, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7ED0, + 0x7F10, 0x7F20, 0x7F50, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F50, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, + 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, + 0x7F20, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7320, + 0x6620, 0x58D0, 0x4D30, 0x4270, 0x38C0, 0x2FF0, 0x26B0, 0x1D80, 0x1400, 0x0AD0, 0x0330, 0xFCC0, 0xF690, 0xF1B0, 0xEDD0, 0xE9D0, + 0xE550, 0xE060, 0xDB30, 0xD6C0, 0xD2F0, 0xD110, 0xD110, 0xD250, 0xD3A0, 0xD4E0, 0xD4C0, 0xD3E0, 0xD3A0, 0xD4C0, 0xD870, 0xDEF0, + 0xE560, 0xEA70, 0xEC00, 0xE9F0, 0xE440, 0xDD50, 0xD630, 0xD110, 0xCED0, 0xCF30, 0xD1B0, 0xD680, 0xDDE0, 0xE940, 0xF850, 0x0A70, + 0x1D60, 0x30B0, 0x3E50, 0x4620, 0x4840, 0x4650, 0x4130, 0x3BE0, 0x3760, 0x3450, 0x32A0, 0x3210, 0x3040, 0x2D80, 0x28A0, 0x21A0, + 0x18F0, 0x0F10, 0x0550, 0xFCC0, 0xF6B0, 0xF130, 0xEC40, 0xE6C0, 0xE010, 0xD920, 0xD270, 0xCC00, 0xC730, 0xC460, 0xC3A0, 0xC4D0, + 0xC7F0, 0xCC10, 0xD180, 0xD750, 0xDCD0, 0xE210, 0xE6B0, 0xEAD0, 0xEFB0, 0xF5E0, 0xFD20, 0x0410, 0x0AE0, 0x0FB0, 0x1330, 0x1490, + 0x1360, 0x0F20, 0x08F0, 0x00C0, 0xF700, 0xEDA0, 0xE5A0, 0xDEC0, 0xDA00, 0xD670, 0xD310, 0xD070, 0xCE20, 0xCB70, 0xC990, 0xC890, + 0xC7A0, 0xC750, 0xC650, 0xC5B0, 0xC500, 0xC4D0, 0xC4F0, 0xC500, 0xC580, 0xC580, 0xC620, 0xC720, 0xC820, 0xC9F0, 0xCC00, 0xCE60, + 0xD150, 0xD2E0, 0xD510, 0xD640, 0xD650, 0xD670, 0xD560, 0xD2A0, 0xCE80, 0xC800, 0xBFE0, 0xB550, 0xAAC0, 0xA050, 0x9580, 0x8C90, + 0x87E0, 0x8600, 0x8560, 0x8520, 0x8500, 0x84F0, 0x84F0, 0x84E0, 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, + 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x84B0, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x84A0, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8490, 0x8480, 0x8470, 0x8480, 0x8490, + 0x8480, 0x8480, 0x84B0, 0x8490, 0x8480, 0x8480, 0x8410, 0x8480, 0x8480, 0x8490, 0x8490, 0x8480, 0x8490, 0x8460, 0x8490, 0x8480, + 0x84A0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x8440, 0x84A0, 0x84A0, 0x84D0, 0x84A0, 0x84A0, 0x84A0, 0x84E0, + 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x8450, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, + 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x84E0, 0x8530, 0x8540, 0x8570, 0x85B0, 0x8610, 0x86F0, 0x8890, 0x8C10, 0x9300, + 0x9A20, 0xA190, 0xAA10, 0xB2F0, 0xBCE0, 0xC760, 0xD300, 0xDF70, 0xEE40, 0xFD40, 0x0B90, 0x18B0, 0x2300, 0x29E0, 0x2CF0, 0x2CB0, + 0x2C60, 0x2B00, 0x2BD0, 0x37E0, 0x3A70, 0x3CD0, 0x3D60, 0x3CE0, 0x3AD0, 0x38B0, 0x3A00, 0x4070, 0x5010, 0x63B0, 0x74C0, 0x7D50, + 0x7D70, 0x7470, 0x5FF0, 0x4380, 0x2730, 0x0B90, 0xF200, 0xDA60, 0xC240, 0xAB30, 0x93E0, 0x8720, 0x8500, 0x84C0, 0x8460, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, + 0x8480, 0x84A0, 0x84E0, 0x8540, 0x8730, 0x90F0, 0xA020, 0xAD80, 0xBA30, 0xC670, 0xD0B0, 0xD9F0, 0xDF10, 0xE050, 0xE010, 0xDDA0, + 0xDA90, 0xD7B0, 0xD4C0, 0xD180, 0xCCA0, 0xC650, 0xBE00, 0xB4D0, 0xAA00, 0x9D30, 0x8FB0, 0x8730, 0x8520, 0x84D0, 0x84A0, 0x8480, + 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, + 0x8400, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83E0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83C0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8430, 0x8420, 0x8420, 0x8420, 0x8450, 0x8430, 0x8430, + 0x8430, 0x8450, 0x8440, 0x8450, 0x8410, 0x8450, 0x8460, 0x8480, 0x8470, 0x8480, 0x8490, 0x84C0, 0x84F0, 0x85C0, 0x9040, 0xAD20, + 0xCAB0, 0xE560, 0xFEC0, 0x1780, 0x2E50, 0x4530, 0x5A40, 0x6D40, 0x7C90, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7F00, 0x7F40, 0x7F10, + 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, + 0x7F60, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, + 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F00, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F20, + 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F50, 0x7860, 0x6CD0, 0x6210, 0x55B0, 0x4820, 0x3AD0, 0x2DB0, 0x2250, 0x18C0, + 0x11D0, 0x0DF0, 0x0D20, 0x0F10, 0x13F0, 0x1AB0, 0x2300, 0x2B90, 0x3570, 0x3F60, 0x48B0, 0x5250, 0x5C00, 0x66C0, 0x70D0, 0x7A90, + 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F40, + 0x7F10, 0x7F80, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7F10, 0x7EF0, + 0x7F30, 0x7F00, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F20, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F10, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F00, + 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7980, + 0x6EC0, 0x61F0, 0x5490, 0x4880, 0x3E20, 0x34F0, 0x2D90, 0x28A0, 0x2420, 0x1F10, 0x1980, 0x12A0, 0x0B80, 0x0470, 0xFDA0, 0xF850, + 0xF450, 0xF0D0, 0xECD0, 0xE8E0, 0xE3D0, 0xDEB0, 0xDA60, 0xD510, 0xD100, 0xCD50, 0xC9E0, 0xC7B0, 0xC5D0, 0xC5F0, 0xC730, 0xC9C0, + 0xCE10, 0xD210, 0xD5A0, 0xD990, 0xDD40, 0xE0B0, 0xE420, 0xE780, 0xEB10, 0xEF20, 0xF280, 0xF580, 0xF7B0, 0xF8A0, 0xF8E0, 0xF6D0, + 0xF3F0, 0xF1E0, 0xEF80, 0xEDD0, 0xEBC0, 0xE940, 0xE640, 0xE370, 0xDFD0, 0xDD10, 0xDA40, 0xD8A0, 0xD730, 0xD620, 0xD560, 0xD510, + 0xD500, 0xD600, 0xD800, 0xDB10, 0xDDF0, 0xE0F0, 0xE3E0, 0xE6A0, 0xEA10, 0xED20, 0xF080, 0xF3F0, 0xF740, 0xFA10, 0xFDA0, 0x01E0, + 0x0610, 0x0AB0, 0x0E60, 0x10F0, 0x13D0, 0x15B0, 0x1870, 0x1AD0, 0x1D20, 0x1FA0, 0x20A0, 0x2190, 0x21B0, 0x21B0, 0x2160, 0x2030, + 0x1FB0, 0x1F40, 0x1D40, 0x1C70, 0x1B60, 0x1AC0, 0x1A30, 0x1930, 0x1860, 0x1730, 0x15E0, 0x1520, 0x14A0, 0x14F0, 0x1550, 0x15E0, + 0x1610, 0x1600, 0x1770, 0x18A0, 0x1A50, 0x1D50, 0x2030, 0x2320, 0x25B0, 0x27B0, 0x2A40, 0x2C70, 0x2F90, 0x3370, 0x3650, 0x39D0, + 0x3CD0, 0x4030, 0x4340, 0x4630, 0x4970, 0x4C00, 0x4EF0, 0x50D0, 0x5220, 0x5440, 0x55C0, 0x5730, 0x57C0, 0x5770, 0x57B0, 0x5700, + 0x5720, 0x5780, 0x5710, 0x5780, 0x5780, 0x5730, 0x56C0, 0x5680, 0x5780, 0x5890, 0x59B0, 0x5A40, 0x5A50, 0x5A90, 0x5A60, 0x5A50, + 0x5AB0, 0x5A60, 0x5B40, 0x5B90, 0x5B30, 0x5B70, 0x5B70, 0x5DB0, 0x5F60, 0x60E0, 0x6280, 0x6390, 0x6520, 0x6700, 0x68D0, 0x6B90, + 0x6DE0, 0x7090, 0x7290, 0x7470, 0x7760, 0x7950, 0x7BD0, 0x7E20, 0x7F00, 0x7F10, 0x7EA0, 0x7EE0, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, + 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EF0, 0x7F20, 0x7F10, 0x7F80, 0x7F00, + 0x7ED0, 0x7F10, 0x7F00, 0x7F30, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7E90, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F20, 0x7F00, 0x7F00, 0x7F10, + 0x7F00, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, + 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, + 0x7EF0, 0x7E90, 0x7EF0, 0x7EE0, 0x7F50, 0x7F00, 0x7440, 0x3C80, 0x0310, 0xC930, 0x90A0, 0x84F0, 0x84A0, 0x8480, 0x8470, 0x8470, + 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x84A0, 0x8470, + 0x8470, 0x8470, 0x8460, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84E0, 0x84F0, 0x8550, 0x8720, 0x92F0, 0xA780, 0xB6C0, + 0xC2F0, 0xCA30, 0xCE00, 0xCC70, 0xC790, 0xC030, 0xB690, 0xAB30, 0x9F80, 0x9470, 0x8BC0, 0x8750, 0x85D0, 0x8540, 0x8500, 0x84E0, + 0x84B0, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8470, 0x8450, 0x8460, 0x8450, 0x8450, 0x8440, 0x8410, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8420, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8520, 0x8560, 0x8600, 0x8740, 0x8A70, 0x9170, 0x9A40, + 0xA170, 0xA890, 0xAD80, 0xB1E0, 0xB450, 0xB5E0, 0xB560, 0xB360, 0xB050, 0xAD90, 0xAB80, 0xACC0, 0xB160, 0xB9A0, 0xC3D0, 0xCF10, + 0xD8B0, 0xDF10, 0xE300, 0xE4E0, 0xE640, 0xE7D0, 0xEA60, 0xEF40, 0xF460, 0xFA90, 0x0240, 0x0800, 0x0DD0, 0x1280, 0x1660, 0x1980, + 0x1C70, 0x2080, 0x2460, 0x2890, 0x2D30, 0x3260, 0x3840, 0x3E10, 0x4370, 0x48E0, 0x4CE0, 0x50B0, 0x5400, 0x55F0, 0x5850, 0x5A00, + 0x5C00, 0x5DC0, 0x5E10, 0x5F10, 0x5E40, 0x5B90, 0x5830, 0x52A0, 0x4B60, 0x4290, 0x38A0, 0x2D20, 0x2050, 0x13B0, 0x0500, 0xF6C0, + 0xE8B0, 0xDAA0, 0xCD70, 0xC0A0, 0xB480, 0xA9D0, 0xA090, 0x9910, 0x9470, 0x91F0, 0x9180, 0x91E0, 0x9440, 0x9770, 0x9BC0, 0xA110, + 0xA6F0, 0xAD40, 0xB410, 0xB9F0, 0xC0E0, 0xC780, 0xCE10, 0xD3F0, 0xD8B0, 0xDD70, 0xE150, 0xE5A0, 0xE940, 0xEC70, 0xF030, 0xF280, + 0xF540, 0xF850, 0xFB70, 0xFEE0, 0x0280, 0x05B0, 0x0940, 0x0CD0, 0x1200, 0x15E0, 0x1950, 0x1CB0, 0x20D0, 0x2500, 0x2940, 0x2DD0, + 0x3200, 0x3640, 0x3A70, 0x3F30, 0x4360, 0x4800, 0x4D50, 0x52F0, 0x5860, 0x5D70, 0x6240, 0x6720, 0x6BE0, 0x7060, 0x7530, 0x79A0, + 0x7CE0, 0x7ED0, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, + 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, + 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7A60, 0x73F0, 0x6DA0, 0x6800, 0x61D0, + 0x5BB0, 0x5670, 0x5160, 0x4D40, 0x4A00, 0x46A0, 0x4370, 0x40B0, 0x3DD0, 0x3B60, 0x38A0, 0x3610, 0x33B0, 0x31B0, 0x2F70, 0x2C90, + 0x29B0, 0x2660, 0x22E0, 0x1F50, 0x1B70, 0x1760, 0x13E0, 0x0FB0, 0x0BE0, 0x0900, 0x0570, 0x01B0, 0xFE00, 0xFAA0, 0xF690, 0xF3F0, + 0xF0E0, 0xEE90, 0xEBF0, 0xE870, 0xE470, 0xE040, 0xDC50, 0xD830, 0xD4A0, 0xD130, 0xCEE0, 0xCBD0, 0xC8C0, 0xC5B0, 0xC280, 0xBF90, + 0xBD50, 0xBA50, 0xB7B0, 0xB500, 0xB220, 0xAF60, 0xABE0, 0xA920, 0xA590, 0xA240, 0x9EC0, 0x9A50, 0x96D0, 0x92A0, 0x8ED0, 0x8B60, + 0x88F0, 0x8770, 0x8690, 0x8600, 0x85B0, 0x8580, 0x8550, 0x8530, 0x8520, 0x8520, 0x8510, 0x8510, 0x8520, 0x8520, 0x8530, 0x8530, + 0x8530, 0x8540, 0x8550, 0x8550, 0x8560, 0x8570, 0x8570, 0x8570, 0x8580, 0x8570, 0x8580, 0x8590, 0x85B0, 0x85D0, 0x85F0, 0x8610, + 0x8630, 0x8640, 0x8670, 0x8670, 0x8680, 0x86C0, 0x86F0, 0x8720, 0x8740, 0x8760, 0x87B0, 0x87C0, 0x87F0, 0x8810, 0x8850, 0x8890, + 0x88D0, 0x8980, 0x8A10, 0x8AF0, 0x8BF0, 0x8D20, 0x8F10, 0x9140, 0x93B0, 0x96F0, 0x9A00, 0x9CF0, 0x9F50, 0xA0F0, 0xA340, 0xA550, + 0xA7A0, 0xA9C0, 0xAC10, 0xAEB0, 0xB040, 0xB2E0, 0xB4A0, 0xB6D0, 0xB8F0, 0xBB90, 0xBE50, 0xC160, 0xC450, 0xC710, 0xC960, 0xCBF0, + 0xCE50, 0xD030, 0xD270, 0xD390, 0xD5D0, 0xD7E0, 0xD990, 0xDBF0, 0xDDA0, 0xDEB0, 0xDFF0, 0xE040, 0xE010, 0xE000, 0xDFD0, 0xE010, + 0xE070, 0xE110, 0xE150, 0xE110, 0xE0C0, 0xE0A0, 0xE090, 0xE0C0, 0xE110, 0xE180, 0xE130, 0xE160, 0xE0E0, 0xE070, 0xDF50, 0xDEC0, + 0xDE50, 0xDE90, 0xDEA0, 0xDF20, 0xDEF0, 0xDF90, 0xE0E0, 0xE250, 0xE480, 0xE720, 0xE8C0, 0xE970, 0xEAB0, 0xEC00, 0xED90, 0xF010, + 0xF300, 0xF670, 0xFBB0, 0x0110, 0x07E0, 0x0DF0, 0x1410, 0x1A80, 0x1F60, 0x22F0, 0x2650, 0x2930, 0x2C40, 0x2F10, 0x31D0, 0x33B0, + 0x3300, 0x3110, 0x2D30, 0x27A0, 0x1FF0, 0x17F0, 0x0F60, 0x0400, 0xF710, 0xE8D0, 0xD810, 0xC500, 0xAE90, 0x9320, 0x8610, 0x84D0, + 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8460, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8450, 0x8430, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, + 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8540, 0x8520, 0x8530, 0x8510, 0x8570, 0x85B0, 0x8630, 0x8690, 0x8740, 0x8860, 0x8A70, 0x8C40, + 0x8DE0, 0x8EF0, 0x8F90, 0x90A0, 0x9280, 0x9560, 0x98A0, 0x9B60, 0x9D70, 0x9F70, 0xA130, 0xA360, 0xA4B0, 0xA5F0, 0xA720, 0xA870, + 0xA9F0, 0xAC80, 0xB0B0, 0xB610, 0xBBD0, 0xC210, 0xC880, 0xCF70, 0xD7A0, 0xDFF0, 0xE9E0, 0xF4A0, 0x01A0, 0x1000, 0x1E20, 0x2D40, + 0x3CF0, 0x4D70, 0x5D00, 0x6AF0, 0x7750, 0x7E80, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7ED0, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, 0x7EB0, + 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F10, 0x7F10, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, + 0x7F40, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, + 0x7F10, 0x7EF0, 0x7EE0, 0x7F30, 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F50, 0x7EF0, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EE0, 0x7EE0, + 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7E00, 0x5DF0, + 0x3E20, 0x2360, 0x0C00, 0xF7D0, 0xE790, 0xDB20, 0xD3D0, 0xD090, 0xD190, 0xD4C0, 0xD790, 0xD9F0, 0xD890, 0xD360, 0xCA10, 0xBDE0, + 0xB1F0, 0xA550, 0x9A70, 0x92E0, 0x8D50, 0x8980, 0x8770, 0x8640, 0x85B0, 0x8580, 0x8590, 0x8600, 0x8730, 0x8B20, 0x9440, 0x9CE0, + 0xA200, 0xA3D0, 0xA310, 0x9F40, 0x9980, 0x9360, 0x8D30, 0x8950, 0x86F0, 0x85E0, 0x8570, 0x8530, 0x8510, 0x84F0, 0x84E0, 0x84D0, + 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8510, 0x85E0, 0x8AE0, 0x9D60, 0xB050, 0xC290, 0xD5B0, + 0xE610, 0xF420, 0xFE80, 0x0550, 0x0690, 0x0460, 0xFEE0, 0xF7E0, 0xF2A0, 0xF100, 0xF450, 0xFC10, 0x0730, 0x1420, 0x20E0, 0x2C10, + 0x3480, 0x39F0, 0x3D30, 0x3E70, 0x3F00, 0x3F40, 0x3FB0, 0x4190, 0x42A0, 0x44C0, 0x46B0, 0x4920, 0x4C80, 0x5000, 0x53E0, 0x5800, + 0x5B40, 0x5E00, 0x5F00, 0x5F80, 0x5E50, 0x5A70, 0x5420, 0x49E0, 0x3C50, 0x2C90, 0x1B20, 0x0980, 0xF630, 0xE550, 0xD5C0, 0xC750, + 0xBA70, 0xAFD0, 0xA680, 0x9F20, 0x9920, 0x94C0, 0x9200, 0x90D0, 0x9070, 0x90B0, 0x9200, 0x93C0, 0x95F0, 0x9930, 0x9E10, 0xA4C0, + 0xAD90, 0xB850, 0xC490, 0xD320, 0xE4D0, 0xF620, 0x07C0, 0x19C0, 0x2A30, 0x38A0, 0x4570, 0x4F90, 0x57F0, 0x5F40, 0x6470, 0x68B0, + 0x6C00, 0x6E10, 0x6FB0, 0x7030, 0x7070, 0x7120, 0x7190, 0x7200, 0x7290, 0x7290, 0x7170, 0x6FC0, 0x6DC0, 0x6C30, 0x6B70, 0x6C10, + 0x6E70, 0x72B0, 0x7790, 0x7C20, 0x7EE0, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7C70, 0x7480, 0x6AC0, 0x5F10, 0x5230, 0x44D0, 0x3810, + 0x2B70, 0x1EA0, 0x1390, 0x0890, 0xFDB0, 0xF3E0, 0xEB00, 0xE390, 0xDD30, 0xD790, 0xD1D0, 0xCCB0, 0xC7E0, 0xC2E0, 0xBE70, 0xBA70, + 0xB6B0, 0xB3B0, 0xB110, 0xADF0, 0xAB90, 0xA910, 0xA720, 0xA4F0, 0xA3C0, 0xA230, 0xA250, 0xA3D0, 0xA7E0, 0xAC90, 0xB2F0, 0xB9D0, + 0xC1A0, 0xC910, 0xD140, 0xD930, 0xE140, 0xEA50, 0xF330, 0xFC70, 0x0560, 0x0EC0, 0x1780, 0x1FC0, 0x2790, 0x2F50, 0x3700, 0x3DE0, + 0x44D0, 0x4B50, 0x5160, 0x5600, 0x59C0, 0x5C30, 0x5D80, 0x5E10, 0x5E10, 0x5D50, 0x5B40, 0x58E0, 0x5580, 0x51E0, 0x4DB0, 0x4970, + 0x4470, 0x4030, 0x3CA0, 0x3880, 0x3490, 0x3160, 0x2E20, 0x2B50, 0x2980, 0x27F0, 0x2710, 0x2530, 0x23D0, 0x20E0, 0x1D40, 0x1850, + 0x12D0, 0x0D00, 0x0600, 0xFED0, 0xF780, 0xF060, 0xE940, 0xE190, 0xDAD0, 0xD400, 0xCD50, 0xC660, 0xC0C0, 0xBB80, 0xB6E0, 0xB320, + 0xB070, 0xAD70, 0xAAC0, 0xA830, 0xA630, 0xA4E0, 0xA400, 0xA3E0, 0xA380, 0xA350, 0xA2C0, 0xA300, 0xA310, 0xA370, 0xA4B0, 0xA580, + 0xA5F0, 0xA660, 0xA6C0, 0xA740, 0xA7C0, 0xA820, 0xA8A0, 0xA9A0, 0xAA90, 0xAB50, 0xAC30, 0xACB0, 0xAE40, 0xB020, 0xB1A0, 0xB370, + 0xB590, 0xB7F0, 0xBAE0, 0xBE90, 0xC230, 0xC5A0, 0xC920, 0xCBC0, 0xCF80, 0xD280, 0xD6C0, 0xDAB0, 0xDEF0, 0xE2A0, 0xE5A0, 0xE990, + 0xED00, 0xF140, 0xF530, 0xF870, 0xFB60, 0xFD80, 0xFFD0, 0x0260, 0x04A0, 0x07D0, 0x0B00, 0x0D60, 0x0ED0, 0x0F80, 0x10B0, 0x1160, + 0x1150, 0x1190, 0x1100, 0x1070, 0x0FB0, 0x0F70, 0x0EC0, 0x0E40, 0x0E60, 0x0D60, 0x0CE0, 0x0C50, 0x0B20, 0x0B20, 0x0B90, 0x0BF0, + 0x0C70, 0x0C60, 0x0C80, 0x0D30, 0x0E20, 0x0F90, 0x10A0, 0x1230, 0x1360, 0x13D0, 0x1600, 0x1700, 0x1920, 0x1B30, 0x1CB0, 0x1E40, + 0x1F10, 0x2070, 0x21F0, 0x2420, 0x2790, 0x2A90, 0x2DF0, 0x3010, 0x3330, 0x36E0, 0x3A40, 0x3F40, 0x4580, 0x4B60, 0x5240, 0x5880, + 0x5E80, 0x6440, 0x6910, 0x6FB0, 0x75E0, 0x7BE0, 0x7ED0, 0x7F20, 0x7F00, 0x7EF0, 0x7F90, 0x7F20, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, + 0x7EE0, 0x7ED0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7EC0, 0x7EB0, 0x7EB0, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7F00, 0x7F20, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, + 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F50, + 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, + 0x7F50, 0x7C30, 0x6F70, 0x5F80, 0x4DD0, 0x3A30, 0x2520, 0x1040, 0xFB70, 0xE900, 0xD840, 0xC9F0, 0xBD30, 0xB480, 0xAE20, 0xA930, + 0xA750, 0xA620, 0xA5D0, 0xA4D0, 0xA3B0, 0xA260, 0xA0E0, 0xA080, 0xA0A0, 0xA1E0, 0xA3B0, 0xA6F0, 0xAA90, 0xAFC0, 0xB590, 0xBB30, + 0xC1A0, 0xC740, 0xCD30, 0xD220, 0xD680, 0xD930, 0xDA20, 0xD950, 0xD820, 0xD590, 0xD370, 0xD050, 0xCD90, 0xCBA0, 0xCA40, 0xC900, + 0xCA00, 0xCB70, 0xCDF0, 0xD140, 0xD4B0, 0xD860, 0xDB30, 0xDE00, 0xE160, 0xE5B0, 0xEAD0, 0xEFC0, 0xF560, 0xFB50, 0x0100, 0x0730, + 0x0CC0, 0x1220, 0x1850, 0x1E50, 0x25F0, 0x2D90, 0x37E0, 0x4270, 0x4D50, 0x5990, 0x6520, 0x6F60, 0x7790, 0x7D70, 0x7EF0, 0x7F10, + 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7C10, 0x6CC0, 0x5B60, 0x47F0, 0x3430, 0x1F70, 0x0BC0, 0xF880, 0xE670, + 0xD660, 0xC5C0, 0xB700, 0xA960, 0x9B50, 0x8EC0, 0x87F0, 0x85B0, 0x8510, 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, + 0x84A0, 0x8490, 0x8490, 0x8470, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84C0, + 0x84E0, 0x8530, 0x8620, 0x89F0, 0x9440, 0x9D20, 0xA120, 0xA050, 0x9B40, 0x9190, 0x8910, 0x85C0, 0x8500, 0x84D0, 0x84C0, 0x84B0, + 0x8490, 0x84B0, 0x84A0, 0x84B0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, + 0x8500, 0x8520, 0x8540, 0x8580, 0x85E0, 0x8690, 0x8800, 0x8B90, 0x9410, 0xA290, 0xB290, 0xC3E0, 0xD610, 0xE710, 0xF680, 0x0360, + 0x0CC0, 0x1350, 0x1640, 0x16F0, 0x1490, 0x0FF0, 0x0920, 0x01C0, 0xFA70, 0xF3B0, 0xEDE0, 0xE890, 0xE480, 0xE0A0, 0xDC40, 0xD690, + 0xCFB0, 0xC750, 0xBE00, 0xB2F0, 0xA7C0, 0x9E70, 0x95B0, 0x8E30, 0x8980, 0x8700, 0x85E0, 0x8550, 0x8510, 0x84F0, 0x84E0, 0x84D0, + 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84F0, 0x8500, 0x8510, 0x8510, 0x8520, 0x8540, 0x8550, 0x8580, 0x85A0, 0x85C0, 0x85A0, 0x8560, 0x8520, 0x84F0, 0x84C0, 0x84B0, + 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8460, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8420, 0x8470, 0x8420, 0x83F0, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x84C0, 0x8480, 0x8490, + 0x8480, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8590, 0x86E0, 0x8B70, 0x9610, 0xA0B0, 0xADF0, 0xB8A0, 0xC300, 0xCE20, + 0xDAB0, 0xE990, 0xF9D0, 0x0AC0, 0x1C10, 0x2C30, 0x3A60, 0x4410, 0x4AB0, 0x4F40, 0x5220, 0x5480, 0x56F0, 0x5A30, 0x5DA0, 0x6090, + 0x62B0, 0x63A0, 0x63D0, 0x62F0, 0x6280, 0x6320, 0x6560, 0x6A50, 0x7160, 0x79C0, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7D00, 0x7540, 0x6E50, 0x6830, 0x63E0, + 0x61D0, 0x61D0, 0x63C0, 0x67B0, 0x6AB0, 0x6D50, 0x6EA0, 0x6C70, 0x6570, 0x5920, 0x4780, 0x3480, 0x20A0, 0x1180, 0x05E0, 0xFE00, + 0xF890, 0xF520, 0xF200, 0xEE10, 0xEA10, 0xE710, 0xE670, 0xE890, 0xEE40, 0xF880, 0x06F0, 0x1870, 0x2B20, 0x3E20, 0x51B0, 0x6230, + 0x7040, 0x7B90, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7840, 0x68F0, 0x5730, 0x4330, 0x3000, 0x1EC0, 0x0FF0, 0x0800, 0x0440, 0x03F0, 0x0530, + 0x06A0, 0x08E0, 0x0C90, 0x12F0, 0x1EA0, 0x2DB0, 0x3EB0, 0x4D20, 0x5640, 0x57D0, 0x5310, 0x4AB0, 0x42C0, 0x3DB0, 0x3CF0, 0x40A0, + 0x46D0, 0x4D80, 0x5420, 0x59A0, 0x5EE0, 0x6330, 0x67A0, 0x6A80, 0x6D70, 0x7010, 0x71F0, 0x73C0, 0x74B0, 0x7530, 0x7520, 0x74D0, + 0x7370, 0x72A0, 0x7340, 0x7580, 0x7850, 0x7BE0, 0x7E40, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F70, 0x7F10, 0x7E90, 0x7F20, 0x7F20, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F40, 0x7F10, 0x7F00, 0x7EC0, 0x7E90, 0x7EB0, 0x7EB0, + 0x7F00, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F00, 0x7F20, 0x7EE0, 0x7F10, + 0x7D30, 0x6D60, 0x5DF0, 0x4DC0, 0x3C90, 0x2A50, 0x1940, 0x08B0, 0xFB90, 0xF0F0, 0xEB50, 0xE9C0, 0xEBC0, 0xF100, 0xF7B0, 0xFD60, + 0x01A0, 0x03F0, 0x0710, 0x09C0, 0x0DC0, 0x1250, 0x1630, 0x1A60, 0x1C30, 0x1DE0, 0x1F00, 0x2090, 0x2550, 0x2BB0, 0x3520, 0x4060, + 0x4C70, 0x56A0, 0x5B60, 0x5990, 0x4DB0, 0x37E0, 0x1BD0, 0xFD30, 0xE170, 0xCAD0, 0xBD10, 0xB630, 0xB300, 0xB1A0, 0xB110, 0xB0B0, + 0xB060, 0xB150, 0xB450, 0xB820, 0xBD40, 0xC2D0, 0xC8B0, 0xCE30, 0xD340, 0xD580, 0xD770, 0xD800, 0xD7F0, 0xD850, 0xDA10, 0xDCA0, + 0xE050, 0xE4F0, 0xE970, 0xECD0, 0xF060, 0xF270, 0xF450, 0xF690, 0xF8B0, 0xFCA0, 0xFF40, 0x0230, 0x05B0, 0x0810, 0x0A30, 0x0AB0, + 0x0A40, 0x0A40, 0x0910, 0x08A0, 0x08C0, 0x0840, 0x0980, 0x0A00, 0x0B10, 0x0B80, 0x0BE0, 0x0CC0, 0x0D40, 0x0D90, 0x0E60, 0x0F50, + 0x1010, 0x1090, 0x1260, 0x13F0, 0x15B0, 0x1850, 0x1A70, 0x1C30, 0x1F70, 0x22A0, 0x2740, 0x2BD0, 0x2FF0, 0x3540, 0x3910, 0x3DF0, + 0x41F0, 0x45D0, 0x4990, 0x4CB0, 0x50E0, 0x53D0, 0x5590, 0x5700, 0x55C0, 0x5430, 0x5070, 0x4A90, 0x4390, 0x3B30, 0x32E0, 0x2A40, + 0x2210, 0x1BF0, 0x1600, 0x11D0, 0x0E90, 0x0C40, 0x0AE0, 0x0A10, 0x09B0, 0x09D0, 0x0870, 0x07B0, 0x0600, 0x03E0, 0x0190, 0xFEC0, + 0xFBC0, 0xF800, 0xF3F0, 0xEF30, 0xE920, 0xE2D0, 0xDCB0, 0xD670, 0xD060, 0xC9D0, 0xC330, 0xBB90, 0xB2C0, 0xA970, 0x9FD0, 0x9800, + 0x9120, 0x8D10, 0x8B30, 0x8A90, 0x8B30, 0x8D30, 0x8FA0, 0x9340, 0x9670, 0x98B0, 0x9530, 0x93C0, 0x9230, 0x90E0, 0x8F90, 0x8E40, + 0x8CD0, 0x8B20, 0x8990, 0x8870, 0x87C0, 0x8760, 0x8710, 0x86E0, 0x86C0, 0x86B0, 0x8690, 0x8680, 0x8670, 0x8670, 0x8670, 0x8670, + 0x8690, 0x86D0, 0x8750, 0x8820, 0x8980, 0x8C30, 0x8FC0, 0x9360, 0x9670, 0x98F0, 0x9AE0, 0x9C20, 0x9E70, 0xA0B0, 0xA3A0, 0xA6D0, + 0xAA30, 0xADE0, 0xB150, 0xB430, 0xB6B0, 0xBA10, 0xBDA0, 0xC250, 0xC750, 0xCCC0, 0xD220, 0xD790, 0xDD00, 0xE240, 0xE8F0, 0xEF30, + 0xF5B0, 0xFD10, 0x02F0, 0x08F0, 0x0F40, 0x1610, 0x1D20, 0x23F0, 0x2BE0, 0x32D0, 0x3A60, 0x4080, 0x4670, 0x4C70, 0x5170, 0x57C0, + 0x5D90, 0x6330, 0x69E0, 0x7030, 0x7620, 0x7BA0, 0x7E90, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7F10, + 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F70, 0x7DF0, 0x7AA0, 0x78E0, 0x7790, 0x76B0, 0x7720, 0x7800, 0x7A50, + 0x7CE0, 0x7E90, 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7F20, + 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F10, 0x7F10, 0x7E90, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7E60, 0x6E40, 0x5F50, 0x50B0, 0x4120, 0x3380, 0x2680, 0x1A60, 0x0F90, + 0x06B0, 0x0010, 0xFB20, 0xF8F0, 0xF950, 0xFB60, 0x0000, 0x0580, 0x0D30, 0x1500, 0x1D10, 0x2600, 0x2D80, 0x3460, 0x3A10, 0x3EB0, + 0x42A0, 0x4580, 0x47F0, 0x49A0, 0x4B80, 0x4D80, 0x4E80, 0x4EF0, 0x4F80, 0x4F70, 0x4EC0, 0x4BE0, 0x47B0, 0x4290, 0x3CA0, 0x3720, + 0x3080, 0x2930, 0x21B0, 0x18D0, 0x1130, 0x0930, 0x0250, 0xFCD0, 0xF850, 0xF430, 0xF060, 0xEC40, 0xE8E0, 0xE540, 0xE050, 0xDAE0, + 0xD330, 0xCAD0, 0xC1C0, 0xB8D0, 0xB030, 0xA770, 0x9FD0, 0x9880, 0x9210, 0x8D30, 0x89A0, 0x87C0, 0x86A0, 0x8600, 0x85A0, 0x8550, + 0x8520, 0x8500, 0x84F0, 0x84E0, 0x84C0, 0x84C0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, + 0x8430, 0x8420, 0x8410, 0x8400, 0x83F0, 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83D0, 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83C0, + 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8410, 0x8430, 0x8430, 0x8450, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x84B0, 0x8520, 0x8C20, 0xB580, 0xDB30, 0xFF20, + 0x2000, 0x3EC0, 0x5B10, 0x7540, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7EF0, 0x6CD0, 0x57F0, 0x4040, 0x2350, 0x0660, 0xE7E0, 0xC930, 0xAB30, 0x9050, 0x8620, 0x84F0, 0x84C0, + 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84D0, 0x8530, 0x8B10, 0xB130, + 0xD720, 0xFD70, 0x24E0, 0x46E0, 0x6470, 0x7BB0, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F00, 0x7ED0, + 0x7ED0, 0x7EE0, 0x7F40, 0x7EF0, 0x7F10, 0x7F60, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F40, + 0x7F10, 0x7ED0, 0x7F00, 0x7F00, 0x7F40, 0x7F10, 0x7EB0, 0x7EE0, 0x7F10, 0x7F30, 0x7EC0, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x6740, + 0x4E00, 0x32E0, 0x1A10, 0x0050, 0xE860, 0xD1C0, 0xBF40, 0xAF10, 0xA280, 0x9840, 0x8F10, 0x89B0, 0x8730, 0x8610, 0x85A0, 0x8580, + 0x8590, 0x85D0, 0x8670, 0x8810, 0x8B40, 0x90E0, 0x98E0, 0xA1C0, 0xAB30, 0xB520, 0xBE60, 0xC6E0, 0xCFD0, 0xD750, 0xDDC0, 0xE2F0, + 0xE7D0, 0xEBF0, 0xF080, 0xF490, 0xF970, 0x0080, 0x07D0, 0x1250, 0x1E90, 0x2CB0, 0x3B80, 0x4800, 0x50B0, 0x5160, 0x4610, 0x30B0, + 0x0F40, 0xE7A0, 0xBCA0, 0x92C0, 0x8540, 0x84C0, 0x84A0, 0x8490, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, + 0x8480, 0x84A0, 0x84B0, 0x8580, 0x94C0, 0xB5F0, 0xCF30, 0xDFF0, 0xE7D0, 0xE6E0, 0xDF90, 0xD4B0, 0xC960, 0xC170, 0xBF00, 0xC210, + 0xCB50, 0xD960, 0xEC20, 0xFF70, 0x1580, 0x2C90, 0x4550, 0x5F60, 0x7720, 0x7F30, 0x7ED0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, + 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x62D0, 0x3D80, 0x1500, 0xE850, 0xB7B0, 0x8880, 0x84C0, 0x8480, + 0x8460, 0x8460, 0x8440, 0x8440, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84D0, 0x8560, 0x8D30, 0xAD50, + 0xC890, 0xE290, 0xF6F0, 0x06B0, 0x1460, 0x1D40, 0x2450, 0x2990, 0x2C30, 0x2CC0, 0x2A00, 0x2500, 0x1670, 0x1970, 0x1D30, 0x2020, + 0x2360, 0x2450, 0x2590, 0x2600, 0x2640, 0x2840, 0x2A10, 0x2D40, 0x2F90, 0x3230, 0x3500, 0x3800, 0x3B80, 0x3FB0, 0x4370, 0x48A0, + 0x4D50, 0x52A0, 0x56E0, 0x58F0, 0x59B0, 0x5720, 0x52E0, 0x4DD0, 0x49B0, 0x4740, 0x4630, 0x46B0, 0x46E0, 0x4690, 0x46C0, 0x46D0, + 0x4720, 0x4810, 0x4AE0, 0x4E60, 0x5280, 0x5770, 0x5C90, 0x6120, 0x6440, 0x6250, 0x59B0, 0x4910, 0x3390, 0x1BF0, 0x0580, 0xF350, + 0xE710, 0xE020, 0xDEF0, 0xE1A0, 0xE850, 0xF1A0, 0xFB90, 0x06B0, 0x1100, 0x19C0, 0x2190, 0x2880, 0x2FA0, 0x3770, 0x3EB0, 0x4660, + 0x4C40, 0x50D0, 0x54B0, 0x57E0, 0x5D40, 0x6280, 0x67E0, 0x6C80, 0x6FD0, 0x7230, 0x7270, 0x71A0, 0x6FC0, 0x6C80, 0x6920, 0x6410, + 0x5FF0, 0x5C70, 0x58A0, 0x5690, 0x5470, 0x5330, 0x52F0, 0x5340, 0x54B0, 0x5870, 0x5E50, 0x6580, 0x6C20, 0x7300, 0x77C0, 0x7910, + 0x7870, 0x7390, 0x6CB0, 0x6260, 0x54C0, 0x44C0, 0x3190, 0x1C80, 0x0500, 0xEB50, 0xD0A0, 0xB700, 0x9E00, 0x8A40, 0x8550, 0x84E0, + 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x8500, 0x8550, 0x8680, 0x8B90, 0x9990, 0xA650, + 0xB160, 0xBA90, 0xC260, 0xC970, 0xD0D0, 0xD8B0, 0xE030, 0xE780, 0xEBE0, 0xEE70, 0xEF60, 0xEE10, 0xEBF0, 0xE7A0, 0xE0C0, 0xD850, + 0xCB20, 0xBD70, 0xAD70, 0x9CA0, 0x8CD0, 0x8620, 0x84F0, 0x84C0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, + 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, + 0x84C0, 0x84F0, 0x8590, 0x8970, 0x9C30, 0xAEB0, 0xC120, 0xD070, 0xDDD0, 0xEA10, 0xF560, 0x0060, 0x0D90, 0x1D00, 0x2F60, 0x44B0, + 0x5970, 0x6C60, 0x7B80, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, + 0x7EE0, 0x7EB0, 0x7F00, 0x7EE0, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7F00, + 0x7EC0, 0x7F30, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, + 0x7F70, 0x7F00, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, + 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F00, + 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F40, + 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F30, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7FB0, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7ED0, 0x7EF0, 0x7F20, 0x7F40, 0x7F40, 0x7EB0, + 0x7F00, 0x7F00, 0x7F30, 0x7F30, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F20, 0x7F00, 0x7ED0, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, 0x7E90, 0x7EE0, + 0x7EE0, 0x7EF0, 0x7F20, 0x7E80, 0x7ED0, 0x7F00, 0x7F20, 0x7F10, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, + 0x7F20, 0x7F40, 0x7F00, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F50, 0x7F00, 0x7F20, + 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F00, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EB0, 0x7E70, 0x7F10, + 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7F40, 0x7F10, + 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7EF0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F20, + 0x7EF0, 0x7EF0, 0x7F60, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7E30, 0x7B00, 0x7790, 0x73F0, 0x7180, 0x6ED0, 0x6CB0, + 0x6A30, 0x6720, 0x65C0, 0x64D0, 0x6540, 0x6640, 0x67B0, 0x69F0, 0x6CA0, 0x6F90, 0x72B0, 0x7570, 0x7920, 0x7BC0, 0x7E60, 0x7EE0, + 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, + 0x7F20, 0x7F20, 0x7F70, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F00, + 0x7EE0, 0x7EF0, 0x7EB0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, + 0x7F10, 0x7F30, 0x7F20, 0x7F80, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F80, 0x7EC0, 0x7F10, + 0x7F10, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7F60, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F90, 0x7F20, + 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7ED0, 0x7DB0, 0x7C00, 0x7A40, 0x78F0, 0x77B0, 0x75E0, 0x74E0, 0x73B0, 0x72E0, 0x7310, 0x7290, + 0x7370, 0x7400, 0x7440, 0x75C0, 0x7630, 0x7760, 0x7890, 0x79E0, 0x7BE0, 0x7C90, 0x7E00, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EA0, 0x7F00, + 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, + 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7ED0, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7E90, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, + 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F30, 0x7600, 0x5D80, 0x4380, + 0x2940, 0x1040, 0xF810, 0xE1B0, 0xCBF0, 0xB770, 0xA0B0, 0x8CC0, 0x85B0, 0x84E0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8410, 0x8430, 0x8430, 0x8430, 0x8460, 0x8430, 0x8430, + 0x8430, 0x8440, 0x8430, 0x8430, 0x8460, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, + 0x8430, 0x8430, 0x8450, 0x8430, 0x8420, 0x8410, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, + 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8430, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8460, 0x8440, 0x8460, 0x8460, + 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8470, 0x8430, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8440, 0x8440, 0x8480, 0x8460, 0x8460, 0x84B0, 0x8490, 0x84A0, 0x84D0, 0x8530, 0x8810, 0x9CB0, 0xB390, 0xC420, 0xCD90, 0xCF10, + 0xC810, 0xB9A0, 0xA4F0, 0x8FB0, 0x8660, 0x8500, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8460, 0x8450, 0x83E0, + 0x8430, 0x8420, 0x8420, 0x8420, 0x8430, 0x8460, 0x8440, 0x8460, 0x8480, 0x84A0, 0x84F0, 0x85B0, 0x8950, 0x9530, 0xA2D0, 0xB180, + 0xC2A0, 0xD230, 0xDF20, 0xE770, 0xEA10, 0xE6A0, 0xDAE0, 0xC4C0, 0xA010, 0x8550, 0x84A0, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8490, 0x84D0, 0x8780, 0xB350, 0xDE50, 0x0290, 0x2130, + 0x3B80, 0x5290, 0x67D0, 0x7AA0, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x62D0, 0x5B20, 0x57B0, + 0x5910, 0x5DE0, 0x6420, 0x6AC0, 0x7130, 0x7720, 0x7BC0, 0x7EB0, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, 0x7EF0, 0x7EE0, 0x7E80, 0x7EF0, 0x7F20, 0x7F00, + 0x7F00, 0x7E80, 0x7EB0, 0x7EA0, 0x7F10, 0x7EB0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F30, 0x7F00, 0x7F90, 0x7F20, 0x7F40, 0x7F10, + 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F80, 0x7F00, 0x7EE0, 0x7D60, 0x7C80, 0x7CB0, 0x7D70, 0x7E40, 0x7ED0, 0x7EE0, + 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7ED0, 0x7EB0, 0x7F00, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F00, + 0x7ED0, 0x7300, 0x6700, 0x5A10, 0x4D10, 0x42B0, 0x3B40, 0x3840, 0x3980, 0x3E70, 0x4800, 0x5140, 0x59E0, 0x6160, 0x66F0, 0x6B30, + 0x6D30, 0x6E30, 0x6E40, 0x6CB0, 0x6BA0, 0x6940, 0x6790, 0x66E0, 0x67A0, 0x6B10, 0x7050, 0x7730, 0x7E40, 0x7F10, 0x7F00, 0x7EF0, + 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7EF0, + 0x7EB0, 0x7EC0, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F40, 0x72E0, 0x5EA0, 0x4960, 0x33D0, 0x2090, + 0x0CC0, 0xFBD0, 0xEDB0, 0xE260, 0xD960, 0xD380, 0xD030, 0xCF90, 0xD060, 0xD340, 0xD5C0, 0xD7C0, 0xD940, 0xDAB0, 0xDC30, 0xDE20, + 0xDF50, 0xE0B0, 0xE160, 0xE2C0, 0xE430, 0xE4B0, 0xE610, 0xE6D0, 0xE790, 0xE780, 0xE670, 0xE550, 0xE460, 0xE460, 0xE500, 0xE530, + 0xE820, 0xEB60, 0xF110, 0xF870, 0x01C0, 0x0BD0, 0x1710, 0x2300, 0x2FC0, 0x3CC0, 0x4A80, 0x5720, 0x6340, 0x6F20, 0x7820, 0x7E70, + 0x7F10, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F80, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F10, + 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F60, 0x7EE0, 0x7E90, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, + 0x7EE0, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F40, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F20, + 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7F00, + 0x7E60, 0x7AB0, 0x7740, 0x7380, 0x6F90, 0x6C70, 0x6960, 0x66F0, 0x64D0, 0x6310, 0x6100, 0x5E50, 0x5A30, 0x56E0, 0x52F0, 0x5090, + 0x4D60, 0x4980, 0x46A0, 0x41F0, 0x3F40, 0x3BE0, 0x3810, 0x34B0, 0x30A0, 0x2CC0, 0x28C0, 0x2500, 0x21E0, 0x1FC0, 0x1E30, 0x1CC0, + 0x1A80, 0x1850, 0x1620, 0x1440, 0x1240, 0x1010, 0x0F20, 0x0E00, 0x0DB0, 0x0D20, 0x0C60, 0x0CF0, 0x0CC0, 0x0BF0, 0x0B10, 0x0AD0, + 0x0B10, 0x0B20, 0x0BC0, 0x0C50, 0x0CA0, 0x0D70, 0x0DF0, 0x0F30, 0x10E0, 0x1360, 0x17B0, 0x1CB0, 0x2130, 0x25F0, 0x2AC0, 0x3100, + 0x3770, 0x3D50, 0x4400, 0x49A0, 0x4F50, 0x53D0, 0x56F0, 0x5AA0, 0x5CC0, 0x5FB0, 0x6260, 0x63C0, 0x65D0, 0x6700, 0x67C0, 0x6850, + 0x68D0, 0x69F0, 0x6A80, 0x6B10, 0x6C90, 0x6E60, 0x7170, 0x7450, 0x77D0, 0x7B20, 0x7D80, 0x7F10, 0x7F20, 0x7F80, 0x7F10, 0x7F10, + 0x7EF0, 0x7EF0, 0x7F80, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7F10, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F00, 0x7EE0, 0x7EE0, + 0x7ED0, 0x7F30, 0x7F20, 0x7E60, 0x7CD0, 0x7B30, 0x7990, 0x78D0, 0x77B0, 0x77E0, 0x7820, 0x78C0, 0x7A90, 0x7C00, 0x7D20, 0x7E60, + 0x7EE0, 0x7F10, 0x7EC0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F20, + 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F80, 0x7EF0, 0x7EB0, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, + 0x7F10, 0x7F30, 0x7EE0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F40, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7F00, 0x7F10, + 0x7F30, 0x7EF0, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F90, 0x7F20, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EE0, + 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F00, 0x7F20, + 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F00, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, + 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7B50, 0x75B0, 0x6EF0, 0x6880, 0x61E0, 0x5B70, + 0x5540, 0x4FB0, 0x4CD0, 0x4BB0, 0x4D20, 0x5180, 0x56A0, 0x5D60, 0x6350, 0x6870, 0x6B50, 0x6AE0, 0x66C0, 0x5EB0, 0x5270, 0x4490, + 0x3600, 0x27E0, 0x1B00, 0x1030, 0x06C0, 0xFE80, 0xF520, 0xEA50, 0xDF60, 0xD460, 0xC950, 0xBED0, 0xB670, 0xAFE0, 0xAAE0, 0xA7D0, + 0xA520, 0xA3D0, 0xA240, 0xA050, 0x9DB0, 0x99A0, 0x9510, 0x9020, 0x8C80, 0x8A30, 0x8930, 0x88F0, 0x8940, 0x89A0, 0x8AA0, 0x8C10, + 0x8DF0, 0x90F0, 0x9530, 0x99C0, 0x9ED0, 0xA340, 0xA770, 0xABD0, 0xAF50, 0xB370, 0xB790, 0xBBA0, 0xBF60, 0xC2B0, 0xC580, 0xC840, + 0xCAA0, 0xCD40, 0xCFD0, 0xD220, 0xD3D0, 0xD530, 0xD640, 0xD800, 0xD9D0, 0xDBF0, 0xDDD0, 0xDFB0, 0xE040, 0xE090, 0xE0D0, 0xE140, + 0xE180, 0xE200, 0xE2A0, 0xE1D0, 0xE0D0, 0xE060, 0xE070, 0xE080, 0xE090, 0xE0B0, 0xE0C0, 0xE080, 0xDFD0, 0xDFF0, 0xE070, 0xE190, + 0xE230, 0xE2D0, 0xE3C0, 0xE450, 0xE470, 0xE5A0, 0xE640, 0xE660, 0xE540, 0xE300, 0xE090, 0xDE10, 0xDBF0, 0xDA50, 0xD8C0, 0xD600, + 0xD2A0, 0xCDB0, 0xC900, 0xC530, 0xC260, 0xBF40, 0xBBB0, 0xB850, 0xB4D0, 0xB0F0, 0xAE50, 0xAC50, 0xAA20, 0xA780, 0xA410, 0xA0E0, + 0x9DE0, 0x9B80, 0x9A10, 0x98C0, 0x97C0, 0x95C0, 0x9340, 0x90A0, 0x8E30, 0x8C50, 0x8B00, 0x89F0, 0x8900, 0x8850, 0x87C0, 0x8730, + 0x86D0, 0x8690, 0x8660, 0x8620, 0x8620, 0x85C0, 0x8590, 0x8570, 0x8560, 0x8550, 0x8540, 0x8530, 0x8520, 0x8520, 0x8510, 0x8510, + 0x8510, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84D0, + 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84B0, 0x84C0, + 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84C0, 0x84E0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84D0, 0x84F0, 0x84F0, 0x8500, + 0x8500, 0x8510, 0x8530, 0x8540, 0x8560, 0x8590, 0x85D0, 0x8600, 0x8660, 0x86B0, 0x8740, 0x87D0, 0x8860, 0x88E0, 0x8940, 0x89C0, + 0x8A50, 0x8B60, 0x8C10, 0x8C90, 0x8D10, 0x8D60, 0x8E00, 0x8E30, 0x8E90, 0x8F30, 0x8FC0, 0x8FE0, 0x9020, 0x9090, 0x9130, 0x9200, + 0x92F0, 0x93F0, 0x9480, 0x9520, 0x95C0, 0x96F0, 0x9920, 0x9BB0, 0x9E30, 0xA070, 0xA320, 0xA640, 0xAA80, 0xAF70, 0xB550, 0xBC70, + 0xC400, 0xCBD0, 0xD3F0, 0xDBF0, 0xE460, 0xEC60, 0xF3D0, 0xFCD0, 0x0360, 0x0930, 0x0E50, 0x11E0, 0x1520, 0x16D0, 0x1870, 0x18F0, + 0x1890, 0x1770, 0x14A0, 0x10A0, 0x0BD0, 0x05B0, 0xFF30, 0xF6C0, 0xEC90, 0xE1C0, 0xD680, 0xCA50, 0xBDB0, 0xB070, 0xA360, 0x95F0, + 0x8B20, 0x8670, 0x8520, 0x84F0, 0x84D0, 0x84C0, 0x84A0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8460, 0x8440, 0x8450, 0x8440, + 0x8430, 0x8420, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, + 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8460, + 0x8430, 0x8430, 0x8460, 0x8420, 0x8430, 0x8410, 0x8410, 0x8420, 0x8420, 0x8410, 0x8420, 0x8420, 0x8420, 0x8450, 0x8430, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, 0x8470, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x84B0, + 0x84D0, 0x8500, 0x8570, 0x86C0, 0x89E0, 0x8EE0, 0x93C0, 0x97E0, 0x9B80, 0x9EF0, 0xA0F0, 0xA310, 0xA510, 0xA780, 0xAAD0, 0xB070, + 0xB820, 0xC330, 0xD0C0, 0xE1D0, 0xF3A0, 0x07F0, 0x19F0, 0x2AC0, 0x3BA0, 0x4BF0, 0x5C70, 0x6C30, 0x79E0, 0x7EF0, 0x7F00, 0x7F60, + 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, + 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F60, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7F20, 0x7F10, 0x7EF0, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, + 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x72A0, 0x5FE0, 0x4B50, 0x3610, 0x1FE0, 0x0900, 0xF3D0, 0xE030, 0xD020, 0xC2C0, 0xB930, 0xB2F0, + 0xAD90, 0xA750, 0xA110, 0x99C0, 0x92A0, 0x8BD0, 0x87D0, 0x8630, 0x8580, 0x8510, 0x84F0, 0x8510, 0x84C0, 0x84B0, 0x84A0, 0x84A0, + 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8490, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8480, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84A0, 0x8500, 0x84D0, + 0x84E0, 0x8500, 0x8530, 0x85B0, 0x86D0, 0x8A30, 0x9240, 0x9B80, 0xA4D0, 0xADB0, 0xB690, 0xBF90, 0xC8E0, 0xD2F0, 0xDE10, 0xE8D0, + 0xF3D0, 0xFF30, 0x0B00, 0x1640, 0x20F0, 0x2C30, 0x3660, 0x4050, 0x48D0, 0x4F50, 0x56F0, 0x5BC0, 0x5FA0, 0x62B0, 0x64A0, 0x65C0, + 0x6690, 0x6750, 0x6760, 0x6720, 0x66E0, 0x6650, 0x6620, 0x6690, 0x67D0, 0x6990, 0x6C80, 0x70E0, 0x75B0, 0x7B10, 0x7EB0, 0x7F30, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7D20, + 0x6AF0, 0x5A30, 0x49D0, 0x39F0, 0x2B30, 0x1D30, 0x0F40, 0x0270, 0xF660, 0xEBA0, 0xE220, 0xDB70, 0xD6D0, 0xD400, 0xD280, 0xD130, + 0xCF80, 0xCD00, 0xCA20, 0xC6C0, 0xC320, 0xBFD0, 0xBDA0, 0xBAF0, 0xB8A0, 0xB6A0, 0xB490, 0xB260, 0xB090, 0xAEB0, 0xACD0, 0xAB20, + 0xA8A0, 0xA5B0, 0xA110, 0x9AF0, 0x9470, 0x8E50, 0x8A00, 0x8790, 0x86B0, 0x8650, 0x8660, 0x8690, 0x8710, 0x87C0, 0x88B0, 0x89E0, + 0x8BB0, 0x8D90, 0x9070, 0x93C0, 0x9890, 0x9E40, 0xA560, 0xADD0, 0xB7A0, 0xC3A0, 0xCF90, 0xDCA0, 0xE9F0, 0xF7D0, 0x0600, 0x14A0, + 0x22C0, 0x3180, 0x4130, 0x4FC0, 0x5D90, 0x6A10, 0x7560, 0x7DF0, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7EF0, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7EB0, 0x7F20, + 0x7F40, 0x7F30, 0x7F10, 0x7EC0, 0x7F10, 0x7EF0, 0x7EB0, 0x7EE0, 0x7E80, 0x7ED0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, 0x7F00, + 0x7F10, 0x7F30, 0x7EE0, 0x7F50, 0x7F00, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7F20, 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EF0, + 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7EF0, 0x7E70, 0x7ED0, + 0x7ED0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7F60, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7EA0, 0x7EF0, + 0x7B50, 0x7430, 0x6DC0, 0x6710, 0x6260, 0x5F60, 0x5CD0, 0x5B50, 0x5760, 0x5140, 0x4800, 0x3C50, 0x2FA0, 0x2150, 0x1510, 0x09D0, + 0xFF80, 0xF750, 0xEFB0, 0xE830, 0xDFE0, 0xD550, 0xC7F0, 0xB990, 0xA850, 0x96E0, 0x89C0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x85B0, 0x87B0, 0x8E00, + 0x97B0, 0xA1A0, 0xA970, 0xB020, 0xB5B0, 0xBA70, 0xBD10, 0xBE20, 0xBCB0, 0xBA80, 0xB6B0, 0xB320, 0xB060, 0xAD40, 0xAA10, 0xA7E0, + 0xA660, 0xA5B0, 0xA5F0, 0xA7A0, 0xAA10, 0xAC70, 0xAF60, 0xB1A0, 0xB510, 0xB940, 0xBE10, 0xC340, 0xC800, 0xCC90, 0xD0C0, 0xD2D0, + 0xD550, 0xD680, 0xD6B0, 0xD5C0, 0xD400, 0xD1D0, 0xCEE0, 0xCCF0, 0xCB80, 0xCA20, 0xC910, 0xC730, 0xC4A0, 0xC120, 0xBD30, 0xBA20, + 0xB730, 0xB3D0, 0xB170, 0xAE00, 0x9E70, 0x9B90, 0x9900, 0x9670, 0x9380, 0x9150, 0x8F80, 0x8EB0, 0x8F00, 0x9060, 0x9350, 0x9720, + 0x9BB0, 0xA180, 0xA990, 0xB320, 0xBE60, 0xCB70, 0xD7F0, 0xE420, 0xF210, 0xFF90, 0x0D90, 0x1B00, 0x2740, 0x33F0, 0x40B0, 0x4D00, + 0x5850, 0x62B0, 0x6D60, 0x7660, 0x7D90, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, + 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7ED0, 0x7F10, 0x7F00, 0x7EE0, 0x7F80, 0x7EF0, 0x7EE0, + 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, + 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F30, 0x7F00, + 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x7EF0, + 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F00, 0x7EC0, 0x7EC0, 0x7ED0, 0x7E80, 0x7D60, 0x7B80, 0x7A10, + 0x7930, 0x7780, 0x7690, 0x7500, 0x7440, 0x73D0, 0x7350, 0x73B0, 0x7400, 0x7440, 0x74B0, 0x74A0, 0x75A0, 0x7680, 0x77F0, 0x79E0, + 0x7AD0, 0x7BF0, 0x7D10, 0x7DE0, 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, + 0x7F10, 0x7F20, 0x7F70, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EB0, 0x7F00, + 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EF0, 0x7F20, 0x7EF0, 0x7E00, 0x7BB0, 0x79B0, 0x7780, 0x7610, 0x7460, 0x71E0, 0x6EF0, + 0x6C30, 0x6A40, 0x6800, 0x65D0, 0x6370, 0x6100, 0x5FA0, 0x5E10, 0x5C30, 0x5A80, 0x5790, 0x5570, 0x5330, 0x4FE0, 0x4D50, 0x49B0, + 0x46C0, 0x4400, 0x40F0, 0x3E60, 0x3C00, 0x3AD0, 0x3B50, 0x3CF0, 0x4040, 0x42C0, 0x45B0, 0x4800, 0x4A10, 0x4DB0, 0x5180, 0x5640, + 0x5AD0, 0x5E90, 0x62B0, 0x66A0, 0x6B30, 0x7030, 0x7460, 0x7950, 0x7D10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7F00, 0x7F00, + 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F30, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, + 0x7BF0, 0x69E0, 0x5A10, 0x48B0, 0x38A0, 0x29A0, 0x1BF0, 0x1100, 0x06A0, 0xFE40, 0xF690, 0xF0A0, 0xEAD0, 0xE770, 0xE550, 0xE3F0, + 0xE3F0, 0xE570, 0xE8C0, 0xECF0, 0xF220, 0xF780, 0xFC70, 0x00C0, 0x0410, 0x06C0, 0x0930, 0x0A30, 0x0AB0, 0x09F0, 0x0830, 0x04F0, + 0x00D0, 0xFAE0, 0xF3B0, 0xECE0, 0xE610, 0xE000, 0xD930, 0xD1D0, 0xC790, 0xB900, 0xA320, 0x8940, 0x84E0, 0x8490, 0x8470, 0x8450, + 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8430, 0x8440, 0x8460, 0x8470, 0x8490, 0x84C0, 0x84E0, 0x8500, 0x8520, 0x8550, 0x85E0, 0x8790, 0x8DE0, 0x9840, 0x9F50, + 0x9F10, 0x9950, 0x8F70, 0x8830, 0x8590, 0x8510, 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84A0, 0x84C0, 0x84C0, 0x84D0, + 0x84F0, 0x8510, 0x8540, 0x85D0, 0x86F0, 0x8950, 0x8DC0, 0x9250, 0x96B0, 0x98B0, 0x99A0, 0x9900, 0x9720, 0x9540, 0x93B0, 0x92F0, + 0x9250, 0x9240, 0x9270, 0x9230, 0x9200, 0x9160, 0x90D0, 0x9090, 0x9000, 0x8FE0, 0x8FC0, 0x9060, 0x9080, 0x9100, 0x9060, 0x8F40, + 0x8DE0, 0x8BA0, 0x89A0, 0x8840, 0x8760, 0x86D0, 0x8650, 0x85F0, 0x85A0, 0x8590, 0x8530, 0x8510, 0x84F0, 0x84F0, 0x84E0, 0x84D0, + 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8470, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x84A0, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, + 0x8490, 0x84B0, 0x8490, 0x84A0, 0x8470, 0x84B0, 0x84C0, 0x84F0, 0x84E0, 0x8500, 0x8520, 0x8590, 0x85E0, 0x86F0, 0x88D0, 0x8CB0, + 0x91F0, 0x9760, 0x9D40, 0xA230, 0xA780, 0xACB0, 0xB180, 0xB540, 0xB8B0, 0xBB60, 0xBE80, 0xC1D0, 0xC5E0, 0xCA40, 0xCE50, 0xD300, + 0xD6E0, 0xDB10, 0xDF00, 0xE260, 0xE680, 0xE9F0, 0xED50, 0xF160, 0xF440, 0xF7D0, 0xFA30, 0xFCC0, 0xFD90, 0xFDF0, 0xFF10, 0x0020, + 0x0060, 0x00F0, 0x0020, 0xFEF0, 0xFCF0, 0xFA90, 0xF8A0, 0xF690, 0xF530, 0xF3E0, 0xF240, 0xF1E0, 0xEFF0, 0xEDE0, 0xEAF0, 0xE890, + 0xE770, 0xE560, 0xE490, 0xE410, 0xE400, 0xE420, 0xE350, 0xE360, 0xE3E0, 0xE3A0, 0xE520, 0xE700, 0xE960, 0xECC0, 0xF010, 0xF4C0, + 0xF900, 0xFEB0, 0x0430, 0x0A20, 0x1050, 0x1710, 0x1DF0, 0x25C0, 0x2C10, 0x33F0, 0x3BC0, 0x42F0, 0x4A10, 0x50E0, 0x5800, 0x5EF0, + 0x65E0, 0x6BA0, 0x7190, 0x76F0, 0x7BB0, 0x7EE0, 0x7EF0, 0x7EB0, 0x7EF0, 0x7F10, 0x7F70, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, + 0x7EE0, 0x7EC0, 0x7F20, 0x7F20, 0x7F40, 0x7ED0, 0x7EA0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, + 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F50, + 0x7F10, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7E80, 0x7EB0, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, 0x7F10, 0x7F10, + 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, + 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EE0, 0x7F10, 0x7F30, + 0x7F10, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, + 0x7F70, 0x7F10, 0x7EB0, 0x7F00, 0x7B90, 0x7530, 0x6F70, 0x68A0, 0x6210, 0x5A80, 0x5070, 0x4580, 0x3720, 0x28C0, 0x1940, 0x0770, + 0xF650, 0xE330, 0xD090, 0xBD80, 0xAB20, 0x9960, 0x8C70, 0x86D0, 0x8560, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, + 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8480, + 0x8480, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8490, 0x8480, 0x8480, 0x8480, 0x84B0, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8510, 0x8560, 0x85F0, 0x8770, 0x8B00, + 0x9250, 0x9AA0, 0xA1D0, 0xA910, 0xB020, 0xB760, 0xBED0, 0xC430, 0xC9A0, 0xCCF0, 0xD050, 0xD370, 0xD610, 0xD900, 0xDB50, 0xDD60, + 0xDF60, 0xE110, 0xE3D0, 0xE620, 0xE850, 0xEAF0, 0xED80, 0xF140, 0xF550, 0xF9D0, 0xFF40, 0x0490, 0x0A50, 0x10A0, 0x1570, 0x1AF0, + 0x1FD0, 0x25A0, 0x2B60, 0x3180, 0x37A0, 0x3D20, 0x42D0, 0x47D0, 0x4C10, 0x50E0, 0x5450, 0x57B0, 0x59A0, 0x5AF0, 0x5C50, 0x5D30, + 0x5E60, 0x5F80, 0x5F90, 0x6000, 0x5F40, 0x5EB0, 0x5E20, 0x5D60, 0x5D40, 0x5CF0, 0x5C30, 0x5C00, 0x5AF0, 0x5AE0, 0x5AC0, 0x59D0, + 0x5990, 0x5830, 0x56E0, 0x54C0, 0x5250, 0x5060, 0x4DC0, 0x4B90, 0x49D0, 0x47E0, 0x4790, 0x4780, 0x4910, 0x4B00, 0x4CF0, 0x4F30, + 0x5040, 0x5150, 0x5250, 0x53E0, 0x5700, 0x59C0, 0x5CD0, 0x5F20, 0x60D0, 0x6350, 0x6670, 0x6970, 0x6CE0, 0x7030, 0x7310, 0x74E0, + 0x76B0, 0x77E0, 0x7900, 0x7A00, 0x79D0, 0x7930, 0x77E0, 0x7590, 0x7350, 0x7070, 0x6DD0, 0x6A80, 0x6660, 0x62C0, 0x5E50, 0x59D0, + 0x55A0, 0x5020, 0x4B10, 0x45E0, 0x4000, 0x3A80, 0x3480, 0x2F00, 0x2A40, 0x2530, 0x20D0, 0x1BA0, 0x1680, 0x1190, 0x0C70, 0x08E0, + 0x0490, 0xFFF0, 0xFC30, 0xF870, 0xF4F0, 0xF200, 0xF040, 0xEEE0, 0xED80, 0xEE30, 0xEEE0, 0xEE40, 0xEEF0, 0xEF50, 0xF0A0, 0xF1F0, + 0xF3A0, 0xF590, 0xF790, 0xF9C0, 0xFC10, 0xFED0, 0x00E0, 0x02D0, 0x0450, 0x0610, 0x07A0, 0x0910, 0x0AF0, 0x0C00, 0x0CE0, 0x0DB0, + 0x0E80, 0x1030, 0x1260, 0x1510, 0x1750, 0x1950, 0x1A50, 0x1AF0, 0x1C20, 0x1DA0, 0x1F10, 0x20F0, 0x2300, 0x2560, 0x27F0, 0x2980, + 0x2B20, 0x2CD0, 0x2E10, 0x2EB0, 0x2EB0, 0x2E90, 0x2E30, 0x2DE0, 0x2DE0, 0x2E50, 0x2E70, 0x2E30, 0x2DD0, 0x2CB0, 0x2D00, 0x2C60, + 0x2B10, 0x29B0, 0x2800, 0x2620, 0x23F0, 0x2230, 0x21B0, 0x21E0, 0x2150, 0x21B0, 0x2250, 0x2350, 0x2450, 0x2560, 0x2680, 0x27D0, + 0x2910, 0x2A70, 0x2C00, 0x2E50, 0x3050, 0x31A0, 0x3310, 0x3410, 0x33B0, 0x3340, 0x3270, 0x3160, 0x3010, 0x2E70, 0x2C40, 0x29F0, + 0x2710, 0x2400, 0x20E0, 0x1DD0, 0x19E0, 0x1650, 0x1350, 0x1070, 0x0E70, 0x0CC0, 0x0C10, 0x0BB0, 0x0B00, 0x0A90, 0x0A70, 0x09A0, + 0x0900, 0x0870, 0x07A0, 0x06A0, 0x0500, 0x0350, 0x0040, 0xFD40, 0xFAD0, 0xF870, 0xF680, 0xF470, 0xF230, 0xEFD0, 0xECD0, 0xE990, + 0xE610, 0xE230, 0xDE90, 0xDA90, 0xD630, 0xD1D0, 0xCD00, 0xC880, 0xC3E0, 0xBF00, 0xBAE0, 0xB5E0, 0xB180, 0xAD70, 0xA960, 0xA5A0, + 0xA1B0, 0x9E60, 0x9B40, 0x9990, 0x9880, 0x98C0, 0x99D0, 0x9A80, 0x9B90, 0x9BF0, 0x9CB0, 0x9D80, 0x9EA0, 0xA090, 0xA2E0, 0xA530, + 0xA800, 0xAB10, 0xAD90, 0xB060, 0xB360, 0xB580, 0xB860, 0xBAA0, 0xBCA0, 0xBED0, 0xC180, 0xC400, 0xC6B0, 0xC790, 0xC7B0, 0xC7A0, + 0xC6F0, 0xC650, 0xC5F0, 0xC580, 0xC4E0, 0xC460, 0xC380, 0xC250, 0xC110, 0xBFB0, 0xBEE0, 0xBD80, 0xBC60, 0xBB30, 0xB950, 0xB7D0, + 0xB5C0, 0xB400, 0xB1F0, 0xAEF0, 0xAC60, 0xA970, 0xA6B0, 0xA350, 0x9FB0, 0x9BA0, 0x96A0, 0x9170, 0x8CB0, 0x8940, 0x8740, 0x8610, + 0x8580, 0x8540, 0x8510, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8480, 0x8470, 0x84A0, 0x8480, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84D0, 0x84F0, 0x8530, 0x85C0, 0x88C0, 0x90F0, 0x9CB0, + 0xA680, 0xB010, 0xB7D0, 0xBF50, 0xC530, 0xCA50, 0xCED0, 0xD200, 0xD530, 0xD7D0, 0xDA20, 0xDC90, 0xDE00, 0xDFE0, 0xE1A0, 0xE2E0, + 0xE510, 0xE6A0, 0xE7E0, 0xEA80, 0xEC30, 0xEEE0, 0xF1E0, 0xF3B0, 0xF660, 0xF840, 0xFA70, 0xFC30, 0xFE20, 0x00B0, 0x0310, 0x0690, + 0x0920, 0x0B50, 0x0D10, 0x0DA0, 0x0DC0, 0x0E00, 0x0D50, 0x0CC0, 0x0B10, 0x08F0, 0x0670, 0x0370, 0x0140, 0xFF50, 0xFDA0, 0xFCE0, + 0xFBD0, 0xFBB0, 0xFAA0, 0xF9D0, 0xF850, 0xF7B0, 0xF760, 0xF690, 0xF5E0, 0xF580, 0xF550, 0xF5C0, 0xF650, 0xF720, 0xF900, 0xFB30, + 0xFDC0, 0x00E0, 0x04B0, 0x08B0, 0x0CF0, 0x11C0, 0x1650, 0x1AB0, 0x1FA0, 0x24D0, 0x2A80, 0x2F60, 0x3410, 0x3A00, 0x3F30, 0x44A0, + 0x4A50, 0x4ED0, 0x5470, 0x5900, 0x5D50, 0x61E0, 0x65E0, 0x6A60, 0x6E10, 0x71B0, 0x7530, 0x7810, 0x7AB0, 0x7C70, 0x7E40, 0x7ED0, + 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F20, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, + 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F30, 0x7F20, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, + 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7EC0, + 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F50, + 0x7F00, 0x7F20, 0x7ED0, 0x7F10, 0x7F60, 0x7EE0, 0x7EC0, 0x7F10, 0x7EF0, 0x7F70, 0x7EF0, 0x7EB0, 0x7EC0, 0x7E10, 0x7CB0, 0x7C20, + 0x7B40, 0x7B50, 0x7AF0, 0x7AA0, 0x7AD0, 0x7A00, 0x79C0, 0x79E0, 0x7910, 0x76B0, 0x75B0, 0x74E0, 0x7400, 0x7280, 0x7220, 0x70C0, + 0x70D0, 0x70B0, 0x7070, 0x7110, 0x7100, 0x7290, 0x73B0, 0x7520, 0x77C0, 0x7A40, 0x7D00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, + 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7E40, 0x79D0, 0x7530, 0x6FE0, 0x6A10, + 0x6330, 0x5C00, 0x5310, 0x48D0, 0x3DD0, 0x31E0, 0x25C0, 0x18F0, 0x0A20, 0xFBD0, 0xED10, 0xE000, 0xD360, 0xC7B0, 0xBCC0, 0xB2B0, + 0xA8A0, 0x9F30, 0x9660, 0x8E90, 0x8980, 0x86D0, 0x85B0, 0x8530, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, + 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8500, 0x8530, 0x8510, + 0x8510, 0x8520, 0x84F0, 0x8530, 0x8520, 0x8520, 0x84C0, 0x8500, 0x84F0, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x8490, 0x84F0, 0x84E0, + 0x84F0, 0x84D0, 0x84C0, 0x84C0, 0x84D0, 0x84B0, 0x8490, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x8490, 0x84B0, + 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84C0, 0x84E0, 0x84B0, 0x84B0, 0x84F0, 0x84C0, 0x84D0, 0x84E0, 0x8510, 0x84E0, + 0x84F0, 0x84F0, 0x8510, 0x8520, 0x8530, 0x8550, 0x8560, 0x8570, 0x8580, 0x8590, 0x8590, 0x8580, 0x85A0, 0x8570, 0x8560, 0x8550, + 0x8550, 0x8530, 0x8530, 0x8520, 0x8510, 0x8510, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8510, 0x8530, + 0x8550, 0x85A0, 0x8640, 0x87B0, 0x8BD0, 0x94C0, 0x9FE0, 0xABE0, 0xB9E0, 0xC750, 0xD560, 0xE300, 0xF070, 0xFCD0, 0x08D0, 0x1400, + 0x1EE0, 0x2D30, 0x3940, 0x4620, 0x5270, 0x5E80, 0x69E0, 0x7410, 0x7CF0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7F40, 0x7F30, + 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x76A0, 0x6B60, 0x5F90, 0x54E0, 0x4AC0, 0x4180, 0x39D0, 0x34D0, 0x3220, + 0x3180, 0x3200, 0x3230, 0x3140, 0x2E50, 0x29D0, 0x2520, 0x2070, 0x1CD0, 0x1990, 0x1640, 0x1320, 0x0F50, 0x0B00, 0x0630, 0x01F0, + 0xFC40, 0xF7D0, 0xF510, 0xF420, 0xF6B0, 0xFBF0, 0x01A0, 0x0680, 0x09D0, 0x0990, 0x0760, 0x0320, 0xFE00, 0xF920, 0xF5F0, 0xF3D0, + 0xF230, 0xF0D0, 0xEF70, 0xED90, 0xEBC0, 0xE9B0, 0xE810, 0xE660, 0xE600, 0xE700, 0xEA00, 0xED50, 0xEFF0, 0xEFC0, 0xEB60, 0xE230, + 0xD690, 0xC960, 0xBD40, 0xB230, 0xA9D0, 0xA460, 0x9FC0, 0x9D70, 0x9CD0, 0x9E30, 0xA000, 0xA2B0, 0xA640, 0xA910, 0xABF0, 0xAE80, + 0xB180, 0xB450, 0xB710, 0xB900, 0xBA50, 0xBAD0, 0xBB50, 0xBC60, 0xBD80, 0xBF70, 0xC2E0, 0xC6A0, 0xCA60, 0xCD20, 0xCF10, 0xCFA0, + 0xCE30, 0xCAF0, 0xC5B0, 0xBDB0, 0xB310, 0xA530, 0x9500, 0x8870, 0x8540, 0x84E0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8470, 0x8450, 0x8440, 0x8450, 0x8440, 0x8450, 0x8440, 0x8440, 0x83E0, 0x8440, 0x8440, + 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8430, 0x8460, 0x8440, 0x8440, 0x8440, 0x8460, 0x8440, 0x8440, 0x8430, 0x8440, + 0x8430, 0x8430, 0x83E0, 0x8430, 0x8430, 0x8430, 0x83E0, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8400, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8440, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8420, 0x8440, 0x8430, 0x8430, 0x83F0, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, + 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84F0, 0x8560, 0x8970, 0x94E0, 0x9C40, 0x9E50, 0x9C20, 0x95B0, + 0x8D60, 0x87C0, 0x8590, 0x8500, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8490, 0x84A0, 0x84A0, 0x84C0, 0x84F0, 0x8590, 0x8910, 0x9D10, 0xB280, 0xC670, 0xD860, 0xE820, 0xF510, 0x00E0, 0x0980, + 0x10C0, 0x1650, 0x1A60, 0x1D20, 0x2010, 0x2230, 0x2360, 0x2480, 0x24F0, 0x2520, 0x25A0, 0x2570, 0x2630, 0x2620, 0x2760, 0x2830, + 0x28E0, 0x2A40, 0x2B50, 0x2C90, 0x2E30, 0x3040, 0x3390, 0x3780, 0x3BF0, 0x4140, 0x4630, 0x4B80, 0x5060, 0x5510, 0x62C0, 0x6600, + 0x6880, 0x6A20, 0x6CC0, 0x6EC0, 0x7110, 0x7360, 0x75F0, 0x7910, 0x7B20, 0x7CA0, 0x7D80, 0x7E30, 0x7E70, 0x7EC0, 0x7F50, 0x7F10, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7ED0, 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, + 0x7ED0, 0x7F10, 0x7F00, 0x7F10, 0x7E90, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, + 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, + 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7EB0, + 0x7F00, 0x7F20, 0x7F40, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F00, 0x7F30, + 0x7EE0, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, + 0x7EF0, 0x7F00, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7EF0, 0x7ED0, 0x7F30, 0x7F00, 0x7EA0, 0x7ED0, 0x7EE0, 0x6FC0, 0x5AB0, 0x4400, + 0x2E20, 0x1860, 0x03F0, 0xF230, 0xE1E0, 0xD330, 0xC790, 0xBDF0, 0xB780, 0xB330, 0xB1C0, 0xB440, 0xB9A0, 0xC1B0, 0xCD40, 0xDA90, + 0xE940, 0xF850, 0x07A0, 0x1580, 0x2110, 0x2AB0, 0x3220, 0x3850, 0x4610, 0x4920, 0x4BA0, 0x4D90, 0x5020, 0x5180, 0x5340, 0x53B0, + 0x5460, 0x55C0, 0x56C0, 0x5890, 0x5B40, 0x5D40, 0x6010, 0x6230, 0x6440, 0x66A0, 0x6880, 0x6AB0, 0x6CE0, 0x6E70, 0x7010, 0x70B0, + 0x7120, 0x70E0, 0x7060, 0x6F80, 0x6DC0, 0x6C30, 0x6A70, 0x68F0, 0x6800, 0x65F0, 0x64A0, 0x61D0, 0x5E90, 0x5B00, 0x55E0, 0x5160, + 0x4BD0, 0x45B0, 0x4030, 0x3A10, 0x33A0, 0x2D20, 0x2740, 0x2240, 0x1CA0, 0x1720, 0x1250, 0x0D10, 0x0890, 0x0340, 0xFF10, 0xFB90, + 0xF7E0, 0xF550, 0xF290, 0xF090, 0xEE40, 0xEBA0, 0xE9B0, 0xE800, 0xE650, 0xE580, 0xE460, 0xE4C0, 0xE550, 0xE680, 0xE790, 0xE8E0, + 0xEA00, 0xEB30, 0xEC40, 0xED20, 0xEF50, 0xF290, 0xF5A0, 0xF850, 0xFBA0, 0xFD60, 0xFF10, 0x00B0, 0x01E0, 0x0420, 0x0660, 0x08C0, + 0x0AF0, 0x0CF0, 0x0E70, 0x0F10, 0x1070, 0x1240, 0x1480, 0x1730, 0x1980, 0x1BE0, 0x1DB0, 0x1EA0, 0x2020, 0x2190, 0x2370, 0x2460, + 0x2540, 0x2670, 0x26C0, 0x27C0, 0x2750, 0x25B0, 0x2440, 0x2250, 0x2070, 0x1EB0, 0x1CC0, 0x1BA0, 0x1930, 0x1760, 0x1650, 0x15C0, + 0x1770, 0x1A60, 0x1ED0, 0x2770, 0x3010, 0x39D0, 0x4520, 0x50E0, 0x5C40, 0x66D0, 0x6FB0, 0x7620, 0x7AE0, 0x7DC0, 0x7ED0, 0x7F00, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F40, 0x7F30, + 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F60, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7E60, 0x7A30, 0x7670, 0x7340, 0x7040, 0x6CB0, 0x6820, 0x6240, 0x5AB0, 0x5290, 0x4AD0, 0x45F0, 0x42F0, 0x4220, 0x4300, 0x44F0, + 0x47B0, 0x4B00, 0x4EA0, 0x5330, 0x5740, 0x5C40, 0x6120, 0x6590, 0x6AB0, 0x6F40, 0x7360, 0x76D0, 0x7960, 0x7A40, 0x7970, 0x7710, + 0x7360, 0x6F40, 0x6A30, 0x64F0, 0x5F60, 0x5880, 0x5230, 0x4B90, 0x44C0, 0x3E00, 0x36B0, 0x3010, 0x29E0, 0x2540, 0x2100, 0x1EC0, + 0x1D90, 0x1D80, 0x1DB0, 0x1EC0, 0x20A0, 0x2350, 0x2650, 0x28C0, 0x29D0, 0x2890, 0x24D0, 0x1FE0, 0x1990, 0x12D0, 0x0BB0, 0x0320, + 0xF950, 0xED30, 0xE060, 0xD230, 0xC330, 0xB520, 0xA720, 0x9A50, 0x8FD0, 0x8920, 0x86A0, 0x85B0, 0x8540, 0x8500, 0x84E0, 0x84D0, + 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8550, 0x85D0, 0x8700, 0x89C0, 0x8F90, 0x96F0, 0x9EA0, 0xA5A0, 0xACD0, + 0xB490, 0xBB20, 0xC110, 0xC620, 0xC980, 0xCDC0, 0xD110, 0xD4C0, 0xD880, 0xDAB0, 0xDD80, 0xDF30, 0xE0F0, 0xE240, 0xE350, 0xE640, + 0xE8C0, 0xEB40, 0xEF20, 0xF2C0, 0xF790, 0xFC90, 0x02D0, 0x0900, 0x0FD0, 0x16D0, 0x1D40, 0x23C0, 0x2AD0, 0x3130, 0x3820, 0x3DC0, + 0x4370, 0x4960, 0x4DF0, 0x53B0, 0x58B0, 0x5D60, 0x6190, 0x64F0, 0x67B0, 0x6960, 0x69F0, 0x6A00, 0x67E0, 0x6590, 0x6130, 0x5B30, + 0x5470, 0x4C00, 0x43D0, 0x3B00, 0x30B0, 0x2750, 0x1E60, 0x15C0, 0x0EE0, 0x0890, 0x0460, 0x0100, 0xFDD0, 0xFC20, 0xFB20, 0xFA70, + 0xFAA0, 0xFA60, 0xFA60, 0xF9E0, 0xF9B0, 0xF900, 0xF850, 0xF880, 0xF880, 0xF9A0, 0xF9B0, 0xF990, 0xFAB0, 0xFBA0, 0xFDD0, 0x0020, + 0x0300, 0x0680, 0x0950, 0x0D30, 0x11A0, 0x16D0, 0x1C50, 0x2270, 0x2940, 0x2F80, 0x35E0, 0x3C80, 0x4340, 0x4A30, 0x5190, 0x5760, + 0x5D80, 0x61B0, 0x65A0, 0x6890, 0x6AC0, 0x6D00, 0x6E00, 0x6E50, 0x6E90, 0x6DC0, 0x6D80, 0x6C90, 0x6C00, 0x6A70, 0x6890, 0x67B0, + 0x6620, 0x6500, 0x64D0, 0x64C0, 0x6720, 0x68F0, 0x6C50, 0x7070, 0x75C0, 0x7C40, 0x7EF0, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, + 0x7F80, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F10, 0x7F70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F20, 0x7F60, 0x7EE0, 0x7E90, 0x7F00, 0x7F10, 0x7F30, + 0x7EF0, 0x7F60, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, + 0x7F20, 0x7EE0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F30, 0x7AE0, 0x6E40, 0x61D0, 0x5490, 0x46B0, 0x3A70, 0x2D30, 0x22A0, 0x1960, 0x10C0, + 0x0990, 0x0420, 0x0060, 0xFE40, 0xFC80, 0xFBA0, 0xFBA0, 0xFC80, 0xFD50, 0xFD70, 0xFD50, 0xFB70, 0xF870, 0xF440, 0xEE60, 0xE920, + 0xE320, 0xDDE0, 0xD9F0, 0xD7B0, 0xD6E0, 0xD7C0, 0xD910, 0xDA60, 0xDB40, 0xDB60, 0xDB30, 0xDBC0, 0xDBE0, 0xDC50, 0xDDD0, 0xE060, + 0xE2B0, 0xE600, 0xE910, 0xED40, 0xF110, 0xF560, 0xFA00, 0xFE10, 0x02D0, 0x0640, 0x08D0, 0x0BF0, 0x0E00, 0x0FA0, 0x10C0, 0x1050, + 0x1060, 0x0FC0, 0x0EA0, 0x0CA0, 0x0A00, 0x0790, 0x05F0, 0x02E0, 0x0060, 0xFD30, 0xFA50, 0xF6A0, 0xF2B0, 0xEF30, 0xEC20, 0xE940, + 0xE610, 0xE3F0, 0xE260, 0xE0E0, 0xDFB0, 0xDEA0, 0xDD90, 0xDC70, 0xDB10, 0xD940, 0xD5E0, 0xD270, 0xD000, 0xCE20, 0xCD50, 0xCF10, + 0xD1A0, 0xD500, 0xD8C0, 0xDCE0, 0xDF40, 0xE210, 0xE590, 0xE920, 0xEDF0, 0xF3D0, 0xFA30, 0x0170, 0x0840, 0x0EF0, 0x14F0, 0x19A0, + 0x1D10, 0x2000, 0x21F0, 0x2500, 0x2850, 0x2CF0, 0x3260, 0x3870, 0x3FF0, 0x4670, 0x4D90, 0x5490, 0x5A60, 0x5FC0, 0x6460, 0x6990, + 0x6E70, 0x73A0, 0x7790, 0x7B10, 0x7DA0, 0x7EC0, 0x7F50, 0x7F20, 0x7EE0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7D90, 0x7C60, + 0x7BF0, 0x7C90, 0x7D80, 0x7EC0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7B30, + 0x7790, 0x7400, 0x70E0, 0x6E10, 0x6BB0, 0x6A00, 0x6900, 0x6830, 0x6770, 0x66C0, 0x6710, 0x67A0, 0x6920, 0x6A50, 0x6BA0, 0x6D40, + 0x6EF0, 0x70B0, 0x71B0, 0x7260, 0x72D0, 0x7250, 0x7130, 0x6F90, 0x6CF0, 0x6A90, 0x67E0, 0x6480, 0x6150, 0x5D70, 0x59A0, 0x54C0, + 0x4EF0, 0x4B60, 0x4790, 0x45B0, 0x4500, 0x45F0, 0x4990, 0x5000, 0x5770, 0x5F90, 0x6530, 0x6930, 0x6AC0, 0x6BC0, 0x6B50, 0x6A60, + 0x6A00, 0x6980, 0x68A0, 0x67A0, 0x6450, 0x6050, 0x59A0, 0x2DA0, 0x1E80, 0x1000, 0x0360, 0xF590, 0xE990, 0xDE30, 0xD2D0, 0xC700, + 0xBA10, 0xACE0, 0x9F90, 0x9420, 0x8C30, 0x8860, 0x86F0, 0x8610, 0x85D0, 0x85B0, 0x8590, 0x8590, 0x8560, 0x8540, 0x8540, 0x8530, + 0x8530, 0x8530, 0x8530, 0x8540, 0x8540, 0x8550, 0x8560, 0x8560, 0x8570, 0x8570, 0x8570, 0x8560, 0x8550, 0x8540, 0x8530, 0x8520, + 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84D0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, + 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x8520, 0x8530, 0x8560, 0x8590, 0x85E0, 0x8640, 0x86F0, 0x87D0, 0x88E0, + 0x8A60, 0x8C20, 0x8E50, 0x9050, 0x9240, 0x93D0, 0x9520, 0x9660, 0x97B0, 0x98C0, 0x9940, 0x9930, 0x9930, 0x9890, 0x9880, 0x97D0, + 0x97A0, 0x9780, 0x9760, 0x96B0, 0x9560, 0x94E0, 0x9460, 0x93D0, 0x93E0, 0x93B0, 0x93E0, 0x93B0, 0x9410, 0x94A0, 0x95B0, 0x96C0, + 0x98B0, 0x99E0, 0x9BA0, 0x9D70, 0x9FC0, 0xA250, 0xA5B0, 0xA8A0, 0xAB80, 0xAE00, 0xB150, 0xB520, 0xB970, 0xBDC0, 0xC110, 0xC440, + 0xC690, 0xC890, 0xCA30, 0xCD20, 0xCFA0, 0xD2F0, 0xD600, 0xD940, 0xDC30, 0xDE60, 0xE0E0, 0xE310, 0xE530, 0xE7E0, 0xEA60, 0xEC80, + 0xEDD0, 0xEE60, 0xEE70, 0xEDD0, 0xEC70, 0xEA70, 0xE7B0, 0xE430, 0xE010, 0xDB80, 0xD5D0, 0xD0C0, 0xCBB0, 0xC760, 0xC380, 0xBE70, + 0xB8D0, 0xB350, 0xAD40, 0xA6A0, 0xA0F0, 0x9BD0, 0x9690, 0x9200, 0x8DB0, 0x8AA0, 0x88A0, 0x8750, 0x8680, 0x8600, 0x85B0, 0x8580, + 0x8560, 0x8540, 0x8530, 0x8530, 0x8530, 0x8520, 0x8520, 0x8530, 0x8530, 0x8530, 0x8530, 0x8540, 0x8550, 0x8550, 0x8570, 0x8590, + 0x85C0, 0x85E0, 0x8620, 0x8660, 0x86B0, 0x8710, 0x87C0, 0x8880, 0x89E0, 0x8B80, 0x8D30, 0x8F80, 0x9210, 0x9590, 0x98F0, 0x9CC0, + 0xA100, 0xA4C0, 0xA990, 0xAE50, 0xB3F0, 0xBA50, 0xC0B0, 0xC790, 0xCE00, 0xD500, 0xDB40, 0xE130, 0xE770, 0xECD0, 0xF1E0, 0xF6F0, + 0xFAF0, 0xFF30, 0x0340, 0x06B0, 0x0A10, 0x0C80, 0x0F90, 0x1190, 0x1370, 0x1660, 0x1980, 0x1DF0, 0x22E0, 0x26B0, 0x2A80, 0x2DA0, + 0x3180, 0x34C0, 0x36D0, 0x38E0, 0x3940, 0x38D0, 0x3760, 0x3520, 0x31F0, 0x2E00, 0x2A40, 0x25E0, 0x2010, 0x1B00, 0x1560, 0x0FD0, + 0x0A50, 0x0530, 0x0040, 0xFA40, 0xF410, 0xEDD0, 0xE680, 0xE070, 0xD980, 0xD220, 0xCAB0, 0xC2B0, 0xBB80, 0xB3A0, 0xACA0, 0xA670, + 0xA110, 0x9C70, 0x9800, 0x9460, 0x9120, 0x8ED0, 0x8D50, 0x8CE0, 0x8D10, 0x8DB0, 0x8E70, 0x9050, 0x9240, 0x94E0, 0x9800, 0x9B00, + 0x9DD0, 0xA120, 0xA430, 0xA850, 0xABD0, 0xB040, 0xB3D0, 0xB6F0, 0xBA70, 0xBD80, 0xC080, 0xC420, 0xC780, 0xCB60, 0xCE90, 0xD1A0, + 0xD4A0, 0xD710, 0xDA60, 0xDD60, 0xDFF0, 0xE1B0, 0xE2A0, 0xE380, 0xE3A0, 0xE3D0, 0xE4B0, 0xE4E0, 0xE580, 0xE550, 0xE570, 0xE530, + 0xE530, 0xE580, 0xE580, 0xE4C0, 0xE410, 0xE2C0, 0xE1B0, 0xE170, 0xE090, 0xDFF0, 0xDDB0, 0xDBE0, 0xDA00, 0xD7E0, 0xD680, 0xD550, + 0xD480, 0xD350, 0xD180, 0xCF50, 0xCC60, 0xCA90, 0xC880, 0xC720, 0xC5F0, 0xC510, 0xC4D0, 0xC520, 0xC770, 0xCC60, 0xD320, 0xDE40, + 0xEC70, 0xFC30, 0x5030, 0x6230, 0x72F0, 0x7D70, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7E90, + 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, + 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F10, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, + 0x7E90, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7EB0, 0x7B80, 0x78C0, 0x7590, 0x7290, 0x7040, 0x6C30, 0x69B0, 0x66C0, 0x63F0, + 0x6180, 0x5E40, 0x5BA0, 0x5710, 0x51D0, 0x4BC0, 0x4550, 0x3FF0, 0x3A30, 0x34F0, 0x30F0, 0x2CA0, 0x29A0, 0x2760, 0x2550, 0x2410, + 0x22E0, 0x2180, 0x2030, 0x1E70, 0x1DC0, 0x1D10, 0x1D80, 0x1E60, 0x1F50, 0x20E0, 0x2180, 0x2380, 0x2550, 0x26B0, 0x28B0, 0x2A00, + 0x2A80, 0x2AB0, 0x2A20, 0x2A10, 0x2A40, 0x2A80, 0x29F0, 0x2810, 0x2610, 0x2200, 0x1E50, 0x1AB0, 0x1660, 0x1250, 0x0D80, 0x07F0, + 0x0270, 0xFD40, 0xF920, 0xF520, 0xF0F0, 0xEC90, 0xE750, 0xE1C0, 0xDBC0, 0xD590, 0xCF80, 0xC7F0, 0xBFE0, 0xB6A0, 0xACF0, 0xA240, + 0x9690, 0x8C50, 0x8730, 0x8570, 0x8500, 0x8490, 0x84C0, 0x84B0, 0x84A0, 0x8430, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84B0, + 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84C0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8550, 0x8590, 0x85E0, 0x8650, 0x86F0, + 0x8790, 0x8850, 0x8930, 0x8A30, 0x8BA0, 0x8D10, 0x8EC0, 0x90E0, 0x92F0, 0x9560, 0x9810, 0x9BC0, 0x9ED0, 0xA1F0, 0xA520, 0xA850, + 0xAB50, 0xADB0, 0xB030, 0xB290, 0xB420, 0xB5A0, 0xB650, 0xB690, 0xB670, 0xB640, 0xB5A0, 0xB4E0, 0xB340, 0xB110, 0xAEC0, 0xAC60, + 0xAA80, 0xA810, 0xA610, 0xA330, 0xA070, 0x9CD0, 0x98B0, 0x9580, 0x9280, 0x8F80, 0x8CE0, 0x8B30, 0x8A20, 0x8930, 0x8850, 0x87A0, + 0x8710, 0x86B0, 0x8670, 0x8650, 0x8630, 0x8630, 0x8640, 0x8650, 0x8660, 0x86B0, 0x8700, 0x8760, 0x87A0, 0x8810, 0x88C0, 0x8930, + 0x8A40, 0x8B30, 0x8C00, 0x8D10, 0x8E60, 0x8FC0, 0x9190, 0x9330, 0x9500, 0x9650, 0x9820, 0x9990, 0x9B20, 0x9CF0, 0x9F50, 0xA120, + 0xA330, 0xA500, 0xA680, 0xA890, 0xA9D0, 0xABB0, 0xAD00, 0xADF0, 0xAE20, 0xAE30, 0xAE70, 0xAE50, 0xAE90, 0xAE10, 0xADE0, 0xAD60, + 0xAD00, 0xACD0, 0xAD10, 0xAD60, 0xAD70, 0xADC0, 0xAE70, 0xAF00, 0xB040, 0xB1A0, 0xB370, 0xB5D0, 0xB880, 0xBAE0, 0xBEA0, 0xC2A0, + 0xC7C0, 0xCDD0, 0xD440, 0xDBE0, 0xE3F0, 0xEB40, 0x06E0, 0x0DF0, 0x1410, 0x1A60, 0x2130, 0x2790, 0x2EE0, 0x36F0, 0x3ED0, 0x46C0, + 0x4F10, 0x5750, 0x5EE0, 0x6720, 0x6F50, 0x7670, 0x7C90, 0x7F10, 0x7F30, 0x7F40, 0x7F40, 0x7F50, 0x7F30, 0x7F40, 0x7F40, 0x7F30, + 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7CA0, 0x7360, 0x6AB0, 0x6230, 0x5A30, 0x5260, 0x4B90, 0x44F0, 0x3D60, 0x36C0, 0x3070, 0x2B20, 0x2740, 0x24C0, + 0x22F0, 0x21F0, 0x2140, 0x2180, 0x2190, 0x2280, 0x2340, 0x23F0, 0x2490, 0x25C0, 0x2750, 0x2910, 0x2B20, 0x2D40, 0x2F30, 0x3170, + 0x3360, 0x3560, 0x3680, 0x37D0, 0x38C0, 0x3970, 0x39E0, 0x39F0, 0x3A80, 0x3AF0, 0x3B90, 0x3BE0, 0x3C40, 0x3C80, 0x3C00, 0x3A40, + 0x3800, 0x3480, 0x2FF0, 0x2980, 0x2090, 0x1640, 0x0A10, 0xFBF0, 0xEE70, 0xE0D0, 0xD420, 0xC7F0, 0xBD10, 0xB270, 0xA830, 0x9F60, + 0x9630, 0x8F30, 0x8A90, 0x8800, 0x86A0, 0x85F0, 0x8590, 0x8550, 0x8530, 0x8510, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, 0x8500, + 0x8510, 0x8510, 0x8530, 0x8510, 0x8510, 0x8510, 0x8530, 0x8530, 0x8540, 0x8570, 0x85C0, 0x8660, 0x8750, 0x88E0, 0x8BF0, 0x9040, + 0x9560, 0x9A40, 0x9F30, 0xA4B0, 0xAAA0, 0xB010, 0xB4D0, 0xB920, 0xBCF0, 0xC070, 0xC3A0, 0xC700, 0xC970, 0xCCE0, 0xCE70, 0xCF70, + 0xCEB0, 0xCD00, 0xCB80, 0xC9E0, 0xC870, 0xC700, 0xC520, 0xC3B0, 0xC190, 0xBF60, 0xBCE0, 0xBA40, 0xB780, 0xB480, 0xB1C0, 0xAF20, + 0xAD70, 0xAC90, 0xABF0, 0xAD00, 0xAEA0, 0xB100, 0xB520, 0xBA30, 0xC030, 0xC5B0, 0xCB60, 0xD1E0, 0xD7C0, 0xDDD0, 0xE490, 0xEAA0, + 0xF110, 0xF780, 0xFD00, 0x0140, 0x0460, 0x0720, 0x0860, 0x0880, 0x0870, 0x0730, 0x06A0, 0x06B0, 0x0830, 0x0BE0, 0x1040, 0x1480, + 0x1750, 0x1720, 0x1480, 0x0EF0, 0x0820, 0x0220, 0xFDF0, 0xFC00, 0xFD30, 0x00C0, 0x0480, 0x07B0, 0x0950, 0x07D0, 0x03A0, 0xFD00, + 0xF490, 0xEB90, 0xE1F0, 0xD860, 0xCF90, 0xC720, 0xC0E0, 0xBCF0, 0xBAD0, 0xB990, 0xB7F0, 0xB7B0, 0xB790, 0xB780, 0xB8D0, 0xBB40, + 0xBF70, 0xC4A0, 0xC9D0, 0xCF10, 0xD330, 0xD720, 0xD940, 0xDB70, 0xDDE0, 0xE0D0, 0xE530, 0xEB60, 0xF2B0, 0xFB20, 0x0390, 0x0C30, + 0x14C0, 0x1B90, 0x2130, 0x2580, 0x2940, 0x2B10, 0x2BB0, 0x2B70, 0x2970, 0x25B0, 0x1FF0, 0x17F0, 0x0DD0, 0x01D0, 0xF6E0, 0xED10, + 0xE6D0, 0xE510, 0xE810, 0xEEF0, 0xF830, 0x0170, 0x0AC0, 0x1150, 0x1750, 0x1B00, 0x1D50, 0x1FF0, 0x2140, 0x2220, 0x23D0, 0x2530, + 0x2730, 0x2940, 0x2B50, 0x2D20, 0x2E80, 0x3080, 0x31C0, 0x32E0, 0x33D0, 0x3430, 0x3530, 0x3520, 0x35A0, 0x3610, 0x3640, 0x38B0, + 0x3B10, 0x3DD0, 0x4100, 0x4390, 0x4510, 0x4430, 0x4080, 0x3B10, 0x3370, 0x2DE0, 0x28D0, 0x25F0, 0x2530, 0x2570, 0x2690, 0x26B0, + 0x2560, 0x21D0, 0x1D70, 0x1750, 0x0F80, 0x0540, 0xFA90, 0xEE60, 0xE210, 0xD650, 0xCB00, 0xC020, 0xB600, 0xAC10, 0xA180, 0x9790, + 0x8FB0, 0x8A20, 0x8780, 0x8670, 0x85B0, 0x8580, 0x8560, 0x8540, 0x8530, 0x8520, 0x8510, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84E0, + 0x84E0, 0x84F0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8500, 0x8510, 0x8510, 0x8510, 0x8500, 0x8500, + 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, + 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84F0, 0x84E0, 0x84E0, + 0x84F0, 0x8500, 0x8530, 0x8550, 0x85B0, 0x86A0, 0x8840, 0x8C20, 0x92A0, 0x9A90, 0xA1E0, 0xA8F0, 0xB020, 0xB610, 0xBB90, 0xC160, + 0xC6C0, 0xCAF0, 0xCF20, 0xD320, 0xD6C0, 0xDA30, 0xDCE0, 0xDF00, 0xDF90, 0xDF80, 0xDDC0, 0xDAF0, 0xD630, 0xCF80, 0xC6C0, 0xBBA0, + 0xAD80, 0x9D40, 0x8E50, 0x8700, 0x8530, 0x84E0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8460, 0x8470, 0x8470, 0x84B0, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x84F0, 0x8550, + 0x8670, 0x8A60, 0x9470, 0x9E10, 0xA6B0, 0xADF0, 0xB2F0, 0xB750, 0xBB10, 0xBDE0, 0xBF80, 0xC210, 0xC560, 0xC920, 0xD030, 0xD720, + 0xDEC0, 0xE7C0, 0xF100, 0xFB00, 0x05C0, 0x1000, 0x1B50, 0x27C0, 0x33D0, 0x4030, 0x4D20, 0x5AE0, 0x6750, 0x7320, 0x7BC0, 0x7F10, + 0x7F20, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, 0x7EF0, 0x7390, 0x6670, 0x5860, 0x4B60, 0x3FD0, 0x3610, 0x2FD0, + 0x2C00, 0x2A40, 0x2B00, 0x2DA0, 0x3210, 0x3710, 0x3DB0, 0x46C0, 0x51C0, 0x5F50, 0x6E00, 0x7C50, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F20, 0x7EC0, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, + 0x7F40, 0x7F10, 0x7F90, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7EB0, 0x7F10, + 0x7EF0, 0x7F70, 0x7F20, 0x7ED0, 0x7ED0, 0x7EE0, 0x7F30, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7F10, + 0x7F20, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, 0x7F10, 0x7E90, 0x6200, 0x4A60, 0x3740, 0x2710, 0x1C70, 0x1200, 0x08C0, 0x0080, 0xF900, + 0xF4E0, 0xF200, 0xF0F0, 0xF0A0, 0xEFF0, 0xEE60, 0xEA80, 0xE490, 0xDCF0, 0xD2C0, 0xC660, 0xB780, 0xA4A0, 0x9160, 0x86D0, 0x8510, + 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84E0, 0x8510, 0x85C0, 0x8840, 0x91A0, 0x9DA0, 0xA7F0, 0xB220, 0xBB50, + 0xC520, 0xCF70, 0xDB20, 0xE6F0, 0xF420, 0x00D0, 0x0DF0, 0x1B80, 0x27A0, 0x3390, 0x3FD0, 0x4B60, 0x5770, 0x63E0, 0x7010, 0x7A50, + 0x7F00, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7910, 0x6DF0, 0x61B0, 0x5740, 0x4BB0, 0x4140, 0x36C0, 0x2C10, 0x2100, 0x15B0, 0x09A0, + 0xFD70, 0xF160, 0xE440, 0xD920, 0xCE50, 0xC350, 0xB880, 0xACE0, 0xA170, 0x9680, 0x8D80, 0x87F0, 0x8600, 0x8550, 0x8510, 0x8530, + 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, + 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8520, 0x8540, 0x8560, 0x85A0, 0x8600, 0x8680, 0x8760, 0x8890, 0x8AA0, + 0x8D70, 0x9180, 0x9600, 0x9A90, 0x9F10, 0xAC50, 0xAF40, 0xB290, 0xB5C0, 0xB840, 0xBA80, 0xBC30, 0xBDA0, 0xBE40, 0xBEA0, 0xBE70, + 0xBDD0, 0xBCF0, 0xBAD0, 0xB9A0, 0xB7D0, 0xB620, 0xB570, 0xB4F0, 0xB5E0, 0xB6B0, 0xB790, 0xB870, 0xB9B0, 0xBA20, 0xBA10, 0xB980, + 0xB990, 0xB950, 0xB8F0, 0xB8D0, 0xB820, 0xB790, 0xB620, 0xB4C0, 0xB2E0, 0xB190, 0xAFF0, 0xAE80, 0xACA0, 0xAB50, 0xAB20, 0xAAF0, + 0xAAD0, 0xAAE0, 0xAAF0, 0xAAE0, 0xAAA0, 0xAB30, 0xABA0, 0xAC90, 0xADB0, 0xAEA0, 0xAF60, 0xB050, 0xB120, 0xB200, 0xB370, 0xB4F0, + 0xB620, 0xB620, 0xB650, 0xB650, 0xB650, 0xB5F0, 0xB4F0, 0xB440, 0xB2A0, 0xB140, 0xAFC0, 0xAE40, 0xAD80, 0xACD0, 0xABB0, 0xAA10, + 0xA8C0, 0xA600, 0xA3E0, 0xA1F0, 0xA010, 0x9DC0, 0x9B10, 0x9760, 0x93C0, 0x9030, 0x8C90, 0x8A00, 0x8800, 0x86B0, 0x85D0, 0x8560, + 0x8520, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84E0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, + 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, + 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x8480, 0x84C0, + 0x84C0, 0x84C0, 0x8490, 0x84D0, 0x84E0, 0x84E0, 0x8510, 0x84F0, 0x8500, 0x8540, 0x8530, 0x8560, 0x85A0, 0x8620, 0x86F0, 0x8800, + 0x8990, 0x8BD0, 0x8ED0, 0x91C0, 0x9390, 0x9550, 0x9610, 0x9490, 0x91B0, 0x8D30, 0x8970, 0x86E0, 0x85A0, 0x8530, 0x8500, 0x84D0, + 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8520, 0x85C0, 0x87E0, 0x9030, + 0x9D90, 0xAC30, 0xB8B0, 0xC410, 0xCF70, 0xD8B0, 0xE0A0, 0xE780, 0xEED0, 0xF5D0, 0xFC80, 0x0310, 0x09D0, 0x1010, 0x16C0, 0x1D00, + 0x2350, 0x2A40, 0x3160, 0x3B10, 0x4440, 0x4F00, 0x5A70, 0x6600, 0x72B0, 0x7C70, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, + 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F60, 0x7ED0, + 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F40, 0x74F0, 0x71A0, 0x7340, 0x7910, 0x7EB0, 0x7E90, 0x7F10, 0x7EF0, 0x7EF0, + 0x7F10, 0x7EA0, 0x6000, 0x3B80, 0x1650, 0xF320, 0xD640, 0xBBD0, 0xA370, 0x8D10, 0x8590, 0x84E0, 0x84A0, 0x8490, 0x8470, 0x8460, + 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, 0x8470, 0x8480, 0x84A0, + 0x84D0, 0x8510, 0x85A0, 0x8760, 0x8D50, 0x9A80, 0xAA50, 0xBC20, 0xCF10, 0xE290, 0xF390, 0x03B0, 0x11A0, 0x1E20, 0x2A00, 0x3480, + 0x3F70, 0x4980, 0x5410, 0x5D00, 0x6440, 0x6B70, 0x7040, 0x7480, 0x7760, 0x7890, 0x7990, 0x7840, 0x75C0, 0x71D0, 0x6B60, 0x6460, + 0x5C50, 0x53B0, 0x49F0, 0x4060, 0x3690, 0x2E70, 0x26A0, 0x1FE0, 0x1A10, 0x1570, 0x11A0, 0x0D40, 0x0910, 0x0300, 0xFCC0, 0xF5B0, + 0xEE30, 0xE660, 0xDD60, 0xD580, 0xCD80, 0xC660, 0xBFA0, 0xB9E0, 0xB4C0, 0xAFB0, 0xAA70, 0xA6A0, 0xA400, 0xA390, 0xA4C0, 0xA940, + 0xAF90, 0xB760, 0xBE80, 0xC490, 0xC8F0, 0xCC10, 0xCD40, 0xCCF0, 0xCBB0, 0xCA20, 0xC8D0, 0xC7B0, 0xC7A0, 0xC6A0, 0xC3D0, 0xBE90, + 0xB7B0, 0xAED0, 0xA680, 0x9FB0, 0x9A60, 0x9680, 0x9270, 0x8FD0, 0x8D80, 0x8C00, 0x8B30, 0x8B00, 0x8B60, 0x8CB0, 0x8F80, 0x9520, + 0x9E00, 0xA9C0, 0xB6B0, 0xC680, 0xD3F0, 0xE0B0, 0xEC20, 0xF6A0, 0x00D0, 0x0A30, 0x11B0, 0x17C0, 0x1930, 0x17E0, 0x1380, 0x0CB0, + 0x05A0, 0xFF40, 0xF9C0, 0xF5B0, 0xF290, 0xF260, 0xF380, 0xF5D0, 0xF900, 0xFC80, 0x00D0, 0x0580, 0x0AC0, 0x1140, 0x1900, 0x2100, + 0x2840, 0x2ED0, 0x3570, 0x3AC0, 0x4080, 0x4610, 0x4BB0, 0x51C0, 0x5650, 0x5AF0, 0x5FA0, 0x63F0, 0x6810, 0x6C30, 0x7100, 0x74E0, + 0x78B0, 0x7B70, 0x7DC0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F30, + 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F30, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F40, + 0x7F10, 0x7F70, 0x7EE0, 0x7F10, 0x7F20, 0x7F00, 0x7F70, 0x7EF0, 0x7F20, 0x7F10, 0x7F00, 0x7F90, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, + 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F50, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7E90, 0x7ED0, 0x7F10, 0x7EF0, + 0x7F10, 0x7EB0, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F40, 0x7F10, + 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7F00, 0x7EF0, + 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, + 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7EE0, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F30, + 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7B50, 0x7570, 0x6FE0, 0x6A80, 0x6690, 0x63A0, 0x6240, 0x6180, 0x6190, 0x6320, 0x6540, 0x6750, 0x6A30, + 0x6CE0, 0x7030, 0x72B0, 0x75B0, 0x7800, 0x79C0, 0x7B10, 0x7BF0, 0x7C60, 0x7C70, 0x7BF0, 0x7B60, 0x7AC0, 0x7A50, 0x79F0, 0x7940, + 0x7840, 0x7790, 0x76E0, 0x7600, 0x7550, 0x7530, 0x7530, 0x7440, 0x73D0, 0x7350, 0x72E0, 0x7290, 0x7250, 0x72E0, 0x7320, 0x73C0, + 0x7450, 0x74B0, 0x74E0, 0x7590, 0x7610, 0x76E0, 0x77E0, 0x7990, 0x7AF0, 0x7C60, 0x7DA0, 0x7E50, 0x7EE0, 0x7F20, 0x7F30, 0x7F10, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F00, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F00, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7DA0, 0x7740, 0x7050, 0x6930, 0x62A0, 0x5C00, + 0x5490, 0x4DB0, 0x4740, 0x4160, 0x3B70, 0x3570, 0x2F60, 0x28E0, 0x21C0, 0x1940, 0x11A0, 0x0A90, 0x0430, 0xFEB0, 0xF970, 0xF450, + 0xEF90, 0xE9E0, 0xE420, 0xDF10, 0xD990, 0xD470, 0xD080, 0xCC50, 0xC950, 0xC600, 0xC350, 0xC0B0, 0xBE30, 0xBB90, 0xB910, 0xB6B0, + 0xB570, 0xB540, 0xB4C0, 0xB4A0, 0xB8D0, 0xBA60, 0xBCE0, 0xBFB0, 0xC230, 0xC520, 0xC770, 0xCAC0, 0xCDC0, 0xD150, 0xD4E0, 0xD720, + 0xD950, 0xDB70, 0xDBE0, 0xDD00, 0xDD20, 0xDD10, 0xDC80, 0xDB80, 0xDB50, 0xDAE0, 0xDC00, 0xDC80, 0xDCE0, 0xDDE0, 0xDDE0, 0xDDE0, + 0xDD40, 0xDD00, 0xDDF0, 0xDEB0, 0xDF30, 0xE010, 0xE110, 0xE230, 0xE310, 0xE330, 0xE3C0, 0xE300, 0xE2B0, 0xE150, 0xDF90, 0xDD20, + 0xDA00, 0xD690, 0xD220, 0xCD80, 0xC840, 0xC260, 0xBD20, 0xB7F0, 0xB310, 0xAEA0, 0xAA10, 0xA5F0, 0xA200, 0x9E90, 0x9A90, 0x9760, + 0x9530, 0x9340, 0x9120, 0x8FE0, 0x8FC0, 0x8F90, 0x8FD0, 0x9070, 0x91D0, 0x9310, 0x9490, 0x9690, 0x99A0, 0x9D70, 0xA120, 0xA550, + 0xA9B0, 0xAE80, 0xB370, 0xB900, 0xBE90, 0xC530, 0xCB60, 0xD120, 0xD640, 0xDBA0, 0xE0A0, 0xE590, 0xEB30, 0xF070, 0xF670, 0xFBB0, + 0xFFE0, 0x04A0, 0x0970, 0x0DB0, 0x11F0, 0x15A0, 0x1970, 0x1C90, 0x1FF0, 0x2280, 0x2530, 0x2790, 0x28E0, 0x29D0, 0x2AD0, 0x2AC0, + 0x2B00, 0x2A90, 0x2960, 0x27C0, 0x25F0, 0x2450, 0x21B0, 0x1EC0, 0x1C40, 0x1890, 0x1500, 0x1090, 0x0CB0, 0x0980, 0x0640, 0x03F0, + 0x01B0, 0xFF00, 0xFCC0, 0xF950, 0xF700, 0xF3F0, 0xF170, 0xF070, 0xEF00, 0xEDF0, 0xED50, 0xEC30, 0xEB80, 0xEA80, 0xEA10, 0xEA20, + 0xE980, 0xE910, 0xE890, 0xE860, 0xE830, 0xE860, 0xE8D0, 0xE8D0, 0xE8D0, 0xE8D0, 0xE830, 0xE840, 0xE7D0, 0xE680, 0xE540, 0xE440, + 0xE3E0, 0xE340, 0xE230, 0xE170, 0xDFB0, 0xDEE0, 0xDD20, 0xDB30, 0xDAA0, 0xD910, 0xD920, 0xD920, 0xD940, 0xD940, 0xD8D0, 0xD910, + 0xD950, 0xD9D0, 0xDAE0, 0xDBA0, 0xDCC0, 0xDE10, 0xDF30, 0xE060, 0xE160, 0xE230, 0xE260, 0xE1F0, 0xE1B0, 0xE130, 0xE100, 0xE0D0, + 0xE0A0, 0xE0C0, 0xDFF0, 0xDF70, 0xDE40, 0xDC90, 0xDB70, 0xDAA0, 0xD940, 0xD560, 0xD4A0, 0xD440, 0xD310, 0xD2A0, 0xD210, 0xD120, + 0xD010, 0xCE40, 0xCD30, 0xCC70, 0xCB70, 0xCAA0, 0xC9C0, 0xC980, 0xC880, 0xC7E0, 0xC7B0, 0xC720, 0xC730, 0xC6E0, 0xC740, 0xC8A0, + 0xC9D0, 0xCBA0, 0xCDE0, 0xD040, 0xD360, 0xD5D0, 0xD870, 0xDB60, 0xDE90, 0xE310, 0xE780, 0xEC90, 0xF190, 0xF620, 0xFB20, 0xFF80, + 0x04F0, 0x0B20, 0x10A0, 0x1790, 0x1EC0, 0x2580, 0x2C80, 0x32B0, 0x39B0, 0x4000, 0x45D0, 0x4B30, 0x50A0, 0x56F0, 0x5B70, 0x5F60, + 0x6260, 0x6490, 0x6670, 0x66A0, 0x65C0, 0x6490, 0x62E0, 0x61E0, 0x6040, 0x5EF0, 0x5DC0, 0x5BD0, 0x5A50, 0x5890, 0x5660, 0x5450, + 0x51F0, 0x5070, 0x4EF0, 0x4D10, 0x4C00, 0x4A40, 0x49D0, 0x48C0, 0x4740, 0x4660, 0x44B0, 0x4380, 0x41C0, 0x4090, 0x40D0, 0x4180, + 0x42C0, 0x4500, 0x4690, 0x4980, 0x4C00, 0x4F10, 0x5230, 0x5500, 0x5810, 0x5B10, 0x5E20, 0x6140, 0x63F0, 0x6700, 0x6980, 0x6CB0, + 0x6F90, 0x71A0, 0x7470, 0x77B0, 0x7AE0, 0x7D60, 0x7ED0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, + 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EF0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, + 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, + 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F70, 0x7F20, 0x7EF0, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, + 0x7EB0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, + 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F50, + 0x7EF0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F80, 0x7ED0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F50, 0x7EE0, + 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7E70, 0x6C20, 0x5750, 0x42B0, 0x2CE0, 0x16A0, 0xFF90, 0xE850, 0xD400, 0xC160, + 0xB3D0, 0xA920, 0xA380, 0xA340, 0xA630, 0xACC0, 0xB790, 0xC590, 0xD750, 0xEB20, 0x0250, 0x1830, 0x2D00, 0x3F40, 0x4C10, 0x5170, + 0x4E20, 0x40F0, 0x2CD0, 0x12E0, 0xFA00, 0xE510, 0xD380, 0xC590, 0xB820, 0xA990, 0x9980, 0x8BB0, 0x8610, 0x8520, 0x84F0, 0x84E0, + 0x84D0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84C0, 0x84C0, 0x8480, 0x8470, 0x8490, 0x8480, 0x8490, 0x84B0, 0x8510, 0x8540, 0x8630, + 0x8810, 0x8A00, 0x89F0, 0x88F0, 0x87A0, 0x8690, 0x85D0, 0x8540, 0x8510, 0x84F0, 0x84E0, 0x84D0, 0x84E0, 0x8500, 0x8570, 0x8630, + 0x8A20, 0x95C0, 0xA100, 0xA910, 0xAEA0, 0xB220, 0xB610, 0xBAD0, 0xC1A0, 0xCA20, 0xD380, 0xDCC0, 0xE3D0, 0xE790, 0xE830, 0xE550, + 0xE100, 0xDD30, 0xDB00, 0xDB90, 0xDED0, 0xE4F0, 0xED60, 0xF760, 0x0400, 0x1080, 0x1D40, 0x2A00, 0x35D0, 0x41F0, 0x4DC0, 0x5910, + 0x6350, 0x6C20, 0x7240, 0x75D0, 0x7840, 0x79D0, 0x7B10, 0x7C00, 0x7C70, 0x7CC0, 0x7BF0, 0x7AA0, 0x77C0, 0x72D0, 0x6C90, 0x6470, + 0x5AA0, 0x5090, 0x45B0, 0x3B00, 0x3240, 0x2A80, 0x2520, 0x20E0, 0x1E50, 0x1E00, 0x1F90, 0x21F0, 0x23F0, 0x2530, 0x2470, 0x2240, + 0x1DD0, 0x17F0, 0x1160, 0x09E0, 0x0110, 0xF5A0, 0xE960, 0xDA40, 0xC810, 0xB4F0, 0xA1D0, 0x9080, 0x8810, 0x85D0, 0x8540, 0x8520, + 0x8500, 0x84E0, 0x84D0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8520, 0x8550, 0x8590, 0x8630, 0x8770, + 0x89A0, 0x8E80, 0x96D0, 0x9E40, 0xA600, 0xAF00, 0xB710, 0xBFD0, 0xC720, 0xCE60, 0xD440, 0xD8D0, 0xDBF0, 0xDEE0, 0xE240, 0xE590, + 0xE9A0, 0xEEC0, 0xF480, 0xFAF0, 0x0320, 0x0A70, 0x1040, 0x1490, 0x1640, 0x1540, 0x12E0, 0x0ED0, 0x0AA0, 0x06C0, 0x0400, 0x0230, + 0x00E0, 0xFE40, 0xFAB0, 0xF520, 0xEEA0, 0xE770, 0xDF40, 0xD880, 0xD220, 0xCCF0, 0xC960, 0xC6A0, 0xC4F0, 0xC410, 0xC3D0, 0xC4C0, + 0xC570, 0xC650, 0xC760, 0xC900, 0xCB70, 0xCED0, 0xD250, 0xD6A0, 0xDB20, 0xDF50, 0xE320, 0xE730, 0xEAB0, 0xEE00, 0xF120, 0xF440, + 0xF790, 0xFB60, 0xFE40, 0x00D0, 0x0220, 0x02A0, 0x0290, 0x0210, 0x02B0, 0x0400, 0x0790, 0x0C00, 0x10E0, 0x1710, 0x1C10, 0x2100, + 0x25C0, 0x2AD0, 0x3030, 0x35F0, 0x3B10, 0x3FF0, 0x4410, 0x4860, 0x4B70, 0x4F10, 0x5300, 0x55E0, 0x59B0, 0x5BA0, 0x5DC0, 0x5E50, + 0x5ED0, 0x6020, 0x60C0, 0x6200, 0x6390, 0x64C0, 0x6610, 0x6580, 0x6460, 0x63A0, 0x6180, 0x60B0, 0x6030, 0x5FE0, 0x5FF0, 0x5FF0, + 0x6070, 0x5F50, 0x5D30, 0x5A20, 0x5580, 0x5050, 0x4A10, 0x41E0, 0x3910, 0x30B0, 0x27E0, 0x1DE0, 0x12C0, 0x06A0, 0xF880, 0xE920, + 0xD580, 0xC160, 0xAC30, 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8480, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8510, 0x8530, + 0x8550, 0x8590, 0x8600, 0x86B0, 0x87F0, 0x8A50, 0x8E60, 0x9420, 0x99D0, 0x9F00, 0xA500, 0xAB00, 0xB120, 0xB7C0, 0xBD60, 0xC300, + 0xC830, 0xCD70, 0xD210, 0xD710, 0xDCD0, 0xE270, 0xE8B0, 0xEEF0, 0xF4A0, 0xFA80, 0x00B0, 0x0670, 0x0D40, 0x13B0, 0x1AF0, 0x2160, + 0x2750, 0x2CB0, 0x3120, 0x35F0, 0x3A80, 0x3D30, 0x4020, 0x4240, 0x44B0, 0x44E0, 0x4510, 0x4550, 0x4530, 0x4520, 0x4470, 0x4450, + 0x4410, 0x43C0, 0x4410, 0x4460, 0x4460, 0x45C0, 0x4650, 0x4710, 0x4820, 0x48E0, 0x4990, 0x4900, 0x48A0, 0x47C0, 0x46F0, 0x4700, + 0x4680, 0x4590, 0x4490, 0x4180, 0x3F90, 0x3CB0, 0x3A30, 0x38E0, 0x36F0, 0x3610, 0x3500, 0x3320, 0x31D0, 0x3100, 0x30D0, 0x3090, + 0x3130, 0x3230, 0x3360, 0x3550, 0x3830, 0x3BE0, 0x4010, 0x44F0, 0x4B00, 0x5180, 0x5890, 0x7700, 0x7D80, 0x7F00, 0x7F00, 0x7EF0, + 0x7ED0, 0x7F30, 0x7F00, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7520, 0x6960, 0x5BB0, 0x4E30, 0x4200, 0x3750, 0x2DD0, + 0x22B0, 0x1820, 0x0BC0, 0xFE00, 0xEE20, 0xDA30, 0xC750, 0xB3A0, 0xA0A0, 0x9110, 0x88E0, 0x8650, 0x85A0, 0x8570, 0x8570, 0x8580, + 0x85D0, 0x8670, 0x8820, 0x8CC0, 0x9540, 0x9EF0, 0xA820, 0xB190, 0xBA50, 0xC270, 0xCA70, 0xD270, 0xD9F0, 0xE240, 0xE9C0, 0xF050, + 0xF500, 0xF6A0, 0xF530, 0xF060, 0xE960, 0xE280, 0xDC80, 0xD930, 0xD9C0, 0xDDF0, 0xE430, 0xEBF0, 0xF380, 0xF8F0, 0xFB10, 0xF880, + 0xF1C0, 0xE810, 0xDA20, 0xCCC0, 0xC0D0, 0xB5B0, 0xAD60, 0xA690, 0xA110, 0x9BE0, 0x9680, 0x9110, 0x8D00, 0x8A30, 0x88D0, 0x8840, + 0x88D0, 0x8A80, 0x8E20, 0x93F0, 0x9B70, 0xA300, 0xAAE0, 0xB2A0, 0xB9E0, 0xC190, 0xC990, 0xD110, 0xD7F0, 0xDF50, 0xE580, 0xEB20, + 0xF040, 0xF4F0, 0xFA90, 0x0020, 0x06F0, 0x0D30, 0x13A0, 0x19F0, 0x1E90, 0x22F0, 0x26A0, 0x2950, 0x2CD0, 0x3000, 0x3400, 0x38F0, + 0x3D40, 0x4200, 0x45C0, 0x49B0, 0x4C20, 0x4D00, 0x4E90, 0x4ED0, 0x4E70, 0x4D80, 0x4C80, 0x4B80, 0x4B80, 0x4D80, 0x5070, 0x5520, + 0x5A60, 0x6010, 0x64B0, 0x68A0, 0x6AF0, 0x6CD0, 0x6DC0, 0x6EC0, 0x6F90, 0x7110, 0x73E0, 0x7650, 0x7930, 0x7BB0, 0x7D40, 0x7E40, + 0x7E80, 0x7D30, 0x79F0, 0x7390, 0x6BA0, 0x6160, 0x5510, 0x4930, 0x3CE0, 0x3180, 0x26D0, 0x1BF0, 0x12A0, 0x0950, 0x0060, 0xF680, + 0xEC40, 0xE1C0, 0xD730, 0xCC20, 0xC040, 0xB290, 0xA410, 0x9420, 0x8870, 0x8540, 0x84E0, 0x84E0, 0x84A0, 0x8490, 0x8480, 0x8470, + 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8490, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84F0, 0x84C0, 0x84D0, 0x84F0, 0x8540, 0x8610, 0x8800, 0x8BC0, 0x90E0, 0x92A0, 0x9240, 0x8FB0, 0x8CD0, + 0x8A40, 0x8830, 0x8710, 0x8670, 0x8620, 0x85F0, 0x8600, 0x8630, 0x86B0, 0x87B0, 0x89F0, 0x8EE0, 0x9670, 0x9F90, 0xA7D0, 0xAFA0, + 0xB560, 0xB9D0, 0xBC60, 0xBCE0, 0xBBF0, 0xB9A0, 0xB5E0, 0xB1D0, 0xAD70, 0xA8B0, 0xA460, 0x9FB0, 0x9B10, 0x96C0, 0x92E0, 0x8F10, + 0x8C30, 0x89F0, 0x88B0, 0x87F0, 0x8790, 0x8780, 0x87B0, 0x8820, 0x88D0, 0x89A0, 0x8A90, 0x8C30, 0x8E50, 0x9170, 0x9590, 0x9940, + 0x9E40, 0xA260, 0xA530, 0xA840, 0xA9F0, 0xAAE0, 0xABF0, 0xADC0, 0xB020, 0xB2B0, 0xB530, 0xB840, 0xBB40, 0xBDF0, 0xC0B0, 0xC370, + 0xC5F0, 0xC870, 0xCB20, 0xCDD0, 0xD080, 0xD3C0, 0xD7D0, 0xDBF0, 0xDFF0, 0xE370, 0xE660, 0xE810, 0xE910, 0xE9A0, 0xE9E0, 0xE980, + 0xE930, 0xE8A0, 0xE850, 0xE7E0, 0xE780, 0xE730, 0xE6E0, 0xE590, 0xE4B0, 0xE3E0, 0xE380, 0xE3B0, 0xE490, 0xE510, 0xE680, 0xE680, + 0xE680, 0xE650, 0xE680, 0xE630, 0xE560, 0xE4D0, 0xE480, 0xE440, 0xE3A0, 0xE310, 0xE330, 0xE3D0, 0xE4C0, 0xE610, 0xE720, 0xE830, + 0xE930, 0xEA80, 0xEBC0, 0xED00, 0xEDB0, 0xEDD0, 0xEE20, 0xEDD0, 0xEDD0, 0xED90, 0xECC0, 0xEBD0, 0xEA90, 0xE990, 0xE870, 0xE770, + 0xE6D0, 0xE5C0, 0xE4C0, 0xE450, 0xE3D0, 0xE3E0, 0xE400, 0xE4D0, 0xE580, 0xE660, 0xE750, 0xE870, 0xE9E0, 0xEBE0, 0xEDB0, 0xF080, + 0xF2D0, 0xF620, 0xF980, 0xFD90, 0x00C0, 0x0490, 0x0830, 0x0BB0, 0x0EE0, 0x1260, 0x16F0, 0x1AA0, 0x1E70, 0x2270, 0x25B0, 0x27A0, + 0x29C0, 0x2BB0, 0x2D30, 0x2EE0, 0x3090, 0x31E0, 0x3340, 0x3480, 0x35F0, 0x36D0, 0x37E0, 0x3A00, 0x3C90, 0x3F80, 0x4420, 0x4980, + 0x4F50, 0x5670, 0x5DB0, 0x64F0, 0x6B90, 0x71E0, 0x7690, 0x7A00, 0x7B70, 0x7BB0, 0x7A80, 0x7740, 0x7230, 0x6B70, 0x6250, 0x58B0, + 0x4D40, 0x4220, 0x36C0, 0x2C50, 0x2280, 0x1AA0, 0x13A0, 0x0CE0, 0x06C0, 0xFF20, 0xF650, 0xEB20, 0xDCE0, 0xCAC0, 0xB470, 0x9A80, + 0x86E0, 0x84E0, 0x84A0, 0x8480, 0x8490, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83E0, + 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x83A0, 0x8380, + 0x8380, 0x8370, 0x8370, 0x8370, 0x8360, 0x8390, 0x8360, 0x8360, 0x8360, 0x8370, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, + 0x8390, 0x83A0, 0x8370, 0x8380, 0x83B0, 0x8390, 0x8380, 0x8390, 0x8390, 0x8380, 0x8380, 0x83B0, 0x8380, 0x8380, 0x8380, 0x8390, + 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, + 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8470, 0x8430, 0x8430, 0x8440, + 0x8430, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, 0x84D0, + 0x84E0, 0x84E0, 0x8500, 0x8550, 0x86B0, 0x94F0, 0xAFF0, 0xCBD0, 0xE440, 0xF480, 0xFAF0, 0xF8E0, 0xF170, 0xEA90, 0xE560, 0xE4F0, + 0xE8F0, 0xEEF0, 0xF6E0, 0xFE40, 0x03D0, 0x0810, 0x09A0, 0x0A30, 0x08D0, 0x0760, 0x05E0, 0x04D0, 0x05E0, 0x0900, 0x0E40, 0x1650, + 0x2000, 0x2B80, 0x3910, 0x46B0, 0x5660, 0x6650, 0x7590, 0x7EE0, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F70, 0x7F20, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, + 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EF0, + 0x7EB0, 0x7EF0, 0x7EF0, 0x7F50, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F30, 0x7EF0, 0x7F00, 0x7F10, 0x7F20, 0x7F10, + 0x7EB0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, + 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7EF0, 0x7F60, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, + 0x7EF0, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7ED0, 0x7F10, 0x7F60, 0x7F00, 0x7F30, 0x7F00, 0x7F00, + 0x7F50, 0x7EF0, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F30, + 0x7EC0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EF0, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, + 0x7F70, 0x7F00, 0x7EE0, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7EE0, 0x7F00, 0x7EE0, 0x7F30, 0x7F10, 0x7ED0, 0x7ED0, 0x7EB0, 0x7F20, + 0x7EF0, 0x7E90, 0x7EE0, 0x7F20, 0x7E60, 0x7890, 0x7160, 0x6A80, 0x6380, 0x5CB0, 0x57C0, 0x5300, 0x5010, 0x4DB0, 0x4BE0, 0x4C50, + 0x4B80, 0x4B80, 0x4B00, 0x4910, 0x4830, 0x4670, 0x4460, 0x41B0, 0x3FB0, 0x3E60, 0x3C50, 0x39F0, 0x3770, 0x3500, 0x32D0, 0x30B0, + 0x2EC0, 0x2D50, 0x2AB0, 0x2840, 0x2560, 0x2230, 0x1E90, 0x1B20, 0x1840, 0x1390, 0x1040, 0x0D80, 0x0AF0, 0x0910, 0x0740, 0x05C0, + 0x0550, 0x0530, 0x0590, 0x0590, 0x0570, 0x0620, 0x06B0, 0x0750, 0x07F0, 0x08C0, 0x0A40, 0x0C00, 0x0E60, 0x0FF0, 0x1190, 0x1380, + 0x15E0, 0x1890, 0x1AD0, 0x1C70, 0x1E80, 0x1F60, 0x1EA0, 0x1C20, 0x1770, 0x1110, 0x0890, 0xFF60, 0xF4D0, 0xE830, 0xDC40, 0xCF00, + 0xC090, 0xB190, 0xA1A0, 0x9250, 0x8850, 0x8570, 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x84A0, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, + 0x8460, 0x8470, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, + 0x84E0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x85D0, 0x8980, 0x9930, 0xAAE0, 0xBCE0, 0xCFD0, 0xE110, 0xF2B0, 0x0420, 0x16B0, 0x2930, + 0x3BF0, 0x4E60, 0x60D0, 0x7500, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F20, 0x7F10, 0x7F10, 0x5FF0, 0x3260, 0x0190, 0xD6B0, 0xAE80, 0x8C40, 0x8500, 0x84B0, 0x8490, 0x8470, 0x8470, 0x8460, 0x8460, + 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x84F0, 0x8530, 0x8620, 0x8A00, 0x9670, 0xA1E0, 0xAAE0, 0xB280, + 0xBC70, 0xC970, 0xDC30, 0xF4C0, 0x1260, 0x33A0, 0x5350, 0x6D10, 0x7B90, 0x7EC0, 0x7A50, 0x67B0, 0x4A40, 0x2740, 0x0180, 0xDA90, + 0xAE80, 0x8750, 0x84B0, 0x8470, 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, + 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x8400, 0x8400, 0x8410, 0x83F0, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x83F0, 0x8430, + 0x8440, 0x83F0, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x8520, 0x86F0, + 0x9880, 0xB440, 0xCE20, 0xE650, 0xFD20, 0x1260, 0x2630, 0x38C0, 0x4A90, 0x59D0, 0x6840, 0x7500, 0x7E30, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F30, + 0x7F40, 0x7F10, 0x7EB0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7F00, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, + 0x7ED0, 0x7F10, 0x7EF0, 0x7F50, 0x7F20, 0x7EC0, 0x7F20, 0x7EF0, 0x7F10, 0x7EE0, 0x7E70, 0x7F10, 0x7EE0, 0x7F20, 0x7ED0, 0x7EB0, + 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F00, 0x7F40, + 0x7ED0, 0x7F10, 0x7F30, 0x7EE0, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, + 0x7EF0, 0x7EE0, 0x7EF0, 0x7F50, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7F10, 0x7F20, 0x7EA0, + 0x7F00, 0x7EF0, 0x7F20, 0x7F20, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, + 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F30, 0x7ED0, 0x7E90, + 0x7F10, 0x7F20, 0x7F40, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, + 0x7F10, 0x7F10, 0x7F30, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F80, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, + 0x7ED0, 0x7F00, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F30, 0x7F00, 0x7EA0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, + 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, + 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7EE0, 0x7F40, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, + 0x7F60, 0x7ED0, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EE0, 0x7F70, + 0x7EF0, 0x7F20, 0x7F20, 0x7EF0, 0x7F70, 0x7EE0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F30, 0x7F10, + 0x7F00, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7ED0, 0x7EF0, 0x7F30, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7F00, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F90, 0x7F00, + 0x7EE0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x79E0, 0x7110, + 0x6680, 0x5990, 0x4920, 0x3850, 0x2580, 0x11A0, 0xFBE0, 0xE2F0, 0xCA50, 0xAF80, 0x9470, 0x8660, 0x84E0, 0x84B0, 0x8490, 0x8480, + 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x83E0, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, 0x83B0, + 0x8400, 0x8400, 0x8420, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, + 0x84D0, 0x84A0, 0x84B0, 0x84D0, 0x84F0, 0x85B0, 0x88F0, 0x9530, 0xA320, 0xB0A0, 0xBBA0, 0xC530, 0xCCB0, 0xD120, 0xD390, 0xD470, + 0xD360, 0xD220, 0xD010, 0xCD30, 0xCA90, 0xC830, 0xC710, 0xC200, 0xB060, 0x8FE0, 0x84E0, 0x8490, 0x8460, 0x8430, 0x8430, 0x8420, + 0x8410, 0x8400, 0x8400, 0x83E0, 0x8400, 0x83E0, 0x83E0, 0x83D0, 0x83F0, 0x83C0, 0x83C0, 0x83A0, 0x83B0, 0x83C0, 0x83C0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83F0, + 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8420, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83E0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, + 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83D0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, 0x8440, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x84B0, + 0x84B0, 0x84C0, 0x84F0, 0x8530, 0x85C0, 0x87B0, 0x8F00, 0x9D10, 0xAB20, 0xB880, 0xC430, 0xCF00, 0xD640, 0xDB10, 0xDDB0, 0xDEE0, + 0xDFE0, 0xE0A0, 0xE150, 0xE0F0, 0xDE50, 0xD7F0, 0xCD20, 0xBCE0, 0xA810, 0x9000, 0x85A0, 0x84D0, 0x84A0, 0x8490, 0x8480, 0x8480, + 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8460, 0x8490, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84D0, + 0x8510, 0x8670, 0x9510, 0xB180, 0xCF10, 0xEE60, 0x0FA0, 0x32B0, 0x5900, 0x7760, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F00, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F70, 0x7F20, 0x7EC0, 0x7F00, + 0x7F10, 0x7EF0, 0x7EF0, 0x7E70, 0x7EF0, 0x7EC0, 0x7EE0, 0x7ED0, 0x7E80, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7ED0, 0x7F10, + 0x7F00, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F30, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, + 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, 0x7EF0, 0x7EE0, 0x7F40, 0x7F10, 0x7F40, 0x7F00, 0x7EC0, 0x7EF0, + 0x7F00, 0x7F50, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7E90, 0x7F00, 0x7EE0, + 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7F30, + 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x73F0, 0x6290, 0x50E0, 0x3EF0, 0x2D50, 0x19F0, 0x09A0, + 0xFA40, 0xECB0, 0xE230, 0xD960, 0xD340, 0xCD90, 0xC9D0, 0xC810, 0xC650, 0xC630, 0xC660, 0xC660, 0xC6F0, 0xC750, 0xC800, 0xC860, + 0xC810, 0xC820, 0xC760, 0xC6D0, 0xC6C0, 0xC6E0, 0xC8E0, 0xCB40, 0xCE30, 0xD1C0, 0xD440, 0xD730, 0xD9E0, 0xDBC0, 0xDD50, 0xDED0, + 0xE0E0, 0xE2E0, 0xE5D0, 0xE910, 0xEC50, 0xEF90, 0xF200, 0xF3A0, 0xF4B0, 0xF480, 0xF3E0, 0xF2C0, 0xF0F0, 0xEF60, 0xECE0, 0xEA80, + 0xE7F0, 0xE4A0, 0xE1F0, 0xDEC0, 0xDB90, 0xD800, 0xD4D0, 0xD180, 0xCE10, 0xCBA0, 0xC8E0, 0xC5D0, 0xC360, 0xBFA0, 0xBD80, 0xBB10, + 0xB8E0, 0xB6D0, 0xB4A0, 0xB310, 0xB120, 0xAF10, 0xACD0, 0xAAE0, 0xA8D0, 0xA6F0, 0xA510, 0xA320, 0x9FF0, 0x9C70, 0x9900, 0x94F0, + 0x9140, 0x8D70, 0x8A10, 0x87E0, 0x8680, 0x85C0, 0x8560, 0x8520, 0x8500, 0x8520, 0x84E0, 0x84E0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84D0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, + 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84E0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84D0, 0x8500, 0x8530, + 0x8580, 0x8650, 0x8830, 0x8CA0, 0x9400, 0x9CB0, 0xA430, 0xAC10, 0xB370, 0xBA90, 0xC390, 0xCBD0, 0xD580, 0xDEC0, 0xE840, 0xF210, + 0xFC10, 0x06B0, 0x1140, 0x1CB0, 0x26A0, 0x2FC0, 0x39F0, 0x4290, 0x4A70, 0x5260, 0x58D0, 0x5F30, 0x6480, 0x6890, 0x6C90, 0x7020, + 0x7440, 0x7890, 0x7BB0, 0x7E30, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7EC0, 0x7F10, + 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7F10, + 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7F00, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7EA0, + 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F00, 0x7EE0, 0x7F50, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F70, 0x7ED0, 0x7EB0, 0x7F00, + 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F40, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7EE0, + 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7ED0, 0x7EB0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, + 0x7F10, 0x7F00, 0x7F10, 0x7E90, 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, + 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7ED0, 0x7F30, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F20, 0x7F70, 0x7ED0, 0x7EB0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7E90, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, + 0x7F10, 0x7F20, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F30, 0x7F10, 0x7F70, 0x7D20, 0x5D10, 0x40B0, 0x2400, 0x0840, 0xEE30, 0xD660, + 0xC1C0, 0xAF00, 0x9F50, 0x9250, 0x8B60, 0x8820, 0x86D0, 0x85F0, 0x85D0, 0x8580, 0x8550, 0x8510, 0x84F0, 0x84D0, 0x84F0, 0x84B0, + 0x84A0, 0x8490, 0x84B0, 0x8480, 0x8470, 0x8430, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84E0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, + 0x8490, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8460, 0x8470, 0x8470, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8460, 0x8490, 0x8410, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8470, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x85B0, + 0x87B0, 0x8E70, 0x9950, 0xA330, 0xAAD0, 0xB040, 0xB350, 0xB4B0, 0xB570, 0xB470, 0xB260, 0xAF80, 0xABD0, 0xA810, 0xA2B0, 0x9D40, + 0x96B0, 0x9070, 0x8B90, 0x8860, 0x86D0, 0x8600, 0x85D0, 0x8570, 0x8560, 0x8560, 0x8590, 0x85C0, 0x8650, 0x87A0, 0x8B40, 0x9380, + 0x9F10, 0xAAB0, 0xB620, 0xC0D0, 0xC940, 0xCF80, 0xD360, 0xD4B0, 0xD360, 0xCFB0, 0xCA90, 0xC3B0, 0xBAE0, 0xB010, 0xA330, 0x94A0, + 0x89A0, 0x85B0, 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84F0, 0x8670, 0x9DC0, 0xBF90, 0xE0F0, 0x03B0, 0x2A70, 0x4E90, 0x6FD0, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F70, 0x7F20, 0x7F10, 0x7F30, + 0x7F00, 0x7F50, 0x7EF0, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7ED0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, + 0x7F60, 0x7F10, 0x7F20, 0x7F10, 0x7EF0, 0x7F30, 0x7F30, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F40, 0x7F50, 0x7EB0, 0x7F00, 0x7EE0, 0x7B80, + 0x6630, 0x4E00, 0x3540, 0x1B30, 0x0420, 0xEFA0, 0xDC00, 0xC950, 0xB610, 0xA220, 0x8FB0, 0x8710, 0x8530, 0x84F0, 0x84E0, 0x84E0, + 0x84E0, 0x84F0, 0x8530, 0x8570, 0x8600, 0x8730, 0x8900, 0x8BE0, 0x8E70, 0x90B0, 0x9230, 0x9310, 0x92D0, 0x9180, 0x8FF0, 0x8E30, + 0x8D40, 0x8C70, 0x8C10, 0x8C20, 0x8BD0, 0x8B80, 0x8B70, 0x8BB0, 0x8C20, 0x8CA0, 0x8D70, 0x8F10, 0x90C0, 0x9300, 0x9530, 0x9680, + 0x97B0, 0x9880, 0x99F0, 0x9B50, 0x9CB0, 0x9E20, 0x9FA0, 0xA0B0, 0xA1D0, 0xA220, 0xA290, 0xA2E0, 0xA370, 0xA3F0, 0xA300, 0xA160, + 0x9F00, 0x9B60, 0x96B0, 0x9150, 0x8BC0, 0x87E0, 0x85E0, 0x8530, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, 0x8470, 0x8480, 0x84A0, 0x84E0, 0x8790, 0xB3E0, 0xE6B0, 0x1220, 0x37F0, + 0x5850, 0x7100, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, + 0x7EA0, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, + 0x7F80, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7BB0, 0x4AA0, 0x1F10, 0xF790, + 0xD690, 0xBB30, 0xA890, 0x9D10, 0x9B60, 0xA110, 0xAB60, 0xB7E0, 0xC2A0, 0xCAA0, 0xCE90, 0xCCA0, 0xC730, 0xC110, 0xBB30, 0xB9E0, + 0xBCE0, 0xC510, 0xD2E0, 0xE370, 0xF380, 0x0080, 0x0800, 0x12E0, 0x1A70, 0x24E0, 0x31C0, 0x4090, 0x4F10, 0x5D30, 0x6960, 0x7390, + 0x7C80, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F50, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, + 0x7F00, 0x7F90, 0x7F10, 0x7EF0, 0x7F10, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EE0, 0x7F00, 0x7EF0, + 0x7F30, 0x7F00, 0x7E70, 0x7EC0, 0x7EF0, 0x7F10, 0x7EF0, 0x7E90, 0x7ED0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, + 0x7F10, 0x7F70, 0x7F00, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7F00, 0x7F10, + 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7E20, 0x7C40, 0x7A50, 0x7800, 0x75E0, 0x7440, 0x7210, 0x7100, 0x6F20, 0x6DD0, 0x6CB0, 0x6B70, + 0x6B20, 0x6A00, 0x6910, 0x6820, 0x6700, 0x6650, 0x6520, 0x63C0, 0x6290, 0x60B0, 0x5F70, 0x5D60, 0x5AD0, 0x58B0, 0x54E0, 0x5190, + 0x4D30, 0x4820, 0x4340, 0x3DD0, 0x38B0, 0x32E0, 0x2D20, 0x2730, 0x20E0, 0x1B10, 0x1490, 0x0F30, 0x09A0, 0x04A0, 0x00D0, 0xFCD0, + 0xF790, 0xF250, 0xEBF0, 0xE5F0, 0xDED0, 0xD6F0, 0xD050, 0xC880, 0xC0C0, 0xB780, 0xAE90, 0xA650, 0x9DB0, 0x95C0, 0x8E60, 0x8960, + 0x86C0, 0x85B0, 0x8530, 0x8500, 0x84E0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8530, + 0x85E0, 0x8800, 0x8F90, 0x9BF0, 0xA910, 0xB400, 0xBBF0, 0xC1F0, 0xC5F0, 0xC820, 0xC760, 0xC4E0, 0xC0F0, 0xBAB0, 0xB450, 0x9DA0, + 0x9A10, 0x99F0, 0x9BA0, 0xA080, 0xA7D0, 0xB060, 0xBBE0, 0xC770, 0xD500, 0xE250, 0xF090, 0xFFB0, 0x0EC0, 0x1E70, 0x2E00, 0x3E90, + 0x4E50, 0x5C70, 0x69C0, 0x7410, 0x7BB0, 0x7F00, 0x7EC0, 0x7EC0, 0x7EE0, 0x7F30, 0x7F10, 0x7E90, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F00, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7EC0, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F70, + 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F20, 0x7EE0, + 0x7E90, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F20, 0x7F10, 0x7F10, 0x7F20, + 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7EB0, 0x63E0, 0x4780, 0x2A10, 0x0D20, 0xF1F0, 0xD980, 0xC490, 0xB480, 0xA5F0, + 0x99A0, 0x8EC0, 0x87D0, 0x8590, 0x8510, 0x84E0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84C0, 0x84B0, 0x8490, 0x8480, + 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, + 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x83E0, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8500, 0x8550, + 0x8680, 0x8AB0, 0x9790, 0xA740, 0xB7D0, 0xC880, 0xDA50, 0xEC20, 0xFD00, 0x0D50, 0x1B80, 0x2760, 0x31F0, 0x3B10, 0x4470, 0x4DC0, + 0x5810, 0x6310, 0x6E40, 0x7820, 0x7E90, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F80, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F20, 0x7F20, 0x7EF0, + 0x7ED0, 0x7F10, 0x7F20, 0x7EF0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7C40, 0x6680, 0x4C30, 0x3370, 0x1AB0, 0x0580, + 0xF3A0, 0xE4D0, 0xDA50, 0xD220, 0xCC10, 0xC650, 0xC180, 0xBC50, 0xB5C0, 0xADD0, 0xA560, 0x9CC0, 0x9520, 0x8EA0, 0x89F0, 0x8790, + 0x8640, 0x85B0, 0x84F0, 0x8530, 0x8520, 0x8510, 0x8540, 0x8510, 0x8510, 0x8530, 0x8570, 0x85B0, 0x86B0, 0x8980, 0x90A0, 0x9A40, + 0xA450, 0xAD50, 0xB630, 0xBE70, 0xC660, 0xCF10, 0xD7F0, 0xE0E0, 0xE940, 0xF1D0, 0xF8D0, 0xFE80, 0x0310, 0x0750, 0x0B30, 0x0EE0, + 0x10F0, 0x1250, 0x1400, 0x1450, 0x1470, 0x13E0, 0x11C0, 0x0F90, 0x0D30, 0x0B00, 0x0960, 0x0830, 0x0890, 0x09A0, 0x0B80, 0x0EA0, + 0x1230, 0x16C0, 0x1B80, 0x2010, 0x24E0, 0x28F0, 0x2DB0, 0x3250, 0x36A0, 0x3B50, 0x3FF0, 0x4570, 0x49C0, 0x4D90, 0x5070, 0x5300, + 0x56C0, 0x59F0, 0x5D70, 0x6100, 0x6440, 0x67B0, 0x6AE0, 0x6D90, 0x70B0, 0x7340, 0x7680, 0x7980, 0x7BB0, 0x7DE0, 0x7E70, 0x7F10, + 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F30, 0x7F00, + 0x7F40, 0x7F30, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F60, 0x7EF0, 0x7E90, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7E90, 0x7F00, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, + 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F60, 0x7F00, + 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, + 0x7F10, 0x7D60, 0x70A0, 0x62E0, 0x5510, 0x4760, 0x3A20, 0x2DF0, 0x2110, 0x1520, 0x06F0, 0xF880, 0xE770, 0xD2C0, 0xBB10, 0xA190, + 0x8AB0, 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8480, 0x84B0, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8480, + 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, + 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x8400, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84D0, 0x8500, 0x8570, 0x8760, + 0x9100, 0x9F00, 0xA8E0, 0xAE20, 0xAE30, 0xA9D0, 0xA180, 0x9750, 0x8D00, 0x8720, 0x8550, 0x84F0, 0x84C0, 0x84C0, 0x8490, 0x8490, + 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8480, 0x8450, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, + 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8420, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, + 0x8490, 0x8480, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8520, 0x8580, 0x8650, 0x8830, 0x8CF0, 0x93F0, 0x9BC0, 0xA250, + 0xA920, 0xAE40, 0xB340, 0xB830, 0xBC30, 0xC090, 0xC3F0, 0xC710, 0xCA40, 0xCC10, 0xCD50, 0xCDE0, 0xCDF0, 0xCED0, 0xCFD0, 0xD100, + 0xD230, 0xD330, 0xD450, 0xD560, 0xD600, 0xD5D0, 0xD4C0, 0xD400, 0xD280, 0xD130, 0xCFC0, 0xCEF0, 0xCE30, 0xCCB0, 0xC7E0, 0xC660, + 0xC550, 0xC480, 0xC340, 0xC280, 0xC2E0, 0xC320, 0xC4B0, 0xC580, 0xC6E0, 0xC820, 0xC8A0, 0xCA00, 0xCB20, 0xCC90, 0xCF80, 0xD270, + 0xD540, 0xD7B0, 0xDA50, 0xDCB0, 0xDF60, 0xE210, 0xE5B0, 0xEA30, 0xEE60, 0xF300, 0xF660, 0xF890, 0xFA30, 0xFB30, 0xFAB0, 0xFA50, + 0xF9A0, 0xF990, 0xFB40, 0xFE40, 0x0270, 0x0700, 0x0B90, 0x0F90, 0x1190, 0x1250, 0x10E0, 0x0D90, 0x0880, 0x0240, 0xFBD0, 0xF450, + 0xEC80, 0xE3C0, 0xDB00, 0xD180, 0xC6E0, 0xBC00, 0xAFA0, 0xA200, 0x92F0, 0x8850, 0x8550, 0x84E0, 0x84B0, 0x84A0, 0x8490, 0x8480, + 0x8480, 0x8470, 0x8470, 0x8470, 0x8440, 0x8470, 0x8470, 0x8450, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, + 0x84E0, 0x8500, 0x8540, 0x8600, 0x8810, 0x8E30, 0x9850, 0xA180, 0xAAB0, 0xB260, 0xB930, 0xBF30, 0xC590, 0xCB00, 0xD000, 0xD530, + 0xDA30, 0xDF80, 0xE3D0, 0xE7B0, 0xEB00, 0xEE80, 0xF210, 0xF610, 0xFA30, 0xFE00, 0x01B0, 0x0520, 0x0880, 0x0BB0, 0x0DE0, 0x0F70, + 0x1070, 0x1120, 0x11D0, 0x1280, 0x1330, 0x1440, 0x1580, 0x1670, 0x16B0, 0x1750, 0x1810, 0x1890, 0x1980, 0x1AB0, 0x1C00, 0x1D70, + 0x1F50, 0x2110, 0x2270, 0x2450, 0x25A0, 0x2770, 0x2970, 0x2BB0, 0x2DB0, 0x3040, 0x3320, 0x3590, 0x3800, 0x3AE0, 0x3DD0, 0x4130, + 0x4500, 0x48C0, 0x4C10, 0x4F30, 0x5190, 0x54C0, 0x5730, 0x5A30, 0x5CE0, 0x5F50, 0x6150, 0x6310, 0x6470, 0x65A0, 0x6690, 0x67B0, + 0x68A0, 0x6930, 0x68F0, 0x68B0, 0x68E0, 0x68F0, 0x68D0, 0x6860, 0x67D0, 0x6780, 0x6700, 0x66A0, 0x6600, 0x65D0, 0x6550, 0x6440, + 0x63D0, 0x62E0, 0x6240, 0x6210, 0x6230, 0x6320, 0x6500, 0x6630, 0x66F0, 0x6770, 0x67C0, 0x6770, 0x6750, 0x6790, 0x6820, 0x68D0, + 0x6B30, 0x6E30, 0x7150, 0x75B0, 0x7980, 0x7D00, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7F10, 0x7EB0, 0x7EE0, 0x7F10, + 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F60, 0x7F10, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F40, 0x7F50, 0x7EB0, 0x7F00, 0x7ED0, 0x7F30, 0x7F40, + 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7E90, + 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F50, + 0x7F00, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, + 0x7E90, 0x7EF0, 0x7EF0, 0x7F30, 0x7EB0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, + 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F90, 0x7F00, 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, + 0x7F10, 0x7F20, 0x7F00, 0x7ED0, 0x7F30, 0x7F00, 0x7EE0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F40, 0x7F10, + 0x7C60, 0x7A40, 0x7A50, 0x7BF0, 0x7EA0, 0x7EA0, 0x7ED0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, + 0x7F20, 0x7840, 0x6DB0, 0x6740, 0x6280, 0x6130, 0x63F0, 0x6980, 0x7110, 0x7810, 0x7D70, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F50, + 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F60, 0x7EC0, 0x7840, 0x6ED0, 0x6430, 0x57F0, 0x4AC0, 0x3C90, 0x2F30, 0x20C0, 0x15F0, 0x0F90, + 0x0F40, 0x1580, 0x2090, 0x2F70, 0x41E0, 0x5550, 0x6AB0, 0x7B70, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7E90, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7EF0, 0x7F10, 0x7E60, 0x7900, + 0x7380, 0x6FB0, 0x6D30, 0x6CC0, 0x6ED0, 0x7230, 0x7710, 0x7C30, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, + 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F00, + 0x7EF0, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, + 0x7F10, 0x7F60, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, + 0x7F70, 0x7F00, 0x7ED0, 0x7F00, 0x7EE0, 0x7F90, 0x7EF0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7F50, + 0x7ED0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, 0x7ED0, 0x70B0, 0x6130, + 0x4F00, 0x3F90, 0x3280, 0x29A0, 0x2560, 0x25D0, 0x2910, 0x2F20, 0x3640, 0x3EB0, 0x46E0, 0x4F40, 0x5810, 0x60F0, 0x6940, 0x6FA0, + 0x73F0, 0x75B0, 0x73D0, 0x7010, 0x6A30, 0x6270, 0x59E0, 0x5110, 0x48B0, 0x40A0, 0x3910, 0x31B0, 0x2C20, 0x2800, 0x25D0, 0x2470, + 0x2460, 0x24C0, 0x25B0, 0x26B0, 0x26F0, 0x2720, 0x2540, 0x2350, 0x20D0, 0x1DA0, 0x1A70, 0x1600, 0x1160, 0x0D20, 0x08C0, 0x05D0, + 0x02D0, 0x0020, 0xFD90, 0xFB40, 0xF9D0, 0xF820, 0xF640, 0xF3B0, 0xF090, 0xED20, 0xE8C0, 0xE370, 0xDD20, 0xD5F0, 0xCE50, 0xC720, + 0xC020, 0xBA20, 0xB480, 0xB0A0, 0xADD0, 0xAAE0, 0xA7F0, 0xA460, 0xA040, 0x9BB0, 0x96B0, 0x9200, 0x8E10, 0x8B80, 0x89B0, 0x88D0, + 0x88A0, 0x8910, 0x8A40, 0x8C60, 0x9080, 0x9580, 0x9B40, 0xA140, 0xA7C0, 0xADF0, 0xB560, 0xBC30, 0xC2E0, 0xC900, 0xCEC0, 0xD510, + 0xDA80, 0xDF80, 0xE540, 0xE980, 0xEE20, 0xF1D0, 0xF590, 0xF990, 0xFD40, 0x00F0, 0x0420, 0x06B0, 0x0A30, 0x0C30, 0x0EA0, 0x1000, + 0x10D0, 0x10D0, 0x10E0, 0x1190, 0x1290, 0x13C0, 0x1490, 0x1520, 0x1570, 0x14F0, 0x1450, 0x1430, 0x14A0, 0x1690, 0x1850, 0x1A70, + 0x1CC0, 0x1DD0, 0x1F40, 0x2020, 0x20C0, 0x2190, 0x2290, 0x2360, 0x2310, 0x21B0, 0x1FE0, 0x1C60, 0x17C0, 0x1210, 0x0B60, 0x03A0, + 0xFA90, 0xF220, 0xEA20, 0xE190, 0xDA10, 0xD270, 0xCBA0, 0xC590, 0xC0E0, 0xBD80, 0xBB60, 0xBB30, 0xBB40, 0xBC10, 0xBEF0, 0xC2A0, + 0xC7C0, 0xCCC0, 0xD320, 0xD7C0, 0xDB90, 0xDF80, 0xE290, 0xE570, 0xE950, 0xEC00, 0xEEF0, 0xF090, 0xF1D0, 0xF200, 0xF0F0, 0xEF30, + 0xEBD0, 0xE720, 0xE120, 0xD7B0, 0xCED0, 0xC480, 0xB990, 0xAE00, 0xA200, 0x95D0, 0x8BD0, 0x86B0, 0x8550, 0x84F0, 0x84D0, 0x84B0, + 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8460, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8470, 0x8460, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84F0, 0x8530, 0x85C0, 0x87E0, 0x9080, + 0x9D20, 0xA9F0, 0xB740, 0xC430, 0xD0E0, 0xDD70, 0xEA00, 0xF670, 0x0350, 0x0F60, 0x1B10, 0x2630, 0x30C0, 0x54E0, 0x5CC0, 0x63B0, + 0x6A20, 0x70D0, 0x7630, 0x7AA0, 0x7DD0, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F30, + 0x7F30, 0x7F40, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7EE0, 0x7CC0, 0x7990, 0x75E0, 0x7140, 0x6BA0, 0x6690, 0x61F0, 0x5E20, + 0x5B40, 0x58D0, 0x56D0, 0x55A0, 0x55E0, 0x56E0, 0x58C0, 0x5B50, 0x5E30, 0x6170, 0x6470, 0x6820, 0x6B50, 0x6E10, 0x7120, 0x7410, + 0x76D0, 0x7990, 0x7B70, 0x7D80, 0x7EB0, 0x7F10, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, + 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, + 0x7F40, 0x7F10, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F70, 0x7F40, 0x7EC0, 0x7F10, 0x7F40, 0x7F50, 0x7F10, 0x7E70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7E80, 0x7EC0, + 0x7F00, 0x7F20, 0x7EE0, 0x7980, 0x7270, 0x6B70, 0x6460, 0x5E80, 0x57A0, 0x52E0, 0x4E10, 0x4900, 0x44A0, 0x3F80, 0x3910, 0x32B0, + 0x2BC0, 0x2450, 0x1D70, 0x1740, 0x12C0, 0x0F30, 0x0E20, 0x0E60, 0x0FD0, 0x1280, 0x15A0, 0x1970, 0x1D30, 0x2120, 0x25E0, 0x2B80, + 0x3330, 0x3BB0, 0x45A0, 0x5160, 0x5C40, 0x66F0, 0x70B0, 0x7930, 0x7EC0, 0x7E90, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, + 0x7EC0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7BB0, 0x6DA0, 0x5F10, 0x5010, 0x4220, 0x3420, 0x26E0, 0x1AC0, 0x0F60, + 0x03D0, 0xF9A0, 0xEFA0, 0xE650, 0xDCF0, 0xD2F0, 0xC8B0, 0xBD30, 0xB010, 0x9FD0, 0x8FE0, 0x8720, 0x8520, 0x84E0, 0x84C0, 0x84C0, + 0x84A0, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, + 0x84E0, 0x8510, 0x8590, 0x8790, 0x9180, 0x9FA0, 0xABC0, 0xB700, 0xC0D0, 0xCA90, 0xD3A0, 0xDC60, 0xE4E0, 0xEE90, 0xF7E0, 0x0110, + 0x0A10, 0x11E0, 0x1840, 0x1DD0, 0x2210, 0x2530, 0x2880, 0x2B90, 0x2FA0, 0x33E0, 0x3A70, 0x4230, 0x4AD0, 0x5440, 0x5C90, 0x6580, + 0x6C20, 0x7150, 0x7610, 0x7960, 0x7C40, 0x7E50, 0x7EF0, 0x7F00, 0x7E90, 0x7ED0, 0x7D60, 0x78A0, 0x72D0, 0x6AD0, 0x61E0, 0x57E0, + 0x4C10, 0x3F40, 0x3380, 0x2800, 0x1CE0, 0x1260, 0x0950, 0x0030, 0xF750, 0xEF20, 0xE690, 0xE030, 0xDA90, 0xD5A0, 0xD290, 0xD110, + 0xD100, 0xD320, 0xD6D0, 0xDE70, 0xE750, 0xF230, 0xFEB0, 0x0C60, 0x1B70, 0x2A40, 0x39E0, 0x4820, 0x55D0, 0x7B20, 0x7ED0, 0x7EF0, + 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7960, 0x6550, 0x4C50, + 0x3100, 0x1480, 0xF650, 0xDB30, 0xC040, 0xA750, 0x9020, 0x8690, 0x8510, 0x84E0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x84F0, 0x8510, 0x8550, 0x8600, 0x87D0, 0x8DF0, 0x9850, 0xA390, + 0xADF0, 0xB820, 0xC1F0, 0xCB70, 0xD490, 0xDCC0, 0xE5A0, 0xECC0, 0xF2D0, 0xF850, 0xFC20, 0x00A0, 0x0390, 0x05B0, 0x07A0, 0x0740, + 0x0640, 0x0410, 0x0020, 0xFC80, 0xF790, 0xF250, 0xEC60, 0xE660, 0xDE30, 0xD4A0, 0xCA10, 0xBE10, 0xB0B0, 0xA230, 0x9340, 0x88E0, + 0x85B0, 0x8500, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, + 0x84A0, 0x84B0, 0x84C0, 0x84F0, 0x8510, 0x8570, 0x86B0, 0x8B50, 0x9690, 0xA2D0, 0xAEE0, 0xBA00, 0xC580, 0xCF80, 0xD920, 0xE210, + 0xEBD0, 0xF570, 0xFFA0, 0x0AC0, 0x1680, 0x2400, 0x2F90, 0x39E0, 0x42B0, 0x4A00, 0x50C0, 0x5510, 0x57A0, 0x5860, 0x5500, 0x4F20, + 0x4480, 0x3690, 0x2730, 0x1660, 0x0500, 0xF4B0, 0xE530, 0xD580, 0xC820, 0xBD20, 0xB340, 0xAAF0, 0xA460, 0x9FE0, 0x9C00, 0x9920, + 0x9780, 0x9670, 0x9630, 0x9510, 0x9500, 0x9520, 0x94A0, 0x9300, 0x8F70, 0x8B70, 0x8840, 0x8650, 0x8570, 0x8510, 0x8520, 0x84D0, + 0x84C0, 0x84B0, 0x84A0, 0x84C0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x84A0, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84E0, 0x8500, 0x8530, 0x8580, 0x8660, + 0x8890, 0x8F70, 0x9AF0, 0xA710, 0xB340, 0xBE80, 0xC970, 0xD0D0, 0xD590, 0xD7D0, 0xD740, 0xD4C0, 0xCF20, 0xC770, 0xBE20, 0xB1F0, + 0xA3F0, 0x9430, 0x88B0, 0x8560, 0x84E0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8460, 0x8450, 0x8450, + 0x8460, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, + 0x8550, 0x8550, 0x85A0, 0x8620, 0x86B0, 0x8710, 0x8780, 0x87B0, 0x87C0, 0x87E0, 0x87B0, 0x8790, 0x8760, 0x8700, 0x86D0, 0x86A0, + 0x8680, 0x8670, 0x8650, 0x8630, 0x8610, 0x85F0, 0x8560, 0x8580, 0x8550, 0x8530, 0x8510, 0x84F0, 0x8500, 0x84D0, 0x84C0, 0x8480, + 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, + 0x84C0, 0x84D0, 0x8500, 0x8540, 0x8610, 0x8810, 0x8D90, 0x9770, 0xA050, 0xA890, 0xB030, 0xB560, 0xB920, 0xBAF0, 0xBC50, 0xBCC0, + 0xBC60, 0xBB10, 0xB980, 0xB6D0, 0xB3F0, 0xAF60, 0xA9C0, 0xA390, 0x9CA0, 0x94E0, 0x8DF0, 0x88F0, 0x8660, 0x8560, 0x8500, 0x84E0, + 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x84A0, + 0x84A0, 0x84C0, 0x84D0, 0x8500, 0x8540, 0x85F0, 0x8750, 0x8A20, 0x8E60, 0x9370, 0x9960, 0x9F80, 0xA5F0, 0xACD0, 0xB2A0, 0xB690, + 0xB820, 0xB6D0, 0xB190, 0xA7E0, 0x9B20, 0x8D70, 0x8630, 0x8500, 0x84C0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8480, + 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, + 0x84B0, 0x84D0, 0x84F0, 0x8530, 0x8600, 0x8730, 0x8AB0, 0x9160, 0x98C0, 0x9F80, 0xA600, 0xAC70, 0xB260, 0xB7F0, 0xBCE0, 0xC1C0, + 0xC670, 0xCB20, 0xCFB0, 0xD400, 0xD820, 0xDBA0, 0xDEB0, 0xE1B0, 0xE500, 0xE780, 0xE8E0, 0xE960, 0xE6E0, 0xE500, 0xE310, 0xE050, + 0xDD10, 0xD930, 0xD4C0, 0xD0D0, 0xCCE0, 0xC880, 0xC560, 0xC2E0, 0xBFE0, 0xBCA0, 0xB9D0, 0xB740, 0xB490, 0xB200, 0xAFD0, 0xAE20, + 0xADE0, 0xADB0, 0xADF0, 0xADF0, 0xAE40, 0xAE90, 0xAEA0, 0xAED0, 0xAFC0, 0xB090, 0xB190, 0xB2C0, 0xB4C0, 0xB6B0, 0xB920, 0xBBA0, + 0xBE00, 0xBFF0, 0xC220, 0xC430, 0xC710, 0xC9F0, 0xCD00, 0xD050, 0xD3F0, 0xD6D0, 0xDA40, 0xDC70, 0xDE80, 0xE0F0, 0xE360, 0xE590, + 0xE750, 0xE9A0, 0xEB80, 0xED80, 0xEFC0, 0xF180, 0xF330, 0xF470, 0xF5E0, 0xF7C0, 0xF930, 0xFAD0, 0xFC60, 0xFCF0, 0xFD30, 0xFD80, + 0xFD60, 0xFD90, 0xFD30, 0xFD90, 0xFDA0, 0xFDB0, 0xFDB0, 0xFCE0, 0xFCD0, 0xFCB0, 0xFC10, 0xFC20, 0xFBC0, 0xFC60, 0xFCD0, 0xFCD0, + 0xFDB0, 0xFE20, 0xFEA0, 0xFE90, 0xFE60, 0xFF60, 0x0040, 0x0190, 0x02A0, 0x0420, 0x0640, 0x0860, 0x0A70, 0x0CC0, 0x0EF0, 0x11F0, + 0x1560, 0x1870, 0x1B70, 0x1F80, 0x23F0, 0x28F0, 0x2EA0, 0x3510, 0x3AD0, 0x4130, 0x4660, 0x4C50, 0x5200, 0x5640, 0x5B60, 0x5F90, + 0x63B0, 0x67A0, 0x6A50, 0x6D30, 0x6F60, 0x7070, 0x71C0, 0x7210, 0x72A0, 0x7300, 0x7210, 0x7150, 0x6F60, 0x6E00, 0x6BB0, 0x68B0, + 0x6660, 0x6340, 0x6080, 0x5DB0, 0x5AD0, 0x5910, 0x5800, 0x5800, 0x5950, 0x5B90, 0x5F70, 0x63C0, 0x68F0, 0x6F20, 0x74E0, 0x7B60, + 0x7ED0, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7280, 0x6460, 0x55C0, 0x44A0, + 0x3560, 0x26F0, 0x1910, 0x0DB0, 0x02E0, 0xFA10, 0xF400, 0xEF60, 0xEC90, 0xEB60, 0xEAB0, 0xEB00, 0xEBD0, 0xED30, 0xEEB0, 0xF020, + 0xF350, 0xF700, 0xFB40, 0x00B0, 0x05E0, 0x0BA0, 0x1090, 0x1610, 0x1BE0, 0x2140, 0x2810, 0x2E80, 0x3570, 0x3B40, 0x40D0, 0x45F0, + 0x49C0, 0x4CD0, 0x4F10, 0x5040, 0x50D0, 0x5010, 0x4E90, 0x4C60, 0x4940, 0x4610, 0x4100, 0x3A70, 0x3270, 0x2910, 0x1E40, 0x1270, + 0x05B0, 0xF920, 0xEC20, 0xDFC0, 0xD450, 0xC8A0, 0xBF20, 0xB610, 0xAE20, 0xA6F0, 0xA020, 0x9B80, 0x9770, 0x9440, 0x9170, 0x8F00, + 0x8D40, 0x8B90, 0x8A80, 0x8990, 0x88F0, 0x88A0, 0x8830, 0x87F0, 0x87D0, 0x8790, 0x8780, 0x8740, 0x8700, 0x86C0, 0x86B0, 0x8710, + 0x8770, 0x87F0, 0x88B0, 0x89E0, 0x8C00, 0x8EE0, 0x9270, 0x9600, 0x98A0, 0x9A70, 0x9B90, 0x9C20, 0x9C30, 0x9BF0, 0x9BF0, 0x9A70, + 0x99B0, 0x9850, 0x9620, 0x9480, 0x9240, 0x90F0, 0x8FA0, 0x8E50, 0x8DA0, 0x8D00, 0x8C40, 0x8B90, 0x8B00, 0x8AA0, 0x8A60, 0x8A50, + 0x8AB0, 0x8B70, 0x8CC0, 0x8F10, 0x9210, 0x95C0, 0x9A10, 0x9EB0, 0xA320, 0xA950, 0xAF30, 0xB4A0, 0xBB60, 0xC150, 0xC800, 0xCEA0, + 0xD470, 0xDAB0, 0xE140, 0xE750, 0xED70, 0xF1D0, 0xF6C0, 0xFAB0, 0xFF30, 0x0450, 0x0920, 0x0F10, 0x13C0, 0x18C0, 0x1DF0, 0x23D0, + 0x2AA0, 0x30C0, 0x36F0, 0x3BB0, 0x3FF0, 0x44B0, 0x4870, 0x4CF0, 0x50D0, 0x5430, 0x5870, 0x5C00, 0x5F70, 0x6330, 0x65C0, 0x68C0, + 0x6B50, 0x6D70, 0x6FE0, 0x7110, 0x72B0, 0x7430, 0x7540, 0x7630, 0x7600, 0x7620, 0x7650, 0x7650, 0x76B0, 0x7640, 0x75C0, 0x7520, + 0x7420, 0x7380, 0x7290, 0x7170, 0x6FE0, 0x6D10, 0x6B80, 0x68A0, 0x6510, 0x62B0, 0x5EB0, 0x5B60, 0x57F0, 0x5490, 0x50B0, 0x4C80, + 0x4890, 0x44F0, 0x4140, 0x3E20, 0x3B80, 0x3980, 0x3760, 0x3590, 0x34F0, 0x33B0, 0x33D0, 0x3390, 0x3430, 0x3540, 0x3590, 0x3710, + 0x38A0, 0x3A40, 0x3C30, 0x3DE0, 0x3F60, 0x4000, 0x40B0, 0x41B0, 0x4240, 0x42D0, 0x4270, 0x4100, 0x3FD0, 0x3E00, 0x3C60, 0x3C10, + 0x3BD0, 0x3CB0, 0x3D60, 0x3E50, 0x3F50, 0x4090, 0x4210, 0x4320, 0x4460, 0x45D0, 0x4710, 0x4770, 0x4660, 0x4470, 0x4230, 0x3EB0, + 0x3B70, 0x3780, 0x3380, 0x2FA0, 0x2C00, 0x28F0, 0x2600, 0x21F0, 0x1F10, 0x1B70, 0x1830, 0x14C0, 0x1150, 0x0DB0, 0x0860, 0x0290, + 0xFB10, 0xF2F0, 0xEB20, 0xE330, 0xDCD0, 0xD820, 0xD4C0, 0xD330, 0xD300, 0xD3B0, 0xD450, 0xD5E0, 0xD8C0, 0xDC60, 0xE0B0, 0xE5B0, + 0xEBC0, 0xF380, 0xFC40, 0x04F0, 0x0E80, 0x1820, 0x22C0, 0x2D90, 0x37F0, 0x4160, 0x48F0, 0x5150, 0x5670, 0x5A60, 0x5CF0, 0x5D90, + 0x5D20, 0x5AA0, 0x55F0, 0x4ED0, 0x4420, 0x39A0, 0x2D50, 0x2030, 0x11E0, 0x01F0, 0xF270, 0xE280, 0xD3A0, 0xC4D0, 0xB840, 0xACB0, + 0xA250, 0x9890, 0x90D0, 0x8B30, 0x8840, 0x86C0, 0x8600, 0x85C0, 0x8590, 0x8590, 0x8550, 0x8590, 0x85B0, 0x85D0, 0x8610, 0x85E0, + 0x85F0, 0x8610, 0x8630, 0x8650, 0x86A0, 0x86C0, 0x86E0, 0x86E0, 0x86C0, 0x86C0, 0x86B0, 0x86A0, 0x8690, 0x8670, 0x8660, 0x8640, + 0x8640, 0x8630, 0x8620, 0x8630, 0x8640, 0x8650, 0x8660, 0x8670, 0x86A0, 0x8700, 0x87B0, 0x88C0, 0x8AB0, 0x8DE0, 0x9200, 0x9730, + 0x9D00, 0xA2F0, 0xA940, 0xB040, 0xB7C0, 0xBF30, 0xC6F0, 0xD150, 0xD930, 0xE140, 0xE880, 0xEF50, 0xF680, 0xFD80, 0x0550, 0x0DD0, + 0x1600, 0x1F00, 0x28F0, 0x3280, 0x3BC0, 0x4520, 0x4EF0, 0x57F0, 0x6060, 0x6840, 0x6F40, 0x7520, 0x7970, 0x7CB0, 0x7E70, 0x7EE0, + 0x7F00, 0x7ED0, 0x7D90, 0x7A20, 0x74D0, 0x6E70, 0x6720, 0x5E40, 0x5430, 0x48B0, 0x3CE0, 0x2FA0, 0x2210, 0x1440, 0x0760, 0xFBD0, + 0xF0D0, 0xE720, 0xDF80, 0xD8F0, 0xD3B0, 0xCF60, 0xCC40, 0xCA70, 0xC960, 0xC910, 0xC910, 0xC9B0, 0xCAC0, 0xCB70, 0xCBD0, 0xCC50, + 0xCBE0, 0xCAD0, 0xCA30, 0xC8B0, 0xC820, 0xC780, 0xC7B0, 0xC810, 0xC7B0, 0xC7B0, 0xC6E0, 0xC600, 0xC580, 0xC4B0, 0xC420, 0xC2C0, + 0xC120, 0xBE90, 0xBC20, 0xBA20, 0xB8D0, 0xB830, 0xB6C0, 0xB530, 0xB310, 0xB090, 0xADE0, 0xAB70, 0xA930, 0xA740, 0xA5A0, 0xA470, + 0xA2E0, 0xA190, 0xA0E0, 0xA0C0, 0xA030, 0x9F50, 0x9E20, 0x9DA0, 0x9D10, 0x9C00, 0x9AF0, 0x98C0, 0x95F0, 0x9360, 0x90A0, 0x8E90, + 0x8D10, 0x8BB0, 0x8AF0, 0x8AD0, 0x8AB0, 0x8A70, 0x8AE0, 0x8BC0, 0x8E60, 0x9320, 0x9A90, 0xA440, 0xAE60, 0xB940, 0xC560, 0xD130, + 0xDC70, 0xE730, 0xF150, 0xFAB0, 0x0340, 0x0AC0, 0x1130, 0x18C0, 0x1FF0, 0x2770, 0x2E00, 0x3340, 0x35B0, 0x3300, 0x29C0, 0x1A80, + 0x0530, 0xEF70, 0xDB20, 0xCB20, 0xBF60, 0xB730, 0xB1C0, 0xAD00, 0xA810, 0xA180, 0x9AE0, 0x93D0, 0x8DD0, 0x89C0, 0x8760, 0x8610, + 0x8580, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8450, 0x8470, 0x8470, 0x8470, 0x8490, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, + 0x84C0, 0x84F0, 0x8570, 0x8920, 0x9F80, 0xB7A0, 0xD0A0, 0xE550, 0xF730, 0x0670, 0x1340, 0x1E90, 0x2860, 0x2FC0, 0x35F0, 0x3930, + 0x3900, 0x3590, 0x3010, 0x29B0, 0x2220, 0x19D0, 0x11C0, 0x08A0, 0x0040, 0xF7C0, 0xEE70, 0xCB00, 0xBE20, 0xAFA0, 0x9EE0, 0x8E30, + 0x8630, 0x84F0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8430, 0x8420, 0x8420, 0x8430, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, + 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8540, 0x85B0, 0x8690, 0x8860, 0x8C40, 0x9260, 0x99A0, 0xA000, + 0xA650, 0xABD0, 0xB020, 0xB400, 0xB710, 0xBAA0, 0xBDC0, 0xC070, 0xC430, 0xC770, 0xC8F0, 0xCA00, 0xC940, 0xC860, 0xC600, 0xC3B0, + 0xC0C0, 0xBE50, 0xBCC0, 0xBB90, 0xB9D0, 0xB870, 0xB770, 0xB6B0, 0xB5C0, 0xB650, 0xB7E0, 0xBB70, 0xBFA0, 0xC4A0, 0xC9E0, 0xCF00, + 0xD400, 0xDA20, 0xE0B0, 0xE770, 0xEEF0, 0xF690, 0xFE90, 0x0570, 0x0BF0, 0x1320, 0x18D0, 0x2000, 0x26C0, 0x2D20, 0x3350, 0x39E0, + 0x4010, 0x45B0, 0x4B70, 0x5160, 0x55C0, 0x5B10, 0x5FD0, 0x6460, 0x6950, 0x6D00, 0x7080, 0x73A0, 0x75D0, 0x7830, 0x79B0, 0x7B20, + 0x7BD0, 0x7C60, 0x7D40, 0x7D90, 0x7DF0, 0x7DC0, 0x7DC0, 0x7D90, 0x7D90, 0x7D40, 0x7C90, 0x7BB0, 0x7AB0, 0x78E0, 0x7650, 0x7310, + 0x6EE0, 0x56F0, 0x4F30, 0x4870, 0x4180, 0x3AB0, 0x3430, 0x2E60, 0x29A0, 0x25C0, 0x2290, 0x1FD0, 0x1CC0, 0x1AE0, 0x19C0, 0x1930, + 0x1AA0, 0x1C40, 0x1F50, 0x2230, 0x2570, 0x2960, 0x2D10, 0x3120, 0x3560, 0x39F0, 0x4100, 0x46A0, 0x4CC0, 0x52D0, 0x58B0, 0x5F20, + 0x6540, 0x6A90, 0x6FF0, 0x7490, 0x78F0, 0x7BC0, 0x7DC0, 0x7EC0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7E70, 0x7E20, 0x7E40, 0x7EB0, + 0x7F30, 0x7F00, 0x7F00, 0x7F10, 0x7EF0, 0x7DB0, 0x79A0, 0x7400, 0x6D90, 0x6750, 0x6260, 0x5EA0, 0x5D80, 0x5E80, 0x6120, 0x64C0, + 0x69C0, 0x6F10, 0x7570, 0x7BE0, 0x7EF0, 0x7F00, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, + 0x7EA0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7F10, 0x7F40, 0x7F10, 0x7F60, 0x7EE0, 0x7F10, 0x7F10, 0x7F10, + 0x7F60, 0x7F10, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, + 0x7F10, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F30, 0x7EF0, 0x7E90, 0x7ED0, 0x7F00, 0x7F10, 0x7F10, 0x7E90, 0x7F00, 0x6050, 0x4390, 0x3110, + 0x2800, 0x27C0, 0x2E40, 0x39A0, 0x4900, 0x59D0, 0x6BD0, 0x79E0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, + 0x7F50, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7D20, 0x6360, 0x3EB0, 0x14E0, 0xE7D0, 0xBAD0, 0x9200, 0x8570, 0x84E0, 0x84C0, + 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8520, 0x8540, 0x8560, 0x8570, 0x8550, 0x8530, 0x8520, + 0x8510, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8500, 0x8520, 0x8560, 0x85E0, 0x8740, 0x8B20, 0x9540, 0x9F20, 0xA860, 0xAFC0, + 0xB4F0, 0xB8E0, 0xBA80, 0xBB50, 0xBA60, 0xB830, 0xB450, 0xAEF0, 0xA7D0, 0x9F40, 0x95F0, 0x8DD0, 0x88A0, 0x8670, 0x8590, 0x8540, + 0x8520, 0x8500, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x84F0, 0x8500, + 0x8510, 0x8520, 0x8550, 0x8580, 0x85E0, 0x8670, 0x8770, 0x8930, 0x8C40, 0x9130, 0x9580, 0x9A80, 0x9F60, 0xA3C0, 0xA8A0, 0xAD80, + 0xB240, 0xB710, 0xBB20, 0xBF10, 0xC200, 0xC510, 0xC820, 0xCAC0, 0xCD40, 0xCF80, 0xD160, 0xD380, 0xD520, 0xD7E0, 0xDA40, 0xDC50, + 0xE000, 0xE3F0, 0xE860, 0xECC0, 0xF230, 0xF780, 0xFC60, 0x0200, 0x07E0, 0x0DC0, 0x1480, 0x1A50, 0x20E0, 0x27F0, 0x2E90, 0x35F0, + 0x3CE0, 0x4450, 0x4BF0, 0x5300, 0x5A40, 0x6040, 0x6760, 0x6DF0, 0x7490, 0x7C00, 0x7ED0, 0x7F10, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x78A0, 0x6A30, 0x5AF0, 0x4C30, 0x3E40, 0x3090, 0x2380, 0x16B0, 0x0B20, 0x00E0, 0xF850, + 0xF230, 0xED70, 0xE8F0, 0xE450, 0xDE30, 0xD810, 0xD280, 0xCD40, 0xCA00, 0xC960, 0xCB50, 0xCFF0, 0xD580, 0xDC30, 0xE330, 0xE9E0, + 0xF000, 0xF410, 0xF620, 0xF510, 0xF230, 0xEC30, 0xE440, 0xDB30, 0xD080, 0xC4A0, 0xB880, 0xAAB0, 0x9D70, 0x90A0, 0x88E0, 0x8630, + 0x8560, 0x8520, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, + 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, 0x84C0, + 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x84D0, 0x8500, 0x84F0, 0x84F0, 0x84B0, 0x8520, 0x8540, 0x8580, 0x85E0, 0x86A0, 0x8800, 0x8AE0, + 0x8FD0, 0x96E0, 0x9D50, 0xA350, 0xA9F0, 0xB080, 0xB640, 0xBBF0, 0xC1D0, 0xC710, 0xCCB0, 0xD310, 0xD870, 0xDD90, 0xE2C0, 0xE740, + 0xEAF0, 0xED80, 0xEFE0, 0xF260, 0xF420, 0xF600, 0xF790, 0xF810, 0xF910, 0xF920, 0xF900, 0xF950, 0xF910, 0xF940, 0xFA40, 0xFB40, + 0xFC20, 0xFD20, 0xFD60, 0xFE10, 0xFF30, 0x0000, 0x00D0, 0x0190, 0x0360, 0x04E0, 0x0640, 0x07F0, 0x08B0, 0x0960, 0x0A00, 0x0A30, + 0x0B60, 0x0C50, 0x0D30, 0x0ED0, 0x1050, 0x12A0, 0x1440, 0x15F0, 0x1810, 0x1A70, 0x1CA0, 0x1F20, 0x22E0, 0x2710, 0x2BB0, 0x31B0, + 0x3760, 0x3D20, 0x4280, 0x4780, 0x4BF0, 0x4FF0, 0x5360, 0x5590, 0x5780, 0x5970, 0x5B70, 0x5DC0, 0x6010, 0x6280, 0x64A0, 0x65A0, + 0x6690, 0x6730, 0x66C0, 0x66D0, 0x6730, 0x6810, 0x68E0, 0x68B0, 0x68B0, 0x6740, 0x6660, 0x6480, 0x62C0, 0x6080, 0x5D10, 0x5A90, + 0x5730, 0x5360, 0x5010, 0x4C10, 0x4780, 0x4280, 0x3C60, 0x36C0, 0x3000, 0x2A50, 0x2420, 0x1D40, 0x1650, 0x0E10, 0x0600, 0xFE40, + 0xF680, 0xF000, 0xE940, 0xE300, 0xDDB0, 0xD790, 0xD1A0, 0xCC50, 0xC730, 0xC2E0, 0xBE60, 0xB9C0, 0xB540, 0xB100, 0xADA0, 0xAA70, + 0xA810, 0xA640, 0xA410, 0xA2D0, 0xA170, 0xA0A0, 0x9F40, 0x9D80, 0x9BA0, 0x9A00, 0x9890, 0x97B0, 0x9700, 0x9760, 0x9720, 0x96E0, + 0x96B0, 0x9570, 0x94B0, 0x9460, 0x94B0, 0x94A0, 0x9440, 0x93E0, 0x9350, 0x92B0, 0x9130, 0x9040, 0x8F00, 0x8DC0, 0x8CA0, 0x8C00, + 0x8B10, 0x8A70, 0x89C0, 0x8940, 0x88E0, 0x8840, 0x87F0, 0x8770, 0x8730, 0x86E0, 0x8660, 0x8640, 0x8620, 0x8600, 0x85E0, 0x85C0, + 0x85A0, 0x8590, 0x8570, 0x8560, 0x8540, 0x8530, 0x8530, 0x8520, 0x8520, 0x8560, 0x8520, 0x8510, 0x8510, 0x8510, 0x8500, 0x8500, + 0x8510, 0x8500, 0x8510, 0x8510, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8530, 0x8530, 0x8540, 0x8550, 0x8560, 0x8580, 0x85A0, + 0x85B0, 0x85D0, 0x85D0, 0x85E0, 0x8600, 0x85D0, 0x85E0, 0x85E0, 0x85F0, 0x8610, 0x8630, 0x8660, 0x8680, 0x8680, 0x8690, 0x86B0, + 0x86E0, 0x8710, 0x8760, 0x87D0, 0x8840, 0x88E0, 0x89A0, 0x8A40, 0x8A90, 0x8AB0, 0x8B10, 0x8B60, 0x8C30, 0x8D40, 0x8DB0, 0x8EF0, + 0x8FB0, 0x9010, 0x9090, 0x9120, 0x9230, 0x9350, 0x9410, 0x9560, 0x9680, 0x97A0, 0x9890, 0x9990, 0x9AF0, 0x9B90, 0x9C70, 0x9CD0, + 0x9D10, 0x9D30, 0x9E00, 0x9E40, 0x9D40, 0x9C90, 0x9CD0, 0x9CB0, 0x9C60, 0x9C20, 0x9C10, 0x9BC0, 0x9B70, 0x9B60, 0x9B50, 0x9B60, + 0x9B40, 0x9AD0, 0x9A30, 0x9A20, 0x99B0, 0x99E0, 0x99A0, 0x9930, 0x9810, 0x9720, 0x96C0, 0x9680, 0x96A0, 0x9700, 0x9690, 0x9630, + 0x95C0, 0x94F0, 0x94A0, 0x93A0, 0x9350, 0x9290, 0x91A0, 0x9090, 0x8F50, 0x8E40, 0x8D40, 0x8C90, 0x8C30, 0x8B90, 0x8B40, 0x8AA0, + 0x8A30, 0x89F0, 0x89B0, 0x8970, 0x8940, 0x8930, 0x8980, 0x89D0, 0x8AD0, 0x8BD0, 0x8CC0, 0x8DF0, 0x8EE0, 0x9010, 0x9140, 0x92C0, + 0x9530, 0x9720, 0x9970, 0x9B10, 0x9D20, 0x9F70, 0xA160, 0xA380, 0xA580, 0xA770, 0xA960, 0xAB60, 0xADC0, 0xAF70, 0xB190, 0xB3D0, + 0xB5F0, 0xB840, 0xBA60, 0xBCC0, 0xBF90, 0xC240, 0xC510, 0xC7A0, 0xC910, 0xCBA0, 0xCD70, 0xD060, 0xD2C0, 0xD4F0, 0xD750, 0xDA40, + 0xDCA0, 0xDF30, 0xE1B0, 0xE570, 0xE830, 0xEB90, 0xEF40, 0xF240, 0xF560, 0xF840, 0xFC40, 0xFF50, 0x0390, 0x0870, 0x0CE0, 0x1180, + 0x1630, 0x1A60, 0x1F60, 0x2340, 0x2700, 0x2B40, 0x2FC0, 0x34D0, 0x3960, 0x3D90, 0x41B0, 0x4470, 0x4840, 0x4AF0, 0x4DF0, 0x50E0, + 0x5320, 0x55B0, 0x57B0, 0x59B0, 0x5BC0, 0x5D50, 0x5F30, 0x60E0, 0x61F0, 0x6310, 0x6370, 0x6440, 0x6450, 0x63B0, 0x63C0, 0x6310, + 0x6390, 0x63B0, 0x63A0, 0x63F0, 0x62B0, 0x6220, 0x6140, 0x5FF0, 0x6000, 0x5F20, 0x5E80, 0x5DD0, 0x5C40, 0x5BC0, 0x5A10, 0x5930, + 0x5860, 0x5770, 0x57D0, 0x57A0, 0x5770, 0x5780, 0x56A0, 0x5690, 0x5690, 0x56B0, 0x5760, 0x57C0, 0x5880, 0x58E0, 0x5920, 0x58F0, + 0x57F0, 0x57A0, 0x56A0, 0x55D0, 0x5490, 0x5370, 0x5220, 0x5010, 0x4E70, 0x4D20, 0x4AD0, 0x4980, 0x4780, 0x4540, 0x43D0, 0x4200, + 0x4120, 0x3F10, 0x3D90, 0x3CB0, 0x3BC0, 0x3B40, 0x3A90, 0x3A10, 0x3A40, 0x3A10, 0x3A60, 0x3B20, 0x3B50, 0x3C90, 0x3DA0, 0x3FA0, + 0x40F0, 0x4250, 0x44F0, 0x4700, 0x49A0, 0x4C60, 0x4E10, 0x5170, 0x5460, 0x5860, 0x5C10, 0x5FB0, 0x63B0, 0x6720, 0x6A10, 0x6E30, + 0x71E0, 0x7560, 0x7890, 0x7B70, 0x7DC0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F20, 0x7EA0, + 0x7ED0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7EC0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F50, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, + 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7EE0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7970, 0x6FC0, 0x6510, + 0x5AB0, 0x4F70, 0x43C0, 0x3850, 0x2BA0, 0x20D0, 0x1780, 0x0E90, 0x07E0, 0x0200, 0xFDD0, 0xFAF0, 0xF900, 0xF7D0, 0xF790, 0xF7E0, + 0xF7A0, 0xF680, 0xF450, 0xEFB0, 0xE9E0, 0xE250, 0xD820, 0xCE00, 0xC390, 0xB870, 0xAD60, 0xA230, 0x9690, 0x8D20, 0x87F0, 0x8620, + 0x8550, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84B0, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, + 0x84F0, 0x8500, 0x8530, 0x8510, 0x8520, 0x8530, 0x8530, 0x8530, 0x8530, 0x8520, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x8500, + 0x8520, 0x8530, 0x8550, 0x8570, 0x8590, 0x85C0, 0x85E0, 0x8600, 0x8620, 0x8680, 0x8670, 0x8670, 0x8670, 0x8650, 0x8630, 0x8610, + 0x85F0, 0x85E0, 0x85C0, 0x85B0, 0x8590, 0x8580, 0x8570, 0x8560, 0x8560, 0x8560, 0x8560, 0x8570, 0x85C0, 0x85A0, 0x85C0, 0x8600, + 0x8640, 0x86D0, 0x87A0, 0x8920, 0x8B80, 0x8F30, 0x93D0, 0x98D0, 0x9D80, 0xA340, 0xA840, 0xAE00, 0xB330, 0xB820, 0xBCC0, 0xC140, + 0xC4D0, 0xC980, 0xCDD0, 0xD230, 0xD5B0, 0xD900, 0xDBC0, 0xDD40, 0xDED0, 0xE060, 0xE220, 0xE370, 0xE4E0, 0xE6C0, 0xE840, 0xE8E0, + 0xE9A0, 0xEAC0, 0xEAE0, 0xEB40, 0xEAD0, 0xEA30, 0xE9D0, 0xE920, 0xE9D0, 0xEA50, 0xEA20, 0xEA80, 0xEAC0, 0xEB10, 0xEB00, 0xE9F0, + 0xE9C0, 0xE930, 0xE980, 0xE9A0, 0xE9E0, 0xEB10, 0xEC20, 0xEC70, 0xEC50, 0xEC10, 0xEBA0, 0xEB10, 0xEB10, 0xEB50, 0xEBF0, 0xECB0, + 0xEE30, 0xEFF0, 0xF1A0, 0xF250, 0xF3B0, 0xF4D0, 0xF5C0, 0xF710, 0xF800, 0xFA40, 0xFBD0, 0xFD50, 0xFF70, 0x0160, 0x03D0, 0x0650, + 0x08C0, 0x0C00, 0x0DF0, 0x10D0, 0x1310, 0x1570, 0x1840, 0x1A90, 0x1E20, 0x2110, 0x24A0, 0x2890, 0x2C80, 0x3120, 0x3620, 0x3950, + 0x3D50, 0x40B0, 0x4420, 0x4690, 0x4860, 0x4B00, 0x4D80, 0x4F50, 0x5130, 0x5280, 0x5410, 0x54D0, 0x5560, 0x5540, 0x54D0, 0x5510, + 0x5570, 0x5540, 0x5590, 0x5530, 0x5600, 0x56D0, 0x57B0, 0x58E0, 0x5A30, 0x5B30, 0x5C60, 0x5D20, 0x5DD0, 0x5E80, 0x6040, 0x6240, + 0x63F0, 0x6630, 0x6760, 0x68C0, 0x6A00, 0x6AF0, 0x6C70, 0x6D10, 0x6E70, 0x6E70, 0x6F00, 0x6F90, 0x6F30, 0x7000, 0x6FE0, 0x6F80, + 0x6F20, 0x6E80, 0x6D90, 0x6CB0, 0x6C20, 0x6BC0, 0x6A20, 0x68D0, 0x6700, 0x64C0, 0x63B0, 0x6220, 0x6060, 0x5E10, 0x5B90, 0x58E0, + 0x5640, 0x5390, 0x5140, 0x4E90, 0x4CB0, 0x4A70, 0x48F0, 0x4750, 0x4630, 0x46C0, 0x4720, 0x47D0, 0x48B0, 0x48C0, 0x49A0, 0x49D0, + 0x4A70, 0x4B60, 0x4C90, 0x4F10, 0x5240, 0x55C0, 0x5A00, 0x5D70, 0x61E0, 0x6560, 0x6810, 0x6AB0, 0x6C00, 0x6B50, 0x68E0, 0x6340, + 0x5C40, 0x5290, 0x4880, 0x3E00, 0x3320, 0x29D0, 0x2020, 0x1880, 0x1140, 0x0AB0, 0x04E0, 0xFFC0, 0xFB50, 0xF730, 0xF2B0, 0xED00, + 0xE790, 0xE0E0, 0xDA30, 0xD240, 0xCA30, 0xC1C0, 0xB900, 0xB050, 0xA670, 0x89E0, 0x8700, 0x85C0, 0x8540, 0x84F0, 0x84F0, 0x84D0, + 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x84C0, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8480, 0x8460, 0x8480, 0x8460, 0x8460, 0x8470, 0x8480, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, + 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8530, 0x8590, 0x8670, 0x88C0, 0x8EA0, 0x9800, 0xA180, 0xAB90, 0xB460, 0xBC90, 0xC3F0, + 0xCB70, 0xD220, 0xD870, 0xDED0, 0xE4B0, 0xEAB0, 0xEFB0, 0xF4E0, 0xF8E0, 0xFD10, 0x0040, 0x0270, 0x0540, 0x0690, 0x0860, 0x0A70, + 0x0C50, 0x0F30, 0x11B0, 0x1500, 0x1800, 0x1B10, 0x1F60, 0x2440, 0x2B60, 0x32A0, 0x3AA0, 0x4490, 0x4F30, 0x5AB0, 0x6640, 0x7140, + 0x7C00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x5BE0, + 0x2FC0, 0xFF50, 0xC750, 0x93A0, 0x84F0, 0x84A0, 0x8480, 0x8470, 0x8480, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8480, + 0x8480, 0x8490, 0x84B0, 0x84D0, 0x85A0, 0x9570, 0xBDD0, 0xE830, 0x12B0, 0x37C0, 0x5190, 0x5E30, 0x5D00, 0x4F90, 0x3BD0, 0x2670, + 0x1600, 0x08C0, 0x01D0, 0xFE90, 0xFD00, 0xFA90, 0xF400, 0xE960, 0xD910, 0xC430, 0xAA30, 0x8DC0, 0x8520, 0x84C0, 0x8490, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x84E0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, + 0x8470, 0x8410, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84F0, 0x84D0, 0x84D0, 0x84E0, 0x8500, 0x8510, 0x8530, 0x8590, + 0x8590, 0x85C0, 0x85F0, 0x8610, 0x8640, 0x8680, 0x86A0, 0x8700, 0x8780, 0x8870, 0x8AE0, 0x90A0, 0x9B30, 0xA890, 0xB860, 0xC950, + 0xDE10, 0xF080, 0x0260, 0x1240, 0x1F90, 0x2A90, 0x30B0, 0x31E0, 0x2C80, 0x1ED0, 0x0B70, 0xF220, 0xD580, 0xB9B0, 0xA110, 0x8F30, + 0x8810, 0x8610, 0x8580, 0x8540, 0x8510, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, + 0x84F0, 0x8520, 0x8550, 0x85B0, 0x8630, 0x86F0, 0x8840, 0x8A30, 0x8D20, 0x9080, 0x9380, 0x9690, 0x9960, 0x9CA0, 0x9FD0, 0xA3C0, + 0xA960, 0xB0D0, 0xBA10, 0xC520, 0xD140, 0xDD90, 0xEA90, 0xF760, 0x0420, 0x0F90, 0x1910, 0x2120, 0x29A0, 0x3110, 0x3990, 0x4330, + 0x4E60, 0x5A50, 0x66B0, 0x7200, 0x7AA0, 0x7ED0, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x79E0, 0x6D40, + 0x5870, 0x3B10, 0x1860, 0xF340, 0xCF80, 0xB010, 0x95F0, 0x8810, 0x8580, 0x8510, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, + 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84F0, 0x8550, 0x8650, 0x8970, 0x9110, 0x9A50, 0xA030, 0xA380, 0xA390, 0xA100, 0x9B80, 0x9470, + 0x8D10, 0x8850, 0x8650, 0x8590, 0x8540, 0x8530, 0x8530, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8520, 0x8540, 0x8580, + 0x8600, 0x86E0, 0x88D0, 0x8CD0, 0x9340, 0x99C0, 0xA000, 0xA570, 0xAA50, 0xAF30, 0xB4D0, 0xBAF0, 0xC0E0, 0xC740, 0xCD60, 0xD350, + 0xD930, 0xDEB0, 0xE520, 0xEC20, 0xF3B0, 0xFBE0, 0x0430, 0x0B90, 0x11F0, 0x1800, 0x1D00, 0x2170, 0x2590, 0x2940, 0x2D50, 0x32C0, + 0x3860, 0x3DB0, 0x41E0, 0x4600, 0x49D0, 0x4C70, 0x4F60, 0x5180, 0x5480, 0x5710, 0x59B0, 0x5BD0, 0x5D40, 0x5D40, 0x5C10, 0x5A60, + 0x5760, 0x5360, 0x4E20, 0x4760, 0x4050, 0x3850, 0x2FB0, 0x2590, 0x1A70, 0x0E90, 0x01C0, 0xF610, 0xEB30, 0xE150, 0xD830, 0xD140, + 0xCB70, 0xC730, 0xC430, 0xC280, 0xC1E0, 0xC1C0, 0xC210, 0xC2F0, 0xC4F0, 0xC7D0, 0xCB20, 0xCF30, 0xD3E0, 0xD8A0, 0xDD50, 0xE1F0, + 0xE750, 0xECC0, 0xF270, 0xF8F0, 0xFF50, 0x0620, 0x0CC0, 0x1270, 0x1880, 0x1E40, 0x23C0, 0x28B0, 0x2DA0, 0x31F0, 0x3690, 0x3AE0, + 0x3DF0, 0x41F0, 0x4480, 0x47C0, 0x4A00, 0x4BF0, 0x4D90, 0x4E20, 0x4E10, 0x4E40, 0x4D30, 0x4CE0, 0x4B40, 0x4A10, 0x48A0, 0x4700, + 0x4480, 0x4210, 0x40A0, 0x3E80, 0x3C80, 0x3AF0, 0x3820, 0x35C0, 0x3340, 0x3070, 0x2F20, 0x2D50, 0x2BF0, 0x2AC0, 0x28E0, 0x26D0, + 0x2490, 0x2300, 0x2130, 0x1FB0, 0x1E70, 0x1D60, 0x1CF0, 0x1C20, 0x1B20, 0x1A80, 0x1830, 0x16E0, 0x1500, 0x1310, 0x11D0, 0x1070, + 0x0FA0, 0x0F10, 0x0D90, 0x0D10, 0x0C40, 0x0B90, 0x0AD0, 0x0A20, 0x0A00, 0x09D0, 0x0A20, 0x0BA0, 0x0BD0, 0x0CE0, 0x0DE0, 0x0F30, + 0x10D0, 0x1190, 0x13C0, 0x15F0, 0x1830, 0x1A90, 0x1CD0, 0x2050, 0x22B0, 0x2560, 0x2750, 0x28F0, 0x2BC0, 0x2DE0, 0x2FD0, 0x3220, + 0x33D0, 0x3670, 0x3870, 0x39F0, 0x3AF0, 0x3B10, 0x3C60, 0x3D40, 0x3DB0, 0x3F30, 0x4040, 0x4200, 0x4290, 0x4370, 0x4440, 0x4440, + 0x44F0, 0x45A0, 0x46C0, 0x4800, 0x4A00, 0x4BE0, 0x4E40, 0x4ED0, 0x50B0, 0x51B0, 0x52D0, 0x5430, 0x5520, 0x5700, 0x5890, 0x5A10, + 0x5B40, 0x5C40, 0x5E10, 0x5FA0, 0x6060, 0x6110, 0x6210, 0x62E0, 0x6340, 0x6390, 0x64B0, 0x65A0, 0x67B0, 0x68C0, 0x69D0, 0x6A30, + 0x6A30, 0x6A60, 0x6AF0, 0x6B30, 0x6CA0, 0x6D40, 0x6EC0, 0x7000, 0x70B0, 0x7240, 0x7290, 0x73F0, 0x7500, 0x75E0, 0x7750, 0x7800, + 0x7940, 0x7A40, 0x7AF0, 0x7C20, 0x7C80, 0x7D90, 0x7E50, 0x7EC0, 0x7F00, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, + 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, + 0x7EB0, 0x7EF0, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7EA0, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7EB0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, + 0x7EA0, 0x7F20, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EE0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, + 0x7F90, 0x7F10, 0x7EE0, 0x7EE0, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7E70, 0x7EF0, 0x7ED0, 0x7F30, + 0x7F00, 0x7E90, 0x7ED0, 0x7F00, 0x7F20, 0x7F10, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, + 0x7EC0, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, + 0x7F80, 0x7F20, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F50, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F90, + 0x7F00, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F50, 0x7F10, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F30, 0x7EF0, + 0x7E90, 0x7ED0, 0x7EE0, 0x7F00, 0x7F10, 0x7EC0, 0x7EC0, 0x7EB0, 0x7F00, 0x7F00, 0x7E90, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, + 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F50, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F30, + 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, + 0x7EB0, 0x7DE0, 0x7360, 0x6840, 0x5C40, 0x4E10, 0x3F70, 0x2F20, 0x1F40, 0x10F0, 0x0310, 0xF700, 0xEC10, 0xE2B0, 0xDA80, 0xD240, + 0xCAD0, 0xC390, 0xBBD0, 0xB500, 0xAF30, 0xAC50, 0xAC00, 0xADB0, 0xB120, 0xB4B0, 0xB710, 0xB7E0, 0xB640, 0xB230, 0xAD70, 0xA8F0, + 0xA580, 0xA3E0, 0xA410, 0xA580, 0xA820, 0xA9D0, 0xAA10, 0xA890, 0xA4C0, 0x9EC0, 0x98C0, 0x9330, 0x8EA0, 0x8B20, 0x88E0, 0x8740, + 0x8660, 0x85C0, 0x8560, 0x8520, 0x8510, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x8520, 0x8540, 0x8580, 0x85D0, 0x8680, 0x8770, + 0x88E0, 0x8B60, 0x8EB0, 0x9310, 0x9810, 0x9DD0, 0xA3E0, 0xAA30, 0xB0B0, 0xB7C0, 0xBFB0, 0xC790, 0xCF20, 0xD740, 0xDEF0, 0xE650, + 0xEE00, 0xF500, 0xFC10, 0x0340, 0x0A10, 0x10D0, 0x16E0, 0x1D90, 0x2350, 0x2890, 0x2C70, 0x2FE0, 0x32B0, 0x33B0, 0x33A0, 0x32F0, + 0x30D0, 0x2E10, 0x2A40, 0x24F0, 0x1F10, 0x1740, 0x0F00, 0x0590, 0xFB70, 0xF170, 0xE6E0, 0xDCD0, 0xD2D0, 0xC960, 0xC080, 0xB980, + 0xB3C0, 0xAF00, 0xAAD0, 0xA7A0, 0xA470, 0xA230, 0xA110, 0xA090, 0xA130, 0xA200, 0xA3D0, 0xA5C0, 0xA840, 0xAAF0, 0xADB0, 0xB030, + 0xB330, 0xB5B0, 0xB870, 0xBB50, 0xBE50, 0xC0E0, 0xC3D0, 0xC6B0, 0xC9D0, 0xCC90, 0xCF50, 0xD230, 0xD4E0, 0xD7E0, 0xDA70, 0xDCE0, + 0xDF70, 0xE170, 0xE3E0, 0xE600, 0xE8A0, 0xEB30, 0xED90, 0xF080, 0xF330, 0xF630, 0xF8E0, 0xFB00, 0xFD10, 0xFE40, 0x0010, 0x0160, + 0x0320, 0x04B0, 0x0670, 0x07A0, 0x0910, 0x0A10, 0x0B10, 0x0C00, 0x0CF0, 0x0DA0, 0x0E10, 0x0ED0, 0x0F90, 0x1000, 0x1160, 0x1270, + 0x13B0, 0x14A0, 0x1560, 0x15F0, 0x16A0, 0x1750, 0x1790, 0x17B0, 0x17E0, 0x17F0, 0x1790, 0x1730, 0x1660, 0x1640, 0x1470, 0x12B0, + 0x1040, 0x0D60, 0x0A50, 0x0650, 0x0250, 0xFF10, 0xFB00, 0xF7A0, 0xF520, 0xF240, 0xEFB0, 0xED90, 0xEBA0, 0xEA20, 0xE8F0, 0xE780, + 0xE6F0, 0xE690, 0xE6B0, 0xE740, 0xE850, 0xE910, 0xE9B0, 0xEA80, 0xEB50, 0xEC00, 0xECB0, 0xED50, 0xEE70, 0xEF90, 0xF0D0, 0xF220, + 0xF440, 0xF5F0, 0xF750, 0xF9B0, 0xFB70, 0xFD60, 0xFF50, 0x0170, 0x0400, 0x06E0, 0x0960, 0x0BF0, 0x0EB0, 0x1140, 0x1390, 0x15B0, + 0x1750, 0x1940, 0x1B10, 0x1BB0, 0x1C40, 0x1C50, 0x1C80, 0x1C30, 0x1C60, 0x1C20, 0x1BB0, 0x1B70, 0x19E0, 0x18C0, 0x1730, 0x1630, + 0x1560, 0x1440, 0x1330, 0x1250, 0x11E0, 0x11B0, 0x1170, 0x10E0, 0x10B0, 0x10B0, 0x10D0, 0x11F0, 0x1310, 0x1490, 0x1720, 0x19C0, + 0x1C50, 0x1F70, 0x22B0, 0x2760, 0x2C50, 0x31B0, 0x3710, 0x3D40, 0x4280, 0x47B0, 0x4BA0, 0x4EC0, 0x5040, 0x4FB0, 0x4E60, 0x4C00, + 0x47D0, 0x4340, 0x3E60, 0x38F0, 0x3280, 0x2C40, 0x2560, 0x1E50, 0x16B0, 0x0DC0, 0x0540, 0xFC70, 0xF3C0, 0xEAC0, 0xE190, 0xD8D0, + 0xD130, 0xC960, 0xC1F0, 0xBCA0, 0xB7E0, 0xB4B0, 0xB2D0, 0xB1A0, 0xB200, 0xB2F0, 0xB520, 0xB890, 0xBBB0, 0xBF40, 0xC2A0, 0xC620, + 0xC9F0, 0xCDB0, 0xD1D0, 0xD520, 0xD8F0, 0xDCF0, 0xE030, 0xE3C0, 0xE680, 0xE950, 0xEB80, 0xEDE0, 0xF080, 0xF300, 0xF560, 0xF840, + 0xFA90, 0xFDE0, 0x0160, 0x0510, 0x09B0, 0x0DB0, 0x1290, 0x1680, 0x1AE0, 0x1F60, 0x2310, 0x2730, 0x2B40, 0x2F70, 0x32F0, 0x3640, + 0x3930, 0x3BD0, 0x3DC0, 0x4060, 0x4210, 0x4530, 0x4770, 0x4A70, 0x4DD0, 0x5030, 0x53A0, 0x5640, 0x58F0, 0x5C60, 0x5F20, 0x6340, + 0x6790, 0x6BE0, 0x7080, 0x7450, 0x7900, 0x7CE0, 0x7EE0, 0x7F10, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7EE0, 0x7F10, 0x7F50, 0x7EF0, 0x7F20, + 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7F20, 0x7F00, 0x7F90, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7ED0, 0x7F10, + 0x7F20, 0x7F40, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F00, + 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7F70, 0x7EF0, 0x7EF0, + 0x7F10, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, + 0x7F00, 0x7F10, 0x7F10, 0x7E70, 0x7ED0, 0x7EB0, 0x7E30, 0x7D20, 0x7BC0, 0x7BD0, 0x7C40, 0x7CE0, 0x7E50, 0x7E80, 0x7ED0, 0x7F10, + 0x7F00, 0x7EF0, 0x7F00, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, + 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F60, 0x7F00, 0x7F70, 0x7EF0, + 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7F10, 0x7EE0, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7710, 0x5720, 0x3840, 0x1910, 0xFB70, 0xE0E0, 0xC9C0, 0xB780, + 0xA950, 0x9F70, 0x9920, 0x9560, 0x9300, 0x91F0, 0x9200, 0x92A0, 0x94E0, 0x9880, 0x9E90, 0xA540, 0xAD30, 0xB5C0, 0xBDB0, 0xC610, + 0xCEF0, 0xD820, 0xE0D0, 0xEB60, 0xF520, 0xFE90, 0x0890, 0x1180, 0x18F0, 0x1FF0, 0x2490, 0x28A0, 0x2B50, 0x2C30, 0x2C00, 0x2A60, + 0x2910, 0x26D0, 0x2300, 0x1F20, 0x1990, 0x12C0, 0x0B50, 0x03F0, 0xFCA0, 0xF450, 0xEC70, 0xE4A0, 0xDD00, 0xD5A0, 0xCDB0, 0xC5E0, + 0xBF10, 0xB7D0, 0xB0F0, 0xAA40, 0xA500, 0x9F90, 0x9A30, 0x9640, 0x92B0, 0x8FE0, 0x8D90, 0x8C00, 0x8B30, 0x8A80, 0x8A10, 0x8A60, + 0x8A90, 0x8B30, 0x8C00, 0x8D00, 0x8EB0, 0x9120, 0x9410, 0x9790, 0x9AF0, 0x9F90, 0xA3D0, 0xA930, 0xAE90, 0xB310, 0xB800, 0xBBB0, + 0xBFE0, 0xC3E0, 0xC740, 0xCBD0, 0xCF90, 0xD300, 0xD560, 0xD640, 0xD680, 0xD500, 0xD240, 0xCE70, 0xCA40, 0xC690, 0xC290, 0xBF30, + 0xBB40, 0xB750, 0xB2F0, 0xAE40, 0xA980, 0xA4D0, 0xA020, 0x91D0, 0x8FB0, 0x8E60, 0x8DB0, 0x8DD0, 0x8FB0, 0x92B0, 0x96F0, 0x9AF0, + 0x9ED0, 0xA2A0, 0xA560, 0xA710, 0xA7C0, 0xA7C0, 0xA7C0, 0xA830, 0xA910, 0xAA60, 0xABE0, 0xADA0, 0xAEC0, 0xAF60, 0xAFC0, 0xAF20, + 0xADC0, 0xAB00, 0xA840, 0xA410, 0x9F60, 0x99F0, 0x9390, 0x8D80, 0x88B0, 0x8650, 0x8560, 0x8510, 0x84E0, 0x84D0, 0x84C0, 0x84B0, + 0x84A0, 0x8490, 0x84C0, 0x8480, 0x8470, 0x8470, 0x8440, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8520, 0x8560, 0x85F0, 0x8710, 0x8990, 0x8ED0, 0x9510, 0x9B00, 0xA040, 0xA450, + 0xA820, 0xAB70, 0xAF30, 0xB2B0, 0xB5D0, 0xB8A0, 0xBB70, 0xBF10, 0xC200, 0xC4B0, 0xC890, 0xCC60, 0xD1A0, 0xD710, 0xDE00, 0xE530, + 0xED30, 0xF4E0, 0xFC50, 0x0350, 0x0A00, 0x0F60, 0x15D0, 0x1B50, 0x2080, 0x24A0, 0x27C0, 0x2AD0, 0x2C80, 0x2DF0, 0x2F70, 0x30B0, + 0x32B0, 0x33A0, 0x3430, 0x34B0, 0x3420, 0x3340, 0x3150, 0x2F30, 0x2D00, 0x2990, 0x2650, 0x2230, 0x1DF0, 0x19D0, 0x14D0, 0x10B0, + 0x0D70, 0x09F0, 0x07A0, 0x07C0, 0x0950, 0x0D10, 0x1250, 0x1960, 0x2310, 0x2F20, 0x3D40, 0x4E40, 0x5EF0, 0x6F20, 0x7C20, 0x7F20, + 0x7F40, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F50, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7E30, 0x77B0, 0x7570, 0x7780, 0x7D10, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x4170, 0xEA20, 0x8E40, 0x8490, 0x8460, 0x8440, + 0x8430, 0x8420, 0x8440, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, + 0x83F0, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x84A0, 0x8490, 0x8490, + 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8530, 0x85F0, 0x87D0, 0x9130, 0x9F90, 0xAE10, 0xBCF0, 0xCAA0, 0xD7C0, 0xE3D0, + 0xEE30, 0xF750, 0xFED0, 0x0460, 0x0860, 0x0BB0, 0x0DD0, 0x0ED0, 0x0F20, 0x0E60, 0x0D30, 0x0C30, 0x0B30, 0x09F0, 0x0910, 0x0810, + 0x05A0, 0x0260, 0xFFE0, 0xFCF0, 0xF9B0, 0xF6F0, 0xF4A0, 0xF2A0, 0xF080, 0xEEB0, 0xEC90, 0xE9A0, 0xE620, 0xE180, 0xDC60, 0xD610, + 0xCE80, 0xC5B0, 0xBB10, 0xAEC0, 0xA020, 0x9180, 0x8760, 0x8530, 0x84D0, 0x84B0, 0x84A0, 0x84B0, 0x8480, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8490, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8460, 0x8440, 0x8440, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8490, 0x8470, 0x8480, 0x8480, 0x84C0, 0x8490, 0x84A0, 0x84B0, + 0x84D0, 0x8500, 0x8570, 0x8730, 0x9040, 0xA0D0, 0xB020, 0xBE70, 0xCC40, 0xD990, 0xE570, 0xF0B0, 0xFB60, 0x0530, 0x0F10, 0x18C0, + 0x2180, 0x2A50, 0x3320, 0x3A90, 0x4250, 0x4990, 0x5100, 0x5960, 0x6180, 0x6B10, 0x7400, 0x7CD0, 0x7F00, 0x7F20, 0x7F00, 0x7F10, + 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EB0, 0x7E70, 0x7EF0, 0x7EE0, 0x7EF0, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F10, + 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, + 0x7F60, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, 0x5160, 0x2380, 0xFD30, 0xDDA0, 0xCA30, 0xBD80, 0xB790, 0xB3E0, 0xB1E0, + 0xB190, 0xB190, 0xB300, 0xB5D0, 0xBA50, 0xBFA0, 0xC5A0, 0xCB00, 0xCF50, 0xD100, 0xD0A0, 0xCDA0, 0xC830, 0xC200, 0xBB90, 0xB060, + 0xB0E0, 0xB300, 0xB530, 0xBA10, 0xC090, 0xCA10, 0xD610, 0xE330, 0xF260, 0x0410, 0x1490, 0x24F0, 0x34C0, 0x4380, 0x5030, 0x5A60, + 0x62C0, 0x6850, 0x6C20, 0x6F00, 0x7050, 0x7200, 0x72B0, 0x72E0, 0x71F0, 0x7000, 0x6D20, 0x6950, 0x6560, 0x6170, 0x5DC0, 0x5A90, + 0x57B0, 0x55B0, 0x5370, 0x5110, 0x4F70, 0x4DD0, 0x4D00, 0x4CC0, 0x4CD0, 0x4D10, 0x4CB0, 0x4BE0, 0x4B10, 0x4990, 0x48D0, 0x46E0, + 0x4460, 0x42C0, 0x4050, 0x3E70, 0x3C60, 0x3A50, 0x3950, 0x3800, 0x36E0, 0x3650, 0x3530, 0x35A0, 0x35C0, 0x3600, 0x3780, 0x3860, + 0x3A50, 0x3B80, 0x3D20, 0x3E80, 0x3FD0, 0x4290, 0x4520, 0x48A0, 0x4CA0, 0x5060, 0x5510, 0x5950, 0x5E20, 0x6260, 0x6650, 0x6A30, + 0x6D60, 0x6F80, 0x7190, 0x7290, 0x73A0, 0x73A0, 0x72F0, 0x7230, 0x6FE0, 0x6DC0, 0x6A10, 0x6660, 0x61D0, 0x5BD0, 0x5670, 0x5040, + 0x4A10, 0x4490, 0x3EE0, 0x39C0, 0x33F0, 0x2E30, 0x2940, 0x2400, 0x2010, 0x1BB0, 0x17E0, 0x1540, 0x1290, 0x10B0, 0x0EF0, 0x0D90, + 0x0CB0, 0x0BC0, 0x0B80, 0x0B90, 0x0B60, 0x0B80, 0x0B20, 0x0B40, 0x0A50, 0x0A10, 0x0A80, 0x0A60, 0x0AF0, 0x0B10, 0x0B00, 0x0B20, + 0x0A70, 0x0A70, 0x0A50, 0x0A60, 0x0AE0, 0x0BD0, 0x0D50, 0x0ED0, 0x1110, 0x1380, 0x1600, 0x1890, 0x1B80, 0x1E00, 0x20E0, 0x23C0, + 0x2630, 0x29C0, 0x2C60, 0x3010, 0x3370, 0x35F0, 0x3940, 0x3B90, 0x3EB0, 0x40F0, 0x4350, 0x46F0, 0x49C0, 0x4D90, 0x51F0, 0x55A0, + 0x5A40, 0x5E40, 0x6260, 0x6610, 0x6910, 0x6D00, 0x6FC0, 0x72F0, 0x75B0, 0x77A0, 0x79A0, 0x7B40, 0x7CC0, 0x7D80, 0x7E20, 0x7EC0, + 0x7ED0, 0x7F30, 0x7EE0, 0x7EE0, 0x7EF0, 0x7EE0, 0x7F40, 0x7ED0, 0x7E50, 0x7DA0, 0x7CA0, 0x7AD0, 0x78D0, 0x75C0, 0x7310, 0x7030, + 0x6CF0, 0x69E0, 0x65C0, 0x6230, 0x5D80, 0x57C0, 0x5220, 0x4B40, 0x4610, 0x4090, 0x3AA0, 0x3540, 0x2E40, 0x2800, 0x2130, 0x19A0, + 0x13F0, 0x0E40, 0x09C0, 0x0620, 0x0210, 0xFF10, 0xF510, 0xF340, 0xF190, 0xF070, 0xEFC0, 0xEF00, 0xEE80, 0xEDA0, 0xEC70, 0xEB70, + 0xE9D0, 0xE8A0, 0xE760, 0xE5C0, 0xE4C0, 0xE3B0, 0xE2E0, 0xE240, 0xE130, 0xE060, 0xDEF0, 0xDD50, 0xDC80, 0xDBD0, 0xDB60, 0xDA80, + 0xD9F0, 0xD9E0, 0xD960, 0xD8E0, 0xD870, 0xD7F0, 0xD790, 0xD700, 0xD6D0, 0xD730, 0xD6A0, 0xD770, 0xD790, 0xD7E0, 0xD750, 0xD6D0, + 0xD6D0, 0xD6A0, 0xD6D0, 0xD6D0, 0xD670, 0xD700, 0xD730, 0xD780, 0xD800, 0xD770, 0xD7E0, 0xD800, 0xD820, 0xD8B0, 0xD8B0, 0xD960, + 0xD950, 0xD930, 0xD8F0, 0xD870, 0xD870, 0xD810, 0xD7B0, 0xD770, 0xD730, 0xD750, 0xD720, 0xD700, 0xD6B0, 0xD6B0, 0xD6D0, 0xD6C0, + 0xD6A0, 0xD5D0, 0xD550, 0xD560, 0xD560, 0xD630, 0xD730, 0xD6F0, 0xD790, 0xD720, 0xD740, 0xD770, 0xD7A0, 0xD810, 0xD8D0, 0xD990, + 0xDA30, 0xDB00, 0xDBB0, 0xDC20, 0xDCB0, 0xDD20, 0xDE40, 0xDE90, 0xDFB0, 0xE1E0, 0xE380, 0xE4D0, 0xE690, 0xE900, 0xEAE0, 0xED10, + 0xEF40, 0xF0E0, 0xF320, 0xF4F0, 0xF740, 0xF9A0, 0xFC90, 0xFF50, 0x0240, 0x0570, 0x0870, 0x0C60, 0x1020, 0x1390, 0x16E0, 0x1A30, + 0x1D80, 0x2040, 0x2330, 0x25C0, 0x28C0, 0x2B20, 0x2DC0, 0x3000, 0x3230, 0x3470, 0x3640, 0x3890, 0x39F0, 0x3C00, 0x3D60, 0x3EF0, + 0x40D0, 0x42B0, 0x4480, 0x4640, 0x4870, 0x4A70, 0x4CE0, 0x4F10, 0x5130, 0x5360, 0x55E0, 0x5850, 0x5A90, 0x5D00, 0x5FE0, 0x62F0, + 0x65B0, 0x68B0, 0x6BC0, 0x6E50, 0x70D0, 0x73A0, 0x76C0, 0x7A50, 0x7DC0, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F00, + 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F50, 0x7F20, 0x7F90, 0x7F30, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F30, + 0x7E70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F00, 0x7F00, 0x7F30, 0x7F00, 0x7E70, 0x7ED0, 0x7ED0, 0x7F10, 0x7F00, 0x7E90, + 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EA0, 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7EE0, 0x7EC0, 0x7F10, + 0x7F20, 0x70C0, 0x5B90, 0x4510, 0x30B0, 0x1DF0, 0x0B70, 0xFC20, 0xED20, 0xDDC0, 0xCCC0, 0xBAD0, 0xA840, 0x9690, 0x8A40, 0x8600, + 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8540, 0x8580, 0x85E0, + 0x86B0, 0x87C0, 0x8980, 0x8C00, 0x8ED0, 0x9260, 0x9540, 0x9800, 0x9A10, 0x9AF0, 0x9C30, 0x9D00, 0x9DD0, 0x9E40, 0x9E80, 0x9EF0, + 0x9EA0, 0x9EF0, 0x9E50, 0x9DC0, 0x9D50, 0x9C30, 0x9BB0, 0x9AE0, 0x9A10, 0x99E0, 0x9900, 0x98A0, 0x97E0, 0x9760, 0x96F0, 0x96A0, + 0x9650, 0x9630, 0x96C0, 0x9720, 0x9750, 0x97C0, 0x98E0, 0x9A40, 0x9B90, 0x9C90, 0x9DC0, 0x9EE0, 0x9FF0, 0xA1E0, 0xA3C0, 0xA650, + 0xA8C0, 0xAA70, 0xAC40, 0xAE40, 0xB050, 0xB2E0, 0xB560, 0xB890, 0xBAD0, 0xBD20, 0xC000, 0xC1E0, 0xC430, 0xC620, 0xC910, 0xCB00, + 0xCD10, 0xCF40, 0xD190, 0xD3F0, 0xD5A0, 0xD710, 0xD940, 0xDAE0, 0xDC70, 0xDF20, 0xE0B0, 0xE2D0, 0xE480, 0xE5F0, 0xE770, 0xE8A0, + 0xEA20, 0xEB40, 0xEC50, 0xEE20, 0xEED0, 0xF090, 0xF180, 0xF1E0, 0xF290, 0xF2B0, 0xF2F0, 0xF2E0, 0xF2C0, 0xF370, 0xF340, 0xF330, + 0xF350, 0xF2A0, 0xF280, 0xF2D0, 0xF250, 0xF290, 0xF2B0, 0xF390, 0xF420, 0xF480, 0xF5A0, 0xF650, 0xF870, 0xFA00, 0xFBD0, 0xFE70, + 0x00C0, 0x0E10, 0x1200, 0x16B0, 0x1AC0, 0x1F80, 0x2510, 0x2AF0, 0x3170, 0x3750, 0x3D50, 0x4300, 0x4840, 0x4DF0, 0x5340, 0x5820, + 0x5D40, 0x6130, 0x6670, 0x6AC0, 0x6E90, 0x7270, 0x74E0, 0x7780, 0x7980, 0x7AE0, 0x7BE0, 0x7BF0, 0x7C90, 0x7CE0, 0x7C90, 0x7C30, + 0x7AE0, 0x79E0, 0x77D0, 0x7530, 0x73B0, 0x7160, 0x6F90, 0x6E00, 0x6C90, 0x6BE0, 0x6A70, 0x6A10, 0x6910, 0x6860, 0x6870, 0x6900, + 0x6A50, 0x6C30, 0x6D20, 0x6EE0, 0x6F00, 0x7030, 0x7180, 0x7240, 0x7350, 0x7460, 0x7580, 0x76B0, 0x77B0, 0x7940, 0x7A50, 0x7B70, + 0x7C00, 0x7C60, 0x7C50, 0x7C10, 0x7AB0, 0x77C0, 0x7390, 0x6F00, 0x6900, 0x61E0, 0x5B10, 0x53E0, 0x4D60, 0x4690, 0x3FB0, 0x3820, + 0x2F40, 0x2690, 0x1D70, 0x1350, 0x09B0, 0x0050, 0xF800, 0xEF70, 0xE770, 0xE090, 0xD8E0, 0xD180, 0xC960, 0xC150, 0xBA60, 0xB350, + 0xACB0, 0xA630, 0xA080, 0x9AE0, 0x9610, 0x91B0, 0x8E00, 0x8B70, 0x8A00, 0x88F0, 0x8840, 0x87E0, 0x87A0, 0x8790, 0x8780, 0x87A0, + 0x87D0, 0x8820, 0x88D0, 0x89F0, 0x8BD0, 0x8ED0, 0x9250, 0x96D0, 0x9BA0, 0xA090, 0xA630, 0xAC50, 0xB3B0, 0xBA40, 0xC040, 0xC610, + 0xCBB0, 0xD1F0, 0xD640, 0xDB50, 0xE0B0, 0xE550, 0xEA40, 0xEE00, 0xF190, 0xF540, 0xF830, 0xFA70, 0xFBE0, 0xFCF0, 0xFE70, 0xFF60, + 0x0050, 0x0150, 0x01F0, 0x02C0, 0x03A0, 0x0510, 0x0680, 0x0740, 0x0910, 0x09F0, 0x0B90, 0x0C60, 0x0C90, 0x0D60, 0x0D80, 0x0CF0, + 0x0BD0, 0x0A50, 0x0870, 0x05E0, 0x0280, 0xFFC0, 0xFB90, 0xF770, 0xF2A0, 0xEDE0, 0xE900, 0xE410, 0xE030, 0xDC60, 0xD830, 0xD400, + 0xCFF0, 0xCCA0, 0xC8E0, 0xC610, 0xC410, 0xC270, 0xC0F0, 0xBF10, 0xBD10, 0xBB20, 0xB8E0, 0xB5F0, 0xB360, 0xB090, 0xADD0, 0xAA80, + 0xA6B0, 0xA2F0, 0x9EA0, 0x9AD0, 0x96F0, 0x9350, 0x8FF0, 0x8D30, 0x8AF0, 0x8940, 0x8840, 0x8780, 0x86E0, 0x86A0, 0x86A0, 0x8640, + 0x8630, 0x8600, 0x85F0, 0x85F0, 0x85E0, 0x85C0, 0x85D0, 0x85C0, 0x85C0, 0x85B0, 0x85D0, 0x85D0, 0x85F0, 0x85F0, 0x8600, 0x8630, + 0x8660, 0x8670, 0x86B0, 0x8700, 0x8770, 0x87E0, 0x8870, 0x8900, 0x89B0, 0x8AE0, 0x8C30, 0x8DC0, 0x8FD0, 0x91E0, 0x93D0, 0x9610, + 0x98C0, 0x9AB0, 0x9DA0, 0xA050, 0xA380, 0xA5C0, 0xA8E0, 0xAB10, 0xAD60, 0xAF50, 0xB100, 0xB300, 0xB4A0, 0xB680, 0xB7F0, 0xB9C0, + 0xBAD0, 0xBBF0, 0xBD80, 0xBE60, 0xBFD0, 0xC130, 0xC270, 0xC440, 0xC5C0, 0xC760, 0xC890, 0xC990, 0xCAB0, 0xCBE0, 0xCCD0, 0xCDD0, + 0xCED0, 0xD060, 0xD190, 0xD250, 0xD330, 0xD350, 0xD380, 0xD350, 0xD240, 0xD0F0, 0xCF70, 0xCE80, 0xCDD0, 0xCCF0, 0xCBD0, 0xCA90, + 0xC8F0, 0xC7A0, 0xC5C0, 0xC3F0, 0xC260, 0xBBE0, 0xBA30, 0xB7D0, 0xB5F0, 0xB400, 0xB180, 0xAF50, 0xAD20, 0xAB00, 0xA8E0, 0xA6D0, + 0xA520, 0xA340, 0xA140, 0x9FA0, 0x9E80, 0x9DE0, 0x9D20, 0x9BF0, 0x9B30, 0x9A50, 0x9A00, 0x99A0, 0x98F0, 0x9910, 0x9890, 0x98B0, + 0x9870, 0x9960, 0x99D0, 0x9A50, 0x9AE0, 0x9BA0, 0x9B60, 0x9C00, 0x9CB0, 0x9D70, 0x9D70, 0x9DB0, 0x9DE0, 0x9E40, 0x9E80, 0x9F70, + 0xA000, 0xA000, 0x9F80, 0x9F00, 0x9E50, 0x9DB0, 0x9D20, 0x9C60, 0x9CB0, 0x9CD0, 0x9D00, 0x9CC0, 0x9CF0, 0x9CE0, 0x9D10, 0x9C50, + 0x9BA0, 0x9B60, 0x9B60, 0x9BB0, 0x9BB0, 0x9BE0, 0x9C80, 0x9CA0, 0x9CE0, 0x9CD0, 0x9CD0, 0x9DB0, 0x9F00, 0xA0A0, 0xA300, 0xA570, + 0xA870, 0xAB40, 0xADF0, 0xB0D0, 0xB480, 0xB800, 0xBBF0, 0xBFF0, 0xC450, 0xC850, 0xCD10, 0xD1B0, 0xD5F0, 0xDA10, 0xDE90, 0xE340, + 0xE8B0, 0xEE10, 0xF390, 0xF8C0, 0xFE30, 0x02A0, 0x0700, 0x0B90, 0x0FD0, 0x1430, 0x1840, 0x1C70, 0x2070, 0x24D0, 0x2920, 0x2D80, + 0x31B0, 0x3550, 0x3940, 0x3CE0, 0x4050, 0x4350, 0x45F0, 0x4850, 0x4B30, 0x4DA0, 0x4FA0, 0x51D0, 0x5370, 0x5400, 0x53A0, 0x5230, + 0x50F0, 0x4FB0, 0x4E20, 0x4C10, 0x4A90, 0x4830, 0x4500, 0x41D0, 0x3DA0, 0x3970, 0x3540, 0x3130, 0x2D20, 0x28C0, 0x24C0, 0x2100, + 0x1D70, 0x19C0, 0x16A0, 0x13D0, 0x1100, 0x0E10, 0x0B60, 0x0910, 0x0780, 0x0570, 0x03D0, 0x0230, 0x0120, 0x0010, 0xFFD0, 0xFFF0, + 0x0020, 0x00C0, 0x00E0, 0x0170, 0x0140, 0x0190, 0x0230, 0x0370, 0x0500, 0x06D0, 0x0890, 0x09D0, 0x0B40, 0x0C90, 0x0DB0, 0x0F60, + 0x10C0, 0x1290, 0x1530, 0x1750, 0x18F0, 0x19A0, 0x1A80, 0x1A80, 0x1B10, 0x1B00, 0x1A60, 0x1B10, 0x1B10, 0x1AE0, 0x1A10, 0x1930, + 0x17E0, 0x1620, 0x1440, 0x1230, 0x0F90, 0x0D40, 0x0AA0, 0x0830, 0x0680, 0x0440, 0x0190, 0xFF00, 0xFC40, 0xFA20, 0xF7A0, 0xF590, + 0xF420, 0xF2F0, 0xF230, 0xF150, 0xF160, 0xF0F0, 0xF070, 0xF070, 0xF0F0, 0xF170, 0xF260, 0xF340, 0xF500, 0xF610, 0xF810, 0xF960, + 0xFA50, 0xFBA0, 0xFC10, 0xFCA0, 0xFCC0, 0xFC50, 0xFCF0, 0xFD20, 0xFE60, 0xFF50, 0x0100, 0x0220, 0x0290, 0x0350, 0x0370, 0x02C0, + 0x0360, 0x0350, 0x03F0, 0x0520, 0x0670, 0x0790, 0x0860, 0x0920, 0x09B0, 0x09A0, 0x0A60, 0x0AE0, 0x0B90, 0x0C70, 0x0D00, 0x0ED0, + 0x10B0, 0x12A0, 0x1420, 0x1560, 0x1730, 0x1930, 0x1C30, 0x1EB0, 0x2160, 0x2490, 0x2810, 0x2AB0, 0x2DA0, 0x2F60, 0x3200, 0x3320, + 0x34E0, 0x3640, 0x3770, 0x3A00, 0x3BE0, 0x3CF0, 0x3E70, 0x3F40, 0x4050, 0x40F0, 0x4110, 0x4200, 0x4110, 0x4150, 0x4100, 0x3FC0, + 0x3EF0, 0x3DA0, 0x3CA0, 0x3B50, 0x3A00, 0x3940, 0x3800, 0x3680, 0x35B0, 0x34B0, 0x3480, 0x33D0, 0x33A0, 0x33A0, 0x32C0, 0x31F0, + 0x3110, 0x2F40, 0x2E10, 0x2CA0, 0x2BD0, 0x2AF0, 0x29A0, 0x2770, 0x2390, 0x1F20, 0x1830, 0x0FE0, 0x0580, 0xFB50, 0xF180, 0xE880, + 0xE090, 0xD9D0, 0xD3A0, 0xCE60, 0xC8C0, 0xC270, 0xBC20, 0xB540, 0xAF00, 0xA870, 0xA290, 0x9D40, 0x9870, 0x9430, 0x9150, 0x8F80, + 0x8F00, 0x8E60, 0x8DC0, 0x8CE0, 0x8B20, 0x8970, 0x87A0, 0x8640, 0x8590, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, + 0x84B0, 0x8450, 0x84B0, 0x84A0, 0x84A0, 0x84D0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, + 0x8510, 0x8530, 0x8570, 0x85F0, 0x8B00, 0x8BC0, 0x8B80, 0x8A60, 0x8930, 0x8830, 0x8790, 0x8720, 0x86E0, 0x86D0, 0x86C0, 0x86A0, + 0x86A0, 0x8680, 0x8690, 0x8680, 0x8690, 0x8690, 0x86A0, 0x86B0, 0x8700, 0x8720, 0x8700, 0x86C0, 0x8660, 0x85E0, 0x8560, 0x8510, + 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84C0, + 0x8500, 0x85C0, 0x8B80, 0xA2E0, 0xB7D0, 0xCC30, 0xDEF0, 0xEFA0, 0xFDD0, 0x0970, 0x1260, 0x1880, 0x1D50, 0x20A0, 0x2340, 0x2650, + 0x28B0, 0x2AB0, 0x2C40, 0x2C30, 0x2BF0, 0x28E0, 0x2490, 0x1FF0, 0x1960, 0x1300, 0x0B50, 0x0230, 0xF770, 0xE9C0, 0xD730, 0xC270, + 0xAAA0, 0x9290, 0x8690, 0x8500, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8450, 0x84D0, 0x8550, + 0x8900, 0x9280, 0x9360, 0x8D00, 0x8700, 0x8520, 0x8500, 0x84B0, 0x84A0, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8420, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8470, 0x8450, 0x8450, + 0x8400, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, + 0x8500, 0x8510, 0x8510, 0x8510, 0x8510, 0x8510, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8500, + 0x8500, 0x8510, 0x8520, 0x8530, 0x8550, 0x85B0, 0x8650, 0x87E0, 0x8BD0, 0x9350, 0x9C70, 0xA4F0, 0xADD0, 0xB6D0, 0xC030, 0xC890, + 0xD120, 0xD940, 0xE140, 0xE990, 0xF090, 0xF6B0, 0xFC80, 0x0180, 0x0590, 0x08B0, 0x09E0, 0x0B40, 0x0B50, 0x0AB0, 0x0A40, 0x0920, + 0x07F0, 0x06E0, 0x05A0, 0x04D0, 0x03B0, 0x0360, 0x0370, 0x03F0, 0x05B0, 0x0830, 0x0C80, 0x1170, 0x1880, 0x2210, 0x2D30, 0x3A40, + 0x4650, 0x50F0, 0x5A00, 0x5EE0, 0x61C0, 0x63D0, 0x66F0, 0x6BC0, 0x7150, 0x7850, 0x7DB0, 0x7F30, 0x7F10, 0x7EA0, 0x7EC0, 0x7EF0, + 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F20, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7C00, 0x79E0, 0x7A70, 0x7DA0, 0x7EF0, + 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x6630, 0x4A70, 0x32C0, 0x2300, 0x1C90, 0x1ED0, 0x26C0, 0x3250, 0x3D50, 0x4610, + 0x4B50, 0x4CC0, 0x4BC0, 0x4A60, 0x48B0, 0x4840, 0x4880, 0x47F0, 0x46C0, 0x44D0, 0x42B0, 0x40D0, 0x3F40, 0x3F80, 0x4030, 0x4260, + 0x4500, 0x4850, 0x4AF0, 0x4C10, 0x4CD0, 0x4C90, 0x4BF0, 0x4A10, 0x48E0, 0x4750, 0x4680, 0x4600, 0x45D0, 0x4600, 0x46E0, 0x4760, + 0x47D0, 0x4830, 0x48E0, 0x4A00, 0x4B90, 0x4DE0, 0x4F70, 0x5180, 0x5350, 0x5530, 0x57E0, 0x5A40, 0x5CF0, 0x6000, 0x62A0, 0x6600, + 0x6880, 0x6B70, 0x6DA0, 0x6F80, 0x7340, 0x7370, 0x7370, 0x7320, 0x72B0, 0x71D0, 0x70C0, 0x7000, 0x6EB0, 0x6DB0, 0x6CC0, 0x6B80, + 0x69D0, 0x6900, 0x6840, 0x68C0, 0x69B0, 0x6AB0, 0x6D00, 0x6E90, 0x7040, 0x7190, 0x7230, 0x71F0, 0x70C0, 0x6EB0, 0x6BF0, 0x68B0, + 0x6460, 0x5F50, 0x5AA0, 0x5570, 0x5070, 0x4B70, 0x4660, 0x4120, 0x3C40, 0x36D0, 0x3120, 0x2B40, 0x2590, 0x1FD0, 0x1A60, 0x1510, + 0x0FD0, 0x0A90, 0x0500, 0xFE80, 0xF8A0, 0xF2E0, 0xEDE0, 0xE910, 0xE4A0, 0xE0C0, 0xDD10, 0xDAD0, 0xD880, 0xD660, 0xD4C0, 0xD3D0, + 0xD290, 0xD220, 0xD140, 0xD0C0, 0xD080, 0xD000, 0xCF60, 0xCEB0, 0xCDB0, 0xCCE0, 0xCCA0, 0xCCD0, 0xCD50, 0xCE40, 0xCEC0, 0xCEF0, + 0xCFA0, 0xCF30, 0xCD70, 0xCAC0, 0xC710, 0xC270, 0xBE00, 0xB910, 0xB4F0, 0xB1C0, 0xAE90, 0xAC40, 0xAB00, 0xA930, 0xA880, 0xA900, + 0xAA70, 0xAD80, 0xB030, 0xB270, 0xB270, 0xAEC0, 0xA740, 0x9B30, 0x8D50, 0x8630, 0x8500, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8480, + 0x8480, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, + 0x8500, 0x8530, 0x8590, 0x8620, 0x8780, 0x89C0, 0x8D30, 0x9110, 0x9440, 0x9820, 0x9AE0, 0x9DC0, 0xA0B0, 0xA460, 0xA9B0, 0xAF60, + 0xB5F0, 0xBDB0, 0xC6E0, 0xD160, 0xDD40, 0xEA10, 0xF9A0, 0x08C0, 0x1930, 0x2A00, 0x3B20, 0x4BF0, 0x5B90, 0x6AA0, 0x76E0, 0x7EF0, + 0x7F00, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7EE0, 0x7F10, 0x7F20, + 0x7EC0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, + 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7F20, 0x7F10, 0x7F10, 0x7F30, + 0x7EE0, 0x7ED0, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7ED0, + 0x7E90, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F10, + 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F70, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, + 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F70, 0x7F00, 0x7ED0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, + 0x7EA0, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, 0x7E90, 0x7EF0, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F00, + 0x7F40, 0x7C50, 0x77F0, 0x7470, 0x7140, 0x6DF0, 0x6500, 0x63D0, 0x6230, 0x6070, 0x5F60, 0x5D00, 0x5B60, 0x5990, 0x57F0, 0x5740, + 0x5640, 0x5590, 0x55B0, 0x5570, 0x56C0, 0x5780, 0x5890, 0x59E0, 0x5B40, 0x5D90, 0x5F90, 0x6130, 0x63A0, 0x6530, 0x66A0, 0x6780, + 0x6890, 0x69B0, 0x6AA0, 0x6C80, 0x6ED0, 0x70B0, 0x7360, 0x75D0, 0x7910, 0x7C00, 0x7E60, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F30, + 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F80, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F80, 0x7F10, 0x7F10, 0x7EF0, + 0x7EE0, 0x7F70, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EE0, 0x7ED0, 0x7EF0, + 0x7F60, 0x7F20, 0x7E90, 0x7EF0, 0x7F00, 0x7F30, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7ED0, 0x7F10, 0x7F20, + 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7F10, + 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, + 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F00, 0x7F20, 0x7ED0, 0x7EB0, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7EB0, 0x7F00, 0x7C40, 0x6E50, 0x6130, 0x5440, 0x4620, 0x38D0, 0x2B00, 0x1DF0, 0x0EC0, 0x01C0, 0xF440, 0xE7B0, 0xDCA0, + 0xD270, 0xCA50, 0xC370, 0xBEA0, 0xBB20, 0xB8D0, 0xB7C0, 0xB7E0, 0xB860, 0xBAB0, 0xBD70, 0xC190, 0xC610, 0xCA50, 0xCE20, 0xD060, + 0xD0C0, 0xD0D0, 0xCF90, 0xCD80, 0xCA70, 0xC6D0, 0xC300, 0xBE10, 0xB9B0, 0xB4B0, 0xAE80, 0xA8A0, 0xA130, 0x9A20, 0x92D0, 0x8C00, + 0x8870, 0x8680, 0x85A0, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8440, 0x8490, 0x8480, 0x8480, 0x8410, + 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, + 0x84D0, 0x84E0, 0x84E0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84C0, 0x8490, 0x8490, 0x84A0, + 0x84C0, 0x84E0, 0x8520, 0x8570, 0x8540, 0x84E0, 0x84B0, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x8510, 0x8850, 0xA6D0, + 0xCB80, 0xF420, 0x20E0, 0x4FD0, 0x79B0, 0x7F00, 0x7F80, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7F00, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7F60, 0x7EF0, 0x7ED0, 0x62B0, 0x4260, 0x20D0, 0xFFD0, 0xDE30, 0xBDE0, 0x9D10, 0x88E0, 0x8540, 0x84E0, 0x84D0, 0x84C0, 0x84C0, + 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8520, 0x8560, 0x8600, 0x87C0, 0x8BE0, 0x9360, 0x9B00, 0xA240, 0xA920, 0xAFA0, 0xB660, + 0xBDB0, 0xC670, 0xCF70, 0xD990, 0xE450, 0xEEE0, 0xF9C0, 0x0310, 0x0BD0, 0x1340, 0x19D0, 0x1E30, 0x21C0, 0x23C0, 0x23F0, 0x2270, + 0x1F70, 0x1AE0, 0x1450, 0x0C10, 0x0360, 0xFA60, 0xF1B0, 0xE910, 0xE1C0, 0xDB20, 0xD610, 0xD200, 0xCF10, 0xCDC0, 0xCDF0, 0xCF60, + 0xD230, 0xD750, 0xDDB0, 0xE600, 0xF0E0, 0xFCB0, 0x0850, 0x1460, 0x1F40, 0x2930, 0x3180, 0x3800, 0x3D00, 0x40C0, 0x43C0, 0x4580, + 0x4680, 0x46F0, 0x4720, 0x4670, 0x4440, 0x3FF0, 0x3B30, 0x3550, 0x3000, 0x2BA0, 0x2840, 0x25E0, 0x2370, 0x2010, 0x1B80, 0x15C0, + 0x0E80, 0x0860, 0x0370, 0x0070, 0x0000, 0x0220, 0x06B0, 0x0D80, 0x15B0, 0x1FC0, 0x28B0, 0x3170, 0x3960, 0x3FF0, 0x4580, 0x49A0, + 0x4CC0, 0x4ED0, 0x4F70, 0x4F90, 0x4EC0, 0x4D50, 0x4B80, 0x4990, 0x4600, 0x42D0, 0x3EC0, 0x39C0, 0x34E0, 0x2F90, 0x2A10, 0x24A0, + 0x1F50, 0x1A50, 0x15B0, 0x1160, 0x0DB0, 0x0A70, 0x08A0, 0x0760, 0x06C0, 0x06D0, 0x06D0, 0x06E0, 0x0740, 0x07F0, 0x08C0, 0x0A30, + 0x0BD0, 0x0E30, 0x1160, 0x14E0, 0x1950, 0x1D00, 0x2110, 0x2430, 0x2760, 0x2AA0, 0x2DB0, 0x30B0, 0x33C0, 0x3660, 0x38D0, 0x3B30, + 0x3D00, 0x3E20, 0x3E90, 0x3E90, 0x3D00, 0x3B90, 0x3950, 0x3630, 0x3300, 0x3000, 0x2C90, 0x2920, 0x2630, 0x2350, 0x1FF0, 0x1DB0, + 0x1B40, 0x1910, 0x1630, 0x0B10, 0x0820, 0x06C0, 0x05F0, 0x05F0, 0x0740, 0x09C0, 0x0E50, 0x1370, 0x19D0, 0x20B0, 0x2960, 0x3140, + 0x39B0, 0x4230, 0x49F0, 0x5230, 0x58C0, 0x5F80, 0x6550, 0x6A10, 0x6F70, 0x7340, 0x76D0, 0x7A80, 0x7D40, 0x7ED0, 0x7EA0, 0x7EC0, + 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EE0, 0x7EF0, 0x7D50, 0x7880, 0x7280, 0x6B80, 0x62F0, 0x59F0, 0x4F00, 0x4200, 0x3550, + 0x2810, 0x1B20, 0x0E00, 0x0140, 0xF4F0, 0xE9E0, 0xE100, 0xD860, 0xD1F0, 0xCD70, 0xCA70, 0xC9E0, 0xCA20, 0xCC30, 0xCFE0, 0xD560, + 0xDD40, 0xE540, 0xEEB0, 0xF970, 0x0440, 0x0F90, 0x1A10, 0x2370, 0x2C70, 0x3530, 0x3D60, 0x4540, 0x4C30, 0x53D0, 0x5A60, 0x60A0, + 0x6550, 0x6890, 0x6BC0, 0x6CD0, 0x6EB0, 0x6FE0, 0x7060, 0x7190, 0x7200, 0x72B0, 0x72C0, 0x71B0, 0x7160, 0x6FC0, 0x6E10, 0x6B90, + 0x6830, 0x65C0, 0x61D0, 0x5E50, 0x5A80, 0x56D0, 0x5440, 0x5210, 0x5040, 0x4F90, 0x4F60, 0x5050, 0x5150, 0x5330, 0x5560, 0x57C0, + 0x5B50, 0x6080, 0x66A0, 0x6EC0, 0x7790, 0x7E90, 0x7F00, 0x7F50, 0x7F10, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, + 0x7EE0, 0x7F20, 0x7F20, 0x7EB0, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7E90, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7E10, 0x77F0, 0x7060, + 0x6790, 0x5E50, 0x5520, 0x4C00, 0x4350, 0x3A00, 0x31A0, 0x28C0, 0x1F10, 0x1510, 0x09A0, 0xFFD0, 0xF600, 0xECD0, 0xE440, 0xDBD0, + 0xD450, 0xCD30, 0xC620, 0xC030, 0xBAF0, 0xB6D0, 0xB300, 0xAFB0, 0xADB0, 0xABB0, 0xAAB0, 0xAA10, 0xA960, 0xAA10, 0xAA30, 0xAB00, + 0xAB80, 0xABB0, 0xAC90, 0xAD80, 0xAFC0, 0xB270, 0xB650, 0xBC20, 0xC300, 0xCB30, 0xD420, 0xDE00, 0xE7F0, 0xF120, 0xFA80, 0x0290, + 0x0910, 0x0F30, 0x1460, 0x19C0, 0x1E30, 0x21B0, 0x24E0, 0x2620, 0x25E0, 0x2400, 0x2050, 0x1AB0, 0x1360, 0x0940, 0xFD10, 0xEE20, + 0xDC40, 0xC950, 0xB590, 0xA1D0, 0x8F10, 0x86B0, 0x8520, 0x84E0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, + 0x84D0, 0x84F0, 0x8510, 0x8570, 0x8650, 0x88C0, 0x8EF0, 0x9760, 0x9D60, 0xA220, 0xA450, 0xA510, 0xA310, 0x9FD0, 0x9C50, 0x98D0, + 0x96F0, 0x9710, 0x9A50, 0xA030, 0xA910, 0xB410, 0xC0B0, 0xCCF0, 0xD990, 0xE610, 0xF170, 0xFC20, 0x0500, 0x0E30, 0x1590, 0x1AE0, + 0x1D80, 0x1D90, 0x1CF0, 0x1A30, 0x1660, 0x12E0, 0x0FD0, 0x0F00, 0x0FC0, 0x1220, 0x14F0, 0x18C0, 0x1C50, 0x1F20, 0x1FF0, 0x1FC0, + 0x1DD0, 0x1B30, 0x16A0, 0x0FF0, 0x0880, 0xFF10, 0xF4E0, 0xE990, 0xDCB0, 0xCFA0, 0xC200, 0xB620, 0xAB30, 0xA280, 0x9EC0, 0x9D90, + 0x9DE0, 0x9E70, 0x9EF0, 0x9F40, 0x9E60, 0x9CA0, 0x9A30, 0x9700, 0x94B0, 0x91B0, 0x8F60, 0x8D90, 0x8C70, 0x8CA0, 0x8DF0, 0x91C0, + 0x97B0, 0x9E90, 0xA660, 0xADB0, 0xB440, 0xB9F0, 0xBF70, 0xC510, 0xCAB0, 0xCFF0, 0xD590, 0xD9B0, 0xDD70, 0xDF10, 0xDF30, 0xDEF0, + 0xDD90, 0xDD40, 0xDDD0, 0xDEB0, 0xE1C0, 0xE570, 0xEA90, 0xF120, 0xF870, 0x0110, 0x0C00, 0x1860, 0x2620, 0x3550, 0x44F0, 0x52A0, + 0x5E20, 0x6690, 0x6C50, 0x7060, 0x7140, 0x7150, 0x6FB0, 0x6C60, 0x67D0, 0x60C0, 0x57B0, 0x4C40, 0x3E10, 0x30B0, 0x2320, 0x1750, + 0x0C10, 0x0290, 0xFAC0, 0xF3D0, 0xEE30, 0xEA20, 0xE900, 0xEAB0, 0xEEF0, 0xF560, 0xFDC0, 0x06F0, 0x10B0, 0x18E0, 0x1FD0, 0x24B0, + 0x27A0, 0x2980, 0x2980, 0x28B0, 0x27C0, 0x2670, 0x25B0, 0x25A0, 0x2570, 0x2590, 0x2550, 0x2500, 0x2460, 0x2350, 0x2260, 0x20A0, + 0x1F10, 0x1C10, 0x17E0, 0x1370, 0x0D50, 0x06B0, 0xFF00, 0xF5C0, 0xEB50, 0xDE00, 0xCF70, 0xBE90, 0xA990, 0x9230, 0x8620, 0x84E0, + 0x84B0, 0x84B0, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8470, + 0x8470, 0x8440, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84B0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x8490, 0x84A0, 0x8490, 0x84A0, + 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, 0x8500, + 0x8520, 0x8540, 0x8580, 0x85E0, 0x8670, 0x8790, 0x88D0, 0x8B70, 0x8F70, 0x9420, 0x98C0, 0x9D70, 0xA270, 0xA710, 0xAC90, 0xB150, + 0xB5F0, 0xBAE0, 0xBFF0, 0xC510, 0xCA50, 0xCFA0, 0xD4F0, 0xDAB0, 0xE000, 0xE590, 0xEB30, 0xF0E0, 0xF6E0, 0xFD40, 0x0380, 0x0A50, + 0x1120, 0x1740, 0x1D50, 0x2370, 0x2910, 0x2E40, 0x3390, 0x37A0, 0x3BF0, 0x4020, 0x43F0, 0x4740, 0x4A20, 0x4CF0, 0x4FD0, 0x51B0, + 0x5360, 0x54D0, 0x5610, 0x5720, 0x5840, 0x5940, 0x5A30, 0x5BA0, 0x5CC0, 0x5E10, 0x5E50, 0x5EC0, 0x5ED0, 0x5EE0, 0x5E70, 0x5DC0, + 0x5D50, 0x5C30, 0x5B30, 0x59C0, 0x5810, 0x5610, 0x5460, 0x52A0, 0x4FD0, 0x4D30, 0x4B70, 0x49C0, 0x4880, 0x4720, 0x45E0, 0x4410, + 0x4230, 0x4090, 0x3F20, 0x3E00, 0x3CB0, 0x3C70, 0x3BF0, 0x3C10, 0x3C20, 0x3C60, 0x3C60, 0x3C80, 0x3C90, 0x3CE0, 0x3DA0, 0x3E60, + 0x3FE0, 0x4140, 0x4310, 0x44D0, 0x4630, 0x4780, 0x48C0, 0x4990, 0x4AF0, 0x4C30, 0x4DA0, 0x4F20, 0x5140, 0x52B0, 0x54D0, 0x5680, + 0x5910, 0x5AF0, 0x5DE0, 0x60E0, 0x6450, 0x67D0, 0x6B80, 0x6F20, 0x7240, 0x75B0, 0x78A0, 0x7B00, 0x7CD0, 0x7E50, 0x7F00, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7EF0, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7ED0, 0x7EF0, 0x7F20, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, + 0x7F20, 0x7F40, 0x7EF0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, + 0x7EF0, 0x7F10, 0x7EC0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7F10, 0x7230, 0x6260, 0x5570, 0x4AB0, + 0x43B0, 0x4020, 0x3F10, 0x4050, 0x4260, 0x4490, 0x4510, 0x45A0, 0x4740, 0x4B40, 0x5450, 0x61B0, 0x72F0, 0x7F10, 0x7F00, 0x7F00, + 0x7EF0, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, + 0x7F70, 0x7EB0, 0x48A0, 0x1010, 0xD570, 0x9B30, 0x8500, 0x84A0, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8420, 0x8430, + 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84E0, 0x84E0, 0x8510, 0x8570, 0x8690, + 0x8980, 0x8EB0, 0x9480, 0x98D0, 0x9C20, 0x9E70, 0x9F80, 0x9FD0, 0x9ED0, 0x9E30, 0x9C30, 0x9960, 0x95D0, 0x9270, 0x8EF0, 0x8BF0, + 0x8990, 0x87F0, 0x86C0, 0x8600, 0x8580, 0x8530, 0x8510, 0x84F0, 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x84D0, 0x84A0, + 0x8490, 0x8490, 0x84B0, 0x84A0, 0x8480, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, + 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8530, 0x8550, 0x85A0, 0x8610, 0x8710, 0x88B0, 0x8BD0, 0x9080, 0x95B0, + 0x9B00, 0xA0E0, 0xA690, 0xAD90, 0xB4B0, 0xBC90, 0xC470, 0xCBE0, 0xD310, 0xDA30, 0xF230, 0xF630, 0xF9B0, 0xFC40, 0xFE50, 0xFFB0, + 0x0140, 0x0340, 0x0580, 0x07E0, 0x0A70, 0x0D40, 0x1090, 0x1350, 0x15C0, 0x1720, 0x1750, 0x16E0, 0x14D0, 0x1190, 0x0D20, 0x0770, + 0x0140, 0xFA50, 0xF3A0, 0xED90, 0xE810, 0xE3C0, 0xDFE0, 0xDC90, 0xD9B0, 0xD7B0, 0xD680, 0xD650, 0xD6B0, 0xD890, 0xDB90, 0xE060, + 0xE690, 0xEEF0, 0xFA00, 0x0610, 0x1320, 0x20A0, 0x2F10, 0x3CB0, 0x48C0, 0x5430, 0x5EB0, 0x6740, 0x6FA0, 0x7600, 0x7B10, 0x7E40, + 0x7ED0, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F20, + 0x7F20, 0x7EF0, 0x7F50, 0x7F10, 0x7DA0, 0x6440, 0x4690, 0x24F0, 0x01A0, 0xDD00, 0xB6E0, 0x9590, 0x8640, 0x8530, 0x84B0, 0x84A0, + 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, + 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, + 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, + 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8500, 0x8540, 0x85D0, 0x86C0, 0x8810, + 0x89D0, 0x8B60, 0x8C60, 0x8CA0, 0x8D00, 0x8CA0, 0x8C60, 0x8C10, 0x8BF0, 0x8C50, 0x8D10, 0x8F10, 0x9080, 0x91D0, 0x9310, 0x94E0, + 0x9680, 0x9800, 0x9970, 0x9B40, 0x9CD0, 0x9E60, 0x9EF0, 0x9ED0, 0x9DD0, 0x9BF0, 0x98D0, 0x9500, 0x9160, 0x8EE0, 0x8CD0, 0x8BF0, + 0x8BA0, 0x8C00, 0x8DB0, 0x9040, 0x9510, 0x9AA0, 0xA220, 0xAA70, 0xB310, 0xBD20, 0xC6A0, 0xD000, 0xD9F0, 0xE300, 0xEB20, 0xF2A0, + 0xF850, 0xFE30, 0x0280, 0x0620, 0x0850, 0x08B0, 0x08E0, 0x07C0, 0x05F0, 0x0380, 0x0080, 0xFE50, 0xFBD0, 0xFA60, 0xFA10, 0xFA70, + 0xFB10, 0xFBC0, 0xFC30, 0xFE00, 0xFFA0, 0x01E0, 0x04D0, 0x0770, 0x0AE0, 0x0D70, 0x1020, 0x1260, 0x13D0, 0x1590, 0x1640, 0x1760, + 0x1790, 0x17B0, 0x1870, 0x1890, 0x19A0, 0x1AD0, 0x1B70, 0x1D50, 0x1F00, 0x2140, 0x2330, 0x2510, 0x2800, 0x2A50, 0x2D50, 0x30B0, + 0x3420, 0x37C0, 0x3B00, 0x3EB0, 0x4240, 0x45D0, 0x4A60, 0x4DC0, 0x5190, 0x5510, 0x5860, 0x5BA0, 0x5F10, 0x6250, 0x65B0, 0x68E0, + 0x6C50, 0x6F80, 0x7270, 0x7520, 0x7750, 0x7A00, 0x7BB0, 0x7D30, 0x7E00, 0x7E70, 0x7ED0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, + 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, + 0x7EF0, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F40, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x76A0, 0x6AF0, 0x5D50, 0x4ED0, 0x3EB0, 0x2D40, + 0x1970, 0x02F0, 0xE9F0, 0xCC70, 0xAE00, 0x8FB0, 0x8570, 0x84C0, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, + 0x8440, 0x8440, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84E0, 0x84C0, 0x84E0, + 0x8510, 0x8580, 0x86B0, 0x89F0, 0x9090, 0x9890, 0x9F50, 0xA4E0, 0xA880, 0xAA80, 0xAB40, 0xABD0, 0xAC70, 0xAE50, 0xB110, 0xB500, + 0xB8D0, 0xB870, 0xB0B0, 0x9FB0, 0x8AE0, 0x8530, 0x84D0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x8570, 0x8610, 0x86B0, + 0x8790, 0x8940, 0x8D60, 0x93D0, 0x9C00, 0xA420, 0xAA60, 0xAFC0, 0xB3C0, 0xB770, 0xBA60, 0xBD50, 0xC030, 0xC3A0, 0xC6B0, 0xC9C0, + 0xCC30, 0xCD80, 0xCD90, 0xCCD0, 0xCB00, 0xC8E0, 0xC8B0, 0xC9C0, 0xCC60, 0xD150, 0xD710, 0xDDF0, 0xE640, 0xF1D0, 0xFD10, 0x0920, + 0x1500, 0x2050, 0x2A90, 0x32E0, 0x39C0, 0x3EF0, 0x4320, 0x4530, 0x4610, 0x4530, 0x42F0, 0x3EF0, 0x3990, 0x3320, 0x2AC0, 0x2050, + 0x1560, 0x0920, 0xFC40, 0xEF00, 0xE1F0, 0xD6B0, 0xCD20, 0xC690, 0xC160, 0xBE40, 0xBBD0, 0xB880, 0xB550, 0xB0C0, 0xAC80, 0xA820, + 0xA470, 0xA170, 0x9FC0, 0x9F40, 0x9FC0, 0xA160, 0xA2F0, 0xA510, 0xA6A0, 0xA770, 0xA770, 0xA650, 0xA4E0, 0xA2B0, 0x9F70, 0x9C20, + 0x9820, 0x93C0, 0x8F90, 0x8B40, 0x8900, 0x8770, 0x8680, 0x8600, 0x85A0, 0x8570, 0x8550, 0x8540, 0x8540, 0x8540, 0x8550, 0x8580, + 0x85C0, 0x8660, 0x8820, 0x8CB0, 0x9670, 0xA170, 0xAB60, 0xB470, 0xBC60, 0xC3C0, 0xCA40, 0xD060, 0xD660, 0xDCC0, 0xE350, 0xE980, + 0xEFB0, 0xF510, 0xF990, 0xFCF0, 0xFF70, 0x02A0, 0x05B0, 0x0A20, 0x0EF0, 0x1590, 0x1DE0, 0x2740, 0x3290, 0x3E30, 0x49B0, 0x56C0, + 0x6410, 0x7210, 0x7D70, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F00, 0x7F30, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, + 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, + 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7F30, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F30, 0x7ED0, 0x7090, 0x5E00, 0x4460, 0x2710, 0x0830, + 0xE800, 0xC880, 0xAA80, 0x8FE0, 0x85F0, 0x84E0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8500, 0x8520, 0x8580, 0x8630, + 0x8810, 0xA710, 0xB130, 0xBA00, 0xC250, 0xCB60, 0xD450, 0xDD00, 0xE510, 0xEC70, 0xF330, 0xF930, 0xFE30, 0x0220, 0x03C0, 0x0410, + 0x01E0, 0xFDD0, 0xF7B0, 0xF010, 0xE700, 0xDDA0, 0xD590, 0xCEB0, 0xC930, 0xC5C0, 0xC410, 0xC560, 0xC890, 0xCEA0, 0xD6B0, 0xDF00, + 0xE7B0, 0xF060, 0xF7E0, 0xFFC0, 0x06C0, 0x0D00, 0x12E0, 0x1700, 0x1BB0, 0x1F30, 0x2280, 0x2560, 0x2780, 0x2AB0, 0x2D00, 0x2EB0, + 0x3060, 0x3180, 0x3290, 0x33B0, 0x3460, 0x3480, 0x33F0, 0x33B0, 0x3360, 0x3260, 0x3130, 0x2EF0, 0x22F0, 0x1FF0, 0x1D60, 0x1B10, + 0x1A30, 0x1970, 0x18C0, 0x1980, 0x1AF0, 0x1C30, 0x1F50, 0x22B0, 0x2670, 0x2A70, 0x2E10, 0x31B0, 0x34A0, 0x3790, 0x3950, 0x3AA0, + 0x3B60, 0x3A50, 0x39D0, 0x3770, 0x34A0, 0x31C0, 0x2D40, 0x28C0, 0x2390, 0x1F90, 0x1CA0, 0x1A00, 0x18F0, 0x19B0, 0x1B70, 0x1EE0, + 0x2150, 0x2200, 0x1F00, 0x17C0, 0x0DA0, 0xFF00, 0xED40, 0xD9F0, 0xC400, 0xACB0, 0x9250, 0x8640, 0x84E0, 0x84B0, 0x8490, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8460, 0x84B0, 0x8500, 0x8590, 0x8E30, 0xA810, 0xB9E0, 0xBF20, 0xB600, 0x9BF0, + 0x8590, 0x8490, 0x8460, 0x8440, 0x8410, 0x8400, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8410, 0x8430, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8470, 0x8450, 0x8440, 0x8440, 0x8470, 0x8440, 0x8440, + 0x8440, 0x8460, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, + 0x8480, 0x8480, 0x8490, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8510, 0x8580, 0x86C0, 0x8AE0, 0x94E0, 0x9FD0, + 0xAA20, 0xB3F0, 0xBE10, 0xCA30, 0xD7E0, 0xE770, 0xF9E0, 0x0AB0, 0x1B50, 0x29D0, 0x3630, 0x4100, 0x4990, 0x5250, 0x5A30, 0x61D0, + 0x6950, 0x7000, 0x76E0, 0x7C40, 0x7ED0, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7EB0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, + 0x7F20, 0x7F10, 0x7F20, 0x7F40, 0x7E50, 0x76B0, 0x6D20, 0x6150, 0x5210, 0x41B0, 0x2E60, 0x1CB0, 0x0BB0, 0xFD10, 0xF1E0, 0xE980, + 0xE450, 0xE100, 0xDF10, 0xDE00, 0xDD30, 0xDBE0, 0xDB00, 0xD970, 0xD900, 0xD860, 0xD940, 0xD980, 0xDA10, 0xDB20, 0xDBB0, 0xDC90, + 0xDDA0, 0xDE40, 0xDFA0, 0xE0F0, 0xE2C0, 0xE580, 0xE830, 0xEC20, 0xF0D0, 0xF630, 0xFCB0, 0x0380, 0x0AC0, 0x11B0, 0x1870, 0x1DE0, + 0x21C0, 0x2480, 0x2640, 0x2680, 0x2730, 0x2710, 0x26E0, 0x2640, 0x2510, 0x2460, 0x22F0, 0x21D0, 0x2110, 0x1FE0, 0x1F00, 0x1E50, + 0x1CE0, 0x1B60, 0x1950, 0x1870, 0x1660, 0x1420, 0x11F0, 0x0E90, 0x0B00, 0x05E0, 0x0030, 0xF9D0, 0xF270, 0xEB90, 0xE4F0, 0xDF30, + 0xDBD0, 0xD8C0, 0xD7A0, 0xD740, 0xD7B0, 0xD870, 0xD920, 0xD890, 0xD5B0, 0xD090, 0xCA40, 0xC110, 0xB890, 0xAF50, 0xA770, 0xA110, + 0x9D80, 0x9C80, 0x9DC0, 0xA1D0, 0xA900, 0xAE70, 0xB320, 0xB610, 0xB760, 0xB790, 0xB7B0, 0xB7F0, 0xB930, 0xBBF0, 0xC020, 0xC620, + 0xCDF0, 0xD6B0, 0xE070, 0xEA50, 0xF5B0, 0xFFD0, 0x0A60, 0x1560, 0x2040, 0x2B50, 0x36B0, 0x41C0, 0x4C40, 0x5730, 0x6000, 0x68C0, + 0x7110, 0x78A0, 0x7E60, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7EF0, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F70, 0x7F10, 0x7EE0, 0x7F20, 0x7F20, 0x7F30, 0x7F40, + 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7EE0, 0x7E50, 0x7ED0, 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, + 0x7F40, 0x7EE0, 0x7EF0, 0x7F30, 0x7EA0, 0x7F40, 0x7F00, 0x7290, 0x6410, 0x55E0, 0x46C0, 0x3A30, 0x2EE0, 0x2660, 0x1ED0, 0x1910, + 0x14C0, 0x10C0, 0x0CD0, 0x0700, 0xFFC0, 0xF6B0, 0xEB30, 0xDDC0, 0xCDC0, 0xBCD0, 0xAA30, 0x97C0, 0x8980, 0x8590, 0x8500, 0x84D0, + 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8480, 0x8450, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8530, 0x8580, 0x8640, 0x8850, 0x8D00, 0x9690, 0xA180, + 0xAC50, 0xB890, 0xC530, 0xD200, 0xDF00, 0xEA90, 0xF5C0, 0x0010, 0x0B10, 0x1540, 0x1DE0, 0x25F0, 0x2BD0, 0x30C0, 0x3340, 0x3480, + 0x3330, 0x2DE0, 0x2650, 0x1A50, 0x0990, 0xF460, 0xD9B0, 0xBF60, 0xA520, 0x8DF0, 0x8600, 0x8500, 0x8480, 0x84B0, 0x8490, 0x8490, + 0x8480, 0x8470, 0x8470, 0x84B0, 0x8460, 0x8450, 0x8450, 0x8490, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, + 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8470, 0x8450, 0x8450, + 0x8460, 0x8470, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x8500, 0x8550, 0x86F0, 0x9110, + 0xA350, 0xEC50, 0xFD60, 0x0F90, 0x2130, 0x3370, 0x4520, 0x55F0, 0x6530, 0x71F0, 0x7AE0, 0x7ED0, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, + 0x5FF0, 0x57F0, 0x5240, 0x4D90, 0x4B10, 0x4A00, 0x4A20, 0x4C90, 0x4FA0, 0x53F0, 0x5A00, 0x6030, 0x6720, 0x6DC0, 0x72B0, 0x77A0, + 0x7AD0, 0x7D90, 0x7EB0, 0x7EF0, 0x7F10, 0x7EC0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F00, + 0x7F30, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, + 0x7F20, 0x7EC0, 0x7E60, 0x7E20, 0x7DF0, 0x7E10, 0x7E30, 0x7EA0, 0x7EC0, 0x7EF0, 0x7F00, 0x7EA0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F20, + 0x7E90, 0x7EB0, 0x7F00, 0x7F10, 0x7F00, 0x7EA0, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F40, + 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7ED0, 0x7EA0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7F00, + 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F40, 0x7ED0, 0x7F00, 0x7F20, 0x7EF0, 0x7F70, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, + 0x7EF0, 0x7EF0, 0x7F00, 0x7EE0, 0x7F70, 0x7F00, 0x7ED0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EC0, 0x7EC0, 0x7F30, 0x7F20, + 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7EC0, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, + 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, + 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F80, 0x7F10, 0x7690, 0x68E0, 0x5940, 0x48B0, 0x3710, 0x25A0, 0x1540, 0x04D0, 0xF490, 0xE3F0, + 0xD1A0, 0xBD30, 0xA6F0, 0x8F00, 0x8610, 0x84F0, 0x84C0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, + 0x84E0, 0x8500, 0x8560, 0x8660, 0x8960, 0x91B0, 0x9C00, 0xA5D0, 0xAF90, 0xB830, 0xBFE0, 0xC5D0, 0xCAF0, 0xCE90, 0xD0E0, 0xD310, + 0xD3E0, 0xD560, 0xD600, 0xD690, 0xD750, 0xD6F0, 0xD630, 0xD440, 0xD240, 0xCFB0, 0xCD20, 0xCA60, 0xC7C0, 0xC5D0, 0xC420, 0xC2D0, + 0xC100, 0xBF10, 0xBDC0, 0xBC00, 0xB9F0, 0xB760, 0xB450, 0xB080, 0xAC20, 0xA7A0, 0xA290, 0x9E60, 0x9830, 0x9330, 0x8E10, 0x8A40, + 0x8790, 0x8630, 0x8580, 0x8540, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, + 0x84F0, 0x8500, 0x8520, 0x8530, 0x8570, 0x85B0, 0x8620, 0x86E0, 0x8800, 0x89C0, 0x8C70, 0x8F80, 0x9230, 0x9640, 0x9A20, 0x9DF0, + 0xA1F0, 0xA490, 0xA790, 0xAA10, 0xAD60, 0xB010, 0xB490, 0xB870, 0xBC30, 0xBF80, 0xC200, 0xC3D0, 0xC610, 0xC870, 0xCB00, 0xCE90, + 0xD160, 0xD4A0, 0xD6C0, 0xD910, 0xDB70, 0xDE80, 0xE1F0, 0xE530, 0xE830, 0xEB20, 0xEE10, 0xF010, 0xF2C0, 0xF560, 0xF880, 0xFAF0, + 0xFED0, 0x02C0, 0x05D0, 0x0920, 0x0C60, 0x0F50, 0x1240, 0x15B0, 0x1920, 0x1CA0, 0x1FD0, 0x22F0, 0x2640, 0x2990, 0x2CB0, 0x3030, + 0x3320, 0x3660, 0x3950, 0x3BB0, 0x3E40, 0x40B0, 0x4260, 0x4400, 0x4640, 0x4850, 0x49D0, 0x4A60, 0x49D0, 0x48F0, 0x47B0, 0x46E0, + 0x4590, 0x44B0, 0x43B0, 0x4300, 0x42E0, 0x4200, 0x40C0, 0x3F10, 0x3DF0, 0x3C90, 0x3B70, 0x3A40, 0x3970, 0x38B0, 0x3880, 0x3800, + 0x37F0, 0x3770, 0x3760, 0x3770, 0x3810, 0x3910, 0x39E0, 0x3A90, 0x3BB0, 0x3D20, 0x3EA0, 0x4040, 0x41F0, 0x42D0, 0x4400, 0x4540, + 0x4610, 0x46B0, 0x4830, 0x49E0, 0x4B10, 0x4CC0, 0x4E00, 0x4FA0, 0x50E0, 0x5210, 0x5370, 0x54A0, 0x5540, 0x55C0, 0x5610, 0x56A0, + 0x5740, 0x58F0, 0x5A90, 0x5C40, 0x5DF0, 0x5F70, 0x6110, 0x6320, 0x66E0, 0x6BD0, 0x7170, 0x7780, 0x7D10, 0x7F10, 0x7F30, 0x7EE0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F40, 0x7DF0, 0x7780, 0x6EE0, 0x62E0, 0x52D0, 0x3EB0, 0x23E0, 0x0270, 0xDAD0, 0xA990, 0x8740, 0x84C0, + 0x8490, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8490, 0x8480, 0x8480, 0x8480, 0x8490, + 0x8480, 0x8470, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8490, 0x8460, 0x8450, 0x8470, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, + 0x8430, 0x8430, 0x8440, 0x8430, 0x8440, 0x8430, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x84A0, 0x84C0, 0x8510, + 0x8690, 0x9230, 0xA460, 0xB260, 0xBDD0, 0xC7E0, 0xCF80, 0xD6B0, 0xDC90, 0xE320, 0xE8E0, 0xEE00, 0xF290, 0xF5F0, 0xF950, 0xFBC0, + 0xFD90, 0xFF10, 0x00B0, 0x0260, 0x0420, 0x05D0, 0x08B0, 0x0B90, 0x0DF0, 0x1150, 0x1490, 0x18F0, 0x1D60, 0x21F0, 0x2770, 0x2CE0, + 0x32D0, 0x38B0, 0x3F60, 0x4660, 0x4D50, 0x5590, 0x5CF0, 0x6460, 0x6C50, 0x73E0, 0x7AC0, 0x7E80, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, + 0x7F10, 0x7F00, 0x7F10, 0x7EB0, 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F00, + 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7F10, + 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F00, + 0x7F00, 0x7EF0, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EF0, + 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7EA0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, + 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7F80, 0x7DA0, 0x75E0, 0x6FA0, 0x6A20, 0x65E0, 0x6350, 0x6270, 0x6430, 0x67C0, 0x6CC0, 0x7330, + 0x7920, 0x7DF0, 0x7EF0, 0x7F70, 0x7F20, 0x7ED0, 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F20, 0x7EA0, + 0x7DD0, 0x7C50, 0x7A50, 0x79B0, 0x78B0, 0x78C0, 0x7890, 0x77D0, 0x7760, 0x7580, 0x7380, 0x7050, 0x6B10, 0x6500, 0x5C00, 0x5140, + 0x4400, 0x3400, 0x2390, 0x1110, 0xFDF0, 0xEB90, 0xDB90, 0xCF00, 0xC710, 0xC540, 0xCA70, 0xD670, 0xE840, 0xFE90, 0x1530, 0x2B60, + 0x4090, 0x5310, 0x6250, 0x6E60, 0x76C0, 0x7B10, 0x7D60, 0x7D50, 0x7BB0, 0x78B0, 0x75F0, 0x75F0, 0x7810, 0x7C30, 0x7EE0, 0x7EF0, + 0x7ED0, 0x7EB0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7ED0, 0x72F0, 0x3E90, 0x0520, 0xC380, 0x87B0, + 0x84A0, 0x8470, 0x8440, 0x8440, 0x8430, 0x8430, 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8440, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8440, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8500, 0x8540, 0x85E0, 0x8720, 0x8890, 0x8980, + 0x8930, 0x8800, 0x8730, 0x86D0, 0x8700, 0x87B0, 0x8A30, 0x8F70, 0x9810, 0xA0F0, 0xAA90, 0xB270, 0xB900, 0xBFA0, 0xC600, 0xCBC0, + 0xD250, 0xD9D0, 0xE1A0, 0xEA50, 0xF300, 0xFC20, 0x0540, 0x0F70, 0x1BE0, 0x2900, 0x3750, 0x4550, 0x5250, 0x5DD0, 0x65B0, 0x6C20, + 0x7080, 0x7210, 0x7310, 0x7180, 0x6E80, 0x6A00, 0x63E0, 0x5EA0, 0x5800, 0x51B0, 0x4C20, 0x45C0, 0x40D0, 0x3B90, 0x3690, 0x32B0, + 0x2FA0, 0x2E90, 0x2E50, 0x3030, 0x32F0, 0x3740, 0x3E10, 0x4730, 0x5270, 0x5EC0, 0x6B80, 0x77B0, 0x7EE0, 0x7F80, 0x7EF0, 0x7EB0, + 0x7F10, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EB0, 0x7F00, 0x7F40, 0x7F40, 0x7ED0, 0x7EA0, 0x7EE0, + 0x7EF0, 0x7F10, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7EF0, + 0x7F30, 0x7F20, 0x7F10, 0x7F90, 0x7B20, 0x6EC0, 0x6390, 0x57F0, 0x4C20, 0x3F10, 0x35D0, 0x2E20, 0x2780, 0x2290, 0x1EB0, 0x1C00, + 0x1A50, 0x1AF0, 0x1D20, 0x2080, 0x25B0, 0x2A90, 0x2FE0, 0x3540, 0x3A70, 0x3F90, 0x4430, 0x48A0, 0x4CF0, 0x5210, 0x56E0, 0x5BF0, + 0x60D0, 0x65A0, 0x6AE0, 0x6F90, 0x73B0, 0x7750, 0x7A50, 0x7C30, 0x7D30, 0x7DA0, 0x7D00, 0x7B50, 0x7890, 0x7400, 0x6E40, 0x6620, + 0x5D80, 0x5290, 0x4530, 0x3680, 0x25E0, 0x1370, 0xFEE0, 0xE860, 0xCE90, 0xB510, 0x9A50, 0x87E0, 0x8500, 0x84C0, 0x84A0, 0x8490, + 0x84B0, 0x8470, 0x8470, 0x8440, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, + 0x84A0, 0x84F0, 0x8540, 0x9180, 0xB7B0, 0xD9F0, 0xF900, 0x13C0, 0x2B90, 0x41D0, 0x54E0, 0x63F0, 0x6FB0, 0x76A0, 0x7A80, 0x7BF0, + 0x7B30, 0x7820, 0x72C0, 0x6A10, 0x5ED0, 0x5070, 0x4180, 0x3310, 0x24F0, 0x1680, 0x06C0, 0xF2A0, 0xDAD0, 0xBF60, 0x9F10, 0x8880, + 0x8500, 0x84C0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8540, 0x8740, + 0x9930, 0xAE50, 0xC1F0, 0xD1C0, 0xDD50, 0xE4C0, 0xE930, 0xEC20, 0xF070, 0xF790, 0x01B0, 0x0EF0, 0x1EA0, 0x3030, 0x41B0, 0x5270, + 0x6150, 0x6E70, 0x7A60, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7390, 0x6770, 0x5B60, + 0x4E60, 0x4150, 0x3460, 0x2740, 0x1A80, 0x0F50, 0x0550, 0xFCA0, 0xF520, 0xECB0, 0xE270, 0xD570, 0xC6A0, 0xB690, 0xA5D0, 0x95D0, + 0x8AF0, 0x86C0, 0x8580, 0x8530, 0x8500, 0x84F0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8520, 0x8530, 0x8540, + 0x8550, 0x8540, 0x8560, 0x8570, 0x8580, 0x85A0, 0x85B0, 0x85D0, 0x85C0, 0x85B0, 0x85C0, 0x85A0, 0x8590, 0x8580, 0x8570, 0x8560, + 0x8550, 0x8540, 0x8550, 0x8560, 0x8580, 0x85A0, 0x85F0, 0x8670, 0x8700, 0x87B0, 0x8890, 0x8970, 0x8A70, 0x8AF0, 0x8BB0, 0x8CB0, + 0x8DD0, 0x8F70, 0x9100, 0x9280, 0x93F0, 0x94F0, 0x9580, 0x9510, 0x9400, 0x9290, 0x90F0, 0x8F90, 0x8DE0, 0x8BC0, 0x89A0, 0x87C0, + 0x8650, 0x8580, 0x8530, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84F0, 0x8500, 0x8500, 0x8510, 0x8510, 0x8510, + 0x8520, 0x8530, 0x8540, 0x8540, 0x8530, 0x8520, 0x84F0, 0x84E0, 0x84C0, 0x84A0, 0x8490, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8450, 0x8430, + 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8430, 0x8450, 0x8450, 0x8460, 0x8470, 0x8490, + 0x84B0, 0x84D0, 0x84F0, 0x8500, 0x84F0, 0x84D0, 0x84C0, 0x8480, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x8510, 0x8520, 0x8590, 0x8660, + 0x87B0, 0x8890, 0x87D0, 0x8600, 0x8500, 0x84C0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8410, + 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8470, 0x84D0, 0x84F0, 0x8510, 0x8550, 0x85E0, 0x8700, 0x8960, 0x8E10, 0x9390, 0x9890, + 0x9C00, 0x9F40, 0xA210, 0xA4E0, 0xA810, 0xAC50, 0xB170, 0xB650, 0xBB00, 0xBEF0, 0xC1F0, 0xC4E0, 0xC6C0, 0xC800, 0xCA90, 0xCD20, + 0xCFF0, 0xD290, 0xD510, 0xD760, 0xD910, 0xD9F0, 0xDBA0, 0xDDD0, 0xDFB0, 0xE210, 0xE420, 0xE650, 0xE890, 0xEB20, 0xEDA0, 0xEFC0, + 0xF2F0, 0xF500, 0xF6C0, 0xF910, 0xFB80, 0xFEB0, 0x0240, 0x06F0, 0x0BE0, 0x1120, 0x1750, 0x1D90, 0x23F0, 0x2B60, 0x33C0, 0x3DD0, + 0x4800, 0x5270, 0x5D90, 0x67A0, 0x7160, 0x7940, 0x7E50, 0x7F20, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7E90, 0x7E80, 0x7F00, + 0x7EF0, 0x7F00, 0x7E90, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7F30, + 0x7F20, 0x7F00, 0x7F50, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7A20, 0x5900, 0x3D50, 0x2480, 0x0F80, + 0xFC00, 0xE7C0, 0xD150, 0xB790, 0x9BC0, 0x8730, 0x84F0, 0x84C0, 0x84A0, 0x8490, 0x8440, 0x8480, 0x8470, 0x8470, 0x8470, 0x8450, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x84F0, 0x8540, 0x86D0, 0x8F70, 0x9FC0, + 0xAE40, 0xB990, 0xC400, 0xCD60, 0xD6C0, 0xE010, 0xE8F0, 0xF190, 0xFA20, 0x0170, 0x08B0, 0x0E70, 0x1330, 0x1750, 0x1B60, 0x1FA0, + 0x2440, 0x2870, 0x2E10, 0x3270, 0x3730, 0x3B60, 0x3F50, 0x43D0, 0x4830, 0x4D80, 0x5290, 0x57F0, 0x5CC0, 0x60C0, 0x7000, 0x7290, + 0x74F0, 0x76C0, 0x7810, 0x7A20, 0x7B60, 0x7C70, 0x7CE0, 0x7D40, 0x7DD0, 0x7E30, 0x7EB0, 0x7EC0, 0x7EB0, 0x7F10, 0x7EF0, 0x7F30, + 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F30, + 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7F20, 0x7F00, 0x7EF0, 0x7EF0, + 0x7F30, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EE0, 0x7ED0, 0x7F60, 0x7F20, 0x7E90, 0x7EB0, 0x7EB0, 0x7F00, + 0x7EF0, 0x7EA0, 0x7F00, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, + 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F10, + 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7EF0, 0x7ED0, 0x7EE0, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F40, 0x7F10, + 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7520, 0x6750, 0x5980, 0x4A20, + 0x3CF0, 0x2FB0, 0x23A0, 0x1860, 0x0D50, 0x02F0, 0xF9E0, 0xF2D0, 0xECE0, 0xEA10, 0xEA10, 0xEC30, 0xF0A0, 0xF680, 0xFCC0, 0x02E0, + 0x0810, 0x0E20, 0x1370, 0x1990, 0x20A0, 0x2940, 0x3460, 0x4090, 0x4D30, 0x5970, 0x6460, 0x6D10, 0x7490, 0x7A60, 0x7EA0, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7CA0, 0x73D0, 0x6B80, 0x6330, 0x5B20, 0x5350, 0x4B60, 0x4450, + 0x3D50, 0x3650, 0x2F20, 0x2790, 0x1FB0, 0x17E0, 0x0FC0, 0x07A0, 0xFF90, 0xF830, 0xEFC0, 0xE710, 0xDE30, 0xD550, 0xCBB0, 0xC2A0, + 0xB890, 0xAED0, 0xA4D0, 0x9B00, 0x9130, 0x8A70, 0x8710, 0x85C0, 0x8540, 0x8500, 0x84F0, 0x84E0, 0x84D0, 0x84D0, 0x84D0, 0x84C0, + 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8530, 0x85B0, 0x86F0, 0x8A80, 0x94C0, 0x9F00, 0xA8F0, 0xB180, 0xB8A0, + 0xBF30, 0xC490, 0xCA10, 0xCF20, 0xD3F0, 0xD830, 0xDC30, 0xE060, 0xE340, 0xE5F0, 0xE700, 0xE5A0, 0xE240, 0xDAA0, 0xCFA0, 0xC1C0, + 0xB070, 0x9C90, 0x8B00, 0x85A0, 0x84F0, 0x84D0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, + 0x8500, 0x8540, 0x85F0, 0x8900, 0x96D0, 0xA910, 0xBA80, 0xCA10, 0xD5A0, 0xD980, 0xD4F0, 0xC820, 0xB3D0, 0x9B00, 0x8820, 0x8500, + 0x84C0, 0x8490, 0x8480, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8420, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, + 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83C0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83B0, 0x83F0, 0x83E0, 0x83E0, 0x83F0, + 0x83C0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8430, 0x8400, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, + 0x8410, 0x83E0, 0x83E0, 0x83D0, 0x83F0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, + 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8480, 0x8450, 0x8460, 0x8430, 0x8470, 0x8460, 0x8490, 0x84A0, 0x84C0, + 0x84E0, 0x8520, 0x8580, 0x86B0, 0x8950, 0x8DB0, 0x9260, 0x9740, 0xAE30, 0xB190, 0xB570, 0xBAD0, 0xC2C0, 0xCC80, 0xD6D0, 0xE0D0, + 0xE840, 0xEDD0, 0xF0A0, 0xF210, 0xF450, 0xF850, 0xFFD0, 0x0A30, 0x17A0, 0x2820, 0x38E0, 0x48F0, 0x55E0, 0x5EA0, 0x6480, 0x6730, + 0x6820, 0x6750, 0x66D0, 0x67B0, 0x69E0, 0x6E60, 0x74F0, 0x7C20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, + 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, 0x7EE0, 0x7F10, 0x7F30, 0x7F00, + 0x7F80, 0x7F10, 0x7F10, 0x7EE0, 0x7EE0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EF0, 0x7F30, + 0x7EE0, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F00, 0x7F10, 0x7E90, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7E90, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, + 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, + 0x7F50, 0x7EF0, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7F00, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, + 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F30, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7F20, 0x7F10, 0x7F00, 0x7F00, + 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7F20, + 0x7F80, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7F20, 0x7EE0, 0x7ED0, 0x7EB0, 0x7F30, + 0x7EF0, 0x7EB0, 0x7EC0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7ED0, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, + 0x7F00, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7EF0, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7F10, 0x7F70, + 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7E90, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7EC0, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F00, + 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F40, 0x7F00, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7C50, 0x7A30, 0x78F0, 0x7900, 0x7AA0, 0x7CD0, 0x7EB0, 0x7F10, 0x7F20, + 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F30, + 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F40, 0x7F30, 0x7F30, + 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7DB0, 0x7B60, 0x7880, 0x7480, 0x7030, 0x6BE0, 0x6720, 0x6250, + 0x5D80, 0x57E0, 0x5290, 0x4D90, 0x4920, 0x4480, 0x4010, 0x3AD0, 0x3570, 0x2FE0, 0x2A00, 0x24B0, 0x1FF0, 0x1C40, 0x1950, 0x1710, + 0x15C0, 0x1520, 0x14C0, 0x1400, 0x1380, 0x1210, 0x1010, 0x1030, 0x1160, 0x14E0, 0x1A40, 0x2190, 0x2AF0, 0x34E0, 0x3F60, 0x49C0, + 0x5490, 0x5F30, 0x6900, 0x7200, 0x79C0, 0x7E90, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7A70, 0x6E20, + 0x6280, 0x5830, 0x5170, 0x4CA0, 0x48B0, 0x4370, 0x3BD0, 0x2F40, 0x1FB0, 0x0C30, 0xF600, 0xDF40, 0xC700, 0xAFE0, 0x9900, 0x88F0, + 0x8520, 0x84D0, 0x84D0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83F0, 0x83F0, 0x8420, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x8350, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, + 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x8410, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, + 0x8460, 0x8460, 0x8470, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x84E0, 0x8530, 0x86D0, 0x9220, 0xA740, 0xBC00, + 0xD030, 0xE410, 0xF4A0, 0x0250, 0x0C60, 0x1180, 0x13C0, 0x1240, 0x0E30, 0x0870, 0x01E0, 0xFB90, 0xF4D0, 0xEF00, 0xEB70, 0xEB80, + 0xEEA0, 0xF460, 0xFD10, 0x0650, 0x0F30, 0x17C0, 0x1F50, 0x2630, 0x2DF0, 0x3720, 0x42B0, 0x4FD0, 0x5EB0, 0x6E60, 0x7C10, 0x7F00, + 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7F10, 0x7EF0, + 0x7F20, 0x7F00, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7F10, 0x7F20, 0x7F00, 0x7F70, 0x7EF0, 0x7F20, + 0x7F20, 0x7F00, 0x7F90, 0x7F20, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, + 0x7EF0, 0x7F00, 0x7ED0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F00, 0x7EB0, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7E90, + 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, + 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F50, 0x7F00, + 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, 0x7F20, + 0x7F00, 0x7EF0, 0x7ED0, 0x7F30, 0x7F10, 0x7EB0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F50, 0x7F10, 0x7E90, + 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, + 0x7EE0, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, + 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F80, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F90, 0x7F10, + 0x7F20, 0x7F10, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E90, + 0x7ED0, 0x7ED0, 0x7F10, 0x7F00, 0x7E90, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, + 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F00, 0x7550, 0x6A30, 0x5DF0, 0x5140, 0x4300, 0x35C0, 0x2880, 0x1AA0, 0x0CE0, + 0xFF10, 0xF1B0, 0xE390, 0xD540, 0xC680, 0xB900, 0xAB90, 0x9E60, 0x91D0, 0x8950, 0x8610, 0x8560, 0x84F0, 0x84D0, 0x84C0, 0x84B0, + 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, + 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x84F0, 0x84F0, 0x8500, 0x84F0, 0x8500, 0x8500, 0x84E0, 0x84D0, 0x84D0, 0x84D0, + 0x84E0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84B0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8440, 0x8460, 0x8450, 0x8450, + 0x8450, 0x8440, 0x8440, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8410, 0x8420, 0x8420, 0x8460, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x8490, + 0x84B0, 0x84C0, 0x84E0, 0x8530, 0x8680, 0x8FA0, 0xA270, 0xB450, 0xC540, 0xD480, 0xE140, 0xEC80, 0xF3C0, 0xF840, 0xF990, 0xF7B0, + 0xF350, 0xECE0, 0xE4B0, 0xDBB0, 0xD170, 0xC6D0, 0xBC80, 0xB2F0, 0xAAC0, 0xA380, 0x9C40, 0x9590, 0x8E80, 0x88D0, 0x85E0, 0x8500, + 0x84C0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8470, 0x8430, 0x8430, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, + 0x8480, 0x8490, 0x8490, 0x84B0, 0x84B0, 0x84D0, 0x84F0, 0x8540, 0x8600, 0x88C0, 0x9170, 0x9DF0, 0xA9F0, 0xB690, 0xC1E0, 0xCCB0, + 0xD770, 0xE130, 0xEB20, 0xF450, 0xFD10, 0x05C0, 0x0DE0, 0x15C0, 0x1DF0, 0x25F0, 0x2F20, 0x3780, 0x4050, 0x4960, 0x51E0, 0x5C10, + 0x6520, 0x6E80, 0x76D0, 0x7D70, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, + 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F50, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7F30, + 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F30, 0x7EC0, 0x7E90, 0x7F00, 0x7F00, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EF0, 0x7F20, 0x7EF0, + 0x7F80, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F70, 0x7EE0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EE0, 0x7EE0, 0x7F30, + 0x7F00, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F10, 0x7F00, 0x7E90, 0x7ED0, 0x7F10, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, + 0x7F60, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F70, + 0x7F00, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EA0, 0x7F00, 0x7EB0, 0x7EE0, 0x7EF0, + 0x7F30, 0x7EE0, 0x7EC0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F80, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F80, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7F20, + 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, + 0x7F10, 0x7F10, 0x7E90, 0x7EB0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, + 0x7EF0, 0x7EF0, 0x7DB0, 0x7A40, 0x7640, 0x72F0, 0x6F00, 0x6B20, 0x6690, 0x6200, 0x5DB0, 0x5940, 0x53B0, 0x4EA0, 0x48F0, 0x4490, + 0x3F30, 0x3A60, 0x3540, 0x3050, 0x2C70, 0x27C0, 0x23F0, 0x2110, 0x1D70, 0x1B00, 0x1890, 0x15F0, 0x14A0, 0x1360, 0x12E0, 0x12C0, + 0x12B0, 0x13A0, 0x1460, 0x15E0, 0x1710, 0x18F0, 0x1BC0, 0x1E40, 0x2170, 0x2470, 0x2720, 0x2B50, 0x2EB0, 0x32B0, 0x3670, 0x3A00, + 0x3E00, 0x4080, 0x42D0, 0x4550, 0x46E0, 0x49A0, 0x4B10, 0x4D70, 0x4F10, 0x50C0, 0x5250, 0x5370, 0x5430, 0x54E0, 0x5490, 0x54B0, + 0x54A0, 0x5460, 0x5420, 0x5380, 0x53D0, 0x53B0, 0x53A0, 0x5420, 0x53C0, 0x5450, 0x54A0, 0x54E0, 0x54D0, 0x5430, 0x5340, 0x5180, + 0x4E90, 0x4C90, 0x4A00, 0x47C0, 0x4570, 0x42F0, 0x4120, 0x3D90, 0x39D0, 0x34C0, 0x2E80, 0x2810, 0x1FB0, 0x1580, 0x0A80, 0xFE70, + 0xF1A0, 0xE2E0, 0xD3C0, 0xC370, 0xB270, 0xA170, 0x8F60, 0x8720, 0x8530, 0x84E0, 0x84C0, 0x84B0, 0x84B0, 0x8490, 0x84A0, 0x84B0, + 0x84B0, 0x84D0, 0x84F0, 0x8530, 0x85D0, 0x8790, 0x8B90, 0x92C0, 0x9A70, 0xA1B0, 0xA810, 0xAE50, 0xB470, 0xB960, 0xBCF0, 0xBE10, + 0xBC90, 0xB7B0, 0xB090, 0xA6F0, 0x9BF0, 0x9090, 0x8900, 0x85F0, 0x8510, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8450, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, + 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8510, 0x8530, 0x8560, 0x85B0, + 0x8620, 0x86D0, 0x87E0, 0x8940, 0x8B10, 0x8CE0, 0x8FB0, 0x9360, 0x9820, 0x9E20, 0xA5C0, 0xAEE0, 0xB8C0, 0xC450, 0xD140, 0xDF00, + 0xEFF0, 0xFFC0, 0x1050, 0x20B0, 0x3080, 0x3FA0, 0x4D90, 0x5AD0, 0x6630, 0x7100, 0x7A00, 0x7EB0, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, + 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7EF0, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x6050, 0x2690, 0xF290, 0xC6B0, 0xA370, 0x9090, 0x8AC0, 0x8C60, 0x9630, + 0xA670, 0xB800, 0xC930, 0xD780, 0xE2C0, 0xEA60, 0xEE50, 0xF130, 0xF4C0, 0xFAB0, 0x0310, 0x0EB0, 0x1B40, 0x27B0, 0x3060, 0x3580, + 0x3750, 0x3730, 0x3620, 0x3540, 0x3480, 0x33B0, 0x3380, 0x32E0, 0x3110, 0x2E10, 0x29E0, 0x25C0, 0x2110, 0x1D10, 0x1970, 0x1620, + 0x13D0, 0x1110, 0x0D70, 0x0A40, 0x06B0, 0x0250, 0xFE20, 0xFB00, 0xF7A0, 0xF4A0, 0xF140, 0xEE20, 0xEB50, 0xE7D0, 0xE4B0, 0xE240, + 0xE100, 0xE0B0, 0xE210, 0xE3A0, 0xE620, 0xE920, 0xEC20, 0xEFB0, 0xF230, 0xF470, 0xF6C0, 0xF840, 0xF960, 0xF9A0, 0xFA10, 0xF990, + 0xF830, 0xF670, 0xF350, 0xF0B0, 0xEDF0, 0xEC60, 0xEBF0, 0xEC80, 0xEEC0, 0xF2A0, 0xF6D0, 0xFB30, 0xFF00, 0x01C0, 0x02D0, 0x02A0, + 0x0140, 0xFF70, 0xFCF0, 0xFAF0, 0xF970, 0xF7D0, 0xF670, 0xF4E0, 0xF440, 0xF450, 0xF580, 0x0B90, 0x1820, 0x2810, 0x3A10, 0x4BA0, + 0x5BA0, 0x6800, 0x7050, 0x7520, 0x7780, 0x7910, 0x7B10, 0x7DA0, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, + 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F90, 0x7F30, 0x7EE0, 0x7F20, 0x7F10, 0x7F50, 0x7F20, 0x7EA0, 0x7F10, 0x7F10, 0x7F40, 0x7F00, + 0x7E90, 0x7E90, 0x7EE0, 0x7EF0, 0x7ED0, 0x7EA0, 0x7F00, 0x7F10, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7D40, 0x78B0, 0x71B0, 0x6970, 0x5E00, 0x51C0, 0x43D0, 0x34B0, 0x24B0, 0x1400, 0x02F0, + 0xF250, 0xE0A0, 0xCF60, 0xC000, 0xB2A0, 0xA7B0, 0xA100, 0x9EA0, 0xA130, 0xA970, 0xB700, 0xC950, 0xDD40, 0xF2A0, 0x06D0, 0x1970, + 0x2860, 0x34E0, 0x3DD0, 0x43E0, 0x4840, 0x4AA0, 0x4BD0, 0x4D20, 0x4DA0, 0x4F10, 0x5080, 0x5270, 0x5420, 0x5430, 0x5270, 0x4D00, + 0x4790, 0x43E0, 0x44C0, 0x4BC0, 0x53F0, 0x59F0, 0x5860, 0x4D40, 0x3950, 0x1EA0, 0x0100, 0xE270, 0xC550, 0xAA30, 0x9040, 0x8580, + 0x84D0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8430, 0x8410, 0x83F0, 0x83E0, 0x83C0, 0x83A0, + 0x8390, 0x8380, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8380, 0x8380, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, + 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x8400, 0x83D0, 0x83D0, 0x83E0, + 0x83A0, 0x83E0, 0x83E0, 0x83F0, 0x8380, 0x8400, 0x8400, 0x8410, 0x8420, 0x8410, 0x8410, 0x8430, 0x8440, 0x8410, 0x8420, 0x8420, + 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x83F0, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8450, 0x8470, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8430, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8460, 0x8440, 0x8440, 0x8440, 0x8460, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8480, 0x8450, 0x8460, 0x8460, 0x8440, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, + 0x84A0, 0x84B0, 0x84E0, 0x8530, 0x8690, 0x9090, 0xA450, 0xB7A0, 0xCB60, 0xDE10, 0xF040, 0x0300, 0x14D0, 0x2700, 0x3860, 0x4B40, + 0x5C80, 0x6E40, 0x7BD0, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F70, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F60, 0x7EE0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, + 0x7EE0, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F20, + 0x7F00, 0x7F10, 0x7EF0, 0x7F00, 0x7F20, 0x7EF0, 0x7F80, 0x7EE0, 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, + 0x7F70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F70, 0x7F00, 0x7ED0, 0x7EB0, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7EC0, 0x7EF0, + 0x7F20, 0x7EA0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7E90, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7E70, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, + 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F40, 0x7F10, 0x7F00, + 0x7F30, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7F70, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, + 0x7EC0, 0x7EB0, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7E90, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, + 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, + 0x7F70, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F90, 0x7F20, 0x6280, 0x3EC0, 0x16D0, 0xEC60, 0xC040, 0x90E0, 0x8500, 0x84B0, 0x8480, + 0x8470, 0x8460, 0x8480, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8450, 0x8440, 0x8440, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84D0, 0x84C0, + 0x84D0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, + 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84A0, + 0x84A0, 0x84A0, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84E0, 0x84F0, + 0x8500, 0x8510, 0x8530, 0x8560, 0x85A0, 0x8610, 0x86F0, 0x8840, 0x8A20, 0x8CC0, 0x8F90, 0x9270, 0x9540, 0x97A0, 0x9990, 0x9B10, + 0x9CD0, 0x9E40, 0x9F80, 0xA070, 0xA0D0, 0xA170, 0xA2F0, 0xA450, 0xA5E0, 0xA7E0, 0xA9C0, 0xABE0, 0xADE0, 0xB0B0, 0xB460, 0xB8D0, + 0xBD70, 0xC1F0, 0xC700, 0xCC80, 0xD1C0, 0xD760, 0xDD50, 0xE430, 0xEAA0, 0xF110, 0xF7A0, 0xFE00, 0x03F0, 0x0A30, 0x1150, 0x1820, + 0x1F10, 0x2530, 0x2AE0, 0x30C0, 0x3650, 0x3BB0, 0x4130, 0x4700, 0x4C50, 0x5240, 0x5740, 0x5B70, 0x6110, 0x65E0, 0x69D0, 0x6E50, + 0x7180, 0x7500, 0x77C0, 0x7970, 0x7B90, 0x7BE0, 0x7C80, 0x7CD0, 0x7C70, 0x7BF0, 0x7460, 0x7150, 0x6D90, 0x68B0, 0x6400, 0x5E10, + 0x5910, 0x5320, 0x4BF0, 0x4550, 0x3DB0, 0x3680, 0x2EE0, 0x2640, 0x1ED0, 0x16A0, 0x0F60, 0x0870, 0x0230, 0xFD70, 0xF8C0, 0xF580, + 0xF290, 0xF090, 0xF020, 0xEF80, 0xEFD0, 0xEF60, 0xEF20, 0xEED0, 0xEDF0, 0xEC60, 0xEA40, 0xE6F0, 0xE3B0, 0xDF30, 0xDA10, 0xD4C0, + 0xCE80, 0xC8F0, 0xC2E0, 0xBCD0, 0xB670, 0xAFD0, 0xA850, 0xA0D0, 0x9980, 0x9160, 0x8BA0, 0x8820, 0x8650, 0x8580, 0x8530, 0x8500, + 0x84E0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x8490, 0x8490, + 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8450, 0x8430, 0x8420, 0x8410, 0x8420, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8420, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, + 0x8420, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84A0, 0x84F0, 0x8580, 0x8910, 0x99C0, 0xAAC0, 0xB990, + 0xC570, 0xCF20, 0xD6A0, 0xDC10, 0xDFE0, 0xE2A0, 0xE560, 0xE790, 0xE870, 0xE8C0, 0xE770, 0xE450, 0xDF20, 0xD7B0, 0xCF10, 0xC4B0, + 0xB9C0, 0xAD00, 0x9EF0, 0x90B0, 0x87B0, 0x8530, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, + 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x84F0, 0x8550, 0x86A0, + 0x8BF0, 0x97D0, 0xA370, 0xAE50, 0xB880, 0xC250, 0xCAC0, 0xD1F0, 0xD700, 0xDAF0, 0xDE40, 0xE120, 0xE490, 0xE910, 0xECC0, 0xF290, + 0xF770, 0xFD20, 0x02E0, 0x0830, 0x0E00, 0x1320, 0x1960, 0x1FD0, 0x2770, 0x2F40, 0x3710, 0x3FF0, 0x47E0, 0x4F70, 0x5800, 0x5E80, + 0x6560, 0x6C60, 0x71F0, 0x7790, 0x7C10, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7F20, + 0x7EC0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EB0, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7E90, + 0x7EA0, 0x7E80, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, + 0x7F20, 0x7EF0, 0x7EF0, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F50, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, + 0x7EC0, 0x7EF0, 0x7F00, 0x7F50, 0x7EB0, 0x7EA0, 0x7EF0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, + 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7E70, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F40, + 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7F80, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F00, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, + 0x7EE0, 0x7ED0, 0x7F00, 0x7F20, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F40, + 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F60, 0x7EA0, 0x79D0, 0x7490, 0x6E30, 0x6760, 0x5FC0, 0x5790, 0x4ED0, 0x4610, 0x3C60, 0x31F0, + 0x2610, 0x1930, 0x0B30, 0xFC20, 0xEC70, 0xDA80, 0xCAD0, 0xBAB0, 0xAB70, 0x9D40, 0x91A0, 0x8A90, 0x8780, 0x8660, 0x85D0, 0x8580, + 0x8530, 0x84F0, 0x84D0, 0x84C0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x8500, 0x8530, 0x8570, + 0x85C0, 0x8700, 0x88E0, 0x8C50, 0x9210, 0x97E0, 0x9E00, 0xA460, 0xAA90, 0xB0E0, 0xB790, 0xBDC0, 0xC330, 0xC950, 0xCED0, 0xD4B0, + 0xDA60, 0xE140, 0xE7F0, 0xEF30, 0xF740, 0xFF40, 0x0820, 0x1170, 0x1AE0, 0x2530, 0x2EE0, 0x38D0, 0x4290, 0x4CC0, 0x56F0, 0x61B0, + 0x6B70, 0x7590, 0x7D90, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, + 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F40, 0x7F30, 0x73B0, 0x6620, 0x5840, 0x49B0, 0x3B50, 0x2D20, 0x1FA0, 0x10F0, 0x03A0, 0xF640, 0xE880, 0xDB20, 0xCD40, 0xBFE0, + 0xB2F0, 0xA6C0, 0x9A50, 0x8F40, 0x88B0, 0x8600, 0x8530, 0x84E0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x84A0, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8450, 0x8450, 0x8440, 0x8450, 0x8440, 0x8480, 0x8450, + 0x8460, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8410, + 0x8400, 0x83F0, 0x83E0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, + 0x83C0, 0x83C0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8450, 0x8460, 0x8480, 0x8480, + 0x8490, 0x84C0, 0x84E0, 0x8520, 0x8580, 0x85B0, 0x85F0, 0x85B0, 0x85A0, 0x8590, 0x8540, 0x85C0, 0x85F0, 0x8660, 0x86F0, 0x87B0, + 0x8840, 0x88D0, 0x8930, 0x8970, 0x89D0, 0x89F0, 0x8970, 0x88E0, 0x87B0, 0x8510, 0x84F0, 0x84F0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, + 0x8490, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8470, 0x8450, 0x8400, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8490, 0x84B0, 0x8520, 0x8A30, 0xA9D0, 0xC2F0, 0xD340, 0xDF30, + 0xE870, 0xF160, 0xFA70, 0x05A0, 0x1160, 0x1D50, 0x2B30, 0x36A0, 0x4270, 0x4DD0, 0x5930, 0x6580, 0x7180, 0x7CD0, 0x7F10, 0x7F40, + 0x7F10, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, + 0x7F20, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7EE0, 0x7F10, 0x7F60, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, + 0x7F60, 0x7F10, 0x7E90, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EE0, 0x7F00, + 0x7EF0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EE0, 0x7F10, + 0x7F10, 0x7F10, 0x7E90, 0x7EC0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7D30, 0x65E0, 0x4F80, 0x37D0, 0x2010, 0x0830, + 0xF240, 0xDE10, 0xCBB0, 0xBBB0, 0xAC50, 0xA140, 0x99E0, 0x9730, 0x9A90, 0xA470, 0xB530, 0xCA70, 0xE2D0, 0xFDE0, 0x1640, 0x2C20, + 0x4090, 0x53B0, 0x6520, 0x7480, 0x7E90, 0x7F00, 0x7F90, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, + 0x7F10, 0x7EB0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7E00, 0x6F10, 0x61E0, 0x5570, + 0x4B90, 0x4340, 0x3E40, 0x39C0, 0x3620, 0x32A0, 0x2E20, 0x2950, 0x2590, 0x2370, 0x2540, 0x29B0, 0x2FF0, 0x36A0, 0x3960, 0x37B0, + 0x2F10, 0x1F60, 0x09F0, 0xED30, 0xD020, 0xB130, 0x9380, 0x8610, 0x84E0, 0x84B0, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8480, 0x8480, + 0x8480, 0x8490, 0x84B0, 0x84D0, 0x8570, 0x8EE0, 0xADF0, 0xC8C0, 0xDF00, 0xF0B0, 0xFD20, 0x05E0, 0x0A90, 0x0CB0, 0x0CC0, 0x0B30, + 0x0970, 0x0760, 0x0600, 0x0610, 0x0870, 0x0C70, 0x11E0, 0x1990, 0x2240, 0x2BE0, 0x3790, 0x4430, 0x5320, 0x62A0, 0x72C0, 0x7EB0, + 0x7EF0, 0x7F60, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EB0, 0x7F00, 0x7EF0, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, + 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F20, 0x7EE0, 0x7F50, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7F00, 0x7F70, 0x7F00, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7EE0, + 0x7F30, 0x7F00, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7F00, 0x7EB0, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F00, 0x7EE0, + 0x7EF0, 0x7F80, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, + 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7EA0, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7F40, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7EF0, 0x7F10, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7740, 0x6BF0, 0x5FB0, 0x5230, 0x4440, + 0x34F0, 0x2550, 0x14B0, 0x0300, 0xEF80, 0xDCB0, 0xC960, 0xB520, 0xA090, 0x8CF0, 0x85D0, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8470, + 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, + 0x8420, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8420, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x85A0, 0x8C00, 0xA450, 0xBB10, 0xD010, 0xE380, 0xF770, 0x0910, + 0x1A30, 0x2B10, 0x3B90, 0x4B30, 0x59E0, 0x6840, 0x7510, 0x7E70, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F50, 0x7F30, + 0x7F80, 0x7F30, 0x7F00, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F00, 0x7EF0, 0x7ED0, 0x7F10, 0x7F40, + 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F50, 0x7EE0, 0x7EA0, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7E90, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x75F0, 0x6A80, 0x5D90, + 0x5050, 0x42F0, 0x3540, 0x2850, 0x1C10, 0x10B0, 0x0700, 0x0010, 0xFB80, 0xF900, 0xF8D0, 0xFB50, 0xFF30, 0x06A0, 0x0F20, 0x1A90, + 0x2730, 0x3460, 0x4360, 0x52F0, 0x6270, 0x7220, 0x7D90, 0x7ED0, 0x7F00, 0x7F30, 0x7F10, 0x7EB0, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, + 0x7EC0, 0x7ED0, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, + 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F80, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, + 0x7EE0, 0x7ED0, 0x7F00, 0x7F00, 0x7F50, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EB0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F10, 0x7ED0, + 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F10, + 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, + 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7ED0, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7F60, 0x7ED0, + 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, + 0x7F10, 0x7EF0, 0x7F00, 0x7F10, 0x7F00, 0x7F60, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, + 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7FA0, 0x7EF0, 0x7B50, 0x7570, 0x6F60, 0x6850, 0x60B0, 0x5830, 0x4F10, 0x45C0, + 0x3B70, 0x3130, 0x2610, 0x1B00, 0x0FA0, 0x0450, 0xF990, 0xEE10, 0xE450, 0xDAC0, 0xD0F0, 0xC7F0, 0xBE30, 0xB5A0, 0xAD30, 0xA5C0, + 0x9EF0, 0x98C0, 0x93E0, 0x9060, 0x8DF0, 0x8CC0, 0x8C30, 0x8D10, 0x8F60, 0x9320, 0x9890, 0x9F00, 0xA690, 0xAF70, 0xB910, 0xC370, + 0xCDD0, 0xD860, 0xE3C0, 0xEE10, 0xF8C0, 0x02C0, 0x0CF0, 0x16F0, 0x2070, 0x2A60, 0x32F0, 0x3BB0, 0x4340, 0x49F0, 0x50F0, 0x56B0, + 0x5BF0, 0x60F0, 0x6590, 0x69B0, 0x6D90, 0x7050, 0x7260, 0x73E0, 0x7550, 0x75D0, 0x75B0, 0x75A0, 0x7500, 0x7440, 0x72F0, 0x7130, + 0x6FE0, 0x6DC0, 0x6BD0, 0x6980, 0x65A0, 0x6300, 0x5E80, 0x5B00, 0x5720, 0x5300, 0x4F90, 0x4B00, 0x46A0, 0x4180, 0x3B30, 0x3500, + 0x2E40, 0x2750, 0x2000, 0x1720, 0x0F40, 0x05F0, 0xFC10, 0xF1A0, 0xE520, 0xD9D0, 0xCDD0, 0xC1C0, 0xB5A0, 0xA910, 0x9C90, 0x9090, + 0x88D0, 0x85D0, 0x8510, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8470, + 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, + 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, + 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8420, 0x8430, 0x8420, 0x8430, + 0x8430, 0x8440, 0x83E0, 0x8440, 0x8450, 0x8440, 0x8450, 0x8460, 0x8450, 0x8450, 0x8410, 0x8460, 0x8460, 0x8450, 0x8460, 0x8460, + 0x8460, 0x83F0, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8410, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8460, 0x8480, 0x8480, 0x8490, 0x8490, 0x84C0, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x84A0, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8490, 0x8460, + 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x8500, 0x85E0, 0x8C10, 0xA140, 0xB4F0, 0xC8F0, + 0xDA20, 0xE8F0, 0xF720, 0x0320, 0x0EE0, 0x1990, 0x2360, 0x2BE0, 0x3440, 0x3AD0, 0x4100, 0x4720, 0x4BD0, 0x5050, 0x5480, 0x5820, + 0x5B70, 0x5E70, 0x6120, 0x6340, 0x6510, 0x6630, 0x66B0, 0x66A0, 0x64D0, 0x6210, 0x5E60, 0x5A00, 0x54D0, 0x4F70, 0x4960, 0x4340, + 0x3CB0, 0x35D0, 0x2E60, 0x2690, 0x1F00, 0x1820, 0x1110, 0x0930, 0x0110, 0xF7C0, 0xECD0, 0xDFF0, 0xCFA0, 0xBEE0, 0xAE00, 0x9C30, + 0x8D30, 0x8690, 0x8530, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8460, 0x8480, 0x8480, + 0x8480, 0x8490, 0x8490, 0x84B0, 0x84C0, 0x84E0, 0x8530, 0x8650, 0x8BF0, 0x9E90, 0xAF70, 0xC050, 0xD030, 0xDFB0, 0xEEF0, 0xFE40, + 0x0D50, 0x1D00, 0x2D40, 0x3C10, 0x4B00, 0x5880, 0x65C0, 0x7150, 0x7AB0, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7E70, 0x7EE0, 0x7EF0, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7ED0, 0x7F00, 0x7EB0, 0x7E60, 0x7EC0, + 0x7ED0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, + 0x7F20, 0x7F00, 0x7F00, 0x7F50, 0x7F10, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7F40, 0x7ED0, 0x7E90, + 0x7F10, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7F10, 0x7F20, 0x7F40, 0x7EC0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7F10, + 0x7F20, 0x7F10, 0x7F10, 0x77F0, 0x6E60, 0x63C0, 0x5B50, 0x53B0, 0x4DA0, 0x49C0, 0x4750, 0x4780, 0x4970, 0x4D70, 0x5340, 0x5940, + 0x6090, 0x68F0, 0x7130, 0x7940, 0x7E00, 0x7ED0, 0x7F00, 0x7EF0, 0x7F10, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, + 0x7F10, 0x7F00, 0x7F00, 0x70C0, 0x5750, 0x3DA0, 0x2040, 0xFCD0, 0xD0B0, 0x95B0, 0x84D0, 0x84A0, 0x8470, 0x8450, 0x8470, 0x8440, + 0x8440, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x83F0, 0x8400, 0x83E0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x8390, + 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x83B0, 0x83C0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83C0, 0x83B0, 0x83B0, + 0x83E0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83E0, 0x83C0, 0x83C0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8450, 0x8460, 0x8490, 0x8490, 0x84A0, 0x84D0, 0x85B0, 0x8B50, 0xA8F0, 0xC4E0, + 0xE1D0, 0xFB60, 0x12C0, 0x2990, 0x3E00, 0x51C0, 0x63E0, 0x73C0, 0x7E70, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, + 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, + 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F80, 0x7F20, 0x7F10, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EF0, + 0x7ED0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7E90, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7EB0, + 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7DE0, 0x73D0, 0x6830, 0x5890, 0x48B0, 0x36E0, 0x2320, 0x0EB0, 0xF800, 0xE020, 0xC6B0, + 0xAB70, 0x8F30, 0x85B0, 0x8500, 0x84A0, 0x8480, 0x84A0, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8450, 0x8420, 0x8410, + 0x8410, 0x8450, 0x8410, 0x8410, 0x8410, 0x8430, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8430, 0x8460, + 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8460, 0x8450, 0x8450, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, + 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84F0, 0x85A0, 0x8E80, 0xA990, 0xC530, + 0xE260, 0x0100, 0x1FB0, 0x3DB0, 0x5C40, 0x73B0, 0x7EF0, 0x7EE0, 0x7F50, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7F10, + 0x7F10, 0x7EF0, 0x7F60, 0x7EE0, 0x7EB0, 0x7F10, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7E90, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F10, 0x7F00, 0x7F30, 0x7F00, + 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EF0, + 0x7EB0, 0x7EE0, 0x7F50, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EC0, 0x7F50, 0x7F10, 0x7E70, 0x7EC0, + 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, + 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7150, 0x5A60, 0x4260, + 0x2B10, 0x13D0, 0xFAD0, 0xE4D0, 0xCF30, 0xBB00, 0xA880, 0x97E0, 0x8C50, 0x8770, 0x8600, 0x85A0, 0x85C0, 0x85E0, 0x86B0, 0x88E0, + 0x8E30, 0x96E0, 0x9E70, 0xA3E0, 0xA710, 0xA6A0, 0xA450, 0x9ED0, 0x9760, 0x8F10, 0x88F0, 0x8600, 0x8520, 0x84D0, 0x84B0, 0x84A0, + 0x8480, 0x8470, 0x8470, 0x8460, 0x8450, 0x8420, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, + 0x8400, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, + 0x83A0, 0x83A0, 0x83C0, 0x83B0, 0x83A0, 0x83B0, 0x83D0, 0x83C0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x8410, 0x83F0, 0x83F0, + 0x83F0, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8470, 0x8480, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, + 0x84B0, 0x84C0, 0x84E0, 0x8570, 0x8A10, 0xA5E0, 0xC170, 0xDB00, 0xF170, 0x0370, 0x1080, 0x1980, 0x1FB0, 0x22A0, 0x22E0, 0x2190, + 0x1CC0, 0x1590, 0x0A50, 0xFD60, 0xEED0, 0xDE80, 0xCD10, 0xBAE0, 0xA7F0, 0x9550, 0x8890, 0x8540, 0x84E0, 0x84B0, 0x84A0, 0x8480, + 0x8470, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8420, 0x8430, + 0x8410, 0x8450, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x8500, 0x8610, 0x93D0, 0xB140, 0xCDE0, 0xE9B0, 0x0350, 0x1B80, 0x3270, + 0x4890, 0x5ED0, 0x7160, 0x7ED0, 0x7F10, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7F70, 0x7EF0, 0x7ED0, 0x7F00, 0x7F10, 0x7F30, + 0x7EB0, 0x7E70, 0x7EF0, 0x7EE0, 0x7F30, 0x7ED0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7EC0, 0x7EF0, 0x7F10, + 0x7F50, 0x7ED0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7EF0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F20, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F20, + 0x7F10, 0x7F90, 0x7EF0, 0x7EE0, 0x7F10, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EE0, 0x7F00, 0x7EF0, + 0x7F30, 0x7F10, 0x7E70, 0x7EC0, 0x7EF0, 0x7F20, 0x7EF0, 0x7E90, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, + 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F10, 0x7F00, 0x7300, 0x5A00, 0x4780, 0x3820, 0x29E0, 0x1DD0, + 0x1690, 0x1740, 0x22A0, 0x37D0, 0x5670, 0x75B0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F20, 0x7EF0, 0x7F90, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F30, 0x7EC0, 0x7EC0, 0x5410, 0x1730, 0xD8B0, 0xA040, 0x8600, 0x84E0, 0x84D0, 0x84E0, 0x8510, 0x8610, 0x8A80, 0x9360, 0x9740, + 0x96F0, 0x9440, 0x92C0, 0x93C0, 0x96A0, 0x9CD0, 0xADB0, 0xAEA0, 0xAEB0, 0xAD30, 0xAD30, 0xAD60, 0xADB0, 0xAEC0, 0xAF90, 0xB0C0, + 0xB110, 0xB150, 0xB1A0, 0xB170, 0xB160, 0xB150, 0xB200, 0xB2C0, 0xB370, 0xB470, 0xB4C0, 0xB510, 0xB450, 0xB340, 0xB120, 0xAE00, + 0xAA20, 0xA5D0, 0xA030, 0x9A80, 0x94B0, 0x8E10, 0x8930, 0x8680, 0x8560, 0x8500, 0x84D0, 0x8450, 0x84A0, 0x8490, 0x8480, 0x8430, + 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83E0, 0x83D0, 0x83D0, 0x83F0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x8400, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84B0, + 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8530, 0x8570, 0x85E0, 0x8660, 0x8690, 0x8630, 0x8590, 0x8520, 0x84E0, + 0x84C0, 0x84B0, 0x8490, 0x8480, 0x8430, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8470, 0x8450, 0x8440, 0x8440, + 0x83F0, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8470, 0x8490, 0x84D0, 0x92F0, 0xDA30, 0x1BC0, 0x5750, 0x7ED0, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x75C0, 0x66F0, 0x5830, 0x4960, 0x3B40, 0x2E10, 0x2180, 0x1720, + 0x0EC0, 0x07F0, 0x0360, 0xFF20, 0xFC60, 0xF9C0, 0xF690, 0xF300, 0xEFB0, 0xEBD0, 0xE810, 0xE460, 0xE090, 0xDD90, 0xDAF0, 0xD970, + 0xD7B0, 0xD690, 0xD4B0, 0xD210, 0xCE40, 0xC960, 0xC390, 0xBD10, 0xB7D0, 0xB290, 0xB020, 0xAE70, 0xAF60, 0xB1F0, 0xB5A0, 0xBA40, + 0xBF50, 0xC4F0, 0xCAD0, 0xCF70, 0xD360, 0xD5F0, 0xD6A0, 0xD490, 0xCFF0, 0xC8B0, 0xBE40, 0xAF30, 0x9D00, 0x8A60, 0x8530, 0x84C0, + 0x8490, 0x8470, 0x8460, 0x8440, 0x8430, 0x8420, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, + 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8440, 0x8450, 0x8480, 0x8460, 0x8460, 0x8470, 0x8430, 0x8490, 0x84A0, 0x84B0, 0x84F0, 0x85E0, 0x90C0, 0xADB0, 0xCA10, 0xE730, + 0x0340, 0x1E60, 0x3A30, 0x5640, 0x6D50, 0x7E30, 0x7F00, 0x7EF0, 0x7EF0, 0x7F50, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7F20, + 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7ED0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F30, 0x7EF0, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, + 0x7F10, 0x7F20, 0x7F20, 0x7ED0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F80, 0x7F10, + 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F70, 0x7F20, 0x7ED0, 0x7030, 0x6020, 0x4F40, 0x3F30, 0x2E30, + 0x1EA0, 0x0ED0, 0xFED0, 0xF080, 0xE220, 0xD980, 0xD610, 0xD820, 0xE2C0, 0xF350, 0x09B0, 0x22E0, 0x3D50, 0x5910, 0x6F70, 0x7E80, + 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EA0, + 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F20, 0x7F00, 0x7F50, + 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7EB0, + 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x72B0, 0x6420, 0x56C0, 0x4BF0, 0x4190, 0x3700, 0x2DD0, 0x24C0, + 0x1C70, 0x1500, 0x0F10, 0x0B90, 0x0A10, 0x0B40, 0x1040, 0x18D0, 0x2610, 0x3560, 0x4690, 0x5660, 0x63C0, 0x6F80, 0x77D0, 0x7DF0, + 0x7EE0, 0x7EE0, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EE0, 0x7F00, 0x7EE0, 0x7F30, 0x7F10, 0x7E70, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, + 0x7EB0, 0x7EE0, 0x7F20, 0x7F10, 0x7F10, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7E90, + 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7ED0, 0x7940, 0x71C0, 0x67F0, 0x5C20, 0x4EE0, 0x4090, 0x3230, 0x2270, 0x12E0, + 0x0250, 0xF2E0, 0xE470, 0xD5D0, 0xC6F0, 0xB700, 0xA660, 0x95F0, 0x8970, 0x8570, 0x84F0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8480, + 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83F0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, + 0x83B0, 0x83B0, 0x8390, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83B0, 0x83A0, 0x83A0, 0x8380, + 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, + 0x83A0, 0x83D0, 0x83E0, 0x83B0, 0x83C0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, + 0x83D0, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8480, 0x84A0, 0x84E0, 0x88F0, 0xBCD0, 0xE9A0, 0x1150, + 0x30A0, 0x48A0, 0x5980, 0x63F0, 0x6C20, 0x7140, 0x7610, 0x7930, 0x7B70, 0x7CC0, 0x7C30, 0x7B10, 0x78C0, 0x7590, 0x72F0, 0x70A0, + 0x7080, 0x7200, 0x7400, 0x7820, 0x7C00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7F50, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, + 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, + 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F30, 0x7F50, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F30, + 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F30, 0x7EF0, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F50, 0x7F10, 0x7EB0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F30, 0x7E70, 0x7ED0, 0x7EF0, + 0x7EF0, 0x7F00, 0x7E80, 0x7EC0, 0x7EB0, 0x7F10, 0x7EF0, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F20, 0x7F20, + 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7F10, 0x7F00, 0x7F00, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, + 0x7EF0, 0x7F60, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F40, 0x7ED0, 0x7E90, 0x7EF0, 0x7F00, 0x7F30, 0x7EB0, 0x7E70, 0x7F20, 0x7EF0, + 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7EC0, 0x7F40, 0x7F10, 0x7520, + 0x5EC0, 0x4840, 0x3310, 0x1F30, 0x0CB0, 0xF9F0, 0xE910, 0xD8C0, 0xC950, 0xB900, 0xA970, 0x9960, 0x8B80, 0x8630, 0x8500, 0x84D0, + 0x84B0, 0x84C0, 0x8480, 0x8480, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x83F0, 0x8400, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, + 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8380, 0x8380, 0x8370, 0x8370, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, + 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8380, 0x8370, 0x8380, 0x8380, 0x8380, + 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8470, 0x8480, 0x8490, 0x84C0, 0x84E0, 0x85B0, 0x8BA0, 0xA340, 0xBA50, 0xD210, 0xE9E0, 0x0220, 0x1A90, + 0x3250, 0x4C20, 0x6310, 0x7790, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F60, 0x7F20, 0x7E90, 0x7EB0, 0x7EB0, + 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F20, 0x7EC0, 0x7ED0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EC0, 0x7F10, + 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7F30, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F80, 0x7EF0, 0x7EB0, + 0x7EF0, 0x7EF0, 0x7F50, 0x7EF0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7EF0, 0x7E90, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7F60, 0x7F00, + 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, + 0x7EB0, 0x7EE0, 0x7F50, 0x7F00, 0x7E70, 0x7ED0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F00, 0x7F10, 0x7E90, 0x7EE0, + 0x7F00, 0x7ED0, 0x7F10, 0x7F00, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, 0x7F70, 0x7ED0, 0x7F00, + 0x7F00, 0x7F10, 0x7F50, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EF0, 0x7EA0, 0x7EE0, + 0x7EF0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, + 0x7F00, 0x7ED0, 0x7F30, 0x7F00, 0x7E70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x6DE0, 0x4EC0, 0x2E30, 0x0E30, 0xEAF0, 0xCAD0, + 0xABD0, 0x8ED0, 0x8590, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8420, 0x8400, 0x83F0, 0x83F0, + 0x8430, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8520, 0x8730, + 0x98F0, 0xB1D0, 0xC970, 0xE120, 0x29D0, 0x38A0, 0x4830, 0x5310, 0x5C20, 0x6450, 0x6A90, 0x7030, 0x7460, 0x7820, 0x7A90, 0x7C90, + 0x7DE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F40, 0x7F30, 0x7F30, 0x7F30, + 0x7F40, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F20, 0x6410, + 0x3FF0, 0x1AD0, 0xF5C0, 0xD150, 0xAD90, 0x8D60, 0x8520, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, + 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83D0, + 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8420, 0x8400, 0x8400, 0x8410, 0x8420, + 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x8500, 0x8600, 0xA2A0, 0xCC70, 0xF550, 0x1DD0, 0x49D0, 0x6E70, 0x7F40, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, + 0x7F40, 0x7F20, 0x7F00, 0x7F00, 0x7ED0, 0x7F10, 0x7EE0, 0x7ED0, 0x7ED0, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F10, + 0x7F10, 0x7E70, 0x7EE0, 0x7EB0, 0x7EF0, 0x7F20, 0x7E90, 0x7EF0, 0x7F00, 0x7F20, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7EF0, + 0x7EA0, 0x7EE0, 0x7F10, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, + 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, + 0x7F00, 0x7ED0, 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, + 0x7EC0, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, + 0x7F80, 0x7EF0, 0x7F10, 0x7EF0, 0x7B60, 0x73D0, 0x6D30, 0x65F0, 0x5FA0, 0x58F0, 0x53B0, 0x4FA0, 0x4D40, 0x4E10, 0x5030, 0x54A0, + 0x5AF0, 0x61B0, 0x68E0, 0x7000, 0x75D0, 0x7B90, 0x7E60, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, + 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7ED0, 0x7F10, + 0x7F60, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7C70, 0x71F0, + 0x6810, 0x5C90, 0x5100, 0x42C0, 0x3490, 0x2570, 0x1570, 0x0580, 0xF550, 0xE410, 0xD320, 0xC190, 0xAE30, 0x9BF0, 0x8C40, 0x8640, + 0x8510, 0x84D0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8450, 0x8440, + 0x8440, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8470, 0x8460, 0x8450, 0x8450, 0x8470, 0x8440, 0x8440, + 0x8440, 0x8410, 0x8430, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8430, 0x8440, 0x8430, + 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84C0, 0x8530, 0x89B0, 0xA7C0, + 0xC710, 0xE030, 0xF720, 0x0B40, 0x1C50, 0x2C60, 0x3A60, 0x4770, 0x5390, 0x5F50, 0x68A0, 0x7120, 0x7740, 0x7B90, 0x7DB0, 0x7EA0, + 0x7EE0, 0x7F50, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F80, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, + 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7EE0, 0x77D0, 0x6B50, 0x5C70, 0x4B40, 0x37D0, 0x2200, 0x0B30, 0xF200, 0xD590, 0xBA20, 0x9DB0, + 0x8900, 0x8510, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, + 0x8410, 0x8440, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x83D0, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8460, 0x8470, 0x8490, 0x84C0, 0x8540, 0x8AF0, 0xA910, 0xC0D0, 0xD480, 0xE470, 0xF2A0, 0xFE10, 0x09C0, 0x11C0, + 0x16B0, 0x19B0, 0x18E0, 0x1660, 0x10C0, 0x09B0, 0x0140, 0xF850, 0xF090, 0xE900, 0xE140, 0xDA70, 0xD1A0, 0xC770, 0xBBA0, 0xAD50, + 0x9D50, 0x8EB0, 0x8710, 0x8530, 0x84E0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8410, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, + 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8510, 0x8510, 0x8500, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, + 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x8460, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84F0, 0x8510, 0x8570, 0x8610, 0x8720, 0x87E0, 0x87C0, 0x86A0, + 0x8580, 0x84F0, 0x84C0, 0x8490, 0x8480, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, + 0x8410, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8440, 0x8430, 0x8430, 0x8440, 0x8450, 0x8470, 0x8490, + 0x84E0, 0x8680, 0x98E0, 0xAA00, 0xB670, 0xC210, 0xD0A0, 0xE450, 0xF900, 0x0C50, 0x1B90, 0x24C0, 0x2760, 0x2410, 0x1CC0, 0x1350, + 0x0880, 0xFF00, 0xF630, 0xD4E0, 0xCBB0, 0xC400, 0xBEC0, 0xBC80, 0xBDE0, 0xC340, 0xCAC0, 0xD530, 0xE0E0, 0xEE30, 0xFC10, 0x09E0, + 0x18C0, 0x26D0, 0x3640, 0x4570, 0x5510, 0x6480, 0x7340, 0x7E40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F30, 0x7F10, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7D20, 0x69E0, 0x5950, 0x4A80, 0x3F00, 0x3740, 0x3150, 0x2DE0, 0x2BD0, + 0x2AB0, 0x29F0, 0x2940, 0x2870, 0x26F0, 0x2430, 0x1FD0, 0x1920, 0x0E90, 0x0330, 0xF5A0, 0xE710, 0xD7D0, 0xC8D0, 0xBA00, 0xABF0, + 0x9E30, 0x9100, 0x88D0, 0x85C0, 0x8500, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, + 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8440, 0x8460, 0x8470, + 0x8480, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x84F0, 0x8560, 0x8690, 0x8A40, 0x9160, 0x97A0, 0x9CC0, 0xA160, 0xA5A0, 0xAAA0, + 0xB1A0, 0xB8E0, 0xBFF0, 0xC730, 0xCE00, 0xD3C0, 0xD900, 0xDD90, 0xE120, 0xE540, 0xE830, 0xEAC0, 0xED20, 0xEDD0, 0xEE30, 0xEDB0, + 0xED20, 0xEC90, 0xEC00, 0xEC80, 0xECD0, 0xEFB0, 0xF300, 0xF6A0, 0xFB50, 0x0030, 0x05E0, 0x0BF0, 0x1130, 0x1760, 0x1D20, 0x22B0, + 0x27F0, 0x2C80, 0x3140, 0x3390, 0x3520, 0x3540, 0x3350, 0x3110, 0x2D30, 0x2940, 0x23B0, 0x1F60, 0x1B20, 0x1640, 0x1310, 0x1100, + 0x0F80, 0x10D0, 0x1370, 0x18A0, 0x1F60, 0x27D0, 0x32A0, 0x3C20, 0x44F0, 0x4C10, 0x5160, 0x5500, 0x5650, 0x55B0, 0x5400, 0x5010, + 0x4C10, 0x48A0, 0x4660, 0x47C0, 0x4BA0, 0x5380, 0x5CC0, 0x6550, 0x6CA0, 0x7040, 0x7290, 0x7510, 0x7A60, 0x7F00, 0x7ED0, 0x7F30, + 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7F20, + 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7EF0, 0x7EF0, 0x7EE0, 0x7ED0, 0x7F50, 0x7F10, 0x7EA0, 0x7ED0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, + 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7EA0, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, + 0x7F20, 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x5FB0, + 0x3A00, 0x10C0, 0xE0F0, 0xB2F0, 0x8950, 0x84C0, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8460, 0x8460, + 0x8460, 0x8470, 0x84A0, 0x8490, 0x84B0, 0x84D0, 0x84E0, 0x84E0, 0x84D0, 0x84D0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8490, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8490, 0x8460, 0x8470, 0x8480, 0x8440, 0x84C0, 0x8510, 0x8720, 0x9A00, + 0xAE70, 0xBFB0, 0xCCD0, 0xD5C0, 0xDAD0, 0xDC70, 0xDAE0, 0xD620, 0xCF40, 0xC860, 0xC130, 0xBAB0, 0xB580, 0xB200, 0xB080, 0xB080, + 0xB310, 0xB6B0, 0xBC10, 0xC170, 0xC8B0, 0xD080, 0xD8A0, 0xE1A0, 0xEB40, 0xF550, 0x01B0, 0x0D00, 0x18F0, 0x2470, 0x2FE0, 0x3C70, + 0x4850, 0x5580, 0x6280, 0x7150, 0x7D90, 0x7EA0, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F40, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, + 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F50, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F60, + 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, + 0x7E90, 0x7EA0, 0x7EE0, 0x7F10, 0x7F20, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, + 0x7F60, 0x7F20, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, + 0x7ED0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F70, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F10, 0x7F00, 0x7F30, 0x7EB0, + 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, 0x7EC0, + 0x7F40, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F90, 0x7F00, 0x7F20, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F70, + 0x7F10, 0x7F20, 0x7F10, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F30, 0x7F10, 0x7EB0, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, + 0x7E70, 0x7EC0, 0x7ED0, 0x7F00, 0x7F00, 0x7B90, 0x7230, 0x6720, 0x5AA0, 0x4D80, 0x3F10, 0x30A0, 0x1FD0, 0x1070, 0x0170, 0xF2C0, + 0xE3D0, 0xD520, 0xC640, 0xB7C0, 0xA8D0, 0x99D0, 0x8DE0, 0x87B0, 0x85D0, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84D0, 0x84C0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84F0, 0x84F0, 0x8520, 0x8590, 0x8700, 0x8BF0, + 0x9750, 0xA330, 0xAF20, 0xBC00, 0xC800, 0xD490, 0xE140, 0xEF50, 0xFCF0, 0x09F0, 0x1760, 0x24E0, 0x3290, 0x40A0, 0x4E60, 0x5C40, + 0x6A30, 0x75E0, 0x7E40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F70, 0x7F10, 0x7EF0, + 0x7F20, 0x7F40, 0x7F50, 0x7F30, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7E60, 0x7EB0, 0x7F20, 0x7F20, 0x7EF0, 0x7E90, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7EC0, 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F20, 0x7EF0, + 0x7F10, 0x7F20, 0x7F20, 0x7F80, 0x7950, 0x6FC0, 0x6790, 0x5F70, 0x5790, 0x50A0, 0x4950, 0x4310, 0x3D10, 0x37C0, 0x32F0, 0x2E60, + 0x2BA0, 0x2840, 0x2510, 0x2270, 0x1FA0, 0x1CF0, 0x1A10, 0x1720, 0x1450, 0x10F0, 0x0E30, 0x0BA0, 0x08D0, 0x06B0, 0x03E0, 0x0100, + 0xFDB0, 0xFA10, 0xF770, 0xF450, 0xF120, 0xEE20, 0xEB70, 0xE910, 0xE680, 0xE3D0, 0xE110, 0xDE70, 0xDCA0, 0xDA60, 0xD8C0, 0xD6D0, + 0xD450, 0xD2C0, 0xD030, 0xCE20, 0xCCC0, 0xCB10, 0xCB50, 0xCB40, 0xCBE0, 0xCC70, 0xCD70, 0xCF00, 0xD000, 0xD110, 0xD220, 0xD2A0, + 0xD390, 0xD510, 0xD6B0, 0xD8F0, 0xDB10, 0xDDF0, 0xE0E0, 0xE2F0, 0xE5F0, 0xE840, 0xEB20, 0xED90, 0xF0B0, 0xF400, 0xF6F0, 0xFB00, + 0xFE20, 0x01C0, 0x0520, 0x0870, 0x0BA0, 0x0F00, 0x12B0, 0x16A0, 0x1A40, 0x1E10, 0x2280, 0x2600, 0x2AA0, 0x2E80, 0x32B0, 0x3740, + 0x3A80, 0x3EE0, 0x41E0, 0x4500, 0x4790, 0x4A50, 0x4DB0, 0x5070, 0x5330, 0x5620, 0x5870, 0x5BD0, 0x5EB0, 0x6120, 0x63C0, 0x6650, + 0x6990, 0x6C80, 0x6EF0, 0x7170, 0x7300, 0x74F0, 0x7600, 0x76F0, 0x7770, 0x77D0, 0x7850, 0x7900, 0x7940, 0x7910, 0x77F0, 0x77E0, + 0x7760, 0x7650, 0x76B0, 0x75F0, 0x7690, 0x7730, 0x7760, 0x78E0, 0x7980, 0x7AB0, 0x7C00, 0x7CC0, 0x7DB0, 0x7E20, 0x7EC0, 0x7F10, + 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F40, 0x7F10, 0x7F00, 0x7F30, 0x7EF0, 0x7F40, 0x7F10, 0x7F00, 0x7F00, 0x7D30, 0x7A60, + 0x7740, 0x72D0, 0x6DF0, 0x6860, 0x61E0, 0x5A50, 0x5160, 0x45E0, 0x0B40, 0xFB40, 0xE9D0, 0xD6C0, 0xC340, 0xAD50, 0x95A0, 0x8720, + 0x84F0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8430, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83D0, + 0x83D0, 0x83E0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83D0, 0x8390, 0x8390, 0x8390, 0x83B0, 0x8390, 0x8390, 0x8390, + 0x83C0, 0x8380, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83C0, 0x83A0, 0x83B0, 0x83A0, 0x83A0, 0x83B0, + 0x83A0, 0x8340, 0x83B0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8420, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8460, 0x84B0, 0x8480, 0x84A0, 0x84C0, 0x84E0, 0x8560, 0x8760, 0x90B0, 0x9E90, 0xAAA0, 0xB490, 0xBC90, + 0xC310, 0xC7D0, 0xCC10, 0xCE70, 0xD090, 0xD260, 0xD410, 0xD630, 0xD800, 0xD9E0, 0xDB80, 0xDC30, 0xDC60, 0xDB90, 0xDA10, 0xD750, + 0xD400, 0xD060, 0xCC30, 0xC730, 0xC1A0, 0xBB90, 0xB650, 0xB070, 0xAA90, 0xA500, 0x9F30, 0x98F0, 0x9170, 0x8A40, 0x86A0, 0x8550, + 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8490, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84F0, 0x8500, 0x8510, 0x8520, + 0x8530, 0x8520, 0x8510, 0x8500, 0x84E0, 0x84C0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, + 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8410, + 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8450, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8550, 0x8780, 0x9380, 0xA410, 0xB1F0, + 0xBF60, 0xCAD0, 0xD590, 0xDF20, 0xE6C0, 0xED30, 0xF1D0, 0xF430, 0xF6A0, 0xF790, 0xF8A0, 0xF920, 0xFA10, 0xFB30, 0xFC30, 0xFDA0, + 0xFFF0, 0x0200, 0x0490, 0x06F0, 0x0930, 0x0AE0, 0x0CC0, 0x0F10, 0x1190, 0x1460, 0x1730, 0x1A30, 0x1D40, 0x2040, 0x22B0, 0x23F0, + 0x2510, 0x2530, 0x24B0, 0x2490, 0x2500, 0x2620, 0x26C0, 0x2730, 0x2800, 0x2790, 0x26F0, 0x2570, 0x2380, 0x2160, 0x1D80, 0x1870, + 0x11E0, 0x08D0, 0xFE30, 0xF130, 0xE210, 0xD3A0, 0xC500, 0xB7A0, 0xABF0, 0xA270, 0x9A60, 0x94A0, 0x8FB0, 0x8BC0, 0x8900, 0x8700, + 0x85C0, 0x8540, 0x8500, 0x84D0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8480, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x8370, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, + 0x8340, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83B0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83B0, + 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x8430, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8440, 0x8450, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84F0, 0x8530, 0x8640, 0x8A10, 0x9580, 0xA250, 0xAF70, + 0xBD60, 0xCBD0, 0xDDB0, 0xF040, 0x04C0, 0x1AF0, 0x32B0, 0x4B00, 0x62A0, 0x76F0, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7FA0, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EB0, 0x7EF0, 0x7F40, 0x7EB0, 0x7EE0, 0x7EC0, + 0x7ED0, 0x7F30, 0x7F40, 0x7EF0, 0x7ED0, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F30, 0x7EA0, 0x7EF0, 0x7EE0, + 0x7F30, 0x7F50, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, + 0x7F10, 0x7E90, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F40, 0x7EC0, 0x7F40, 0x7EF0, 0x7F20, 0x7F40, + 0x7F10, 0x7F80, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F00, 0x7F00, 0x7F00, 0x7F00, + 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F30, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E90, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F00, 0x7EC0, 0x7EB0, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7F10, 0x7F20, 0x7F20, + 0x7EE0, 0x6B50, 0x5520, 0x3A80, 0x1E30, 0xFF90, 0xE070, 0xC160, 0xA390, 0x8BB0, 0x8550, 0x84E0, 0x84C0, 0x84B0, 0x84C0, 0x84B0, + 0x84E0, 0x8570, 0x90C0, 0xC3B0, 0xFAC0, 0x39F0, 0x7810, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7ED0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, + 0x7EE0, 0x7E90, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F40, 0x7F10, 0x7EE0, 0x7F10, + 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7F00, 0x7EF0, 0x7ED0, + 0x7F60, 0x7F10, 0x7ED0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F00, 0x7E90, 0x7EB0, 0x7EE0, 0x7EE0, + 0x7EF0, 0x7E90, 0x7EC0, 0x7ED0, 0x7F10, 0x7F10, 0x7EC0, 0x7F00, 0x7F10, 0x7F00, 0x7ED0, 0x7F00, 0x7F00, 0x7E90, 0x7ED0, 0x7F00, + 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, 0x7F10, 0x7F00, 0x7EE0, 0x7EF0, 0x7F60, 0x7F00, 0x7F20, + 0x7F10, 0x7EF0, 0x7F50, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F60, 0x7EE0, 0x7EB0, 0x7EF0, + 0x7EE0, 0x7F20, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F00, 0x7E90, 0x7EF0, 0x7EE0, + 0x7ED0, 0x7F10, 0x7F00, 0x7F40, 0x7ED0, 0x7F10, 0x7F40, 0x7F00, 0x7F30, 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F20, + 0x7F20, 0x7F00, 0x7F90, 0x7EF0, 0x7EF0, 0x7EE0, 0x7ED0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, + 0x7EC0, 0x7F30, 0x7F00, 0x7E70, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, 0x7E90, 0x7E90, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7F30, 0x7F20, + 0x7F00, 0x7F10, 0x7F50, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x78D0, 0x6A50, 0x5860, 0x4580, + 0x30D0, 0x1AF0, 0x0440, 0xEAF0, 0xD0D0, 0xB560, 0x9960, 0x8710, 0x84F0, 0x84D0, 0x84C0, 0x8480, 0x8470, 0x8470, 0x8450, 0x8450, + 0x8440, 0x8460, 0x8430, 0x8420, 0x83C0, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8430, 0x83F0, 0x83F0, 0x83F0, 0x83E0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83F0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, + 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, + 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, + 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8460, 0x8420, 0x8430, 0x8420, + 0x8440, 0x8440, 0x8450, 0x84A0, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84E0, 0x8550, 0x87F0, 0x9910, 0xAED0, 0xC520, + 0xDB80, 0xF570, 0x0DE0, 0x2700, 0x4080, 0x5A30, 0x70D0, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F50, 0x7F20, 0x7F40, 0x7A10, 0x5F20, 0x4070, 0x2210, + 0x02B0, 0xE220, 0xC0F0, 0x9E90, 0x8740, 0x84E0, 0x84D0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, + 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, + 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83F0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8430, 0x8400, + 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x8550, 0x85F0, 0xA040, 0xC580, 0xE180, 0xF450, + 0xFDB0, 0x0030, 0xFEB0, 0xFDB0, 0xFF40, 0x04D0, 0x0EF0, 0x1CB0, 0x2C40, 0x3D00, 0x4B40, 0x55C0, 0x5C90, 0x6050, 0x6430, 0x6920, + 0x6F50, 0x7790, 0x7EA0, 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F70, + 0x7F10, 0x7EE0, 0x7F10, 0x7ED0, 0x7F30, 0x7F00, 0x7ED0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F00, 0x7F00, 0x7F10, 0x7F20, + 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7160, 0x5290, 0x3970, 0x2790, 0x1D20, + 0x1B50, 0x23A0, 0x3460, 0x4D50, 0x6AF0, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, + 0x7F00, 0x7EC0, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7EB0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7ED0, 0x7E70, 0x7EF0, 0x7EF0, 0x7F30, 0x7EE0, + 0x7EC0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7EF0, 0x7F00, 0x7F20, 0x7F00, + 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F00, 0x7F00, 0x7F00, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, + 0x7F00, 0x7EE0, 0x7EF0, 0x7F00, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F50, 0x7F00, + 0x7F00, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, + 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F00, 0x7F30, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F70, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F90, 0x7F00, 0x7F20, 0x7F10, 0x7F20, 0x7F40, 0x7F10, + 0x7F70, 0x7EF0, 0x7F00, 0x7F30, 0x7F00, 0x7F80, 0x7F10, 0x7F10, 0x7EE0, 0x7EE0, 0x7F70, 0x7F10, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F60, + 0x7F20, 0x7EC0, 0x7EB0, 0x7EB0, 0x7EF0, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7B00, 0x5E80, 0x43D0, 0x2AB0, 0x1240, 0x00C0, + 0xF200, 0xE570, 0xDAE0, 0xD280, 0xCD90, 0xCB60, 0xCDA0, 0xD2E0, 0xDAC0, 0xE440, 0xEDE0, 0xF5D0, 0xFB20, 0xFC20, 0xFAF0, 0xF6C0, + 0xF240, 0xEE80, 0xECE0, 0xEDC0, 0xF0C0, 0xF610, 0xFD50, 0x0410, 0x0A40, 0x0E70, 0x0E30, 0x0A60, 0x0210, 0xF710, 0xE960, 0xDAA0, + 0xCB50, 0xBB80, 0xAA60, 0x9A70, 0x8BC0, 0x8610, 0x8500, 0x84D0, 0x84B0, 0x8490, 0x8490, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8450, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8460, 0x8430, 0x8430, 0x8430, 0x83C0, 0x8430, 0x8430, 0x8460, + 0x8430, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8550, 0x8A40, 0xA760, + 0xC390, 0xE090, 0xFB20, 0x1420, 0x2CE0, 0x4490, 0x5BB0, 0x7120, 0x7EC0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, + 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F80, + 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7EB0, 0x7EF0, 0x7F20, 0x7EF0, 0x7ED0, 0x7EA0, 0x7F00, 0x7F00, 0x7F30, 0x7F00, + 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F30, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, + 0x7F30, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7F00, 0x7F90, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, + 0x7F20, 0x7EC0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7E70, 0x7ED0, 0x7ED0, 0x7F00, 0x7F00, + 0x7E90, 0x7E90, 0x7F00, 0x7F20, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F00, + 0x7F30, 0x7F20, 0x7EF0, 0x7EF0, 0x7F10, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F40, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7ED0, 0x7EB0, 0x7EE0, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, + 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F00, + 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7AA0, 0x6270, 0x4B00, 0x3240, + 0x1850, 0xFDB0, 0xE1C0, 0xC600, 0xAA40, 0x90E0, 0x8620, 0x8500, 0x84D0, 0x84D0, 0x84D0, 0x84F0, 0x8530, 0x8650, 0x8B80, 0x9590, + 0x9700, 0x8F00, 0x86C0, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8450, 0x8430, 0x8420, 0x8420, 0x8410, + 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8480, 0x8490, 0x84B0, 0x84F0, 0x86B0, 0xA680, 0xD0B0, 0xFB60, + 0x2500, 0x4C40, 0x6D50, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7E20, 0x6F90, 0x6090, 0x50A0, 0x3F60, 0x2CB0, 0x1850, + 0x02D0, 0xEB40, 0xCFE0, 0xB430, 0x96A0, 0x8620, 0x84B0, 0x84A0, 0x8480, 0x8460, 0x8460, 0x8440, 0x8460, 0x8430, 0x8420, 0x8410, + 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, + 0x83C0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, + 0x83E0, 0x83F0, 0x83E0, 0x83F0, 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8410, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, + 0x8480, 0x8490, 0x84C0, 0x8500, 0x8650, 0x9710, 0xB330, 0xCCD0, 0xE540, 0xFB60, 0x0F40, 0x20B0, 0x30C0, 0x3DF0, 0x48B0, 0x52E0, + 0x5B40, 0x6250, 0x6A10, 0x7030, 0x7740, 0x7D30, 0x7F00, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F00, 0x7EE0, 0x7F10, + 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, + 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x7E90, 0x7F00, + 0x7EE0, 0x7EF0, 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, + 0x7F10, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7EE0, 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7F10, 0x7F20, + 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F60, 0x7F10, 0x7ED0, 0x7EF0, 0x7F00, 0x7F50, 0x7F10, 0x7E90, 0x7EE0, + 0x7ED0, 0x7F30, 0x7F00, 0x7E80, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7EC0, + 0x7F10, 0x7F00, 0x7EF0, 0x7D50, 0x7500, 0x6DC0, 0x6750, 0x6190, 0x5D40, 0x5980, 0x5680, 0x54A0, 0x5470, 0x55E0, 0x5900, 0x5F40, + 0x6750, 0x7170, 0x7C60, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x6710, 0x4210, 0x1820, 0xEC80, 0xC310, 0x9CE0, 0x86D0, 0x84E0, + 0x8490, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x84B0, 0x84B0, 0x8480, 0x8490, 0x84C0, 0x8490, 0x84D0, 0x84B0, 0x84C0, 0x84B0, + 0x84C0, 0x8490, 0x84E0, 0x8510, 0x85A0, 0x8830, 0x94F0, 0xA720, 0xB640, 0xC250, 0xCBD0, 0xD1F0, 0xD500, 0xD560, 0xD470, 0xD270, + 0xD0F0, 0xD010, 0xD090, 0xD1F0, 0xD350, 0xD4D0, 0xD630, 0xD6F0, 0xD6C0, 0xD580, 0xD440, 0xD2C0, 0xD170, 0xD210, 0xD360, 0xD7A0, + 0xDD10, 0xE4B0, 0xEEE0, 0xF9C0, 0x0600, 0x12E0, 0x1FE0, 0x2D10, 0x3900, 0x43A0, 0x4D40, 0x55B0, 0x5D60, 0x6300, 0x6790, 0x6B60, + 0x6DA0, 0x6EE0, 0x6E50, 0x6C30, 0x6960, 0x6550, 0x61F0, 0x5D00, 0x5760, 0x5180, 0x4A50, 0x4330, 0x3B40, 0x30B0, 0x2600, 0x1AC0, + 0x0E50, 0x0010, 0xF090, 0xE0A0, 0xCEF0, 0xBD50, 0xA980, 0x9650, 0x88D0, 0x8540, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, + 0x8450, 0x8410, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8420, 0x8400, 0x8400, + 0x8400, 0x8420, 0x8420, 0x8440, 0x8480, 0x8460, 0x8470, 0x8490, 0x84B0, 0x84E0, 0x8550, 0x8820, 0x9A70, 0xAF30, 0xC340, 0xD580, + 0xE770, 0xF560, 0x00F0, 0x09D0, 0x1090, 0x15A0, 0x1770, 0x16F0, 0x14E0, 0x0E70, 0x05B0, 0xF9C0, 0xEA40, 0xD840, 0xC370, 0xADF0, + 0x9740, 0x8840, 0x8520, 0x84D0, 0x84B0, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8480, + 0x8450, 0x8450, 0x8400, 0x8450, 0x8450, 0x8470, 0x8440, 0x8440, 0x8450, 0x8450, 0x8440, 0x8450, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8460, 0x8460, 0x84A0, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x84F0, + 0x8510, 0x8530, 0x8570, 0x85B0, 0x8600, 0x8670, 0x8760, 0x8A00, 0x90F0, 0x9C80, 0xAA40, 0xB8E0, 0xC760, 0xD4F0, 0xE160, 0xEB80, + 0xF4B0, 0xFBA0, 0x0180, 0x05E0, 0x0960, 0x0B40, 0x0BA0, 0x0A20, 0x07C0, 0x0470, 0x0060, 0xFC00, 0xF780, 0xF290, 0xEE60, 0xEAB0, + 0xE6D0, 0xE360, 0xDFD0, 0xDC70, 0xD8F0, 0xD530, 0xD150, 0xCD40, 0xC890, 0xC360, 0xBE40, 0xB890, 0xB270, 0xAC80, 0xA620, 0x9FE0, + 0x9880, 0x90A0, 0x89B0, 0x8650, 0x8530, 0x84E0, 0x84F0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, + 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83F0, 0x8400, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x84A0, 0x84D0, 0x8500, 0x8610, 0x8E90, 0xA4A0, 0xB8B0, 0xCC80, 0xDE90, + 0xF050, 0x00E0, 0x1060, 0x2030, 0x2E70, 0x3B20, 0x46A0, 0x5110, 0x5A60, 0x6220, 0x6900, 0x6F30, 0x7520, 0x79E0, 0x7D50, 0x7EF0, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F90, 0x7F20, 0x7EE0, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7ED0, 0x7F20, 0x7F00, 0x7F10, 0x7E10, 0x7CC0, 0x7B80, 0x7A50, 0x78F0, 0x7760, 0x7490, 0x71D0, 0x6D90, 0x6800, + 0x6150, 0x5930, 0x5100, 0x47C0, 0x3D30, 0x32D0, 0x2700, 0x1B10, 0x0E90, 0x00A0, 0xF3D0, 0xE5D0, 0xD7F0, 0xC940, 0xB9E0, 0xAA80, + 0x9BA0, 0x8E10, 0x8710, 0x8550, 0x84F0, 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, + 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8430, 0x8400, 0x8400, + 0x8410, 0x8400, 0x8410, 0x8410, 0x8430, 0x8410, 0x8410, 0x8420, 0x8440, 0x8420, 0x8420, 0x8450, 0x8450, 0x8430, 0x8440, 0x8470, + 0x8450, 0x8450, 0x8470, 0x84A0, 0x8480, 0x8490, 0x84C0, 0x8500, 0x86D0, 0x9C90, 0xBBD0, 0xD790, 0xF290, 0x0B70, 0x2210, 0x36B0, + 0x49F0, 0x5A20, 0x68D0, 0x7600, 0x7E30, 0x7F10, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F90, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, + 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7F10, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, + 0x7F00, 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F30, 0x7F10, + 0x7F70, 0x7EE0, 0x7EF0, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7EF0, 0x7EE0, + 0x7ED0, 0x7F70, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F60, 0x7F10, 0x6C30, 0x55C0, 0x3CE0, 0x2070, 0x06B0, 0xECA0, 0xD1F0, 0xB5E0, + 0x97B0, 0x86A0, 0x84D0, 0x84A0, 0x8480, 0x8470, 0x8450, 0x8440, 0x8440, 0x8430, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, + 0x83E0, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, + 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x8500, 0x85D0, 0x91F0, + 0xB130, 0xD040, 0xF090, 0x1280, 0x3860, 0x5CF0, 0x7B90, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7F10, 0x7F10, 0x7F00, + 0x7EE0, 0x7F50, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, + 0x7F70, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, + 0x7EA0, 0x6980, 0x5A10, 0x4D90, 0x4400, 0x3F60, 0x3D80, 0x3FD0, 0x45E0, 0x4EC0, 0x5D00, 0x6C00, 0x7C00, 0x7F10, 0x7F10, 0x7F20, + 0x7EF0, 0x7F90, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F00, 0x7EE0, 0x7EE0, 0x7ED0, + 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F50, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F00, 0x7F20, + 0x7F20, 0x7EC0, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, + 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F10, 0x7F50, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F60, 0x7F00, 0x7ED0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7F20, + 0x7F10, 0x7EB0, 0x7F10, 0x7EE0, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F80, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F00, 0x7F20, 0x7F00, 0x7EF0, 0x7F30, 0x7EF0, 0x7EC0, 0x7ED0, 0x7EE0, + 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F20, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, + 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F50, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, + 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x72D0, 0x4900, 0x1BA0, 0xEB90, 0xBA70, 0x8D10, 0x84E0, 0x84A0, 0x8480, 0x8470, 0x8460, + 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x83B0, 0x8410, 0x8410, 0x8410, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8420, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x8400, 0x83E0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8380, 0x8370, 0x8370, 0x8360, 0x8350, 0x8370, 0x8350, 0x8350, + 0x8350, 0x8380, 0x8350, 0x8360, 0x8310, 0x8370, 0x8370, 0x8370, 0x8380, 0x8380, 0x8380, 0x83C0, 0x8390, 0x8390, 0x8390, 0x8390, + 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83F0, 0x8400, 0x8410, 0x8430, + 0x8450, 0x8470, 0x84B0, 0x86E0, 0xBE00, 0xF710, 0x2C80, 0x5C80, 0x7E60, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, + 0x7EF0, 0x7EF0, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7EF0, 0x7F30, 0x7EC0, 0x7F40, + 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EF0, 0x7F00, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F80, 0x7F10, + 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F10, 0x7E70, + 0x7ED0, 0x7F10, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7EC0, 0x7F40, + 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F40, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, 0x7F50, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EE0, 0x7F50, 0x7EF0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7EB0, 0x7EC0, + 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7EB0, 0x7F20, 0x6890, 0x5130, 0x3720, 0x1AD0, 0xFF50, 0xE350, 0xC900, 0xB080, 0x9A90, 0x8B20, + 0x8610, 0x8520, 0x84E0, 0x84C0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8480, 0x8450, 0x8440, 0x8420, 0x8430, 0x8420, 0x8410, + 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8410, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83E0, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8440, 0x8450, 0x8440, 0x8440, 0x8490, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8460, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, + 0x8490, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8E20, 0xBB50, 0xE9E0, + 0x17E0, 0x4640, 0x6E50, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7EF0, 0x7F00, 0x7EC0, + 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7F80, 0x7F00, 0x7F20, 0x7F10, 0x7EF0, 0x7F70, + 0x7F20, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7ED0, 0x7ED0, 0x7EB0, 0x7EF0, 0x7EF0, + 0x7E90, 0x7ED0, 0x7F00, 0x7F10, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, + 0x7F20, 0x7850, 0x6A10, 0x5F30, 0x55E0, 0x4F10, 0x4A30, 0x4800, 0x49C0, 0x4D70, 0x53E0, 0x5D60, 0x68E0, 0x7690, 0x7EF0, 0x7F70, + 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, 0x7EE0, 0x7F00, 0x7F10, 0x7F70, 0x7EF0, 0x7ED0, 0x7EF0, 0x7EF0, 0x7F30, 0x7ED0, + 0x7EB0, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7E90, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, + 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F00, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, + 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F10, 0x7F30, 0x7F10, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7EE0, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F70, 0x7F20, 0x7EF0, + 0x7F30, 0x7F30, 0x7F30, 0x7EF0, 0x7E90, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7E80, 0x7D80, 0x4F00, 0x2090, 0xF470, 0xCC20, 0xAB70, + 0x9120, 0x8730, 0x8550, 0x84F0, 0x84D0, 0x8470, 0x84A0, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8410, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8420, 0x8430, 0x8420, 0x8420, 0x8420, 0x8440, 0x8420, 0x8410, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8420, 0x8410, 0x8410, 0x8410, 0x83E0, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8410, 0x8430, + 0x8410, 0x8410, 0x83C0, 0x8410, 0x8410, 0x8410, 0x83F0, 0x8420, 0x8420, 0x8420, 0x8450, 0x8420, 0x8420, 0x8410, 0x8430, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8450, 0x8440, 0x8430, 0x8430, 0x8460, + 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8490, 0x8480, 0x8470, 0x8480, 0x84A0, 0x8490, 0x8490, 0x8490, 0x84D0, 0x84A0, + 0x84B0, 0x84C0, 0x84C0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84B0, 0x84A0, 0x8480, 0x8470, 0x8470, 0x8470, + 0x8450, 0x8440, 0x8430, 0x8440, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8410, 0x83F0, 0x83E0, 0x83E0, 0x8400, 0x83E0, + 0x83E0, 0x83E0, 0x83F0, 0x83D0, 0x83D0, 0x8370, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x8380, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83B0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, + 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x8360, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x8410, 0x8400, 0x8400, 0x83B0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8390, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, + 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x84E0, 0x8520, 0x85A0, 0x8730, 0x8D90, 0x9B30, 0xA9A0, 0xB860, 0xC790, 0xD820, 0xE800, + 0xF880, 0x0A10, 0x1D60, 0x33C0, 0x4D00, 0x6850, 0x7E60, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, + 0x7F00, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, + 0x7EA0, 0x7ED0, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EE0, 0x7F10, 0x7F10, 0x7E90, 0x7ED0, 0x7ED0, 0x7F00, 0x7EE0, 0x7E90, + 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, 0x7F30, 0x7F20, 0x7EF0, 0x7F00, 0x7F40, + 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F50, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, + 0x7EF0, 0x7830, 0x5070, 0x2950, 0x01D0, 0xDAE0, 0xB4C0, 0x8FE0, 0x8510, 0x84D0, 0x8490, 0x8470, 0x8460, 0x8480, 0x8450, 0x8450, + 0x8440, 0x8470, 0x8440, 0x8450, 0x8420, 0x8450, 0x8450, 0x8450, 0x8420, 0x8450, 0x8450, 0x8460, 0x8450, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8430, 0x8430, 0x8440, 0x8440, 0x8480, 0x8460, 0x8480, 0x84B0, 0x8530, 0x91F0, 0xB790, 0xD450, 0xE980, 0xFC20, 0x0F10, + 0x23F0, 0x3D30, 0x5720, 0x6FE0, 0x7ED0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F80, 0x7F00, 0x7EC0, 0x7F00, 0x7F10, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, + 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, + 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F40, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, 0x7F20, 0x7EF0, 0x7ED0, 0x7F00, 0x7EC0, 0x7EC0, 0x7EE0, 0x7F20, 0x7EC0, + 0x7F10, 0x7F30, 0x7EC0, 0x7EF0, 0x7F10, 0x7EE0, 0x7F40, 0x7ED0, 0x7F00, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7EE0, 0x7F10, 0x7EF0, + 0x7F30, 0x7EE0, 0x7E90, 0x7F30, 0x7F00, 0x7F20, 0x7EE0, 0x7EA0, 0x7F00, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7EF0, + 0x7EF0, 0x7EB0, 0x7F30, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F80, 0x7F00, 0x7F40, 0x7EF0, + 0x7EF0, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7EF0, 0x7F00, 0x7EF0, 0x7F60, 0x7F20, 0x7ED0, 0x7ED0, 0x7EB0, + 0x7EF0, 0x7EF0, 0x7E90, 0x7EE0, 0x7EC0, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, + 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7960, 0x6450, 0x4DE0, + 0x3320, 0x15F0, 0xF6D0, 0xD580, 0xB410, 0x9110, 0x8530, 0x84B0, 0x8480, 0x8460, 0x8460, 0x8450, 0x8440, 0x8410, 0x8420, 0x8420, + 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, + 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x83C0, 0x8390, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, + 0x83B0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, + 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8420, 0x8400, 0x8400, 0x8410, + 0x8400, 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8440, 0x8420, 0x8420, 0x8420, 0x8470, 0x8420, 0x8420, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8430, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8440, 0x8410, 0x8410, 0x8440, 0x8410, 0x8430, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84C0, 0x8540, 0x9210, 0xBC50, 0xE680, 0x0B60, 0x2F80, 0x51B0, + 0x7030, 0x7E70, 0x7EC0, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F60, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F80, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7F00, 0x7F00, + 0x7F00, 0x7F60, 0x7F00, 0x7ED0, 0x7EB0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F20, 0x7EA0, 0x7ED0, 0x7EF0, + 0x7F00, 0x7EE0, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7F00, + 0x7EF0, 0x7F10, 0x7F60, 0x7F40, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F80, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F10, 0x7F70, 0x7EF0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, + 0x7F40, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, 0x7EF0, 0x7F00, + 0x7F40, 0x7F00, 0x7F40, 0x7EF0, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F70, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F00, 0x7F20, 0x7F10, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, + 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F50, 0x7F40, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7890, 0x6BB0, 0x5DE0, 0x4F80, 0x3FF0, 0x2FD0, 0x1F70, 0x0DE0, + 0xFB10, 0xE5F0, 0xD170, 0xBCD0, 0xA760, 0x9290, 0x8740, 0x8510, 0x84D0, 0x84D0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, + 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83D0, 0x8380, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83E0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, + 0x83C0, 0x83C0, 0x8400, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, + 0x84C0, 0x84E0, 0x8540, 0x86E0, 0x9320, 0xA5E0, 0xB910, 0xCC50, 0xDF50, 0xF2E0, 0x0680, 0x19F0, 0x2DB0, 0x4340, 0x5710, 0x6990, + 0x79D0, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7ED0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7E90, 0x7F00, 0x7F00, 0x7F00, 0x7F00, + 0x7E80, 0x7ED0, 0x7EF0, 0x7F10, 0x7EF0, 0x7E80, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, + 0x7EF0, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7EB0, 0x4110, 0x16D0, 0xFCB0, 0xF4A0, 0xFBE0, 0x0CF0, + 0x23F0, 0x3B80, 0x51C0, 0x64B0, 0x72A0, 0x7CA0, 0x7ED0, 0x7F10, 0x7EF0, 0x7F30, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7C00, + 0x7960, 0x7C50, 0x7EF0, 0x7F20, 0x7F00, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F00, + 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7F00, 0x7F20, 0x7F20, 0x7F20, 0x7F90, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F70, + 0x7F20, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EE0, 0x7F50, 0x7F00, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, + 0x7EC0, 0x7ED0, 0x7EE0, 0x7F10, 0x7F10, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x6390, + 0x36E0, 0x04E0, 0xCE10, 0x9550, 0x84E0, 0x8480, 0x8480, 0x8450, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, + 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, + 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, + 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84B0, 0x84C0, + 0x84F0, 0x8540, 0x8670, 0x8D80, 0x9BC0, 0xA8A0, 0xB380, 0xBB50, 0xC0E0, 0xC420, 0xC570, 0xC520, 0xC2E0, 0xC030, 0xBB90, 0xB660, + 0xB0D0, 0xAAB0, 0xA410, 0x9D20, 0x9530, 0x8E50, 0x89D0, 0x87C0, 0x86D0, 0x8690, 0x86D0, 0x87D0, 0x8B00, 0x93B0, 0xA100, 0xAFA0, + 0xBEE0, 0xCE30, 0xDD00, 0xEAE0, 0xF830, 0x0500, 0x1260, 0x2210, 0x3120, 0x42C0, 0x5500, 0x6710, 0x77F0, 0x7F20, 0x7EF0, 0x7EF0, + 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F60, + 0x7EE0, 0x7E90, 0x7F20, 0x7F20, 0x6D70, 0x4A30, 0x2330, 0xFB70, 0xD4A0, 0xB0F0, 0x9280, 0x8670, 0x8500, 0x84D0, 0x84C0, 0x84E0, + 0x84B0, 0x84B0, 0x84B0, 0x84D0, 0x84F0, 0x8540, 0x86B0, 0x8F50, 0xA3C0, 0xBA40, 0xD1F0, 0xEBF0, 0x07B0, 0x2650, 0x4370, 0x5EE0, + 0x7660, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F80, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, + 0x7F10, 0x7EC0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7EC0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7E90, 0x7EE0, 0x7F20, 0x7F10, 0x7F10, + 0x7EA0, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7EF0, 0x7EE0, + 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EE0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, + 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7E90, 0x7EF0, 0x7EF0, 0x7EF0, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F30, 0x7F00, + 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7EF0, 0x7F00, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7F00, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x53F0, 0x2AD0, 0x01E0, 0xD960, 0xB0B0, 0x8C80, 0x8510, + 0x84B0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8440, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, + 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84A0, 0x84D0, + 0x8500, 0x8550, 0x8560, 0x84E0, 0x84C0, 0x8490, 0x8480, 0x8480, 0x8490, 0x84B0, 0x94D0, 0xB0B0, 0xCD30, 0xEA60, 0x05E0, 0x1BF0, + 0x28B0, 0x26C0, 0x1340, 0xED10, 0xB420, 0x8570, 0x8480, 0x8450, 0x8430, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8430, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, + 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83D0, 0x83E0, 0x8390, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8440, 0x8410, 0x8410, 0x8410, 0x8410, 0x8430, 0x8420, 0x8440, + 0x8420, 0x8430, 0x8430, 0x8430, 0x8450, 0x8400, 0x8460, 0x8480, 0x84B0, 0x84D0, 0x85B0, 0x9400, 0xB1E0, 0xCC00, 0xE330, 0xF8A0, + 0x0980, 0x17F0, 0x22A0, 0x2A40, 0x2DF0, 0x2D50, 0x2A20, 0x23E0, 0x1A10, 0x0EE0, 0x0160, 0xF290, 0xE2B0, 0xD230, 0xC180, 0xB1D0, + 0xA330, 0x9680, 0x8DD0, 0x8940, 0x8730, 0x8640, 0x85E0, 0x85B0, 0x85B0, 0x85C0, 0x8610, 0x86C0, 0x8820, 0x8B30, 0x9080, 0x9750, + 0x9E40, 0xA650, 0xAE90, 0xB740, 0xBE40, 0xC370, 0xC540, 0xC480, 0xC140, 0xBD40, 0xBA40, 0xB9E0, 0xBDD0, 0xC7D0, 0xD750, 0xEC50, + 0x0720, 0x2840, 0x4CC0, 0x7180, 0x7F10, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F20, + 0x7EF0, 0x7ED0, 0x7F80, 0x7F00, 0x7F00, 0x7ED0, 0x7EF0, 0x7F70, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7EC0, + 0x7EE0, 0x7F30, 0x7F00, 0x7E90, 0x7EB0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7EA0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, + 0x7F00, 0x7EE0, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, + 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F20, 0x7F20, 0x7F00, 0x7F80, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F50, 0x7EE0, 0x7ED0, 0x7F10, + 0x7F20, 0x7F50, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7E90, + 0x7D90, 0x7B00, 0x7960, 0x7A80, 0x7C30, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F30, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F10, 0x7F80, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7EF0, + 0x7F10, 0x7F00, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7EE0, 0x7EA0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7E90, + 0x7EF0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EE0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, + 0x7EF0, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7F30, 0x7F20, 0x76C0, 0x6BF0, 0x6070, 0x52C0, 0x4360, 0x30F0, 0x1D70, 0x0760, 0xEE80, + 0xD420, 0xB900, 0x9C40, 0x87F0, 0x8500, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8440, 0x8430, 0x8450, 0x8440, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8460, 0x8450, 0x8430, 0x8420, 0x8410, + 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x8400, 0x8410, 0x8420, 0x8440, 0x8450, 0x8470, + 0x8480, 0x84A0, 0x84D0, 0x8530, 0x88C0, 0xA340, 0xBDA0, 0xD370, 0xE2E0, 0xEC90, 0xF090, 0xF0F0, 0xEF90, 0xEF30, 0xF120, 0xF6A0, + 0xFF50, 0x0BB0, 0x19A0, 0x28F0, 0x3910, 0x4700, 0x5370, 0x5D40, 0x65B0, 0x6D00, 0x73C0, 0x79C0, 0x7DB0, 0x7F00, 0x7EC0, 0x7F10, + 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F20, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7EE0, 0x7EF0, 0x7F80, 0x7EE0, + 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7EF0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, + 0x7F10, 0x7F00, 0x7F40, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F30, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x6D10, 0x4A50, 0x27D0, 0x0770, 0xE920, 0xCC50, 0xB070, 0x9530, 0x8640, 0x84E0, 0x84B0, 0x84A0, + 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, + 0x8460, 0x8470, 0x84A0, 0x8500, 0x87C0, 0x9FA0, 0xB360, 0xC390, 0xD290, 0xE5A0, 0xFA80, 0x1350, 0x2EB0, 0x4BE0, 0x68F0, 0x7E90, + 0x7F20, 0x7F20, 0x7F10, 0x7F60, 0x7F00, 0x7F00, 0x7F00, 0x7EE0, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F40, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F20, + 0x7F40, 0x7B30, 0x4570, 0x0FE0, 0xD6C0, 0x9A20, 0x84F0, 0x8480, 0x8450, 0x8440, 0x8420, 0x8410, 0x8400, 0x83F0, 0x83E0, 0x83D0, + 0x8390, 0x83C0, 0x83C0, 0x83E0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, + 0x8460, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x8500, 0x85C0, 0x8B10, 0x9DA0, 0xAD60, 0xBA20, 0xC3D0, 0xCA90, 0xCF20, 0xD190, 0xD460, + 0xD6D0, 0xD8E0, 0xDB60, 0xDCE0, 0xDD30, 0xD8C0, 0xCF20, 0xC050, 0xABE0, 0x9330, 0x8620, 0x84E0, 0x84C0, 0x8490, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8450, 0x8430, 0x8430, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8460, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x83D0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8380, + 0x8380, 0x8360, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8390, 0x8380, 0x8380, + 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x83D0, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, + 0x8370, 0x8370, 0x8370, 0x8380, 0x8370, 0x8380, 0x8380, 0x8380, 0x8390, 0x8390, 0x8340, 0x83A0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, + 0x83D0, 0x83E0, 0x8440, 0x8400, 0x8410, 0x8430, 0x8450, 0x8470, 0x84A0, 0x8640, 0xC110, 0x02F0, 0x4240, 0x76F0, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7EB0, 0x7F00, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F70, 0x7EF0, 0x7F10, 0x7F00, + 0x7F00, 0x7F80, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7EE0, 0x7ED0, 0x7ED0, 0x7EE0, 0x7F40, 0x7F10, 0x7E90, 0x7EB0, 0x7ED0, + 0x7F10, 0x7F00, 0x7E70, 0x7EC0, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7F00, 0x7EF0, + 0x7F10, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, + 0x7F00, 0x7F80, 0x7EF0, 0x7F20, 0x7F10, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F40, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, + 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, 0x7EF0, 0x7F00, + 0x7F00, 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, + 0x7EF0, 0x7F80, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EE0, 0x7EE0, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, + 0x7F10, 0x7F00, 0x7E90, 0x7EB0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, + 0x7F00, 0x7EC0, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, + 0x7EF0, 0x7F50, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, + 0x7F60, 0x7EE0, 0x7E90, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EA0, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, + 0x7F20, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, + 0x7EF0, 0x7F80, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F50, 0x7EE0, 0x7EE0, 0x7ED0, 0x7EE0, + 0x7F30, 0x7F00, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7E70, 0x7EC0, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F10, + 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F30, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F10, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, + 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F00, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7EF0, 0x7F30, 0x7F30, 0x7C20, 0x6A70, 0x59D0, 0x48F0, 0x3860, 0x2820, 0x1790, 0x0800, 0xF960, + 0xEB60, 0xDE10, 0xD170, 0xC550, 0xB9E0, 0xAF40, 0xA610, 0x9D20, 0x9130, 0x8780, 0x8500, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8450, + 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8420, 0x8450, 0x8460, 0x8480, 0x84B0, + 0x8510, 0x8E10, 0xBAA0, 0xE380, 0x09C0, 0x3040, 0x5110, 0x6D30, 0x7EE0, 0x7EE0, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F00, 0x7F60, + 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7EE0, 0x7EC0, 0x7F30, 0x7F00, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, + 0x7F00, 0x7F20, 0x7F10, 0x7F80, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F60, 0x7F00, 0x7F00, 0x7F00, 0x7EF0, 0x7F30, 0x7EE0, 0x7EC0, + 0x7ED0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7EC0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7E90, 0x7F10, 0x7F10, 0x7EE0, 0x7EC0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F40, + 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EE0, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F70, 0x7F00, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7E90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7ED0, 0x7EB0, 0x7F00, + 0x7F00, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7ED0, 0x7F30, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, + 0x7F10, 0x7EF0, 0x7EE0, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F90, 0x7EF0, 0x7EE0, + 0x7EE0, 0x7ED0, 0x7F50, 0x7F10, 0x7F70, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F10, 0x7EB0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EA0, 0x7EC0, 0x7F00, 0x7F30, 0x7F20, 0x7E90, 0x7EB0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F20, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F50, + 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F20, 0x7F80, 0x7EF0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F30, 0x7EE0, + 0x7EC0, 0x7F10, 0x7F10, 0x7F40, 0x7ED0, 0x7E90, 0x7F00, 0x7EE0, 0x7EF0, 0x7EE0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, + 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F90, 0x7F20, 0x7F40, 0x7F40, 0x7F10, 0x7F70, + 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F80, 0x7C10, 0x6C20, 0x5CC0, 0x4AD0, 0x37F0, 0x24B0, 0x1060, 0xFC40, 0xE470, 0xCDE0, 0xB780, + 0xA000, 0x8BB0, 0x8580, 0x84D0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8410, 0x8430, 0x8450, 0x8430, 0x8410, + 0x8410, 0x8400, 0x8400, 0x83F0, 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x83F0, 0x83D0, 0x83D0, 0x8380, 0x83C0, 0x83C0, 0x83C0, 0x8340, + 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x8350, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, + 0x83B0, 0x8340, 0x83C0, 0x83C0, 0x83E0, 0x83C0, 0x83C0, 0x83C0, 0x83F0, 0x83C0, 0x83D0, 0x83C0, 0x83F0, 0x83B0, 0x83C0, 0x8380, + 0x83B0, 0x83B0, 0x83B0, 0x8350, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83C0, 0x83C0, 0x83B0, + 0x83C0, 0x83F0, 0x83C0, 0x83F0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83E0, 0x83C0, 0x83B0, 0x83B0, 0x83E0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8470, 0x8480, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, + 0x84D0, 0x84E0, 0x8520, 0x8600, 0x88C0, 0x8F10, 0x96B0, 0x9E60, 0xA510, 0xACF0, 0xB640, 0xC1D0, 0xD020, 0xE220, 0xF520, 0x0940, + 0x1E90, 0x35E0, 0x4D00, 0x6370, 0x77D0, 0x7EA0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7EB0, + 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F40, 0x7EF0, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, + 0x7F00, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F40, 0x7F20, 0x7F20, 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7EF0, 0x7F20, 0x7F00, + 0x6E30, 0x5BF0, 0x4870, 0x34E0, 0x2090, 0x0C20, 0xF7A0, 0xE2C0, 0xCE90, 0xB910, 0xA500, 0x9200, 0x8770, 0x8540, 0x84E0, 0x84B0, + 0x84A0, 0x8490, 0x8470, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8400, 0x8410, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8430, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8430, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x8370, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83B0, + 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x8400, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x8350, + 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8380, 0x83A0, 0x83A0, 0x83A0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8430, 0x8410, 0x8410, 0x8400, 0x8420, 0x8420, + 0x8430, 0x8420, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8460, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x84F0, 0x8550, 0x8640, + 0x8850, 0x8BC0, 0x8F70, 0x9160, 0x9220, 0x9110, 0x8ED0, 0x8BF0, 0x8910, 0x86F0, 0x85B0, 0x8520, 0x84F0, 0x84C0, 0x84D0, 0x84A0, + 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8470, 0x8440, 0x8440, 0x8430, + 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, 0x8460, + 0x8470, 0x8480, 0x84C0, 0x8500, 0x8750, 0xA400, 0xC9D0, 0xF3D0, 0x1FE0, 0x4BE0, 0x7200, 0x7F30, 0x7EF0, 0x7F10, 0x7F10, 0x7EF0, + 0x7F60, 0x7ED0, 0x7EF0, 0x7F00, 0x7F00, 0x7F50, 0x7F00, 0x7EE0, 0x7F10, 0x7F10, 0x7F30, 0x7EC0, 0x7E90, 0x7F10, 0x7F20, 0x7F30, + 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F50, 0x7EE0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EE0, 0x7F10, 0x7F00, 0x7EC0, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7F10, + 0x7F10, 0x7EE0, 0x7F70, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F50, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7EC0, 0x7ED0, + 0x7EE0, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, + 0x7F10, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F00, 0x7F20, 0x7EC0, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F40, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F60, 0x7ED0, 0x7EF0, 0x7EE0, + 0x7EF0, 0x7F50, 0x7EE0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7EE0, 0x7E90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EA0, 0x7F20, 0x7F00, + 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7F00, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F60, 0x7F10, 0x7F10, + 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7F10, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F80, 0x7F10, 0x7EE0, 0x7EE0, + 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7EF0, 0x7EE0, 0x7F40, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7E80, 0x7EC0, 0x7F00, + 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, + 0x7EF0, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, + 0x7F10, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7EB0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, 0x7EC0, 0x7E90, 0x7F10, 0x7F00, + 0x7F00, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F00, 0x7F10, + 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F90, 0x7F00, 0x7F40, 0x7EF0, 0x7EF0, 0x7F70, 0x7EE0, 0x7F10, 0x7EF0, + 0x7EE0, 0x7F70, 0x7F10, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7F20, + 0x7F10, 0x7F20, 0x7EA0, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F40, 0x7F00, 0x7470, 0x5D80, 0x4500, 0x2C60, 0x1380, 0xFA40, + 0xE270, 0xCAA0, 0xB1E0, 0x9CA0, 0x8A90, 0x8580, 0x8530, 0x84C0, 0x84A0, 0x8490, 0x84B0, 0x8470, 0x8460, 0x8460, 0x8480, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8490, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x84E0, 0x8500, 0x84E0, + 0x8510, 0x8530, 0x8500, 0x8500, 0x8500, 0x84F0, 0x84D0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, + 0x8470, 0x8470, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84B0, 0x84C0, + 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, + 0x8460, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, + 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8380, 0x83B0, 0x8380, 0x8380, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, + 0x8370, 0x8370, 0x8360, 0x8350, 0x8360, 0x8360, 0x8380, 0x8360, 0x8360, 0x8370, 0x8370, 0x8360, 0x8370, 0x8370, 0x8370, 0x8380, + 0x8380, 0x8380, 0x83B0, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83D0, 0x83B0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8390, 0x8380, + 0x8380, 0x8380, 0x8370, 0x8360, 0x8360, 0x8360, 0x8350, 0x8350, 0x8350, 0x8350, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, + 0x8340, 0x8340, 0x8340, 0x8340, 0x8350, 0x8350, 0x8350, 0x8350, 0x8350, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, + 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8360, 0x8370, 0x8370, 0x8370, 0x8380, + 0x8380, 0x8380, 0x8380, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8420, 0x8430, 0x8430, 0x8450, 0x8460, 0x8480, 0x84A0, 0x84F0, 0x8840, 0xB250, 0xE0E0, + 0x1110, 0x4450, 0x7500, 0x7F20, 0x7EF0, 0x7EA0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EC0, 0x7F20, 0x7EF0, 0x7EE0, 0x7EF0, 0x7ED0, + 0x7F30, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, 0x7F20, 0x7EF0, 0x7ED0, 0x7F60, + 0x7F00, 0x7EF0, 0x7EB0, 0x7EE0, 0x7F50, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F30, 0x7F00, 0x7EA0, 0x7EB0, 0x7EB0, 0x7EE0, 0x7EF0, + 0x7E90, 0x7EA0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7E90, 0x7EE0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, + 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F30, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7F50, + 0x7ED0, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F00, 0x7EE0, 0x7F50, 0x7EB0, + 0x7E70, 0x7EE0, 0x7EF0, 0x7F20, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, + 0x7EF0, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F80, + 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, + 0x7F50, 0x7F00, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x6BD0, 0x3AC0, 0x0FD0, 0xE790, 0xC2E0, 0xA170, 0x8960, 0x8510, + 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8470, 0x8400, 0x8460, 0x8460, 0x8460, 0x8440, 0x8450, 0x8460, 0x8460, + 0x8460, 0x8470, 0x8470, 0x8470, 0x84A0, 0x84B0, 0x84F0, 0x85F0, 0x93E0, 0xB320, 0xD0C0, 0xEE40, 0x09A0, 0x2480, 0x3D00, 0x5380, + 0x6790, 0x78F0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F70, + 0x7F00, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7F30, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7EF0, 0x6860, + 0x4A40, 0x24A0, 0xFCE0, 0xD100, 0xA410, 0x8670, 0x84C0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8470, 0x8440, 0x8430, 0x8420, 0x8420, + 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8420, 0x8420, 0x8420, 0x8430, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, + 0x84F0, 0x8520, 0x8580, 0x85C0, 0x85C0, 0x8580, 0x8560, 0x8500, 0x84D0, 0x84D0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, + 0x8490, 0x8490, 0x8460, 0x8460, 0x8480, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x83E0, 0x8440, 0x8430, 0x8440, 0x8400, + 0x8430, 0x8430, 0x8460, 0x8420, 0x8450, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8470, 0x8450, 0x8450, + 0x8460, 0x8470, 0x8490, 0x84B0, 0x8540, 0x9770, 0xC440, 0xED20, 0x0FC0, 0x2AD0, 0x3CC0, 0x4580, 0x4800, 0x4610, 0x4830, 0x50A0, + 0x6250, 0x7970, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F50, + 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7EC0, 0x7EF0, 0x7F00, 0x7F70, 0x7ED0, 0x7E90, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, + 0x7EA0, 0x7EF0, 0x7F00, 0x7F20, 0x7F00, 0x7E90, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, + 0x7F50, 0x7EF0, 0x7F00, 0x7F10, 0x7EF0, 0x7F60, 0x7EE0, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, + 0x7EE0, 0x7EE0, 0x7ED0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EE0, 0x7F50, 0x7EF0, 0x7E70, 0x7EC0, 0x7ED0, 0x7EF0, 0x7EF0, + 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, + 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, + 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7AC0, 0x3B30, 0x00F0, 0xC340, 0x89C0, + 0x84B0, 0x8470, 0x8450, 0x8460, 0x8420, 0x8400, 0x83F0, 0x83F0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8390, + 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83E0, 0x83C0, 0x83D0, 0x8370, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, + 0x8390, 0x8390, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8380, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, + 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83E0, + 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83F0, + 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84D0, 0x86E0, 0xB6C0, 0xEFC0, 0x29C0, + 0x6360, 0x7F00, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7F80, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F40, 0x7EF0, 0x7EF0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F00, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F60, 0x7F10, 0x7E90, 0x7EE0, + 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7EE0, 0x7F00, 0x7F00, 0x7E90, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x6960, 0x33C0, + 0xFCD0, 0xC740, 0x9470, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8510, 0x85E0, 0x87D0, 0x8890, 0x8750, 0x85D0, 0x8550, + 0x8520, 0x8540, 0x85C0, 0x8850, 0x9810, 0xAB50, 0xBF30, 0xD3A0, 0xE990, 0x0090, 0x1740, 0x2E40, 0x4190, 0x5260, 0x5EC0, 0x66D0, + 0x6E30, 0x75A0, 0x7DA0, 0x7EF0, 0x7EF0, 0x7F00, 0x7EF0, 0x7F80, 0x7F20, 0x7EE0, 0x7EF0, 0x7ED0, 0x7F30, 0x7EF0, 0x7E90, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EC0, 0x7F00, 0x7F10, 0x7F10, 0x7E90, 0x7ED0, 0x7F00, 0x7EE0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F20, + 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, 0x7F20, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, + 0x7F00, 0x7EE0, 0x7F50, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F00, 0x7F80, 0x7EF0, 0x7EB0, 0x7EE0, + 0x7EF0, 0x7F30, 0x7EE0, 0x7D20, 0x5710, 0x2BF0, 0x0070, 0xD200, 0xA150, 0x8570, 0x84D0, 0x8470, 0x83F0, 0x8400, 0x83F0, 0x83F0, + 0x8410, 0x83D0, 0x83C0, 0x8360, 0x83B0, 0x83A0, 0x8390, 0x8350, 0x8380, 0x83B0, 0x8370, 0x8370, 0x8360, 0x8360, 0x8350, 0x8350, + 0x8350, 0x8350, 0x8350, 0x8340, 0x8350, 0x8350, 0x8350, 0x8350, 0x8350, 0x8340, 0x8350, 0x8350, 0x8340, 0x8350, 0x8350, 0x8350, + 0x8350, 0x8360, 0x8360, 0x8360, 0x8370, 0x8350, 0x8380, 0x8380, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83A0, 0x83C0, 0x83D0, 0x83E0, + 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, + 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x8400, + 0x8410, 0x8410, 0x8430, 0x8440, 0x8450, 0x84D0, 0x85F0, 0xA270, 0xCC20, 0xF470, 0x1B70, 0x4120, 0x6470, 0x7E90, 0x7EB0, 0x7F00, + 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F10, + 0x7F20, 0x7F00, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F70, 0x7EF0, 0x7EB0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, + 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F80, 0x7EF0, + 0x7F10, 0x7F20, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, + 0x7EB0, 0x7EF0, 0x4D90, 0x0FF0, 0xD240, 0x9590, 0x84E0, 0x8490, 0x8460, 0x8490, 0x8430, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, + 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8420, 0x8420, + 0x8440, 0x8460, 0x8480, 0x84C0, 0x8700, 0xC400, 0x0640, 0x4DB0, 0x7EB0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7EF0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F10, 0x7EF0, 0x7F00, 0x7F00, 0x7EF0, 0x7F80, 0x7F00, + 0x7F20, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7F10, 0x7F10, + 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7EE0, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F60, 0x7EF0, 0x7EB0, 0x7F10, 0x7F40, 0x7F10, 0x7ED0, 0x7E80, 0x7F40, 0x7F10, + 0x7EB0, 0x7E70, 0x7E60, 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7E90, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F40, 0x7EF0, 0x7EE0, + 0x7EF0, 0x7ED0, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7EF0, 0x7F30, 0x7EF0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7F10, 0x7F20, 0x7F00, + 0x7EF0, 0x7F60, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7F40, 0x7EF0, 0x7EB0, 0x7EF0, 0x7ED0, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, + 0x7960, 0x5D40, 0x4F90, 0x4DB0, 0x5260, 0x5840, 0x5D90, 0x5E00, 0x5B40, 0x54D0, 0x4C30, 0x4460, 0x3C40, 0x3680, 0x3120, 0x2A20, + 0x22F0, 0x1A40, 0x10A0, 0x05F0, 0xFB90, 0xF240, 0xEAE0, 0xE570, 0xE190, 0xDE30, 0xDBF0, 0xD890, 0xD510, 0xD0C0, 0xCAD0, 0xC5D0, + 0xC0C0, 0xBCB0, 0xB9D0, 0xB810, 0xB810, 0xB8B0, 0xB9B0, 0xBB60, 0xBB90, 0xB980, 0xB4B0, 0xAC20, 0x9FD0, 0x90C0, 0x8750, 0x8520, + 0x84D0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84C0, 0x8530, 0x8CB0, 0xAD10, 0xC270, 0xC760, 0xBAC0, 0x9E70, 0x8660, + 0x84C0, 0x8490, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84B0, 0x84F0, 0x8580, 0x8700, 0x8940, + 0x8C00, 0x9150, 0x9D30, 0xAFB0, 0xC8F0, 0xE260, 0xFB00, 0x10C0, 0x2230, 0x30B0, 0x3C40, 0x4650, 0x50B0, 0x5B00, 0x6490, 0x6D10, + 0x7470, 0x7B20, 0x7E60, 0x7ED0, 0x7F00, 0x7F20, 0x7F10, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, + 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F20, 0x7F20, 0x7F10, + 0x7F10, 0x7F60, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F80, 0x7F00, 0x7ED0, 0x6A90, 0x2140, + 0x1530, 0x0EC0, 0x0A70, 0x08C0, 0x0870, 0x0A70, 0x0CA0, 0x0F50, 0x1300, 0x1660, 0x1B40, 0x1F70, 0x2230, 0x23A0, 0x2180, 0x1CB0, + 0x13B0, 0x05D0, 0xF690, 0xE5B0, 0xD3B0, 0xC080, 0xAC50, 0x9820, 0x88F0, 0x8550, 0x84E0, 0x84B0, 0x84C0, 0x8490, 0x8480, 0x8480, + 0x8470, 0x8470, 0x8470, 0x8490, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x8500, + 0x85B0, 0x8950, 0x9A70, 0xAE60, 0xC020, 0xD1D0, 0xDF30, 0xE920, 0xF060, 0xF350, 0xF390, 0xEFF0, 0xE8A0, 0xDE60, 0xD050, 0xC2F0, + 0xB6D0, 0xAEE0, 0xACE0, 0xB0A0, 0xB980, 0xC680, 0xD590, 0xE810, 0xF900, 0x0A60, 0x1AC0, 0x2910, 0x35F0, 0x3F60, 0x4600, 0x4990, + 0x4940, 0x46D0, 0x3FD0, 0x3560, 0x26B0, 0x1400, 0xFEC0, 0xE590, 0xC980, 0xA8B0, 0x8C30, 0x8520, 0x84C0, 0x84A0, 0x8490, 0x8480, + 0x8470, 0x8470, 0x8410, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84C0, 0x84F0, 0x85E0, 0x8FE0, + 0xA8A0, 0xBEA0, 0xD1F0, 0xE200, 0xF0E0, 0xFB50, 0x0350, 0x0A00, 0x0E80, 0x10D0, 0x1170, 0x0EE0, 0x0B80, 0x0510, 0xFDC0, 0xF5F0, + 0xEC50, 0xE2B0, 0xD890, 0xCDE0, 0xC2F0, 0xB7E0, 0xABC0, 0x9FB0, 0x9300, 0x8A30, 0x8660, 0x8540, 0x84F0, 0x84D0, 0x84E0, 0x84B0, + 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x8500, 0x8570, 0x8830, 0x9EC0, 0xBA90, 0xD830, 0xF620, 0x1360, 0x2E40, 0x4430, 0x5700, + 0x6460, 0x6E90, 0x7600, 0x7A80, 0x7E00, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, + 0x7F10, 0x7F00, 0x7EE0, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x6F50, 0x5080, 0x2A10, 0x0230, 0xD520, 0xA540, + 0x8690, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8490, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x84B0, 0x84D0, 0x8530, 0x8AE0, 0xB430, 0xE0F0, 0x1160, 0x4170, 0x6DC0, 0x7ED0, + 0x7F30, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, + 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F30, 0x7EE0, 0x7ED0, 0x7F00, 0x7F20, + 0x7F50, 0x7ED0, 0x7E90, 0x7F00, 0x7F10, 0x7EE0, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F50, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F30, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F10, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F40, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F60, 0x7F40, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, + 0x7EF0, 0x6120, 0x30C0, 0xFD30, 0xC530, 0x8CB0, 0x84C0, 0x8480, 0x8450, 0x8440, 0x8420, 0x8410, 0x8400, 0x83F0, 0x83F0, 0x83E0, + 0x83E0, 0x83D0, 0x83D0, 0x8390, 0x83D0, 0x83D0, 0x83D0, 0x83B0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83A0, 0x83B0, + 0x83A0, 0x83A0, 0x8380, 0x8390, 0x83C0, 0x8380, 0x83A0, 0x8380, 0x8380, 0x8390, 0x83A0, 0x8370, 0x8380, 0x8310, 0x8380, 0x8380, + 0x83B0, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83F0, 0x83D0, 0x83D0, 0x83D0, 0x8370, 0x83E0, 0x83E0, 0x83F0, 0x83F0, + 0x8430, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8520, 0x86C0, 0x9370, 0xA810, + 0xBAA0, 0xCC60, 0xDF40, 0xEF30, 0xFF20, 0x0D50, 0x1B00, 0x27F0, 0x3300, 0x3E60, 0x48F0, 0x5360, 0x5D40, 0x6600, 0x6FB0, 0x7860, + 0x7EE0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F80, + 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7EE0, + 0x7EC0, 0x7F10, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EC0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, + 0x7F80, 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F90, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F70, + 0x7F00, 0x7EE0, 0x7ED0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, + 0x7E90, 0x7EB0, 0x7F00, 0x7EF0, 0x7EF0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7EB0, + 0x7F20, 0x7EB0, 0x7ED0, 0x7ED0, 0x7F00, 0x7F00, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7EE0, 0x7F40, 0x7F30, 0x7F20, 0x7EF0, 0x7F10, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F20, 0x7EE0, 0x7EF0, + 0x7F70, 0x7F00, 0x7F00, 0x7F10, 0x7ED0, 0x78F0, 0x7140, 0x6910, 0x61E0, 0x59F0, 0x51A0, 0x48F0, 0x4010, 0x3760, 0x2E00, 0x23F0, + 0x1AE0, 0x1140, 0x0810, 0xFEA0, 0xF560, 0xED00, 0xE4D0, 0xDDD0, 0xD6E0, 0xD010, 0xC9A0, 0xC310, 0xBCE0, 0xB6D0, 0xB1B0, 0xADA0, + 0xAAE0, 0xA970, 0xA890, 0xA830, 0xA870, 0xA8E0, 0xA920, 0xA9E0, 0xAA90, 0xAB80, 0xACD0, 0xADD0, 0xAFB0, 0xB150, 0xB2A0, 0xB3C0, + 0xB450, 0xB540, 0xB560, 0xB530, 0xB3D0, 0xB1F0, 0xB030, 0xAD80, 0xAAF0, 0xA820, 0xA5D0, 0xA450, 0xA320, 0xA260, 0xA200, 0xA220, + 0xA360, 0xA530, 0xA900, 0xAD80, 0xB3F0, 0xBCE0, 0xC600, 0xD140, 0xDBF0, 0xE7D0, 0xF4C0, 0x01C0, 0x0FC0, 0x1EB0, 0x2E40, 0x3D80, + 0x4BB0, 0x59E0, 0x6660, 0x7140, 0x7AF0, 0x7F00, 0x7F60, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, + 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7D70, 0x7560, 0x6DA0, 0x6430, 0x5AB0, 0x5120, 0x4690, 0x3D10, 0x32C0, 0x27D0, + 0x1E10, 0x1400, 0x09F0, 0x0180, 0xFA30, 0xF4E0, 0xF020, 0xED40, 0xEBA0, 0xEAB0, 0xEB00, 0xEBB0, 0xED40, 0xEF20, 0xF0D0, 0xF3B0, + 0xF620, 0xF970, 0xFCF0, 0xFF50, 0x0140, 0x0040, 0xFD10, 0xF760, 0xEF50, 0xE630, 0xDC90, 0xD2E0, 0xCAC0, 0xC3E0, 0xBF40, 0xBD00, + 0xBDA0, 0xC190, 0xC890, 0xD2D0, 0xDE90, 0xEB10, 0xF740, 0xFFB0, 0x0500, 0x06C0, 0x0490, 0x00D0, 0xFA80, 0xF320, 0xE9F0, 0xDDF0, + 0xD040, 0xBF80, 0xABF0, 0x9560, 0x8720, 0x8500, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, + 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8450, 0x8430, 0x8430, 0x8440, 0x8430, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8440, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, + 0x83C0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, + 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, + 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8440, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x8500, 0x8590, 0x8820, + 0x9220, 0xA120, 0xAD70, 0xB760, 0xBF60, 0xC570, 0xC8D0, 0xC9C0, 0xC9C0, 0xC830, 0xC610, 0xC470, 0xC2B0, 0xC180, 0xBF30, 0xBC50, + 0xB710, 0xAF70, 0xA570, 0x9860, 0x8BB0, 0x8600, 0x84F0, 0x84C0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, + 0x8450, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8460, 0x84A0, 0x8470, 0x8490, 0x8480, 0x8490, 0x8490, + 0x84A0, 0x84B0, 0x84B0, 0x84D0, 0x84E0, 0x8500, 0x8560, 0x8690, 0x8B00, 0x9820, 0xA6A0, 0xB4D0, 0xC190, 0xCD90, 0xD850, 0xE1B0, + 0xEAD0, 0xF230, 0xF990, 0x0170, 0x09C0, 0x12E0, 0x1C90, 0x26D0, 0x3120, 0x3CF0, 0x47F0, 0x53A0, 0x5E70, 0x6970, 0x72F0, 0x7B40, + 0x7F00, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F90, 0x7F30, 0x7F00, 0x7F40, 0x7F30, 0x7F50, 0x7F40, 0x7EE0, + 0x7F10, 0x7F10, 0x7EF0, 0x7EF0, 0x7EB0, 0x7470, 0x6620, 0x5590, 0x4370, 0x2E30, 0x1800, 0xFEC0, 0xE330, 0xC380, 0xA440, 0x8970, + 0x84F0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83A0, 0x8390, 0x8390, 0x8380, 0x8370, 0x8360, 0x8360, 0x8350, 0x8350, + 0x8350, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8340, 0x8350, + 0x8350, 0x8350, 0x8350, 0x8360, 0x8360, 0x8360, 0x8360, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8370, 0x8380, 0x8380, 0x8380, + 0x8380, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x8400, + 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8470, 0x8480, 0x84A0, 0x84C0, 0x8510, 0x8700, 0x9830, 0xAD10, 0xBE50, 0xCD10, 0xD900, + 0xE450, 0xEDF0, 0xF6E0, 0xFF80, 0x0850, 0x1260, 0x1BA0, 0x2680, 0x3180, 0x3EA0, 0x4C90, 0x5B30, 0x6B70, 0x7A00, 0x7F20, 0x7F10, + 0x7F20, 0x7F20, 0x7ED0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F50, 0x7F00, 0x7F20, + 0x7F00, 0x7F10, 0x7F70, 0x7EE0, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7E60, 0x68E0, 0x5310, 0x3D10, 0x2870, 0x1500, 0x0290, 0xF120, + 0xE1A0, 0xD4D0, 0xC9A0, 0xC030, 0xB820, 0xB150, 0xAC80, 0xA860, 0xA580, 0xA3B0, 0xA260, 0xA1A0, 0xA100, 0xA080, 0x9FF0, 0x9E60, + 0x9C10, 0x9860, 0x9340, 0x8560, 0x8500, 0x84E0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84F0, 0x8550, 0x8800, + 0x9DE0, 0xBB00, 0xD950, 0xF7B0, 0x15A0, 0x31C0, 0x4CC0, 0x67A0, 0x7BC0, 0x7EF0, 0x7ED0, 0x7F00, 0x7EE0, 0x7F30, 0x7F10, 0x7E70, + 0x7ED0, 0x7EB0, 0x7F10, 0x7EF0, 0x7E90, 0x7ED0, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, + 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, 0x7F10, + 0x7F20, 0x7F10, 0x7F10, 0x7F70, 0x7EF0, 0x7F10, 0x7EF0, 0x7F20, 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, + 0x7EF0, 0x7EF0, 0x7F20, 0x7ED0, 0x7E90, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, 0x7F00, 0x7EC0, 0x7F00, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, + 0x7F10, 0x7F20, 0x7F00, 0x7F80, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EE0, 0x7ED0, 0x7EF0, 0x7F60, 0x7F00, 0x7E90, + 0x7EB0, 0x7EB0, 0x7EF0, 0x7F00, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7E90, 0x7EE0, + 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F00, 0x7ED0, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F40, 0x7EF0, + 0x7F20, 0x7F00, 0x7F00, 0x7F50, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7E90, + 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F20, + 0x7EF0, 0x7F10, 0x7EE0, 0x7EC0, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EE0, 0x7F10, 0x7F10, 0x7EE0, 0x7F60, 0x7EF0, + 0x7F20, 0x7F00, 0x7F00, 0x7F50, 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F70, 0x7F10, 0x7EE0, + 0x7EE0, 0x7ED0, 0x7F30, 0x7EF0, 0x7E70, 0x7EC0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7E90, 0x7EE0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7ED0, + 0x7F10, 0x7F00, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F40, 0x7F40, 0x6780, 0x4630, 0x28A0, 0x0CA0, 0xEF90, + 0xCF00, 0xA5A0, 0x86C0, 0x84C0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8470, + 0x8480, 0x84D0, 0x8FB0, 0xEAA0, 0x3190, 0x6730, 0x7EB0, 0x7F20, 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F10, + 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x63C0, 0x3AB0, 0x0D30, 0xDFD0, 0xB580, 0x8F10, 0x8500, 0x84B0, 0x84B0, 0x8470, + 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83E0, 0x83C0, 0x83C0, 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, + 0x8390, 0x8390, 0x8390, 0x8380, 0x8380, 0x8380, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83E0, 0x83A0, 0x8390, 0x8390, + 0x8390, 0x8390, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8390, 0x83F0, 0x83F0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8420, + 0x8450, 0x8440, 0x8450, 0x8460, 0x8480, 0x8490, 0x84B0, 0x84E0, 0x8650, 0xA820, 0xDE50, 0x1F90, 0x6820, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, + 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7EF0, + 0x7F20, 0x7F00, 0x7F20, 0x7F20, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, + 0x7F00, 0x7F10, 0x7F30, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7F20, 0x7EA0, 0x7F10, 0x7F20, 0x7F40, + 0x7EF0, 0x7E90, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7E80, 0x7EA0, 0x7ED0, 0x7F20, 0x7F00, 0x7EC0, 0x7F00, 0x7EB0, 0x7F20, 0x7F20, + 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7ED0, 0x7EF0, + 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, 0x7EF0, 0x7ED0, 0x7F10, 0x7EE0, 0x7EC0, 0x7EF0, 0x7EE0, 0x7F20, + 0x7F10, 0x7E90, 0x7EF0, 0x7EE0, 0x7F10, 0x7F00, 0x7E70, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F10, 0x7F10, + 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F10, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EE0, + 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7EB0, 0x7A40, 0x7550, 0x7060, 0x6B70, 0x6680, 0x6000, 0x5920, 0x5100, 0x4810, + 0x3F50, 0x3580, 0x2CF0, 0x2470, 0x1BE0, 0x1420, 0x0CF0, 0x0610, 0xFF90, 0xF9A0, 0xF3C0, 0xEE70, 0xEAE0, 0xE780, 0xE410, 0xE1A0, + 0xDF40, 0xDDC0, 0xDC90, 0xDB60, 0xDAF0, 0xDAC0, 0xDAE0, 0xDB00, 0xDC20, 0xDD90, 0xDF10, 0xE170, 0xE480, 0xE770, 0xEB70, 0xEDC0, + 0xF030, 0xF2D0, 0xF500, 0xF780, 0xFAB0, 0xFDA0, 0x0020, 0x01B0, 0x0310, 0x0360, 0x0350, 0x0310, 0x0130, 0xFF60, 0xFC80, 0xF930, + 0xF560, 0xF0A0, 0xEB50, 0xE530, 0xDEC0, 0xD860, 0xD140, 0xC900, 0xC020, 0xB6A0, 0xAD60, 0xA360, 0x9930, 0x8FE0, 0x8940, 0x8640, + 0x8540, 0x84F0, 0x84D0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84D0, 0x84F0, 0x8530, + 0x85A0, 0x85F0, 0x8600, 0x85D0, 0x85D0, 0xB680, 0xCEF0, 0xE410, 0xF290, 0xFBF0, 0x0370, 0x0E60, 0x1E00, 0x2E30, 0x3760, 0x2AD0, + 0xFE30, 0xA990, 0x84B0, 0x8460, 0x8440, 0x8420, 0x8410, 0x8400, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x8400, + 0x8420, 0x8440, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, 0x84B0, 0x84E0, 0x8520, 0x8520, 0x84E0, 0x84A0, 0x8470, 0x8460, 0x8440, + 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, + 0x83A0, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8350, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8390, 0x8330, 0x8390, 0x8390, + 0x8390, 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x8370, + 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8370, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, + 0x8390, 0x83C0, 0x83B0, 0x8380, 0x8380, 0x8390, 0x8380, 0x8370, 0x8370, 0x8350, 0x8360, 0x8360, 0x8370, 0x8350, 0x8350, 0x8350, + 0x8360, 0x8340, 0x8340, 0x8340, 0x8350, 0x8340, 0x8340, 0x8370, 0x8360, 0x8340, 0x8340, 0x8380, 0x8350, 0x8350, 0x8350, 0x8380, + 0x8350, 0x8360, 0x8380, 0x8370, 0x8380, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83D0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, + 0x8390, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84D0, 0x8520, 0x8670, 0x8F20, 0xA190, 0xB330, 0xC370, 0xD2E0, 0xE080, + 0xECF0, 0xF7F0, 0x0410, 0x0F20, 0x1C20, 0x2A40, 0x3950, 0x4890, 0x56A0, 0x6410, 0x7080, 0x7C60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, + 0x7F70, 0x7F10, 0x7EB0, 0x7EC0, 0x7ED0, 0x7F30, 0x7F00, 0x7EA0, 0x7ED0, 0x7EE0, 0x7F20, 0x7F20, 0x7E90, 0x7EE0, 0x7EE0, 0x7F10, + 0x7F10, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7E90, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F00, 0x7EF0, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7C00, 0x6F50, 0x6410, 0x59B0, 0x5020, 0x46F0, 0x3E30, 0x3580, 0x2D20, 0x2620, 0x2190, 0x21B0, 0x27D0, + 0x3590, 0x4C30, 0x69F0, 0x7EF0, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F50, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F10, + 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F10, 0x48C0, 0x16C0, 0xEEC0, 0xD730, 0xD1D0, 0xDED0, 0xFA00, + 0x20F0, 0x4740, 0x6880, 0x7E50, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F10, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F00, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F00, + 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F20, + 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7560, 0x6310, 0x4E30, 0x3670, 0x1D20, 0x02A0, 0xE730, 0xCC50, 0xAF20, + 0x9450, 0x8690, 0x84E0, 0x84C0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8460, 0x8430, 0x8440, 0x8490, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8490, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, + 0x8470, 0x8480, 0x84B0, 0x84A0, 0x84B0, 0x84C0, 0x84E0, 0x8520, 0x85F0, 0x8C10, 0xA380, 0xBDB0, 0xDA90, 0xF5B0, 0x0FE0, 0x27C0, + 0x3D50, 0x5030, 0x5F70, 0x6CA0, 0x7610, 0x7DE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EA0, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F30, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7D40, 0x7590, 0x6E20, 0x66C0, 0x5F80, 0x5870, 0x5030, 0x4920, 0x4210, 0x3B90, 0x35E0, + 0x3080, 0x2BF0, 0x2740, 0x2180, 0x1A10, 0x0FB0, 0x0130, 0xEF70, 0xDAC0, 0xC380, 0xAEC0, 0x9D00, 0x8F30, 0x8870, 0x8630, 0x85B0, + 0x8510, 0x84F0, 0x84C0, 0x84C0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, 0x84F0, + 0x8510, 0x8530, 0x8580, 0x8610, 0x8730, 0x8990, 0x8CB0, 0x90D0, 0x9420, 0x9770, 0x9B30, 0x9F30, 0xA510, 0xACD0, 0xB630, 0xC250, + 0xD080, 0xE060, 0xF160, 0x0450, 0x1990, 0x2FF0, 0x49D0, 0x6130, 0x76F0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7ED0, 0x7EE0, + 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, 0x7F00, + 0x7EF0, 0x7F00, 0x7F00, 0x7EC0, 0x7F20, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7F50, 0x7F00, + 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7ED0, 0x7EE0, 0x7ED0, 0x7F60, 0x7F00, 0x7EC0, + 0x7ED0, 0x7ED0, 0x7EF0, 0x7F00, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EE0, 0x7F00, 0x7F10, 0x7F00, 0x7E90, 0x7ED0, + 0x7F00, 0x7EE0, 0x7EF0, 0x7EC0, 0x7F20, 0x7F20, 0x7F10, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7EC0, + 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F40, 0x7F20, 0x7F10, 0x7EF0, 0x7EE0, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F50, + 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F50, 0x7EF0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, + 0x7E90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7EF0, 0x7F00, 0x7F00, 0x7EE0, + 0x7F50, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7EE0, 0x7F80, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, + 0x7F00, 0x7DD0, 0x3C90, 0xFB60, 0xB160, 0x8580, 0x8490, 0x8470, 0x8450, 0x8440, 0x8440, 0x8440, 0x8450, 0x8470, 0x8490, 0x84F0, + 0x9370, 0xD410, 0x0D20, 0x4250, 0x7200, 0x7EA0, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EA0, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F10, 0x7F60, + 0x7F00, 0x7F20, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F30, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7F40, 0x7ED0, + 0x7E90, 0x7EF0, 0x7EE0, 0x7F30, 0x7EE0, 0x7EA0, 0x7ED0, 0x7F10, 0x7F20, 0x7F20, 0x7E90, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F00, + 0x7F20, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F00, 0x7F40, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F80, + 0x7F10, 0x7F20, 0x7F00, 0x7A10, 0x6F90, 0x64F0, 0x5920, 0x4C30, 0x3FB0, 0x32C0, 0x25C0, 0x18C0, 0x0CC0, 0x01C0, 0xF830, 0xF0D0, + 0xEBC0, 0xEA10, 0xEB80, 0xEF50, 0xF770, 0x0040, 0x0C10, 0x18A0, 0x2660, 0x36F0, 0x45B0, 0x54E0, 0x63D0, 0x7110, 0x7C30, 0x7EC0, + 0x7F40, 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, + 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7F00, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EB0, 0x7F00, 0x7F10, 0x7F70, 0x7F00, + 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7EE0, 0x7EF0, 0x7F10, 0x7F10, 0x7EA0, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7E90, + 0x7F10, 0x7EF0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F90, + 0x7F20, 0x7F10, 0x7F20, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F20, 0x7F10, + 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, + 0x7EF0, 0x7F10, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F30, + 0x7F30, 0x7EE0, 0x5370, 0x2A50, 0x02D0, 0xE320, 0xC800, 0xAFF0, 0x9B90, 0x8BE0, 0x8630, 0x8540, 0x84E0, 0x84B0, 0x84A0, 0x8490, + 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8470, 0x8440, 0x8440, 0x8450, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8400, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, + 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83F0, + 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, + 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, + 0x83D0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x8390, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8490, + 0x8490, 0x8480, 0x8480, 0x8440, 0x84A0, 0x84A0, 0x84C0, 0x84D0, 0x84F0, 0x8530, 0x85D0, 0x8840, 0x9210, 0xA0C0, 0xB000, 0xC030, + 0xF970, 0x0860, 0x1820, 0x27C0, 0x3700, 0x4740, 0x5600, 0x6530, 0x7400, 0x7E10, 0x7F00, 0x7EE0, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F10, 0x7F40, 0x7EF0, 0x7F20, 0x7F40, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, + 0x7F60, 0x7ED0, 0x7EB0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7E90, 0x7EF0, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, + 0x7F10, 0x7EA0, 0x7F10, 0x7EF0, 0x7F20, 0x7F00, 0x7EC0, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7F10, 0x7F20, + 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F10, 0x7ED0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EE0, + 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F30, 0x7EF0, 0x7E90, 0x7ED0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7EE0, 0x7F10, 0x7F10, + 0x7F00, 0x7EC0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7EE0, + 0x7EF0, 0x7F70, 0x7F00, 0x7F20, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, 0x7F50, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F00, 0x7F30, 0x7EF0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F40, + 0x7F00, 0x7EB0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, 0x7F00, 0x7F20, 0x7EF0, + 0x7F10, 0x7F40, 0x7EF0, 0x7F30, 0x7F30, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F90, 0x7730, 0x6600, + 0x5650, 0x47A0, 0x3AE0, 0x3050, 0x2730, 0x1FA0, 0x17E0, 0x0F40, 0x0570, 0xF960, 0xEC70, 0xDE40, 0xCF70, 0xC120, 0xB3A0, 0xA740, + 0x9CC0, 0x9190, 0x8A40, 0x8660, 0x8530, 0x84E0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, + 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, + 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8490, 0x84A0, 0x84E0, 0x8560, 0x88B0, 0x9A70, 0xACC0, 0xBD40, 0xCB60, + 0xD830, 0xE2A0, 0xEBF0, 0xF360, 0xF980, 0xFED0, 0x0300, 0x0620, 0x08C0, 0x0A30, 0x0C30, 0x0DE0, 0x0ED0, 0x1010, 0x1080, 0x11D0, + 0x11D0, 0x1110, 0x10F0, 0x1000, 0x0F10, 0x0D70, 0x0BE0, 0x0BB0, 0x0AE0, 0x0AC0, 0x0A60, 0x09C0, 0x08F0, 0x0740, 0x0510, 0x0230, + 0xFE60, 0xFA40, 0xF600, 0xF150, 0xEC30, 0xE5E0, 0xDF30, 0xD880, 0xD160, 0xC9D0, 0xC250, 0xBAE0, 0xB2C0, 0xAAB0, 0xA290, 0x99C0, + 0x9250, 0x8C50, 0x8880, 0x8680, 0x8590, 0x8530, 0x8500, 0x84E0, 0x84D0, 0x84B0, 0x84A0, 0x84A0, 0x8490, 0x8480, 0x8480, 0x8460, + 0x8450, 0x8440, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x8410, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, + 0x83C0, 0x83E0, 0x83C0, 0x83C0, 0x83D0, 0x83C0, 0x83D0, 0x83F0, 0x8400, 0x83D0, 0x83E0, 0x8390, 0x83E0, 0x83F0, 0x8400, 0x83F0, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, + 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8450, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83D0, + 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, + 0x8420, 0x8400, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8490, + 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, + 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, + 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, + 0x8430, 0x8430, 0x8460, 0x8440, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8450, 0x8460, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8470, 0x84A0, + 0x84B0, 0x84D0, 0x8510, 0x8620, 0x9000, 0xA780, 0xBE40, 0xD390, 0xE950, 0xFC10, 0x0C70, 0x1C40, 0x2AE0, 0x37E0, 0x43B0, 0x4EA0, + 0x58C0, 0x6150, 0x6860, 0x6DD0, 0x7280, 0x7610, 0x78B0, 0x7B20, 0x7C40, 0x7D50, 0x7DC0, 0x7E10, 0x7E50, 0x7E90, 0x7EA0, 0x7EC0, + 0x7EB0, 0x7EB0, 0x7E70, 0x7E40, 0x7DF0, 0x7D20, 0x7CA0, 0x7C30, 0x7C30, 0x7C90, 0x7D40, 0x7E40, 0x7F00, 0x7F20, 0x7F20, 0x7EF0, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7F30, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F30, 0x7F20, 0x7F00, 0x7F00, 0x7EB0, + 0x7F00, 0x7ED0, 0x7F10, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F60, 0x7F00, 0x7ED0, 0x7EF0, 0x7F00, 0x7F40, + 0x7EF0, 0x7EB0, 0x7EF0, 0x7EF0, 0x7F30, 0x7F20, 0x7EC0, 0x7F40, 0x7F10, 0x7F20, 0x7EE0, 0x7E90, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, + 0x7EB0, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7C10, 0x71B0, 0x67E0, 0x5F80, 0x56F0, 0x4FE0, 0x49E0, 0x4450, 0x4090, 0x3D60, + 0x3A80, 0x3830, 0x35B0, 0x33E0, 0x3240, 0x2FF0, 0x2E60, 0x2B20, 0x2890, 0x24C0, 0x2040, 0x1C40, 0x1790, 0x12F0, 0x0DF0, 0x0850, + 0x03B0, 0xFEE0, 0xF8F0, 0xF350, 0xEDB0, 0xE900, 0xE4B0, 0xE180, 0xDEA0, 0xDCF0, 0xDD10, 0xDE10, 0xE0A0, 0xE440, 0xE910, 0xEEA0, + 0xF520, 0xFC90, 0x0330, 0x0900, 0x0E50, 0x12D0, 0x16E0, 0x19E0, 0x1CA0, 0x1F70, 0x21C0, 0x2400, 0x25D0, 0x27A0, 0x29F0, 0x3760, + 0x3DB0, 0x4470, 0x4BA0, 0x5410, 0x5B00, 0x6100, 0x6680, 0x6A30, 0x6DA0, 0x6F40, 0x7130, 0x72E0, 0x7460, 0x7740, 0x7A40, 0x7D80, + 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F80, 0x7F10, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F70, 0x7EF0, + 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F00, 0x7ED0, 0x7EB0, 0x7EE0, 0x7F50, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, + 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7EA0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F30, + 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F30, 0x7F00, 0x7A40, 0x7610, 0x7290, 0x6E20, 0x69D0, 0x63F0, 0x5CA0, 0x53A0, + 0x4890, 0x3F30, 0x34C0, 0x2A70, 0x1FF0, 0x15A0, 0x0BE0, 0x02D0, 0xF970, 0xF0A0, 0xE7E0, 0xDFA0, 0xB9E0, 0xB030, 0xA5D0, 0x9AA0, + 0x9040, 0x88E0, 0x85E0, 0x8520, 0x84E0, 0x84C0, 0x84A0, 0x8490, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8480, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84C0, 0x8530, 0x8AF0, + 0xAE50, 0xCF10, 0xEC50, 0x0560, 0x19C0, 0x2950, 0x35C0, 0x3DF0, 0x4550, 0x4C70, 0x5430, 0x5D60, 0x6690, 0x70A0, 0x79E0, 0x7F50, + 0x7F10, 0x7EC0, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7EA0, 0x7ED0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, + 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EC0, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, 0x7EE0, + 0x7F50, 0x7F10, 0x7F20, 0x7EF0, 0x7D30, 0x6DF0, 0x5DF0, 0x4CF0, 0x3C30, 0x2A90, 0x18F0, 0x07C0, 0xF560, 0xE540, 0xD5A0, 0xC6B0, + 0xB920, 0xABB0, 0x9E90, 0x9170, 0x88C0, 0x85C0, 0x84F0, 0x84D0, 0x84B0, 0x8490, 0x8490, 0x8480, 0x8470, 0x8460, 0x8460, 0x8450, + 0x8490, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8450, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8400, 0x8420, 0x8420, + 0x8430, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x84A0, 0x8470, 0x8470, 0x8470, 0x8490, 0x84B0, 0x84D0, 0x8510, + 0x8610, 0x8C40, 0x9F60, 0xB150, 0xC400, 0xD3C0, 0xE330, 0xF180, 0xFE00, 0x09C0, 0x13D0, 0x1C30, 0x22B0, 0x2810, 0x2BD0, 0x2EF0, + 0x32A0, 0x36D0, 0x3CD0, 0x44B0, 0x4EA0, 0x5A50, 0x66A0, 0x71C0, 0x7B50, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7F20, 0x7F80, + 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F30, 0x7EB0, 0x7EA0, 0x7890, 0x6C70, 0x60F0, 0x56C0, 0x4DB0, 0x47A0, 0x43A0, 0x40B0, 0x3F00, + 0x3D00, 0x3A10, 0x3610, 0x31A0, 0x2E60, 0x2A80, 0x28B0, 0x27B0, 0x2860, 0x29E0, 0x2A40, 0x2960, 0x2650, 0x1FF0, 0x18B0, 0x0FE0, + 0x0670, 0xFDD0, 0xF5E0, 0xEE90, 0xE830, 0xE230, 0xDCA0, 0xD690, 0xD080, 0xCA70, 0xC570, 0xC1A0, 0xBEE0, 0xBD40, 0xBDE0, 0xBF80, + 0xC380, 0xC820, 0xCE50, 0xD5B0, 0xDD90, 0xE710, 0xF0B0, 0xFB30, 0x0660, 0x1140, 0x1C80, 0x26E0, 0x30A0, 0x3950, 0x40B0, 0x4740, + 0x4C10, 0x5110, 0x5530, 0x5840, 0x5BC0, 0x5E00, 0x60B0, 0x63C0, 0x65D0, 0x68E0, 0x6B80, 0x6E80, 0x7190, 0x73F0, 0x7670, 0x78C0, + 0x7B00, 0x7CE0, 0x7E40, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, + 0x7EB0, 0x7E10, 0x7D40, 0x7C80, 0x7BF0, 0x7B70, 0x7B20, 0x7A90, 0x7A70, 0x7AA0, 0x7B90, 0x7C40, 0x7D70, 0x7E60, 0x7EE0, 0x7F30, + 0x7F30, 0x7F40, 0x7F30, 0x7F00, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F40, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F20, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, 0x7F20, 0x7F20, 0x6790, 0x48A0, 0x2A70, 0x0E50, 0xF480, 0xDD60, 0xC6D0, 0xB480, + 0xA360, 0x93C0, 0x8990, 0x85F0, 0x8520, 0x84E0, 0x84C0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8480, 0x84C0, + 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x84D0, 0x84B0, 0x84E0, 0x8530, 0x8690, 0x8EB0, 0xA060, 0xB150, 0xC2D0, 0xD4B0, 0xE7B0, + 0xFC30, 0x11E0, 0x29E0, 0x3F70, 0x50E0, 0x5C90, 0x5FB0, 0x5920, 0x46C0, 0x2810, 0xFEF0, 0xCAC0, 0x9860, 0x8530, 0x84B0, 0x8490, + 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8410, 0x8470, 0x8480, 0x84B0, 0x8520, 0x91E0, 0xBC50, 0xD5C0, 0xE310, + 0xE710, 0xE560, 0xE220, 0xE040, 0xE0D0, 0xE3A0, 0xE780, 0xEA50, 0xEB70, 0xE770, 0xDDD0, 0xCD40, 0xB5B0, 0x98F0, 0x86C0, 0x8500, + 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8440, 0x8450, 0x8460, 0x8480, + 0x84A0, 0x84D0, 0x8550, 0x8EE0, 0xB030, 0xD000, 0xF050, 0x10E0, 0x3090, 0x4E50, 0x6930, 0x7CA0, 0x7F10, 0x7F00, 0x7EA0, 0x7EF0, + 0x7EF0, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F00, 0x7ED0, 0x7EF0, 0x7EA0, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F20, + 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F30, 0x7EE0, 0x7F40, 0x7F10, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, + 0x7EF0, 0x7EF0, 0x7F60, 0x7ED0, 0x7ED0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7EC0, 0x7F10, 0x7F10, 0x7F30, 0x7EC0, 0x7E90, 0x7EF0, + 0x7F10, 0x7F20, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7EC0, 0x7F10, 0x7EF0, 0x7EE0, 0x7F10, 0x7F00, 0x7F30, 0x7F00, + 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F70, 0x7F00, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EB0, 0x7EE0, 0x7ED0, 0x7F70, 0x7F20, 0x7EC0, 0x7ED0, 0x7EB0, 0x7F10, 0x7EF0, 0x7E90, 0x7EB0, + 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7E90, 0x7F00, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F20, 0x7F20, + 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7EE0, 0x7EF0, 0x7F50, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7ED0, 0x7F10, + 0x7EF0, 0x7EE0, 0x7F50, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7EF0, 0x7F00, 0x7F50, 0x7ED0, 0x7EA0, 0x7EE0, + 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7EB0, 0x7F00, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EE0, 0x7F10, + 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7ED0, 0x7F00, 0x7F40, 0x7EB0, 0x7F00, + 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F00, 0x7EF0, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F40, 0x7F10, + 0x7F10, 0x7F00, 0x7EF0, 0x7F50, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7E80, 0x7C90, 0x7A30, 0x77A0, 0x74A0, 0x7150, 0x6DB0, + 0x69F0, 0x6650, 0x6270, 0x5EA0, 0x5A10, 0x55D0, 0x5120, 0x4BB0, 0x46E0, 0x4000, 0x39B0, 0x3290, 0x2AF0, 0x23F0, 0x1D00, 0x15C0, + 0x0EF0, 0x0710, 0xFFB0, 0xF880, 0xF170, 0xEB20, 0xE4F0, 0xDF90, 0xDAC0, 0xD5B0, 0xD1C0, 0xCD30, 0xC970, 0xC5C0, 0xC1D0, 0xBE60, + 0xBA00, 0xB6A0, 0xB2F0, 0xAF60, 0xAB90, 0xA7D0, 0xA450, 0xA0B0, 0x9CC0, 0x9930, 0x9530, 0x9160, 0x8D70, 0x8A50, 0x8860, 0x8700, + 0x8640, 0x85C0, 0x8570, 0x8540, 0x8520, 0x8510, 0x8500, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, + 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x84F0, 0x8520, 0x84D0, 0x84C0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, + 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84A0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84D0, 0x84E0, 0x84F0, 0x8520, 0x8580, + 0x8670, 0x8940, 0x9190, 0x9F20, 0xAC70, 0xBAC0, 0xC990, 0xD870, 0xE720, 0xF440, 0x0090, 0x0B80, 0x1670, 0x2050, 0x2850, 0x3000, + 0x3480, 0x35D0, 0x3510, 0x3100, 0x2BA0, 0x24B0, 0x1E50, 0x18A0, 0x1400, 0x1190, 0x1170, 0x13C0, 0x1880, 0x1F90, 0x2800, 0x2F90, + 0x3670, 0x3D40, 0x4260, 0x4650, 0x48F0, 0x4960, 0x48C0, 0x4410, 0x3D20, 0x3440, 0x29B0, 0x1F90, 0x1420, 0x0840, 0xFC10, 0xEF70, + 0xE090, 0xD110, 0xC090, 0xAEE0, 0x9B40, 0x8A60, 0x8550, 0x84D0, 0x84B0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8420, + 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8460, 0x8450, 0x8460, 0x8470, 0x8470, 0x8480, + 0x84A0, 0x84D0, 0x8550, 0x8C10, 0xAB40, 0xC8B0, 0xE510, 0xFC50, 0x0FB0, 0x1EF0, 0x2AA0, 0x32C0, 0x3790, 0x3A80, 0x3AC0, 0x3960, + 0x3540, 0x2EF0, 0x2610, 0x19B0, 0x0B00, 0xF870, 0xE2F0, 0xCC60, 0xB210, 0x98B0, 0x87D0, 0x8500, 0x84C0, 0x8490, 0x8480, 0x8470, + 0x8450, 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, + 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x8490, 0x84A0, 0x8490, 0x8490, 0x8480, + 0x84A0, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8450, 0x8450, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, 0x8420, 0x8420, 0x8420, + 0x8420, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8450, 0x8440, + 0x8440, 0x8460, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8480, 0x8480, 0x8480, + 0x8480, 0x8480, 0x8480, 0x8480, 0x8470, 0x8470, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8450, 0x8460, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8480, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, + 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8490, 0x8450, 0x8450, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, + 0x8450, 0x8450, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8460, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8460, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, + 0x84B0, 0x84D0, 0x84F0, 0x8540, 0x8630, 0x8960, 0x9230, 0x9DB0, 0xA810, 0xB270, 0xBBD0, 0xC560, 0xCE70, 0xD8C0, 0xE260, 0xEBD0, + 0xF5C0, 0xFE90, 0x0690, 0x0CB0, 0x1130, 0x1560, 0x1930, 0x1D70, 0x21C0, 0x2570, 0x2980, 0x2D60, 0x3140, 0x33B0, 0x3510, 0x3620, + 0x3500, 0x3270, 0x2DA0, 0x26C0, 0x1E90, 0x1400, 0x0800, 0xFB40, 0xEB80, 0xDD90, 0xCF10, 0xC0E0, 0xB3A0, 0xA700, 0x9B50, 0x90A0, + 0x8900, 0x85C0, 0x8500, 0x84C0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8400, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, + 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x8400, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x8400, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x83C0, 0x8410, 0x8410, 0x8410, 0x8440, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8440, 0x8430, 0x8440, 0x8450, + 0x8450, 0x8460, 0x8470, 0x8470, 0x8490, 0x84A0, 0x84C0, 0x8500, 0x85C0, 0x8730, 0x8B90, 0x9360, 0x9A90, 0xA260, 0xAB90, 0xB6D0, + 0xC420, 0xD270, 0xE120, 0xEEF0, 0xFB60, 0x03C0, 0x0810, 0x0770, 0x0360, 0xFBE0, 0xF1B0, 0xE570, 0xD790, 0xC890, 0xBF00, 0xBDF0, + 0xCA50, 0xE430, 0x0B90, 0x39A0, 0x66C0, 0x7EF0, 0x7EA0, 0x7EC0, 0x7EC0, 0x7F10, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F10, + 0x7EA0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F00, + 0x7F60, 0x7EF0, 0x7F20, 0x7F00, 0x7F00, 0x7F90, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7F00, 0x7F40, + 0x7EC0, 0x7E90, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F50, 0x7ED0, 0x7E70, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7EC0, 0x7F10, 0x7EF0, + 0x7EE0, 0x7EF0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7EF0, 0x7F00, 0x7F10, 0x7F00, 0x7F30, 0x7EE0, 0x7EF0, + 0x7F30, 0x7F10, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F70, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, 0x7F00, + 0x7F00, 0x7F50, 0x7F10, 0x7EA0, 0x7EC0, 0x7ED0, 0x7F30, 0x7EE0, 0x7E90, 0x7ED0, 0x7EE0, 0x7F20, 0x7F10, 0x7ED0, 0x7EF0, 0x7EE0, + 0x7EF0, 0x7ED0, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7EE0, 0x7E90, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, + 0x7F40, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7EF0, 0x7F80, 0x7F10, 0x7F20, 0x7F10, + 0x7EF0, 0x7F70, 0x7F00, 0x7F10, 0x7EF0, 0x7EE0, 0x7F60, 0x7F10, 0x7D30, 0x6860, 0x56E0, 0x4670, 0x3700, 0x29F0, 0x1EF0, 0x1430, + 0x09B0, 0x0040, 0xF740, 0xEF10, 0xE720, 0xDF70, 0xD9E0, 0xD460, 0xD0A0, 0xCCD0, 0xC970, 0xC620, 0xC2C0, 0xBEC0, 0xB9E0, 0xB4E0, + 0xB040, 0xAB20, 0xA6F0, 0xA460, 0xA270, 0xA2D0, 0xA3A0, 0xA630, 0xAA30, 0xAF90, 0xB700, 0xC180, 0xCEF0, 0xDF80, 0xF340, 0x0A40, + 0x24C0, 0x3EC0, 0x5690, 0x6990, 0x77E0, 0x7E70, 0x7F70, 0x7EF0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7ED0, 0x7F10, 0x7F00, + 0x7F30, 0x7ED0, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7F10, 0x7E10, 0x6C70, 0x5D90, 0x5200, 0x4890, 0x4260, 0x3E50, + 0x3D50, 0x3E10, 0x4140, 0x4560, 0x4A00, 0x4F40, 0x5340, 0x5590, 0x5630, 0x5470, 0x5260, 0x4F50, 0x4C30, 0x49F0, 0x48F0, 0x4A10, + 0x4BC0, 0x4DE0, 0x5110, 0x5370, 0x56A0, 0x5940, 0x5CB0, 0x6070, 0x6540, 0x6B10, 0x70F0, 0x7740, 0x7CC0, 0x7E90, 0x7EB0, 0x7EF0, + 0x7F50, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F00, 0x7010, 0x5E00, 0x4B20, 0x3900, 0x2850, + 0x1C90, 0x1340, 0x0F40, 0x0E90, 0x1120, 0x1600, 0x1BD0, 0x22B0, 0x2960, 0x2E60, 0x31B0, 0x3270, 0x30C0, 0x2D50, 0x2A10, 0x2860, + 0x2960, 0x2D90, 0x37F0, 0x4900, 0x5D50, 0x7200, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F60, 0x7F00, 0x7F00, 0x7F00, 0x7ED0, + 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F10, 0x7F40, 0x7ED0, 0x7EB0, 0x7F00, 0x7F00, 0x7F10, 0x7E90, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, + 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F10, 0x7F20, 0x7EF0, 0x7EF0, 0x7F10, 0x7EF0, 0x7F30, 0x7F20, + 0x7F00, 0x7590, 0x6B50, 0x61F0, 0x5AE0, 0x57C0, 0x5A10, 0x6170, 0x6C60, 0x7890, 0x7EF0, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F20, + 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7200, 0x6030, 0x4F20, 0x3F70, 0x32A0, 0x28D0, 0x2130, 0x1C60, 0x1970, 0x18B0, 0x1A10, 0x1D30, 0x2350, 0x2C30, + 0x3860, 0x4760, 0x57A0, 0x68C0, 0x7660, 0x7E80, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7F30, 0x7F20, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7EC0, + 0x7210, 0x63F0, 0x5470, 0x4480, 0x34E0, 0x2530, 0x1660, 0x07B0, 0xFB50, 0xF080, 0xE650, 0xDD70, 0xD550, 0xCD60, 0xC560, 0xBD70, + 0xB480, 0xABA0, 0xA1C0, 0x9630, 0x8B30, 0x8620, 0x8500, 0x84C0, 0x84B0, 0x8480, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, + 0x8450, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8430, + 0x8420, 0x8420, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, + 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8410, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, + 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8460, + 0x8470, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, 0x84B0, 0x84C0, 0x84C0, 0x84D0, + 0x84E0, 0x84F0, 0x8510, 0x8510, 0x8520, 0x8520, 0x8520, 0x8540, 0x8570, 0x8620, 0x8830, 0x8F00, 0x99A0, 0x9F60, 0xA220, 0xA020, + 0x9C50, 0x96C0, 0x9190, 0x8D80, 0x8B00, 0x89D0, 0x8990, 0x89C0, 0x8AF0, 0x8D30, 0x92A0, 0x9B90, 0xA6F0, 0xB5B0, 0xC700, 0xD7F0, + 0xE850, 0xF830, 0x0670, 0x1390, 0x1FF0, 0x2CE0, 0x38C0, 0x4690, 0x52C0, 0x5E40, 0x68B0, 0x71B0, 0x7970, 0x7E40, 0x7F50, 0x7F20, + 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7E90, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7E70, 0x7EC0, 0x7ED0, 0x7F10, 0x7F20, 0x7EC0, + 0x7F10, 0x7F10, 0x7F10, 0x7F10, 0x7EB0, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F40, 0x7F30, 0x7E00, 0x7540, 0x6B10, 0x5FF0, + 0x5360, 0x44C0, 0x35F0, 0x2520, 0x1240, 0xFF50, 0xEAB0, 0xD670, 0xC070, 0xAA80, 0x9450, 0x8750, 0x8510, 0x84D0, 0x84A0, 0x8490, + 0x8480, 0x8470, 0x8460, 0x8450, 0x8440, 0x8440, 0x8430, 0x8420, 0x8420, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83E0, 0x8400, 0x83D0, + 0x83C0, 0x83D0, 0x83C0, 0x83B0, 0x83B0, 0x83E0, 0x83B0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83F0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83B0, 0x83A0, 0x83B0, + 0x83A0, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, + 0x8400, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84D0, 0x8520, 0x8640, + 0x8C30, 0x9C40, 0xAA60, 0xB710, 0xC240, 0xEB00, 0xF3D0, 0xFBF0, 0x0380, 0x0C40, 0x1530, 0x1F60, 0x2A30, 0x3590, 0x4310, 0x5160, + 0x5FF0, 0x6E30, 0x7AB0, 0x7F00, 0x7F10, 0x7F60, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7E90, 0x7F10, 0x7EF0, 0x7F70, + 0x7F00, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7EE0, 0x7EA0, 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F10, + 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F50, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, + 0x7F80, 0x7F10, 0x7F20, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EF0, 0x7EF0, 0x7EE0, 0x7F40, 0x7F10, 0x7EE0, 0x7EE0, 0x7ED0, 0x7F50, + 0x7F20, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F40, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7E90, 0x7F10, 0x7F20, + 0x7EC0, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7EF0, 0x7F00, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, + 0x7F30, 0x7EF0, 0x7F00, 0x7EF0, 0x7F10, 0x7F60, 0x7F00, 0x7EF0, 0x7F20, 0x7F10, 0x7F90, 0x7EF0, 0x7EE0, 0x7EE0, 0x7EF0, 0x7F30, + 0x7F00, 0x7ED0, 0x7A80, 0x6A20, 0x5970, 0x4850, 0x3630, 0x23E0, 0x1140, 0xFE30, 0xE9B0, 0xD640, 0x8E50, 0x8670, 0x8500, 0x84D0, + 0x84B0, 0x84A0, 0x84B0, 0x8480, 0x8470, 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, + 0x8460, 0x8460, 0x8470, 0x8460, 0x8470, 0x8470, 0x84A0, 0x8470, 0x8480, 0x8480, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84B0, 0x84B0, + 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84B0, 0x84C0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x8530, + 0x8520, 0x8570, 0x8630, 0x87A0, 0x8B70, 0x9260, 0x9AC0, 0xA240, 0xA9B0, 0xB2A0, 0xBA20, 0xC1F0, 0xC960, 0xD060, 0xD810, 0xE000, + 0xE8A0, 0xF1A0, 0xFBF0, 0x06E0, 0x1240, 0x1ED0, 0x2C30, 0x3A60, 0x4AC0, 0x5A50, 0x6970, 0x77C0, 0x7EF0, 0x7F10, 0x7F00, 0x7F60, + 0x7EF0, 0x7F30, 0x7F20, 0x7F00, 0x7F90, 0x7F00, 0x7F40, 0x7F10, 0x7EF0, 0x7F70, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F00, 0x7F50, 0x7F10, + 0x7EE0, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7E70, 0x7ED0, 0x7EB0, 0x7F20, 0x7EF0, 0x7E90, 0x7EB0, 0x7F00, 0x7F10, 0x7F10, 0x7EA0, + 0x7ED0, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F60, + 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F70, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7EF0, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7EF0, 0x7F00, 0x7F30, + 0x7F10, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F20, 0x7F20, 0x7F30, + 0x7F30, 0x7F40, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F20, + 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F30, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F30, + 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7EE0, 0x7F10, 0x7F30, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F20, + 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F40, 0x7F30, 0x7460, 0x5E10, 0x42A0, 0x2420, 0x02E0, 0xDFC0, 0xBB80, 0x9760, 0x8580, + 0x84C0, 0x8490, 0x8470, 0x8460, 0x8450, 0x8440, 0x8430, 0x8430, 0x8410, 0x8410, 0x8420, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, + 0x83E0, 0x83E0, 0x83E0, 0x8410, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x83F0, 0x83F0, 0x83F0, 0x83F0, + 0x83E0, 0x83F0, 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x83A0, 0x8390, 0x8390, 0x8380, + 0x8390, 0x8390, 0x83A0, 0x83A0, 0x83A0, 0x83A0, 0x83B0, 0x83C0, 0x83C0, 0x83D0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8480, 0x8490, 0x84A0, + 0x84D0, 0x8570, 0x92F0, 0xB400, 0xD110, 0xE9B0, 0xFDC0, 0x0DB0, 0x1AB0, 0x26A0, 0x3260, 0x3FF0, 0x4F00, 0x5E00, 0x6CF0, 0x7A30, + 0x7F00, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F10, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7EF0, 0x62A0, 0x3C70, 0x1460, 0xE820, + 0xB980, 0x8C80, 0x84E0, 0x84A0, 0x8480, 0x8470, 0x8460, 0x8460, 0x8460, 0x8460, 0x8460, 0x8470, 0x8470, 0x8470, 0x8490, 0x84B0, + 0x84F0, 0x8880, 0xB970, 0xEC10, 0x1C00, 0x46A0, 0x6800, 0x7E00, 0x7EA0, 0x7ED0, 0x7EB0, 0x7F20, 0x7F10, 0x7E90, 0x7F10, 0x7F00, + 0x7EF0, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F60, 0x7EF0, 0x7F10, + 0x7F10, 0x7F00, 0x7F60, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F70, 0x7EE0, 0x7EC0, 0x7EF0, 0x7F10, 0x7F60, 0x7ED0, 0x7ED0, 0x7F00, + 0x7F00, 0x7F10, 0x7EB0, 0x7E70, 0x7EE0, 0x7EF0, 0x7F30, 0x7EC0, 0x7E90, 0x7F10, 0x7F00, 0x7F00, 0x7F10, 0x7EB0, 0x7F00, 0x7F10, + 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7F20, 0x7F00, 0x7F10, 0x7F10, 0x7EF0, 0x7F60, 0x7EF0, 0x7F10, + 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, 0x7F20, 0x7EF0, 0x7EF0, 0x7F60, 0x7EE0, 0x7F10, 0x7EE0, 0x7EE0, 0x7F50, 0x7F10, 0x7EB0, 0x7EE0, + 0x7ED0, 0x7F10, 0x7F00, 0x7EC0, 0x7EB0, 0x7EB0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7EA0, + 0x7ED0, 0x7ED0, 0x7F00, 0x7EE0, 0x7E90, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7EA0, 0x7F00, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F40, + 0x7F10, 0x7F20, 0x7EF0, 0x7F00, 0x7F60, 0x7F20, 0x7F10, 0x7F10, 0x7EF0, 0x7F40, 0x7EF0, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, 0x7F00, + 0x7F00, 0x7F10, 0x7F10, 0x7F30, 0x7EF0, 0x7ED0, 0x7EF0, 0x7EE0, 0x7F50, 0x7ED0, 0x7EA0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, + 0x7EF0, 0x7F00, 0x7EF0, 0x7EF0, 0x7EB0, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7EC0, 0x7F40, 0x7F10, 0x7F10, 0x7F20, 0x7EF0, 0x7F20, + 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, 0x7F10, 0x7C30, 0x6F60, 0x63F0, 0x5930, 0x4E20, 0x4440, 0x3A10, 0x2FF0, 0x26E0, + 0x1CE0, 0x1380, 0x0A00, 0x0140, 0xF8D0, 0xF030, 0xE860, 0xE0D0, 0xD990, 0xD400, 0xCE90, 0xCAB0, 0xC7D0, 0xC660, 0xC680, 0xC7D0, + 0xCA80, 0xCD10, 0xD0C0, 0xD570, 0xD920, 0xDCC0, 0xDF70, 0xE020, 0xDFE0, 0xDCC0, 0xD7D0, 0xD060, 0xC4E0, 0xB810, 0xA730, 0x93E0, + 0x8710, 0x84F0, 0x84B0, 0x8480, 0x8470, 0x8450, 0x8430, 0x8420, 0x8410, 0x83F0, 0x83F0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83C0, + 0x83C0, 0x83C0, 0x83C0, 0x83D0, 0x83D0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8410, 0x8420, 0x8430, 0x8430, 0x8440, 0x8440, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x84B0, 0x84C0, 0x84E0, + 0x8520, 0x8580, 0x8690, 0x8890, 0x8C50, 0x9140, 0x96C0, 0x9C20, 0xA150, 0xA640, 0xAB20, 0xB050, 0xB510, 0xB980, 0xBE10, 0xC320, + 0xC800, 0xCDC0, 0xD310, 0xD960, 0xE0C0, 0xE890, 0xF150, 0xFAB0, 0x0520, 0x10D0, 0x1C70, 0x29A0, 0x3720, 0x4670, 0x54C0, 0x62C0, + 0x7090, 0x7C10, 0x7F00, 0x7EF0, 0x7E90, 0x7F00, 0x7ED0, 0x7F10, 0x7F20, 0x7EA0, 0x7F00, 0x7F10, 0x7F30, 0x7EE0, 0x7EA0, 0x7EF0, + 0x7F10, 0x7F20, 0x7F10, 0x7E90, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7EE0, 0x7EF0, 0x7F30, 0x7F20, 0x7F60, 0x7F10, + 0x7F10, 0x7F10, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7EF0, 0x7F80, 0x7F00, 0x7F00, 0x7F10, 0x7F00, 0x7F70, 0x7F10, 0x7EB0, + 0x7EE0, 0x7ED0, 0x7F50, 0x7F20, 0x7ED0, 0x7ED0, 0x7EE0, 0x7F30, 0x7F10, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7E70, 0x7EC0, + 0x7F10, 0x7F20, 0x7F20, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F20, 0x7F00, 0x7F10, 0x7F20, 0x7F10, 0x7F10, 0x7F00, + 0x7EF0, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, + 0x7F10, 0x7F10, 0x7F10, 0x7F20, 0x7F40, 0x7F30, 0x7F30, 0x7F00, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F10, 0x7F30, 0x7F20, 0x7F40, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F50, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F30, 0x7F40, 0x7F40, 0x7F30, + 0x75F0, 0x6AC0, 0x6080, 0x5750, 0x5100, 0x4BD0, 0x4710, 0x41D0, 0x3BC0, 0x34C0, 0x2CD0, 0x24A0, 0x1B50, 0x1300, 0x0B10, 0x0400, + 0xFD80, 0xF790, 0xF270, 0xEDD0, 0xEA10, 0xE6D0, 0xE460, 0xE250, 0xE0F0, 0xDF30, 0xDD50, 0xDB60, 0xD8A0, 0xD490, 0xCDF0, 0xC5A0, + 0xBAD0, 0xAD50, 0x9D00, 0x8C90, 0x85F0, 0x84F0, 0x84B0, 0x8490, 0x8480, 0x8470, 0x8460, 0x8450, 0x8450, 0x8440, 0x8430, 0x8430, + 0x8420, 0x8420, 0x8410, 0x8400, 0x8410, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, 0x8400, + 0x8410, 0x8410, 0x8430, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, 0x8460, 0x8460, 0x8460, 0x84A0, 0x8480, 0x84B0, 0x8490, + 0x84B0, 0x84C0, 0x84E0, 0x8510, 0x85D0, 0x8840, 0x9170, 0x9F60, 0xAC30, 0xB920, 0xC600, 0xD2A0, 0xDF50, 0xED00, 0xF9A0, 0x0650, + 0x12F0, 0x1F70, 0x2BF0, 0x37E0, 0x4350, 0x4EF0, 0x5A40, 0x6550, 0x6F30, 0x7870, 0x7EA0, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F30, + 0x7F30, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7F10, 0x7F20, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7F20, 0x7F40, 0x7F50, + 0x7F30, 0x7FC0, 0x7F40, 0x7EF0, 0x7EF0, 0x7EF0, 0x7EF0, 0x7F30, 0x7E90, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EA0, 0x7EC0, 0x7EF0, + 0x7F10, 0x7EF0, 0x7E90, 0x7EB0, 0x7EE0, 0x7EF0, 0x7F10, 0x7EA0, 0x7F40, 0x7F10, 0x7F10, 0x7EF0, 0x7E90, 0x7F10, 0x7EE0, 0x7EE0, + 0x7EF0, 0x7F00, 0x7F30, 0x7F00, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F20, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EF0, 0x7F30, + 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F20, 0x7EE0, 0x7F40, 0x7EE0, 0x7F00, 0x7EF0, 0x7F10, 0x7F70, 0x7F00, 0x7EC0, 0x7EF0, 0x7EF0, + 0x7F70, 0x7ED0, 0x7EA0, 0x7EE0, 0x7EF0, 0x7F10, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F10, 0x7EB0, 0x7F10, 0x7EE0, 0x7EF0, + 0x7F10, 0x7F00, 0x7EF0, 0x7F10, 0x7F20, 0x7F20, 0x7F00, 0x7F50, 0x7EF0, 0x7F20, 0x7EF0, 0x7F00, 0x7F60, 0x7EF0, 0x7F10, 0x7F20, + 0x7F20, 0x7F80, 0x7F10, 0x7EF0, 0x7F10, 0x7F10, 0x7F70, 0x7EF0, 0x7EE0, 0x7EF0, 0x7EF0, 0x7F60, 0x7F20, 0x6C80, 0x5570, 0x3F10, + 0x2BF0, 0x1DB0, 0x12E0, 0x0CA0, 0x0890, 0x0600, 0x0370, 0x0090, 0xFE00, 0xFB20, 0xF900, 0xF870, 0xFAB0, 0xFFA0, 0x06C0, 0x1050, + 0x1B20, 0x2680, 0x3230, 0x3D30, 0x46E0, 0x5060, 0x57C0, 0x5EB0, 0x6400, 0x6850, 0x6D30, 0x7160, 0x75C0, 0x7A10, 0x7DE0, 0x7F00, + 0x7F00, 0x7F70, 0x7F20, 0x7F40, 0x7ED0, 0x7F10, 0x7F60, 0x7EE0, 0x7ED0, 0x7F10, 0x7EF0, 0x7F50, 0x7F00, 0x7EE0, 0x7F00, 0x7D80, + 0x77F0, 0x7270, 0x6CE0, 0x6830, 0x64B0, 0x61F0, 0x5FF0, 0x5CF0, 0x59E0, 0x5540, 0x4E50, 0x4710, 0x3CC0, 0x32D0, 0x2780, 0x1BB0, + 0x1040, 0x0580, 0xFB90, 0xF3D0, 0xEE20, 0xEB30, 0xEB00, 0xEC40, 0xEE10, 0xEFF0, 0xF0B0, 0xEE40, 0xE9D0, 0xE310, 0xD8C0, 0xCE90, + 0xC210, 0xB520, 0xA890, 0x9C70, 0x92F0, 0x8CA0, 0x8970, 0x8820, 0x87B0, 0x86F0, 0x86F0, 0x8750, 0x87C0, 0x8890, 0x89E0, 0x8AF0, + 0x8BA0, 0x8B30, 0x8A20, 0x8910, 0x87B0, 0x86F0, 0x8650, 0x85D0, 0x8590, 0x8560, 0x8530, 0x8510, 0x8500, 0x84F0, 0x84E0, 0x84D0, + 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84A0, 0x84C0, 0x84A0, 0x84A0, 0x84A0, 0x8470, + 0x84B0, 0x84B0, 0x84C0, 0x84C0, 0x84C0, 0x84D0, 0x84C0, 0x84D0, 0x84D0, 0x84E0, 0x84E0, 0x84E0, 0x84E0, 0x84D0, 0x84E0, 0x84E0, + 0x84F0, 0x84F0, 0x8500, 0x8510, 0x8520, 0x8530, 0x8560, 0x85A0, 0x8620, 0x86B0, 0x87D0, 0x8940, 0x8B40, 0x8E00, 0x9140, 0x9450, + 0x9850, 0x9B70, 0x9F40, 0xA290, 0xA630, 0xA930, 0xAA90, 0xAC30, 0xACC0, 0xAC20, 0xAB50, 0xA970, 0xA7B0, 0xA5C0, 0xA590, 0xA460, + 0xA360, 0xA1E0, 0x9EC0, 0x98F0, 0x9030, 0x87E0, 0x8530, 0x84C0, 0x8490, 0x8480, 0x8460, 0x8440, 0x8430, 0x8420, 0x8410, 0x8400, + 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8450, 0x8450, 0x8420, + 0x8440, 0x8440, 0x8440, 0x8450, 0x8490, 0x8460, 0x8490, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x84A0, 0x84B0, 0x84C0, 0x84C0, + 0x84D0, 0x84D0, 0x84E0, 0x84C0, 0x84D0, 0x84C0, 0x84C0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8490, 0x8480, 0x8470, + 0x8470, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, 0x8470, 0x8450, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8420, 0x8420, 0x8420, 0x8410, 0x8410, 0x8410, 0x8410, 0x8400, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x83E0, 0x83E0, + 0x83E0, 0x83D0, 0x83D0, 0x83D0, 0x83C0, 0x83C0, 0x83B0, 0x83B0, 0x83A0, 0x83A0, 0x8390, 0x8380, 0x8380, 0x8370, 0x8370, 0x8370, + 0x8370, 0x8370, 0x8360, 0x8370, 0x8370, 0x8370, 0x8380, 0x8380, 0x8390, 0x8390, 0x8390, 0x83A0, 0x83B0, 0x83B0, 0x83B0, 0x83C0, + 0x83C0, 0x83D0, 0x83D0, 0x83E0, 0x83E0, 0x83F0, 0x83F0, 0x8400, 0x8400, 0x8400, 0x8400, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, + 0x8410, 0x8410, 0x83F0, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8410, 0x8420, 0x8420, 0x8430, 0x8430, 0x8430, 0x8440, 0x8440, + 0x8440, 0x8440, 0x8450, 0x8450, 0x8450, 0x8460, 0x8460, 0x8470, 0x8470, 0x8480, 0x8480, 0x8490, 0x8490, 0x8490, 0x84A0, 0x84A0, + 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84B0, 0x84A0, 0x8490, 0x8490, 0x8490, 0x8480, 0x8480, 0x8470, 0x8470, 0x8460, + 0x8460, 0x8450, 0x8460, 0x8450, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, + 0x8450, 0x8450, 0x8460, 0x8470, 0x8480, 0x8490, 0x8490, 0x84B0, 0x84C0, 0x84E0, 0x8500, 0x8550, 0x85F0, 0x8770, 0x8AE0, 0x91C0, + 0x9950, 0xA140, 0xA940, 0xB210, 0xBC20, 0xC660, 0xD0D0, 0xDC90, 0xE8C0, 0xF580, 0x02C0, 0x1010, 0x1DF0, 0x2D40, 0x3B90, 0x49F0, + 0x5940, 0x67C0, 0x7530, 0x7E90, 0x7F20, 0x7F00, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F10, 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7EF0, + 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7B00, 0x61B0, 0x4950, 0x3100, 0x1890, 0x0380, 0xEFE0, 0xDDD0, 0xCC60, 0xBC10, 0xAC80, 0x9D60, + 0x8F90, 0x8740, 0x8540, 0x84E0, 0x84B0, 0x8490, 0x8490, 0x8470, 0x8470, 0x8460, 0x8460, 0x8470, 0x8460, 0x8460, 0x8460, 0x8450, + 0x8450, 0x8440, 0x8430, 0x8430, 0x8420, 0x8410, 0x8410, 0x8400, 0x8400, 0x83F0, 0x83F0, 0x83F0, 0x8400, 0x8410, 0x8420, 0x8430, + 0x8430, 0x8440, 0x8450, 0x8450, 0x8460, 0x84A0, 0x8470, 0x8490, 0x84B0, 0x8500, 0x87A0, 0x9FE0, 0xB640, 0xC630, 0xD170, 0xD810, + 0xDC20, 0xDDF0, 0xDED0, 0xDEA0, 0xDDA0, 0xDCC0, 0xDDA0, 0xE1C0, 0xEA50, 0xF930, 0x0CA0, 0x24C0, 0x3FF0, 0x5B60, 0x73B0, 0x7F40, + 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F30, 0x7F20, 0x7EF0, 0x7F30, 0x7F30, 0x7F20, 0x7F20, 0x7EF0, + 0x7F30, 0x7F20, 0x7F30, 0x7F30, 0x7F00, 0x7F20, 0x7F10, 0x7F30, 0x7F20, 0x7F40, 0x7F20, 0x7F30, 0x7F20, 0x7F40, 0x7F30, 0x7F30, + 0x7F20, 0x7F20, 0x7F30, 0x7F30, 0x7EF0, 0x7E90, 0x7F30, 0x7F20, 0x7F20, 0x7F00, 0x7E90, 0x7F10, 0x7EB0, 0x7EF0, 0x7EB0, 0x7E60, + 0x7ED0, 0x7ED0, 0x7F30, 0x7F20, 0x7F00, 0x7F50, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, + 0x7F00, 0x7F20, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EE0, 0x7EC0, 0x7EE0, 0x7F60, 0x7EF0, 0x7EF0, 0x7F00, 0x7EE0, 0x7EF0, 0x7EF0, + 0x7E70, 0x7F10, 0x7EB0, 0x7F30, 0x7EE0, 0x7E90, 0x7ED0, 0x7F00, 0x7F00, 0x7F10, 0x7EA0, 0x7EC0, 0x7EC0, 0x7F10, 0x7F00, 0x7EA0, + 0x7EF0, 0x7F10, 0x7F20, 0x7EF0, 0x7EB0, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7EF0, 0x7EF0, 0x7F70, + 0x7F10, 0x7F40, 0x7F10, 0x7F10, 0x7F30, 0x7F10, 0x7F10, 0x7F00, 0x7EE0, 0x7F70, 0x7EF0, 0x7EE0, 0x7F00, 0x7F10, 0x7F70, 0x7F00, + 0x7ED0, 0x7F10, 0x7F00, 0x7F30, 0x7ED0, 0x7E90, 0x7F00, 0x7EF0, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7EC0, + 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F30, 0x7F00, 0x7F00, 0x7EF0, 0x7F10, 0x7F80, + 0x7F00, 0x7F40, 0x7F30, 0x7F00, 0x7F90, 0x7F10, 0x7F10, 0x7EE0, 0x7EF0, 0x7F50, 0x7F10, 0x7EF0, 0x7EF0, 0x7F00, 0x7F60, 0x7F10, + 0x7EB0, 0x7EB0, 0x7EC0, 0x7EF0, 0x7F10, 0x7E70, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, 0x7EC0, 0x7ED0, 0x7F00, 0x7F10, 0x7F10, 0x7EB0, + 0x7EE0, 0x7EF0, 0x7F10, 0x7F20, 0x7F00, 0x7F40, 0x7F20, 0x7F20, 0x7F10, 0x7F00, 0x7F20, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F40, + 0x7F10, 0x7F20, 0x7F20, 0x7F10, 0x7F50, 0x7EF0, 0x7F00, 0x7EF0, 0x7F00, 0x7F40, 0x7EF0, 0x7F10, 0x7F00, 0x7F20, 0x7F70, 0x7ED0, + 0x7EB0, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EC0, 0x7F10, 0x7F20, 0x7F40, 0x7EC0, 0x7A30, 0x7740, 0x74B0, 0x76C0, 0x7A10, 0x7D20, + 0x7EC0, 0x7ED0, 0x7F10, 0x7F00, 0x7F40, 0x7ED0, 0x7EB0, 0x7EF0, 0x7F10, 0x7F30, 0x7F00, 0x7EC0, 0x7F10, 0x7F10, 0x7F20, 0x7F00, + 0x7EA0, 0x7F00, 0x7EF0, 0x7EF0, 0x7F20, 0x7F00, 0x7F40, 0x7F10, 0x7F10, 0x7F40, 0x7F00, 0x7F30, 0x7F00, 0x7F00, 0x7F40, 0x7F10, + 0x7F70, 0x7F00, 0x7F20, 0x7F20, 0x7F00, 0x7F90, 0x7F00, 0x7F20, 0x7EF0, 0x7ED0, 0x7F70, 0x7EF0, 0x7F10, 0x7F10, 0x7F00, 0x7F70, + 0x7F10, 0x7EB0, 0x7EB0, 0x7EE0, 0x7F30, 0x7F00, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F20, 0x7F20, 0x7E90, 0x7EB0, 0x7EE0, 0x7F10, 0x7F10, + 0x7E70, 0x7EE0, 0x7F10, 0x7F10, 0x7F20, 0x7F00, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F00, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7EE0, + 0x7F40, 0x7F30, 0x7F20, 0x7F10, 0x7F10, 0x7F30, 0x7EE0, 0x7EF0, 0x7F10, 0x7EE0, 0x7F50, 0x7EF0, 0x7F20, 0x7F20, 0x7F10, 0x7F90, + 0x7EF0, 0x7F10, 0x7F10, 0x7F10, 0x7F60, 0x7EE0, 0x7EB0, 0x7F10, 0x7F20, 0x7F40, 0x7F00, 0x7EA0, 0x7F10, 0x7F10, 0x7F20, 0x7EE0, + 0x7EC0, 0x7F10, 0x7F10, 0x7EF0, 0x7F10, 0x7EB0, 0x7F20, 0x7F10, 0x7F10, 0x7F10, 0x7F00, 0x7F40, 0x7F00, 0x7F00, 0x7F10, 0x7F00, + 0x7F60, 0x7F20, 0x7F40, 0x7F10, 0x7F00, 0x7F80, 0x7F10, 0x7F10, 0x7F00, 0x7EF0, 0x7F90, 0x7F10, 0x7F20, 0x7F00, 0x7F10, 0x7F70, + 0x7F10, 0x7EF0, 0x7EB0, 0x7B20, 0x72F0, 0x6A50, 0x6030, 0x5570, 0x4A50, 0x3F30, 0x3500, 0x29F0, 0x1FB0, 0x14D0, 0x0A30, 0x0050, + 0xF4F0, 0xEA40, 0xDFB0, 0xD4D0, 0xCA60, 0xC000, 0xB560, 0xAB10, 0xA170, 0x97B0, 0x9010, 0x8AB0, 0x8800, 0x86A0, 0x8600, 0x85B0, + 0x8580, 0x8580, 0x8590, 0x8580, 0x8610, 0x8690, 0x8790, 0x8970, 0x8CC0, 0x9260, 0x9910, 0xA0A0, 0xA830, 0xB070, 0xB880, 0xC040, + 0xC8B0, 0xD0E0, 0xD9F0, 0xE270, 0xEBE0, 0xF500, 0xFE20, 0x0770, 0x1050, 0x1960, 0x2190, 0x29B0, 0x3260, 0x3AD0, 0x41F0, 0x4970, + 0x5000, 0x5680, 0x5CB0, 0x61F0, 0x6720, 0x6C00, 0x7120, 0x7500, 0x7890, 0x7C30, 0x7E00, 0x7F00, 0x7EF0, 0x7F10, 0x7F30, 0x7EC0, + 0x7F30, 0x7F20, 0x7F20, 0x7F40, 0x7F10, 0x7F70, 0x7EE0, 0x7EF0, 0x7F20, 0x7EE0, 0x7F80, 0x7F10, 0x7F20, 0x7F00, 0x7EF0, 0x7F50, + 0x7F00, 0x7F10, 0x7EF0, 0x7EF0, 0x7F60, 0x7EF0, 0x7ED0, 0x7F00, 0x7F00, 0x7F30, 0x7F20, 0x7EC0, 0x7ED0, 0x7ED0, 0x7F30, 0x7F00, + 0x7E80, 0x7AF0, 0x75E0, 0x6EF0, 0x68F0, 0x6230, 0x5BC0, 0x5490, 0x4D30, 0x4630, 0x3EC0, 0x3740, 0x2FA0, 0x27E0, 0x20F0, 0x1980, + 0x1220, 0x0AE0, 0x0390, 0xFA70, 0xF400, 0xED20, 0xE760, 0xE100, 0xDB80, 0xD650, 0xD0C0, 0xCC00, 0xC710, 0xC2D0, 0xBEB0, 0xBAE0, + 0xB7C0, 0xB4F0, 0xB230, 0xAFD0, 0xADE0, 0xAB90, 0xA9E0, 0xA8C0, 0xA850, 0xA7A0, 0xA780, 0xA750, 0xA7E0, 0xA7F0, 0xA9A0, 0xAA90, + 0xAC00, 0xADB0, 0xAFB0, 0xB270, 0xB510, 0xB800, 0xBB70, 0xBF60, 0xC3E0, 0xC790, 0xCCA0, 0xD130, 0xD640, 0xDBE0, 0xE130, 0xE710, + 0xEDA0, 0xF3F0, 0xFAA0, 0x0150, 0x07B0, 0x0EA0, 0x1570, 0x1BF0, 0x2340, 0x2AC0, 0x31D0, 0x3870, 0x3F40, 0x4590, 0x4B30, 0x5100, + 0x5640, 0x5AF0, 0x5FA0, 0x6330, 0x6670, 0x68D0, 0x6AE0, 0x6CA0, 0x6E20, 0x6F10, 0x6FB0, 0x7000, 0x7070, 0x7090, 0x6FE0, 0x6F80, + 0x6ED0, 0x6EB0, 0x6DD0, 0x6D80, 0x6CB0, 0x6C00, 0x6B60, 0x6AC0, 0x6A50, 0x6780, 0x66C0, 0x6640, 0x6550, 0x64C0, 0x6410, 0x6390, + 0x62E0, 0x6200, 0x6190, 0x6070, 0x5FC0, 0x5EC0, 0x5D50, 0x5C10, 0x5A70, 0x58A0, 0x56C0, 0x54D0, 0x52B0, 0x5060, 0x4E50, 0x4AD0, + 0x4790, 0x44A0, 0x40E0, 0x3D70, 0x3950, 0x35E0, 0x3240, 0x2ED0, 0x2AA0, 0x2780, 0x2350, 0x2090, 0x1D00, 0x1A40, 0x1750, 0x14D0, + 0x1210, 0x0FA0, 0x0D10, 0x0A30, 0x0840, 0x05C0, 0x03B0, 0x0170, 0xFF20, 0xFCC0, 0xF9B0, 0xF6E0, 0xF3C0, 0xF110, 0xEE30, 0xEB50, + 0xE8A0, 0xE610, 0xE450, 0xE300, 0xE1B0, 0xE110, 0xE070, 0xE0C0, 0xE0A0, 0xE110, 0xE1B0, 0xE300, 0xE480, 0xE610, 0xE7E0, 0xEA30, + 0xEC50, 0xEE40, 0xF000, 0xF260, 0xF440, 0xF620, 0xF7E0, 0xF950, 0xFAD0, 0xFBB0, 0xFCF0, 0xFDC0, 0xFE80, 0xFED0, 0xFF20, 0xFF90, + 0x0010, 0x0050, 0x0120, 0x0210, 0x02D0, 0x03D0, 0x04E0, 0x05D0, 0x0710, 0x08A0, 0x09C0, 0x0BA0, 0x0D80, 0x0F40, 0x11A0, 0x12F0, + 0x1540, 0x1700, 0x18F0, 0x1AD0, 0x1C70, 0x1EF0, 0x2140, 0x2350, 0x2540, 0x2840, 0x2AB0, 0x2CA0, 0x2E60, 0x30C0, 0x3270, 0x3470, + 0x36E0, 0x3870, 0x3B30, 0x3CC0, 0x3F10, 0x40F0, 0x41F0, 0x4460, 0x45D0, 0x4790, 0x4960, 0x4A50, 0x4C70, 0x4DB0, 0x4F20, 0x5050, + 0x5130, 0x5220, 0x5300, 0x53D0, 0x54B0, 0x54C0, 0x5590, 0x5680, 0x56B0, 0x57A0, 0x57C0, 0x58B0, 0x5940, 0x5980, 0x59D0, 0x59C0, + 0x5A60, 0x59D0, 0x59F0, 0x5A20, 0x5960, 0x5940, 0x5920, 0x58C0, 0x5840, 0x57B0, 0x5820, 0x5760, 0x5710, 0x5730, 0x5670, 0x5680, + 0x5630, 0x55F0, 0x5660, 0x55F0, 0x5660, 0x5600, 0x5550, 0x5590, 0x54E0, 0x54E0, 0x5480, 0x5370, 0x52F0, 0x51C0, 0x5140, 0x5000, + 0x4E60, 0x4E10, 0x4CB0, 0x4CA0, 0x4BA0, 0x4AC0, 0x4A50, 0x4980, 0x4840, 0x4780, 0x45F0, 0x4520, 0x4440, 0x4350, 0x41C0, 0x4020, + 0x3F30, 0x3DB0, 0x3C30, 0x3A70, 0x3870, 0x3730, 0x35A0, 0x3410, 0x32F0, 0x30E0, 0x2FE0, 0x2E80, 0x2C40, 0x2B40, 0x2910, 0x27D0, + 0x25F0, 0x23E0, 0x22C0, 0x20A0, 0x1F70, 0x1D90, 0x1B90, 0x1A20, 0x1840, 0x1750, 0x1590, 0x13E0, 0x1240, 0x1040, 0x0E70, 0x0CC0, + 0x0A10, 0x0890, 0x0650, 0x0500, 0x0310, 0x0130, 0xFFF0, 0xFE50, 0xFCF0, 0xFBE0, 0xFA60, 0xF9D0, 0xF860, 0xF720, 0xF5E0, 0xF550, + 0xF460, 0xF420, 0xF2D0, 0xF210, 0xF230, 0xF250, 0xF150, 0xF170, 0xF130, 0xF120, 0xF180, 0xF130, 0xF160, 0xF180, 0xF190, 0xF1D0, + 0xF220, 0xF2A0, 0xF2E0, 0xF3C0, 0xF3E0, 0xF3F0, 0xF430, 0xF4C0, 0xF4F0, 0xF530, 0xF590, 0xF570, 0xF5D0, 0xF5A0, 0xF670, 0xF680, + 0xF630, 0xF720, 0xF700, 0xF740, 0xF6C0, 0xF780, 0xF800, 0xF810, 0xF830, 0xF920, 0xF870, 0xF8D0, 0xF8C0, 0xF960, 0xFB50, 0xFBB0, + 0xFC80, 0xFCF0, 0xFDC0, 0xFE30, 0xFEC0, 0xFF90, 0x0010, 0x0120, 0x0180, 0x0200, 0x0270, 0x02C0, 0x0370, 0x0390, 0x03C0, 0x0400, + 0x0460, 0x0530, 0x05B0, 0x0680, 0x0710, 0x0790, 0x0860, 0x0940, 0x09F0, 0x0A90, 0x0B40, 0x0C40, 0x0CB0, 0x0D60, 0x0E20, 0x0ED0, + 0x0FE0, 0x10C0, 0x1150, 0x11F0, 0x12B0, 0x1390, 0x13D0, 0x1440, 0x1500, 0x1550, 0x1650, 0x1700, 0x1740, 0x1810, 0x1820, 0x1920, + 0x1990, 0x19B0, 0x1A20, 0x1A60, 0x1AD0, 0x1AF0, 0x1B60, 0x1B80, 0x1C10, 0x1C60, 0x1CA0, 0x1C40, 0x1CC0, 0x1C80, 0x1C60, 0x1C90, + 0x1BC0, 0x1BE0, 0x1BD0, 0x1B90, 0x1B10, 0x1AC0, 0x1A90, 0x1A70, 0x19C0, 0x1990, 0x19B0, 0x1960, 0x18A0, 0x1850, 0x17D0, 0x16F0, + 0x16A0, 0x1580, 0x1470, 0x1400, 0x12C0, 0x1270, 0x1170, 0x10E0, 0x0F80, 0x0E70, 0x0D60, 0x0BD0, 0x0A70, 0x0970, 0x0860, 0x0750, + 0x0630, 0x0460, 0x0440, 0x0200, 0x00B0, 0xFF40, 0xFDB0, 0xFCF0, 0xFC00, 0xFAA0, 0xF9C0, 0xF880, 0xF700, 0xF580, 0xF430, 0xF2B0, + 0xF140, 0xF000, 0xEE50, 0xECC0, 0xEBA0, 0xE9D0, 0xE880, 0xE6F0, 0xE5A0, 0xE3F0, 0xE280, 0xE1C0, 0xDFF0, 0xDF30, 0xDE40, 0xDCD0, + 0xDC60, 0xDB60, 0xDA40, 0xD910, 0xD7D0, 0xD6B0, 0xD560, 0xD430, 0xD2F0, 0xD1F0, 0xD150, 0xD030, 0xCF30, 0xCE60, 0xCD50, 0xCC30, + 0xCB40, 0xC990, 0xC880, 0xC7B0, 0xC700, 0xC5E0, 0xC510, 0xC4A0, 0xC3E0, 0xC2F0, 0xC1B0, 0xC0C0, 0xC060, 0xBFC0, 0xBF00, 0xBEA0, + 0xBD90, 0xBD00, 0xBC20, 0xBB50, 0xBAB0, 0xB970, 0xB910, 0xB830, 0xB770, 0xB6A0, 0xB5C0, 0xB540, 0xB460, 0xB360, 0xB200, 0xB0D0, + 0xB030, 0xAEF0, 0xAD70, 0xAC90, 0xABC0, 0xAAD0, 0xA9A0, 0xA870, 0xA780, 0xA660, 0xA550, 0xA420, 0xA2F0, 0xA250, 0xA160, 0xA040, + 0x9F40, 0x9DE0, 0x9CD0, 0x9BD0, 0x9A80, 0x99D0, 0x9890, 0x97D0, 0x9690, 0x95F0, 0x94C0, 0x9350, 0x9200, 0x90E0, 0x8F90, 0x8E90, + 0x8D80, 0x8CF0, 0x8C70, 0x8BB0, 0x8B60, 0x8AB0, 0x8A50, 0x89B0, 0x8950, 0x88D0, 0x8890, 0x8840, 0x87F0, 0x87C0, 0x8790, 0x8760, + 0x8730, 0x86F0, 0x86D0, 0x8680, 0x86A0, 0x8690, 0x8690, 0x8680, 0x8670, 0x8670, 0x8650, 0x8650, 0x8650, 0x8650, 0x8640, 0x8650, + 0x8660, 0x8640, 0x8650, 0x8640, 0x8640, 0x8680, 0x8660, 0x8640, 0x8640, 0x8660, 0x8640, 0x8640, 0x8650, 0x8660, 0x8660, 0x8660, + 0x8670, 0x8680, 0x8670, 0x8670, 0x8680, 0x8670, 0x8680, 0x8670, 0x8680, 0x8680, 0x8670, 0x8670, 0x8670, 0x8680, 0x8660, 0x8650, + 0x8660, 0x8650, 0x8640, 0x8630, 0x8630, 0x8630, 0x8620, 0x8620, 0x8620, 0x8610, 0x8610, 0x8600, 0x8600, 0x8600, 0x8600, 0x8600, + 0x8610, 0x8630, 0x8600, 0x8600, 0x85F0, 0x85F0, 0x85F0, 0x85F0, 0x85F0, 0x8600, 0x8600, 0x8610, 0x8620, 0x8630, 0x8640, 0x8640, + 0x8640, 0x8650, 0x8650, 0x8670, 0x8680, 0x86A0, 0x86B0, 0x86D0, 0x8710, 0x8700, 0x8720, 0x8730, 0x8760, 0x8790, 0x87B0, 0x87E0, + 0x8800, 0x8810, 0x8850, 0x8860, 0x88B0, 0x8900, 0x8970, 0x8A10, 0x8A70, 0x8AF0, 0x8B90, 0x8C30, 0x8CC0, 0x8D40, 0x8DC0, 0x8E90, + 0x8F00, 0x8F70, 0x9030, 0x9120, 0x9200, 0x92B0, 0x93E0, 0x9450, 0x9510, 0x9600, 0x96C0, 0x9770, 0x98B0, 0x99A0, 0x9AB0, 0x9BC0, + 0x9C80, 0x9D50, 0x9DC0, 0x9E80, 0x9EF0, 0xA030, 0xA130, 0xA210, 0xA2E0, 0xA470, 0xA540, 0xA680, 0xA7A0, 0xA880, 0xA990, 0xAAB0, + 0xAB80, 0xAC80, 0xAD40, 0xAE40, 0xAF20, 0xAFD0, 0xB0E0, 0xB1A0, 0xB2B0, 0xB320, 0xB420, 0xB4C0, 0xB5A0, 0xB610, 0xB6D0, 0xB790, + 0xB830, 0xB8E0, 0xB9A0, 0xBA70, 0xBB40, 0xBC40, 0xBD20, 0xBDB0, 0xBEA0, 0xBF80, 0xBFE0, 0xC020, 0xC0D0, 0xC110, 0xC1B0, 0xC230, + 0xC240, 0xC2C0, 0xC330, 0xC3A0, 0xC440, 0xC4D0, 0xC570, 0xC620, 0xC6E0, 0xC710, 0xC750, 0xC780, 0xC850, 0xC8A0, 0xC910, 0xC970, + 0xC9F0, 0xCA50, 0xCAE0, 0xCB30, 0xCB40, 0xCB70, 0xCBE0, 0xCC70, 0xCCC0, 0xCD60, 0xCD90, 0xCE40, 0xCDD0, 0xCE70, 0xCE90, 0xCE50, + 0xCE80, 0xCEF0, 0xCEF0, 0xCF60, 0xCF70, 0xCF60, 0xCF80, 0xD010, 0xD090, 0xD0E0, 0xD130, 0xD150, 0xD130, 0xD130, 0xD130, 0xD170, + 0xD1B0, 0xD1B0, 0xD1F0, 0xD1B0, 0xD220, 0xD290, 0xD2C0, 0xD2D0, 0xD3A0, 0xD3D0, 0xD3F0, 0xD430, 0xD420, 0xD410, 0xD410, 0xD430, + 0xD460, 0xD440, 0xD440, 0xD430, 0xD3E0, 0xD3E0, 0xD3B0, 0xD3D0, 0xD420, 0xD3D0, 0xD410, 0xD460, 0xD450, 0xD430, 0xD3B0, 0xD400, + 0xD390, 0xD360, 0xD370, 0xD320, 0xD330, 0xD320, 0xD300, 0xD310, 0xD330, 0xD2D0, 0xD2C0, 0xD2C0, 0xD2F0, 0xD250, 0xD270, 0xD1D0, + 0xD1B0, 0xD190, 0xD0B0, 0xD0A0, 0xD030, 0xD000, 0xCFB0, 0xCF60, 0xCF00, 0xCF00, 0xCED0, 0xCE40, 0xCD80, 0xCDC0, 0xCD20, 0xCD80, + 0xCCD0, 0xCC40, 0xCC40, 0xCBB0, 0xCB60, 0xCAF0, 0xCA50, 0xCA30, 0xC9A0, 0xC990, 0xC8F0, 0xC8D0, 0xC8A0, 0xC810, 0xC790, 0xC6E0, + 0xC630, 0xC5C0, 0xC510, 0xC490, 0xC410, 0xC3D0, 0xC350, 0xC2F0, 0xC270, 0xC200, 0xC190, 0xC1A0, 0xC140, 0xC010, 0xBFF0, 0xBF20, + 0xBEE0, 0xBD90, 0xBCE0, 0xBCA0, 0xBC30, 0xBBB0, 0xBB40, 0xBA40, 0xB9C0, 0xB920, 0xB820, 0xB790, 0xB710, 0xB670, 0xB610, 0xB570, + 0xB570, 0xB510, 0xB500, 0xB440, 0xB3F0, 0xB3B0, 0xB2F0, 0xB280, 0xB240, 0xB190, 0xB110, 0xB020, 0xAFF0, 0xAF30, 0xAE50, 0xADE0, + 0xAD80, 0xAD30, 0xAC70, 0xABC0, 0xABA0, 0xAAF0, 0xAB20, 0xAAB0, 0xAA30, 0xAA50, 0xAA50, 0xA9B0, 0xA940, 0xA910, 0xA8C0, 0xA840, + 0xA820, 0xA7E0, 0xA790, 0xA6F0, 0xA710, 0xA630, 0xA5A0, 0xA4C0, 0xA4B0, 0xA450, 0xA430, 0xA400, 0xA3F0, 0xA3B0, 0xA2F0, 0xA280, + 0xA270, 0xA150, 0xA160, 0xA0E0, 0xA0A0, 0xA030, 0xA020, 0xA040, 0xA000, 0x9FB0, 0x9FB0, 0x9F70, 0x9EE0, 0x9EF0, 0x9E90, 0x9E00, + 0x9D50, 0x9D40, 0x9C80, 0x9C40, 0x9C30, 0x9BA0, 0x9B90, 0x9B70, 0x9AC0, 0x9AB0, 0x9A30, 0x99E0, 0x99E0, 0x9970, 0x9960, 0x9970, + 0x9950, 0x9920, 0x9850, 0x9880, 0x9810, 0x97B0, 0x9770, 0x9700, 0x9730, 0x96E0, 0x96C0, 0x9680, 0x9600, 0x95E0, 0x95A0, 0x9580, + 0x9510, 0x94E0, 0x9500, 0x94B0, 0x94E0, 0x94A0, 0x94B0, 0x9470, 0x9430, 0x9440, 0x9400, 0x9430, 0x9400, 0x93D0, 0x9440, 0x9420, + 0x9440, 0x9450, 0x9430, 0x9460, 0x9480, 0x9480, 0x9490, 0x9420, 0x9470, 0x9430, 0x9410, 0x9410, 0x9420, 0x9470, 0x9450, 0x9410, + 0x9470, 0x93F0, 0x9450, 0x94A0, 0x94A0, 0x9460, 0x9490, 0x94B0, 0x94E0, 0x94D0, 0x9510, 0x9520, 0x9530, 0x9550, 0x9590, 0x95C0, + 0x95D0, 0x95C0, 0x9550, 0x9510, 0x9570, 0x95A0, 0x9580, 0x95C0, 0x9650, 0x96F0, 0x96F0, 0x96F0, 0x9700, 0x9700, 0x96F0, 0x9720, + 0x9710, 0x9720, 0x9720, 0x97D0, 0x98A0, 0x98F0, 0x9930, 0x9910, 0x9960, 0x98D0, 0x9890, 0x98B0, 0x9890, 0x98D0, 0x9900, 0x9920, + 0x9960, 0x9940, 0x9A10, 0x9A30, 0x9A60, 0x9A70, 0x9A80, 0x9A80, 0x9A40, 0x9A40, 0x9AC0, 0x9AF0, 0x9B70, 0x9B40, 0x9B30, 0x9B50, + 0x9B60, 0x9B80, 0x9B50, 0x9B30, 0x9BA0, 0x9C00, 0x9CB0, 0x9CD0, 0x9D40, 0x9DC0, 0x9DD0, 0x9E20, 0x9E10, 0x9DC0, 0x9E20, 0x9E60, + 0x9E50, 0x9EB0, 0x9ED0, 0x9EC0, 0x9F10, 0x9ED0, 0x9F60, 0x9F40, 0x9F90, 0x9FD0, 0x9FF0, 0xA030, 0xA050, 0xA110, 0xA120, 0xA170, + 0xA1A0, 0xA1E0, 0xA270, 0xA2A0, 0xA340, 0xA390, 0xA3B0, 0xA420, 0xA470, 0xA480, 0xA4E0, 0xA4C0, 0xA4C0, 0xA4D0, 0xA4C0, 0xA4F0, + 0xA510, 0xA580, 0xA530, 0xA540, 0xA570, 0xA580, 0xA5B0, 0xA5E0, 0xA600, 0xA6E0, 0xA740, 0xA810, 0xA860, 0xA910, 0xA980, 0xAA00, + 0xAA10, 0xAA90, 0xAA70, 0xAAE0, 0xAB60, 0xABA0, 0xAC00, 0xABD0, 0xABB0, 0xABA0, 0xAB80, 0xABA0, 0xABB0, 0xABC0, 0xABF0, 0xAC10, + 0xAC80, 0xAC60, 0xACF0, 0xACE0, 0xACF0, 0xAD00, 0xAD50, 0xAE20, 0xAE40, 0xAED0, 0xAF30, 0xAFA0, 0xAFF0, 0xB030, 0xAFD0, 0xB080, + 0xB050, 0xB060, 0xB0D0, 0xB070, 0xB0F0, 0xB0E0, 0xB160, 0xB1B0, 0xB1B0, 0xB260, 0xB200, 0xB230, 0xB230, 0xB200, 0xB1E0, 0xB230, + 0xB220, 0xB280, 0xB230, 0xB330, 0xB300, 0xB300, 0xB310, 0xB300, 0xB3A0, 0xB390, 0xB380, 0xB3C0, 0xB3B0, 0xB400, 0xB400, 0xB3A0, + 0xB3D0, 0xB3C0, 0xB3C0, 0xB3D0, 0xB3B0, 0xB400, 0xB3A0, 0xB440, 0xB410, 0xB430, 0xB4B0, 0xB4A0, 0xB4D0, 0xB500, 0xB530, 0xB5C0, + 0xB5B0, 0xB660, 0xB670, 0xB630, 0xB650, 0xB5F0, 0xB650, 0xB670, 0xB630, 0xB6C0, 0xB6E0, 0xB710, 0xB770, 0xB780, 0xB7F0, 0xB7C0, + 0xB800, 0xB840, 0xB7F0, 0xB810, 0xB800, 0xB800, 0xB7F0, 0xB7F0, 0xB7D0, 0xB820, 0xB810, 0xB820, 0xB870, 0xB900, 0xB8F0, 0xB8F0, + 0xB9B0, 0xBA20, 0xBAC0, 0xBB50, 0xBB70, 0xBBD0, 0xBBE0, 0xBB80, 0xBB60, 0xBB50, 0xBAC0, 0xBA70, 0xBA60, 0xBA40, 0xBA30, 0xBA50, + 0xBA60, 0xBA90, 0xBA30, 0xBA80, 0xBAE0, 0xBA80, 0xBB10, 0xBB20, 0xBB60, 0xBB60, 0xBB90, 0xBBA0, 0xBBA0, 0xBBD0, 0xBBF0, 0xBC00, + 0xBC70, 0xBCD0, 0xBD70, 0xBDA0, 0xBDB0, 0xBDA0, 0xBD60, 0xBD90, 0xBDB0, 0xBDA0, 0xBE20, 0xBE80, 0xBEE0, 0xBEF0, 0xBED0, 0xBF10, + 0xBF60, 0xBF40, 0xBFD0, 0xC010, 0xC040, 0xC080, 0xC0F0, 0xC110, 0xC140, 0xC170, 0xC1E0, 0xC1B0, 0xC1F0, 0xC220, 0xC280, 0xC2E0, + 0xC2D0, 0xC2C0, 0xC2E0, 0xC2D0, 0xC340, 0xC380, 0xC3C0, 0xC430, 0xC480, 0xC4B0, 0xC4D0, 0xC520, 0xC550, 0xC5E0, 0xC5B0, 0xC600, + 0xC650, 0xC670, 0xC6C0, 0xC6A0, 0xC6B0, 0xC6E0, 0xC6E0, 0xC6D0, 0xC7A0, 0xC780, 0xC7D0, 0xC810, 0xC820, 0xC850, 0xC830, 0xC810, + 0xC830, 0xC810, 0xC840, 0xC820, 0xC830, 0xC830, 0xC860, 0xC840, 0xC890, 0xC8E0, 0xC8A0, 0xC860, 0xC880, 0xC8C0, 0xC8F0, 0xC8F0, + 0xC910, 0xC910, 0xC960, 0xC8F0, 0xC950, 0xC920, 0xC930, 0xC940, 0xC930, 0xC930, 0xC960, 0xC960, 0xC940, 0xC9B0, 0xC990, 0xC980, + 0xC9D0, 0xC9A0, 0xC990, 0xCA00, 0xCA10, 0xCA20, 0xCA10, 0xC9D0, 0xC9E0, 0xC9F0, 0xC9F0, 0xC9F0, 0xC9F0, 0xCA50, 0xCA30, 0xCA00, + 0xC9E0, 0xC9E0, 0xC980, 0xC940, 0xC990, 0xC980, 0xC900, 0xC9B0, 0xC9D0, 0xCA50, 0xCA20, 0xCA30, 0xCAA0, 0xCA50, 0xCAC0, 0xCAA0, + 0xCAE0, 0xCAD0, 0xCAB0, 0xCB40, 0xCB30, 0xCB30, 0xCB00, 0xCAC0, 0xCAB0, 0xCAB0, 0xCA80, 0xCA80, 0xCA80, 0xCA40, 0xC9D0, 0xC9D0, + 0xCA00, 0xC9E0, 0xC9A0, 0xC990, 0xC9F0, 0xCA40, 0xCAA0, 0xCAE0, 0xCAE0, 0xCAE0, 0xCBB0, 0xCBD0, 0xCB70, 0xCC40, 0xCBE0, 0xCC30, + 0xCC40, 0xCBC0, 0xCC50, 0xCC00, 0xCC60, 0xCC90, 0xCC50, 0xCC50, 0xCC20, 0xCC70, 0xCC40, 0xCC20, 0xCC40, 0xCCC0, 0xCD40, 0xCD70, + 0xCD50, 0xCDB0, 0xCDD0, 0xCDD0, 0xCDE0, 0xCDB0, 0xCDE0, 0xCE10, 0xCDF0, 0xCE00, 0xCDA0, 0xCE30, 0xCE70, 0xCEA0, 0xCE80, 0xCE90, + 0xCEC0, 0xCEB0, 0xCEC0, 0xCE60, 0xCE30, 0xCE60, 0xCE70, 0xCE60, 0xCEF0, 0xCE60, 0xCEE0, 0xCED0, 0xCED0, 0xCF20, 0xCF10, 0xCF70, + 0xCF80, 0xCF40, 0xCF70, 0xCF00, 0xCF70, 0xCF80, 0xCF50, 0xD050, 0xD050, 0xD040, 0xD050, 0xD030, 0xD100, 0xD080, 0xD0D0, 0xD100, + 0xD0E0, 0xD130, 0xD100, 0xD140, 0xD160, 0xD190, 0xD1A0, 0xD190, 0xD180, 0xD180, 0xD110, 0xD190, 0xD160, 0xD190, 0xD1A0, 0xD1B0, + 0xD1F0, 0xD210, 0xD1E0, 0xD1E0, 0xD170, 0xD1F0, 0xD1E0, 0xD180, 0xD190, 0xD180, 0xD1B0, 0xD1C0, 0xD190, 0xD1E0, 0xD1C0, 0xD1F0, + 0xD1F0, 0xD1D0, 0xD240, 0xD260, 0xD2F0, 0xD2D0, 0xD2D0, 0xD300, 0xD310, 0xD370, 0xD320, 0xD2F0, 0xD300, 0xD2D0, 0xD310, 0xD300, + 0xD2D0, 0xD320, 0xD310, 0xD370, 0xD360, 0xD360, 0xD380, 0xD3A0, 0xD3C0, 0xD3D0, 0xD3A0, 0xD440, 0xD450, 0xD450, 0xD490, 0xD470, + 0xD4A0, 0xD470, 0xD430, 0xD480, 0xD3E0, 0xD430, 0xD470, 0xD4F0, 0xD500, 0xD540, 0xD580, 0xD500, 0xD530, 0xD520, 0xD4F0, 0xD580, + 0xD520, 0xD560, 0xD550, 0xD570, 0xD580, 0xD5C0, 0xD570, 0xD5A0, 0xD580, 0xD580, 0xD5F0, 0xD570, 0xD640, 0xD5D0, 0xD600, 0xD600, + 0xD5A0, 0xD5D0, 0xD590, 0xD590, 0xD510, 0xD490, 0xD510, 0xD4E0, 0xD4F0, 0xD4A0, 0xD450, 0xD4C0, 0xD500, 0xD520, 0xD520, 0xD4F0, + 0xD580, 0xD5A0, 0xD580, 0xD5C0, 0xD540, 0xD590, 0xD590, 0xD5A0, 0xD580, 0xD4C0, 0xD510, 0xD4D0, 0xD4F0, 0xD4C0, 0xD4C0, 0xD4D0, + 0xD4B0, 0xD480, 0xD490, 0xD480, 0xD490, 0xD480, 0xD4D0, 0xD4E0, 0xD4A0, 0xD480, 0xD470, 0xD490, 0xD430, 0xD3F0, 0xD440, 0xD3C0, + 0xD3D0, 0xD3B0, 0xD320, 0xD390, 0xD380, 0xD370, 0xD340, 0xD2B0, 0xD2C0, 0xD2A0, 0xD280, 0xD250, 0xD250, 0xD290, 0xD270, 0xD260, + 0xD260, 0xD250, 0xD240, 0xD210, 0xD240, 0xD230, 0xD1D0, 0xD1D0, 0xD180, 0xD150, 0xD180, 0xD100, 0xD0D0, 0xD0C0, 0xD0B0, 0xD0A0, + 0xCFA0, 0xCFC0, 0xCF60, 0xCFE0, 0xCFB0, 0xCF60, 0xD010, 0xD000, 0xCFF0, 0xD010, 0xCF70, 0xCF40, 0xCF20, 0xCEA0, 0xCE50, 0xCE90, + 0xCE90, 0xCE20, 0xCDB0, 0xCDF0, 0xCDD0, 0xCD80, 0xCD50, 0xCDB0, 0xCDA0, 0xCD90, 0xCD90, 0xCD00, 0xCCB0, 0xCCF0, 0xCC90, 0xCC70, + 0xCC90, 0xCC50, 0xCC90, 0xCC90, 0xCCD0, 0xCCB0, 0xCD00, 0xCCF0, 0xCCC0, 0xCC60, 0xCC80, 0xCC30, 0xCC20, 0xCB40, 0xCB20, 0xCAD0, + 0xCA30, 0xCAC0, 0xC9F0, 0xC9C0, 0xC960, 0xC950, 0xC9E0, 0xC990, 0xC9B0, 0xC980, 0xC980, 0xC9F0, 0xC9A0, 0xC9D0, 0xC990, 0xC970, + 0xC9A0, 0xC950, 0xC9B0, 0xC970, 0xC940, 0xC930, 0xC920, 0xC930, 0xC940, 0xC890, 0xC890, 0xC840, 0xC810, 0xC870, 0xC840, 0xC860, + 0xC890, 0xC7D0, 0xC820, 0xC830, 0xC890, 0xC860, 0xC850, 0xC8B0, 0xC880, 0xC8B0, 0xC920, 0xC8D0, 0xC990, 0xC940, 0xC950, 0xC910, + 0xC8F0, 0xC8F0, 0xC8F0, 0xC890, 0xC8C0, 0xC880, 0xC890, 0xC8B0, 0xC8A0, 0xC900, 0xC8B0, 0xC8D0, 0xC8E0, 0xC8C0, 0xC8B0, 0xC880, + 0xC8F0, 0xC8F0, 0xC910, 0xC970, 0xC950, 0xC9B0, 0xC9D0, 0xC9D0, 0xCA20, 0xC9F0, 0xCA80, 0xCA80, 0xCAA0, 0xCB40, 0xCB90, 0xCB90, + 0xCBB0, 0xCC40, 0xCBD0, 0xCBE0, 0xCC00, 0xCC30, 0xCBD0, 0xCC30, 0xCBD0, 0xCC80, 0xCC30, 0xCC00, 0xCC70, 0xCC80, 0xCCD0, 0xCCC0, + 0xCCB0, 0xCDA0, 0xCDA0, 0xCE20, 0xCDF0, 0xCD90, 0xCE00, 0xCE00, 0xCE50, 0xCE10, 0xCE10, 0xCE80, 0xCE70, 0xCEE0, 0xCEE0, 0xCF40, + 0xCFD0, 0xD030, 0xD040, 0xD050, 0xD0B0, 0xD070, 0xD080, 0xD0E0, 0xD0E0, 0xD0F0, 0xD150, 0xD140, 0xD0F0, 0xD110, 0xD170, 0xD180, + 0xD160, 0xD150, 0xD170, 0xD1C0, 0xD1C0, 0xD1D0, 0xD1F0, 0xD2A0, 0xD290, 0xD2E0, 0xD300, 0xD310, 0xD350, 0xD390, 0xD3A0, 0xD3F0, + 0xD3C0, 0xD430, 0xD400, 0xD440, 0xD450, 0xD420, 0xD470, 0xD470, 0xD470, 0xD4A0, 0xD490, 0xD4F0, 0xD530, 0xD520, 0xD510, 0xD520, + 0xD550, 0xD5C0, 0xD5B0, 0xD620, 0xD660, 0xD650, 0xD670, 0xD660, 0xD660, 0xD5F0, 0xD610, 0xD640, 0xD630, 0xD6B0, 0xD690, 0xD6E0, + 0xD740, 0xD710, 0xD7B0, 0xD790, 0xD780, 0xD7D0, 0xD730, 0xD7A0, 0xD7C0, 0xD7E0, 0xD7E0, 0xD830, 0xD870, 0xD8C0, 0xD860, 0xD870, + 0xD810, 0xD7A0, 0xD790, 0xD780, 0xD760, 0xD780, 0xD740, 0xD790, 0xD7D0, 0xD7C0, 0xD790, 0xD750, 0xD730, 0xD720, 0xD7D0, 0xD780, + 0xD7D0, 0xD7C0, 0xD7B0, 0xD7F0, 0xD850, 0xD850, 0xD8C0, 0xD8D0, 0xD920, 0xD960, 0xD970, 0xD930, 0xD9F0, 0xDA00, 0xDA20, 0xDA30, + 0xDA10, 0xDA10, 0xD9E0, 0xD9B0, 0xDA00, 0xDA20, 0xD9E0, 0xDA30, 0xDA20, 0xDA40, 0xDA40, 0xDA50, 0xDA60, 0xDA60, 0xDAB0, 0xDA80, + 0xDAF0, 0xDAE0, 0xDB10, 0xDB30, 0xDB20, 0xDB50, 0xDB40, 0xDBB0, 0xDC50, 0xDC20, 0xDCD0, 0xDD20, 0xDCE0, 0xDCD0, 0xDD40, 0xDD20, + 0xDD20, 0xDD20, 0xDCF0, 0xDCB0, 0xDD00, 0xDCC0, 0xDCC0, 0xDC70, 0xDC90, 0xDCA0, 0xDC50, 0xDC90, 0xDCB0, 0xDC70, 0xDC70, 0xDC70, + 0xDC80, 0xDC90, 0xDC50, 0xDC40, 0xDC70, 0xDC30, 0xDC50, 0xDCA0, 0xDCD0, 0xDD10, 0xDD70, 0xDD80, 0xDD80, 0xDE00, 0xDE00, 0xDE90, + 0xDE50, 0xDEC0, 0xDE60, 0xDE50, 0xDE70, 0xDE80, 0xDE20, 0xDE50, 0xDEA0, 0xDEC0, 0xDEC0, 0xDED0, 0xDEE0, 0xDEF0, 0xDF10, 0xDEA0, + 0xDE60, 0xDEA0, 0xDEE0, 0xDEF0, 0xDF60, 0xDF40, 0xDFA0, 0xDFD0, 0xE000, 0xE020, 0xE030, 0xE080, 0xE0A0, 0xE0C0, 0xE0C0, 0xE110, + 0xE150, 0xE170, 0xE150, 0xE130, 0xE150, 0xE0E0, 0xE100, 0xE110, 0xE0C0, 0xE0F0, 0xE130, 0xE1C0, 0xE1F0, 0xE250, 0xE290, 0xE2A0, + 0xE350, 0xE340, 0xE310, 0xE330, 0xE390, 0xE3A0, 0xE3A0, 0xE3D0, 0xE350, 0xE340, 0xE2F0, 0xE2F0, 0xE2D0, 0xE2E0, 0xE2E0, 0xE2C0, + 0xE300, 0xE360, 0xE340, 0xE340, 0xE340, 0xE380, 0xE390, 0xE390, 0xE3B0, 0xE3E0, 0xE460, 0xE3D0, 0xE3F0, 0xE450, 0xE440, 0xE480, + 0xE4D0, 0xE530, 0xE5C0, 0xE650, 0xE6F0, 0xE7A0, 0xE7E0, 0xE880, 0xE870, 0xE870, 0xE830, 0xE8B0, 0xE860, 0xE860, 0xE870, 0xE7D0, + 0xE7E0, 0xE7E0, 0xE790, 0xE7E0, 0xE7B0, 0xE7D0, 0xE870, 0xE830, 0xE900, 0xE8B0, 0xE870, 0xE8C0, 0xE8A0, 0xE910, 0xE920, 0xE940, + 0xE9B0, 0xE950, 0xE9F0, 0xE9D0, 0xE950, 0xE960, 0xE940, 0xE940, 0xE940, 0xE930, 0xE9A0, 0xE9A0, 0xE9B0, 0xE9A0, 0xE9C0, 0xEA10, + 0xEA20, 0xEA60, 0xEA50, 0xEA80, 0xEB20, 0xEB50, 0xEBF0, 0xEBF0, 0xEC40, 0xEC50, 0xEC00, 0xEBE0, 0xEBA0, 0xEBB0, 0xEBE0, 0xEC20, + 0xEC20, 0xEC70, 0xECA0, 0xEC40, 0xECA0, 0xEC50, 0xEC70, 0xEC70, 0xECD0, 0xECB0, 0xECD0, 0xED60, 0xED00, 0xED90, 0xED80, 0xED90, + 0xEDB0, 0xED60, 0xEDC0, 0xED90, 0xED70, 0xEDA0, 0xEDA0, 0xEDF0, 0xEDF0, 0xEDB0, 0xEE00, 0xEE20, 0xEE70, 0xEEC0, 0xEE90, 0xEF30, + 0xEF30, 0xEF90, 0xEFF0, 0xF010, 0xF050, 0xF080, 0xF0C0, 0xF090, 0xF070, 0xF070, 0xF060, 0xF010, 0xF090, 0xF060, 0xF020, 0xF000, + 0xF020, 0xEFF0, 0xEFE0, 0xF050, 0xEFF0, 0xEFE0, 0xF010, 0xF030, 0xF0A0, 0xF0A0, 0xF090, 0xF060, 0xF0A0, 0xF0F0, 0xF150, 0xF130, + 0xF1B0, 0xF1A0, 0xF250, 0xF250, 0xF1A0, 0xF1C0, 0xF220, 0xF250, 0xF290, 0xF210, 0xF2B0, 0xF210, 0xF260, 0xF210, 0xF1D0, 0xF220, + 0xF220, 0xF250, 0xF280, 0xF250, 0xF2E0, 0xF350, 0xF3B0, 0xF3E0, 0xF3C0, 0xF400, 0xF3B0, 0xF3F0, 0xF420, 0xF3C0, 0xF470, 0xF430, + 0xF3E0, 0xF420, 0xF420, 0xF470, 0xF470, 0xF4A0, 0xF480, 0xF440, 0xF480, 0xF470, 0xF440, 0xF4A0, 0xF480, 0xF4E0, 0xF540, 0xF550, + 0xF5E0, 0xF5B0, 0xF5F0, 0xF5D0, 0xF5B0, 0xF5E0, 0xF5C0, 0xF630, 0xF680, 0xF600, 0xF680, 0xF6B0, 0xF6B0, 0xF680, 0xF650, 0xF670, + 0xF640, 0xF680, 0xF670, 0xF660, 0xF600, 0xF630, 0xF660, 0xF640, 0xF6C0, 0xF6B0, 0xF6C0, 0xF750, 0xF760, 0xF760, 0xF750, 0xF700, + 0xF700, 0xF720, 0xF710, 0xF730, 0xF720, 0xF760, 0xF710, 0xF760, 0xF730, 0xF770, 0xF750, 0xF7A0, 0xF7B0, 0xF7D0, 0xF7A0, 0xF800, + 0xF7F0, 0xF850, 0xF810, 0xF800, 0xF790, 0xF790, 0xF770, 0xF7A0, 0xF730, 0xF7A0, 0xF7A0, 0xF790, 0xF880, 0xF890, 0xF900, 0xF910, + 0xF890, 0xF8E0, 0xF840, 0xF800, 0xF860, 0xF870, 0xF8E0, 0xF900, 0xF900, 0xF920, 0xF8D0, 0xF8F0, 0xF880, 0xF8E0, 0xF890, 0xF860, + 0xF900, 0xF900, 0xF8F0, 0xF900, 0xF820, 0xF890, 0xF870, 0xF850, 0xF860, 0xF840, 0xF8D0, 0xF8D0, 0xF930, 0xF960, 0xF940, 0xF950, + 0xF950, 0xF970, 0xF9C0, 0xF990, 0xFA30, 0xFA20, 0xF9C0, 0xFA30, 0xFA10, 0xFA60, 0xFA20, 0xF9C0, 0xF9E0, 0xF980, 0xF990, 0xF9B0, + 0xF960, 0xFA20, 0xFA00, 0xF9E0, 0xF9B0, 0xF970, 0xF950, 0xF960, 0xF9A0, 0xF950, 0xF950, 0xF9F0, 0xFA60, 0xFA40, 0xFA80, 0xFA50, + 0xFB40, 0xFB00, 0xFB20, 0xFB40, 0xFA40, 0xFAB0, 0xFAA0, 0xFAA0, 0xFA70, 0xFA50, 0xFAD0, 0xFB00, 0xFB20, 0xFB50, 0xFB30, 0xFB60, + 0xFB40, 0xFB70, 0xFB30, 0xFB00, 0xFB00, 0xFB10, 0xFA90, 0xFAB0, 0xFAA0, 0xFB40, 0xFB90, 0xFB60, 0xFBD0, 0xFC30, 0xFC30, 0xFC20, + 0xFC00, 0xFBF0, 0xFBF0, 0xFC00, 0xFC10, 0xFB90, 0xFBE0, 0xFBC0, 0xFB90, 0xFB90, 0xFB60, 0xFB50, 0xFB20, 0xFB30, 0xFB80, 0xFB90, +}; + +#endif // MIC_BLOW_H diff --git a/src/frontend/qt_sdl/AudioSettingsDialog.ui b/src/frontend/qt_sdl/AudioSettingsDialog.ui index b6c215e..c4e993e 100644 --- a/src/frontend/qt_sdl/AudioSettingsDialog.ui +++ b/src/frontend/qt_sdl/AudioSettingsDialog.ui @@ -95,7 +95,7 @@ <html><head/><body><p>Noise will be forwarded to the emulated microphone, simulating blowing into the microphone.</p></body></html> - White noise + Blow noise diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index caa78e9..ffd7d17 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -12,6 +12,7 @@ SET(SOURCES_QT_SDL ../Util_ROM.cpp ../Util_Audio.cpp ../FrontendUtil.h + ../mic_blow.h ../../../melon.qrc ) -- 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') 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') 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 ffd9c61bf79852f2364166c4770719146500f4b9 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Thu, 21 May 2020 19:45:33 +0200 Subject: fix screen layout with emphasis --- src/frontend/Util_Video.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/Util_Video.cpp b/src/frontend/Util_Video.cpp index cd4e21c..0f5ff66 100644 --- a/src/frontend/Util_Video.cpp +++ b/src/frontend/Util_Video.cpp @@ -235,14 +235,14 @@ void SetupScreenLayout(int screenWidth, int screenHeight, int screenLayout, int if (layout == 0) { if (screenHeight - primVSize * primScale < secVSize) - primScale = std::min((screenWidth - secHSize) / primHSize, (screenHeight - secVSize) / primVSize); + primScale = std::min(screenWidth / 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); + primScale = std::min((screenWidth - secHSize) / primHSize, screenHeight / primVSize); else secScale = std::min((screenWidth - primHSize * primScale) / secHSize, screenHeight / secVSize); } -- 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') 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') 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') 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') 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') 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') 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 256360aebba709d7b8565cd35bd9d42473219fd5 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 27 May 2020 19:18:45 +0200 Subject: texture2D -> texture Intel driver threw a fit about it --- src/frontend/qt_sdl/main_shaders.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/main_shaders.h b/src/frontend/qt_sdl/main_shaders.h index 2e57e59..96b9ecd 100644 --- a/src/frontend/qt_sdl/main_shaders.h +++ b/src/frontend/qt_sdl/main_shaders.h @@ -55,7 +55,7 @@ out vec4 oColor; void main() { - vec4 pixel = texture2D(ScreenTex, fTexcoord); + vec4 pixel = texture(ScreenTex, fTexcoord); oColor = vec4(pixel.bgr, 1.0); } -- 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') 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') 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') 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') 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 5005a7c3f0f78c4684dbdcde0d88ae48050ab6fe Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 13:21:25 +0200 Subject: populate the dialog. also add setting for vsync interval. --- src/frontend/qt_sdl/PlatformConfig.cpp | 6 ++++-- src/frontend/qt_sdl/PlatformConfig.h | 1 + src/frontend/qt_sdl/VideoSettingsDialog.cpp | 19 ++++++++++++++++++- src/frontend/qt_sdl/VideoSettingsDialog.h | 7 +++++++ 4 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index 28c224d..03fd2ac 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -45,6 +45,7 @@ int ScreenFilter; int ScreenUseGL; int ScreenVSync; +int ScreenVSyncInterval; int LimitFPS; int AudioSync; @@ -124,8 +125,9 @@ ConfigEntry PlatformConfigFile[] = {"IntegerScaling", 0, &IntegerScaling, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, - {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, - {"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0}, + {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, + {"ScreenVSync", 0, &ScreenVSync, 0, NULL, 0}, + {"ScreenVSyncInterval", 0, &ScreenVSyncInterval, 1, 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 539f9a4..cc288b6 100644 --- a/src/frontend/qt_sdl/PlatformConfig.h +++ b/src/frontend/qt_sdl/PlatformConfig.h @@ -58,6 +58,7 @@ extern int ScreenFilter; extern int ScreenUseGL; extern int ScreenVSync; +extern int ScreenVSyncInterval; extern int LimitFPS; extern int AudioSync; diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index c0ec42a..0aeb154 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -36,12 +36,29 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui( ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); - // + oldRenderer = Config::_3DRenderer; + oldGLDisplay = Config::ScreenUseGL; + oldVSync = Config::ScreenVSync; + oldVSyncInterval = Config::ScreenVSyncInterval; + oldSoftThreaded = Config::Threaded3D; + oldGLScale = Config::GL_ScaleFactor; grp3DRenderer = new QButtonGroup(this); grp3DRenderer->addButton(ui->rb3DSoftware, 0); grp3DRenderer->addButton(ui->rb3DOpenGL, 1); //connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int))); + grp3DRenderer->button(Config::_3DRenderer)->setChecked(true); + + ui->cbGLDisplay->setChecked(Config::ScreenUseGL != 0); + + ui->cbVSync->setChecked(Config::ScreenVSync != 0); + ui->sbVSyncInterval->setValue(Config::ScreenVSyncInterval); + + 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); } VideoSettingsDialog::~VideoSettingsDialog() diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h index d64cee2..05dfecb 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.h +++ b/src/frontend/qt_sdl/VideoSettingsDialog.h @@ -61,6 +61,13 @@ private: Ui::VideoSettingsDialog* ui; QButtonGroup* grp3DRenderer; + + int oldRenderer; + int oldGLDisplay; + int oldVSync; + int oldVSyncInterval; + int oldSoftThreaded; + int oldGLScale; }; #endif // VIDEOSETTINGSDIALOG_H -- 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') 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') 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 d25dc40e70e9a1c25966db8e16a5efd5284fd336 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 16:04:22 +0200 Subject: make it a bit better --- src/frontend/qt_sdl/VideoSettingsDialog.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index 09f1ab4..9645a3d 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); @@ -145,6 +145,9 @@ void VideoSettingsDialog::on_cbSoftwareThreaded_stateChanged(int state) void VideoSettingsDialog::on_cbxGLResolution_currentIndexChanged(int idx) { + // prevent a spurious change + if (ui->cbxGLResolution->count() < 16) return; + Config::GL_ScaleFactor = idx+1; emit updateVideoSettings(false); -- cgit v1.2.3 From d1d572210fdcef0932aaa2f0c6df71f6f2161c75 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 16:07:34 +0200 Subject: fix that bug here too --- src/frontend/qt_sdl/InputConfigDialog.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 2c0afc4..81baa65 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -199,6 +199,9 @@ void InputConfigDialog::on_InputConfigDialog_rejected() void InputConfigDialog::on_cbxJoystick_currentIndexChanged(int id) { + // prevent a spurious change + if (ui->cbxJoystick->count() < 2) return; + Input::JoystickID = id; Input::OpenJoystick(); } -- 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') 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') 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') 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 b7946c1384ce7c44172036f0a04410a9c04ed78c Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 28 May 2020 22:21:36 +0200 Subject: * flesh out design for wifi settings dialog * move the pcap shit to a betterer place --- src/frontend/qt_sdl/LAN_PCap.cpp | 387 ++++++++ src/frontend/qt_sdl/LAN_PCap.h | 53 ++ src/frontend/qt_sdl/LAN_Socket.cpp | 1145 ++++++++++++++++++++++++ src/frontend/qt_sdl/LAN_Socket.h | 38 + src/frontend/qt_sdl/WifiSettingsDialog.ui | 165 ++++ src/frontend/qt_sdl/pcap/bluetooth.h | 56 ++ src/frontend/qt_sdl/pcap/bpf.h | 270 ++++++ src/frontend/qt_sdl/pcap/can_socketcan.h | 56 ++ src/frontend/qt_sdl/pcap/compiler-tests.h | 152 ++++ src/frontend/qt_sdl/pcap/dlt.h | 1389 +++++++++++++++++++++++++++++ src/frontend/qt_sdl/pcap/funcattrs.h | 242 +++++ src/frontend/qt_sdl/pcap/ipnet.h | 43 + src/frontend/qt_sdl/pcap/namedb.h | 85 ++ src/frontend/qt_sdl/pcap/nflog.h | 94 ++ src/frontend/qt_sdl/pcap/pcap-inttypes.h | 117 +++ src/frontend/qt_sdl/pcap/pcap.h | 966 ++++++++++++++++++++ src/frontend/qt_sdl/pcap/sll.h | 131 +++ src/frontend/qt_sdl/pcap/usb.h | 143 +++ src/frontend/qt_sdl/pcap/vlan.h | 46 + src/pcap/bluetooth.h | 56 -- src/pcap/bpf.h | 270 ------ src/pcap/can_socketcan.h | 56 -- src/pcap/compiler-tests.h | 152 ---- src/pcap/dlt.h | 1389 ----------------------------- src/pcap/funcattrs.h | 242 ----- src/pcap/ipnet.h | 43 - src/pcap/namedb.h | 85 -- src/pcap/nflog.h | 94 -- src/pcap/pcap-inttypes.h | 117 --- src/pcap/pcap.h | 966 -------------------- src/pcap/sll.h | 131 --- src/pcap/usb.h | 143 --- src/pcap/vlan.h | 46 - 33 files changed, 5578 insertions(+), 3790 deletions(-) create mode 100644 src/frontend/qt_sdl/LAN_PCap.cpp create mode 100644 src/frontend/qt_sdl/LAN_PCap.h create mode 100644 src/frontend/qt_sdl/LAN_Socket.cpp create mode 100644 src/frontend/qt_sdl/LAN_Socket.h create mode 100644 src/frontend/qt_sdl/WifiSettingsDialog.ui create mode 100644 src/frontend/qt_sdl/pcap/bluetooth.h create mode 100644 src/frontend/qt_sdl/pcap/bpf.h create mode 100644 src/frontend/qt_sdl/pcap/can_socketcan.h create mode 100644 src/frontend/qt_sdl/pcap/compiler-tests.h create mode 100644 src/frontend/qt_sdl/pcap/dlt.h create mode 100644 src/frontend/qt_sdl/pcap/funcattrs.h create mode 100644 src/frontend/qt_sdl/pcap/ipnet.h create mode 100644 src/frontend/qt_sdl/pcap/namedb.h create mode 100644 src/frontend/qt_sdl/pcap/nflog.h create mode 100644 src/frontend/qt_sdl/pcap/pcap-inttypes.h create mode 100644 src/frontend/qt_sdl/pcap/pcap.h create mode 100644 src/frontend/qt_sdl/pcap/sll.h create mode 100644 src/frontend/qt_sdl/pcap/usb.h create mode 100644 src/frontend/qt_sdl/pcap/vlan.h delete mode 100644 src/pcap/bluetooth.h delete mode 100644 src/pcap/bpf.h delete mode 100644 src/pcap/can_socketcan.h delete mode 100644 src/pcap/compiler-tests.h delete mode 100644 src/pcap/dlt.h delete mode 100644 src/pcap/funcattrs.h delete mode 100644 src/pcap/ipnet.h delete mode 100644 src/pcap/namedb.h delete mode 100644 src/pcap/nflog.h delete mode 100644 src/pcap/pcap-inttypes.h delete mode 100644 src/pcap/pcap.h delete mode 100644 src/pcap/sll.h delete mode 100644 src/pcap/usb.h delete mode 100644 src/pcap/vlan.h (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/LAN_PCap.cpp b/src/frontend/qt_sdl/LAN_PCap.cpp new file mode 100644 index 0000000..ce278bc --- /dev/null +++ b/src/frontend/qt_sdl/LAN_PCap.cpp @@ -0,0 +1,387 @@ +/* + 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/. +*/ + +// direct LAN interface. Currently powered by libpcap, may change. + +#include +#include +#include +#include +#include +#include "../Wifi.h" +#include "LAN_PCap.h" +#include "PlatformConfig.h" + +#ifdef __WIN32__ + #include +#else + #include + #include + #include + #include +#endif + + +// welp +#ifndef PCAP_OPENFLAG_PROMISCUOUS +#define PCAP_OPENFLAG_PROMISCUOUS 1 +#endif + + +#define DECL_PCAP_FUNC(ret, name, args, args2) \ + typedef ret (*type_##name) args; \ + type_##name ptr_##name = NULL; \ + ret name args { return ptr_##name args2; } + +DECL_PCAP_FUNC(int, pcap_findalldevs, (pcap_if_t** alldevs, char* errbuf), (alldevs,errbuf)) +DECL_PCAP_FUNC(void, pcap_freealldevs, (pcap_if_t* alldevs), (alldevs)) +DECL_PCAP_FUNC(pcap_t*, pcap_open_live, (const char* src, int snaplen, int flags, int readtimeout, char* errbuf), (src,snaplen,flags,readtimeout,errbuf)) +DECL_PCAP_FUNC(void, pcap_close, (pcap_t* dev), (dev)) +DECL_PCAP_FUNC(int, pcap_setnonblock, (pcap_t* dev, int nonblock, char* errbuf), (dev,nonblock,errbuf)) +DECL_PCAP_FUNC(int, pcap_sendpacket, (pcap_t* dev, const u_char* data, int len), (dev,data,len)) +DECL_PCAP_FUNC(int, pcap_dispatch, (pcap_t* dev, int num, pcap_handler callback, u_char* data), (dev,num,callback,data)) +DECL_PCAP_FUNC(const u_char*, pcap_next, (pcap_t* dev, struct pcap_pkthdr* hdr), (dev,hdr)) + + +namespace LAN_PCap +{ + +const char* PCapLibNames[] = +{ +#ifdef __WIN32__ + // TODO: name for npcap in non-WinPCap mode + "wpcap.dll", +#else + // Linux lib names + "libpcap.so.1", + "libpcap.so", +#endif + NULL +}; + +AdapterData* Adapters = NULL; +int NumAdapters = 0; + +void* PCapLib = NULL; +pcap_t* PCapAdapter = NULL; +AdapterData* PCapAdapterData; + +u8 PacketBuffer[2048]; +int PacketLen; +volatile int RXNum; + + +#define LOAD_PCAP_FUNC(sym) \ + ptr_##sym = (type_##sym)SDL_LoadFunction(lib, #sym); \ + if (!ptr_##sym) return false; + +bool TryLoadPCap(void* lib) +{ + LOAD_PCAP_FUNC(pcap_findalldevs) + LOAD_PCAP_FUNC(pcap_freealldevs) + LOAD_PCAP_FUNC(pcap_open_live) + LOAD_PCAP_FUNC(pcap_close) + LOAD_PCAP_FUNC(pcap_setnonblock) + LOAD_PCAP_FUNC(pcap_sendpacket) + LOAD_PCAP_FUNC(pcap_dispatch) + LOAD_PCAP_FUNC(pcap_next) + + return true; +} + +bool Init(bool open_adapter) +{ + // TODO: how to deal with cases where an adapter is unplugged or changes config?? + if (!PCapLib) + { + PCapLib = NULL; + + for (int i = 0; PCapLibNames[i]; i++) + { + void* lib = SDL_LoadObject(PCapLibNames[i]); + if (!lib) continue; + + if (!TryLoadPCap(lib)) + { + SDL_UnloadObject(lib); + continue; + } + + printf("PCap: lib %s, init successful\n", PCapLibNames[i]); + PCapLib = lib; + break; + } + + if (PCapLib == NULL) + { + printf("PCap: init failed\n"); + return false; + } + } + + PCapAdapter = NULL; + PacketLen = 0; + RXNum = 0; + + NumAdapters = 0; + + char errbuf[PCAP_ERRBUF_SIZE]; + int ret; + + pcap_if_t* alldevs; + ret = pcap_findalldevs(&alldevs, errbuf); + if (ret < 0 || alldevs == NULL) + { + printf("PCap: no devices available\n"); + return false; + } + + pcap_if_t* dev = alldevs; + while (dev) { NumAdapters++; dev = dev->next; } + + Adapters = new AdapterData[NumAdapters]; + memset(Adapters, 0, sizeof(AdapterData)*NumAdapters); + + AdapterData* adata = &Adapters[0]; + dev = alldevs; + while (dev) + { + adata->Internal = dev; + +#ifdef __WIN32__ + // hax + int len = strlen(dev->name); + len -= 12; if (len > 127) len = 127; + strncpy(adata->DeviceName, &dev->name[12], len); + adata->DeviceName[len] = '\0'; +#else + strncpy(adata->DeviceName, dev->name, 127); + adata->DeviceName[127] = '\0'; + + strncpy(adata->FriendlyName, adata->DeviceName, 127); + adata->FriendlyName[127] = '\0'; +#endif // __WIN32__ + + dev = dev->next; + adata++; + } + +#ifdef __WIN32__ + + ULONG bufsize = 16384; + IP_ADAPTER_ADDRESSES* buf = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, bufsize); + ULONG uret = GetAdaptersAddresses(AF_INET, 0, NULL, buf, &bufsize); + if (uret == ERROR_BUFFER_OVERFLOW) + { + HeapFree(GetProcessHeap(), 0, buf); + buf = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, bufsize); + uret = GetAdaptersAddresses(AF_INET, 0, NULL, buf, &bufsize); + } + if (uret != ERROR_SUCCESS) + { + printf("GetAdaptersAddresses() shat itself: %08X\n", uret); + return false; + } + + for (int i = 0; i < NumAdapters; i++) + { + adata = &Adapters[i]; + IP_ADAPTER_ADDRESSES* addr = buf; + while (addr) + { + if (strcmp(addr->AdapterName, adata->DeviceName)) + { + addr = addr->Next; + continue; + } + + WideCharToMultiByte(CP_UTF8, 0, addr->FriendlyName, 127, adata->FriendlyName, 127, NULL, NULL); + adata->FriendlyName[127] = '\0'; + + WideCharToMultiByte(CP_UTF8, 0, addr->Description, 127, adata->Description, 127, NULL, NULL); + adata->Description[127] = '\0'; + + if (addr->PhysicalAddressLength != 6) + { + printf("weird MAC addr length %d for %s\n", addr->PhysicalAddressLength, addr->AdapterName); + } + else + memcpy(adata->MAC, addr->PhysicalAddress, 6); + + IP_ADAPTER_UNICAST_ADDRESS* ipaddr = addr->FirstUnicastAddress; + while (ipaddr) + { + SOCKADDR* sa = ipaddr->Address.lpSockaddr; + if (sa->sa_family == AF_INET) + { + struct in_addr sa4 = ((sockaddr_in*)sa)->sin_addr; + memcpy(adata->IP_v4, &sa4, 4); + } + + ipaddr = ipaddr->Next; + } + + break; + } + } + + HeapFree(GetProcessHeap(), 0, buf); + +#else + + struct ifaddrs* addrs; + if (getifaddrs(&addrs) != 0) + { + printf("getifaddrs() shat itself :(\n"); + return false; + } + + for (int i = 0; i < NumAdapters; i++) + { + adata = &Adapters[i]; + struct ifaddrs* curaddr = addrs; + while (curaddr) + { + if (strcmp(curaddr->ifa_name, adata->DeviceName)) + { + curaddr = curaddr->ifa_next; + continue; + } + + if (!curaddr->ifa_addr) + { + printf("Device (%s) does not have an address :/\n", curaddr->ifa_name); + curaddr = curaddr->ifa_next; + continue; + } + + u16 af = curaddr->ifa_addr->sa_family; + if (af == AF_INET) + { + struct sockaddr_in* sa = (sockaddr_in*)curaddr->ifa_addr; + memcpy(adata->IP_v4, &sa->sin_addr, 4); + } + else if (af == AF_PACKET) + { + struct sockaddr_ll* sa = (sockaddr_ll*)curaddr->ifa_addr; + if (sa->sll_halen != 6) + printf("weird MAC length %d for %s\n", sa->sll_halen, curaddr->ifa_name); + else + memcpy(adata->MAC, sa->sll_addr, 6); + } + + curaddr = curaddr->ifa_next; + } + } + + freeifaddrs(addrs); + +#endif // __WIN32__ + + if (!open_adapter) return true; + if (PCapAdapter) pcap_close(PCapAdapter); + + // open pcap device + PCapAdapterData = &Adapters[0]; + for (int i = 0; i < NumAdapters; i++) + { + if (!strncmp(Adapters[i].DeviceName, Config::LANDevice, 128)) + PCapAdapterData = &Adapters[i]; + } + + dev = (pcap_if_t*)PCapAdapterData->Internal; + PCapAdapter = pcap_open_live(dev->name, 2048, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf); + if (!PCapAdapter) + { + printf("PCap: failed to open adapter %s\n", errbuf); + return false; + } + + pcap_freealldevs(alldevs); + + if (pcap_setnonblock(PCapAdapter, 1, errbuf) < 0) + { + printf("PCap: failed to set nonblocking mode\n"); + pcap_close(PCapAdapter); PCapAdapter = NULL; + return false; + } + + return true; +} + +void DeInit() +{ + if (PCapLib) + { + if (PCapAdapter) + { + pcap_close(PCapAdapter); + PCapAdapter = NULL; + } + + SDL_UnloadObject(PCapLib); + PCapLib = NULL; + } +} + + +void RXCallback(u_char* blarg, const struct pcap_pkthdr* header, const u_char* data) +{ + while (RXNum > 0); + + if (header->len > 2048-64) return; + + PacketLen = header->len; + memcpy(PacketBuffer, data, PacketLen); + RXNum = 1; +} + +int SendPacket(u8* data, int len) +{ + if (PCapAdapter == NULL) + return 0; + + if (len > 2048) + { + printf("LAN_SendPacket: error: packet too long (%d)\n", len); + return 0; + } + + pcap_sendpacket(PCapAdapter, data, len); + // TODO: check success + return len; +} + +int RecvPacket(u8* data) +{ + if (PCapAdapter == NULL) + return 0; + + int ret = 0; + if (RXNum > 0) + { + memcpy(data, PacketBuffer, PacketLen); + ret = PacketLen; + RXNum = 0; + } + + pcap_dispatch(PCapAdapter, 1, RXCallback, NULL); + return ret; +} + +} diff --git a/src/frontend/qt_sdl/LAN_PCap.h b/src/frontend/qt_sdl/LAN_PCap.h new file mode 100644 index 0000000..250b8e9 --- /dev/null +++ b/src/frontend/qt_sdl/LAN_PCap.h @@ -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/. +*/ + +#ifndef LAN_PCAP_H +#define LAN_PCAP_H + +#include "../types.h" + +namespace LAN_PCap +{ + +typedef struct +{ + char DeviceName[128]; + char FriendlyName[128]; + char Description[128]; + + u8 MAC[6]; + u8 IP_v4[4]; + + void* Internal; + +} AdapterData; + + +extern AdapterData* Adapters; +extern int NumAdapters; + + +bool Init(bool open_adapter); +void DeInit(); + +int SendPacket(u8* data, int len); +int RecvPacket(u8* data); + +} + +#endif // LAN_PCAP_H diff --git a/src/frontend/qt_sdl/LAN_Socket.cpp b/src/frontend/qt_sdl/LAN_Socket.cpp new file mode 100644 index 0000000..c6fbd4b --- /dev/null +++ b/src/frontend/qt_sdl/LAN_Socket.cpp @@ -0,0 +1,1145 @@ +/* + 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/. +*/ + +// indirect LAN interface, powered by BSD sockets. + +#include +#include +#include +#include "../Wifi.h" +#include "LAN_Socket.h" +#include "../Config.h" + +#ifdef __WIN32__ + #include + #include + #define socket_t SOCKET + #define sockaddr_t SOCKADDR +#else + #include + #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 + + +namespace LAN_Socket +{ + +const u32 kSubnet = 0x0A400000; +const u32 kServerIP = kSubnet | 0x01; +const u32 kDNSIP = kSubnet | 0x02; +const u32 kClientIP = kSubnet | 0x10; + +const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44}; +const u8 kDNSMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x55}; + +u8 PacketBuffer[2048]; +int PacketLen; +volatile int RXNum; + +u16 IPv4ID; + + +// TODO: UDP sockets +// * use FIFO list +// * assign new socket when seeing new IP/port + + +typedef struct +{ + u8 DestIP[4]; + u16 SourcePort; + u16 DestPort; + + u32 SeqNum; // sequence number for incoming frames + u32 AckNum; + + // 0: unused + // 1: connected + u8 Status; + + socket_t Backend; + +} TCPSocket; + +typedef struct +{ + u8 DestIP[4]; + u16 SourcePort; + u16 DestPort; + + socket_t Backend; + struct sockaddr_in BackendAddr; + +} UDPSocket; + +TCPSocket TCPSocketList[16]; +UDPSocket UDPSocketList[4]; + +int UDPSocketID = 0; + + +bool Init() +{ + // TODO: how to deal with cases where an adapter is unplugged or changes config?? + //if (PCapLib) return true; + + //Lib = NULL; + PacketLen = 0; + RXNum = 0; + + IPv4ID = 1; + + memset(TCPSocketList, 0, sizeof(TCPSocketList)); + memset(UDPSocketList, 0, sizeof(UDPSocketList)); + + UDPSocketID = 0; + + return true; +} + +void DeInit() +{ + for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++) + { + TCPSocket* sock = &TCPSocketList[i]; + if (sock->Backend) closesocket(sock->Backend); + } + + for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++) + { + UDPSocket* sock = &UDPSocketList[i]; + if (sock->Backend) closesocket(sock->Backend); + } +} + + +void FinishUDPFrame(u8* data, int len) +{ + u8* ipheader = &data[0xE]; + u8* udpheader = &data[0x22]; + + // lengths + *(u16*)&ipheader[2] = htons(len - 0xE); + *(u16*)&udpheader[4] = htons(len - (0xE + 0x14)); + + // IP checksum + u32 tmp = 0; + + for (int i = 0; i < 20; i += 2) + tmp += ntohs(*(u16*)&ipheader[i]); + while (tmp >> 16) + tmp = (tmp & 0xFFFF) + (tmp >> 16); + tmp ^= 0xFFFF; + *(u16*)&ipheader[10] = htons(tmp); + + // UDP checksum + // (note: normally not mandatory, but some older sgIP versions require it) + tmp = 0; + tmp += ntohs(*(u16*)&ipheader[12]); + tmp += ntohs(*(u16*)&ipheader[14]); + tmp += ntohs(*(u16*)&ipheader[16]); + tmp += ntohs(*(u16*)&ipheader[18]); + tmp += ntohs(0x1100); + tmp += (len-0x22); + for (u8* i = udpheader; i < &udpheader[len-0x23]; i += 2) + tmp += ntohs(*(u16*)i); + if (len & 1) + tmp += ntohs((u_short)udpheader[len-0x23]); + while (tmp >> 16) + tmp = (tmp & 0xFFFF) + (tmp >> 16); + tmp ^= 0xFFFF; + if (tmp == 0) tmp = 0xFFFF; + *(u16*)&udpheader[6] = htons(tmp); +} + +void FinishTCPFrame(u8* data, int len) +{ + u8* ipheader = &data[0xE]; + u8* tcpheader = &data[0x22]; + + // lengths + *(u16*)&ipheader[2] = htons(len - 0xE); + + // IP checksum + u32 tmp = 0; + + for (int i = 0; i < 20; i += 2) + tmp += ntohs(*(u16*)&ipheader[i]); + while (tmp >> 16) + tmp = (tmp & 0xFFFF) + (tmp >> 16); + tmp ^= 0xFFFF; + *(u16*)&ipheader[10] = htons(tmp); + + u32 tcplen = ntohs(*(u16*)&ipheader[2]) - 0x14; + + // TCP checksum + tmp = 0; + tmp += ntohs(*(u16*)&ipheader[12]); + tmp += ntohs(*(u16*)&ipheader[14]); + tmp += ntohs(*(u16*)&ipheader[16]); + tmp += ntohs(*(u16*)&ipheader[18]); + tmp += ntohs(0x0600); + tmp += tcplen; + for (u8* i = tcpheader; i < &tcpheader[tcplen-1]; i += 2) + tmp += ntohs(*(u16*)i); + if (tcplen & 1) + tmp += ntohs((u_short)tcpheader[tcplen-1]); + while (tmp >> 16) + tmp = (tmp & 0xFFFF) + (tmp >> 16); + tmp ^= 0xFFFF; + *(u16*)&tcpheader[16] = htons(tmp); +} + + +void HandleDHCPFrame(u8* data, int len) +{ + u8 type = 0xFF; + + u32 transid = *(u32*)&data[0x2E]; + + u8* options = &data[0x11A]; + for (;;) + { + if (options >= &data[len]) break; + u8 opt = *options++; + if (opt == 255) break; + + u8 len = *options++; + switch (opt) + { + case 53: // frame type + type = options[0]; + break; + } + + options += len; + } + + if (type == 0xFF) + { + printf("DHCP: bad frame\n"); + return; + } + + printf("DHCP: frame type %d, transid %08X\n", type, transid); + + if (type == 1 || // discover + type == 3) // request + { + u8 resp[512]; + u8* out = &resp[0]; + + // ethernet + memcpy(out, &data[6], 6); out += 6; + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x11; // protocol (UDP) + *(u16*)out = 0; out += 2; // checksum + *(u32*)out = htonl(kServerIP); out += 4; // source IP + if (type == 1) + { + *(u32*)out = htonl(0xFFFFFFFF); out += 4; // destination IP + } + else if (type == 3) + { + *(u32*)out = htonl(kClientIP); out += 4; // destination IP + } + + // UDP + u8* udpheader = out; + *(u16*)out = htons(67); out += 2; // source port + *(u16*)out = htons(68); out += 2; // destination port + *(u16*)out = 0; out += 2; // length + *(u16*)out = 0; out += 2; // checksum + + // DHCP + u8* body = out; + *out++ = 0x02; + *out++ = 0x01; + *out++ = 0x06; + *out++ = 0x00; + *(u32*)out = transid; out += 4; + *(u16*)out = 0; out += 2; // seconds elapsed + *(u16*)out = 0; out += 2; + *(u32*)out = htonl(0x00000000); out += 4; // client IP + *(u32*)out = htonl(kClientIP); out += 4; // your IP + *(u32*)out = htonl(kServerIP); out += 4; // server IP + *(u32*)out = htonl(0x00000000); out += 4; // gateway IP + memcpy(out, &data[6], 6); out += 6; + memset(out, 0, 10); out += 10; + memset(out, 0, 192); out += 192; + *(u32*)out = 0x63538263; out += 4; // DHCP magic + + // DHCP options + *out++ = 53; *out++ = 1; + *out++ = (type==1) ? 2 : 5; // DHCP type: offer/ack + *out++ = 1; *out++ = 4; + *(u32*)out = htonl(0xFFFFFF00); out += 4; // subnet mask + *out++ = 3; *out++ = 4; + *(u32*)out = htonl(kServerIP); out += 4; // router + *out++ = 51; *out++ = 4; + *(u32*)out = htonl(442030); out += 4; // lease time + *out++ = 54; *out++ = 4; + *(u32*)out = htonl(kServerIP); out += 4; // DHCP server + *out++ = 6; *out++ = 4; + *(u32*)out = htonl(kDNSIP); out += 4; // DNS (hax) + + *out++ = 0xFF; + memset(out, 0, 20); out += 20; + + u32 framelen = (u32)(out - &resp[0]); + if (framelen & 1) { *out++ = 0; framelen++; } + FinishUDPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; + } +} + +void HandleDNSFrame(u8* data, int len) +{ + u8* ipheader = &data[0xE]; + u8* udpheader = &data[0x22]; + u8* dnsbody = &data[0x2A]; + + u32 srcip = ntohl(*(u32*)&ipheader[12]); + u16 srcport = ntohs(*(u16*)&udpheader[0]); + + u16 id = ntohs(*(u16*)&dnsbody[0]); + u16 flags = ntohs(*(u16*)&dnsbody[2]); + u16 numquestions = ntohs(*(u16*)&dnsbody[4]); + u16 numanswers = ntohs(*(u16*)&dnsbody[6]); + u16 numauth = ntohs(*(u16*)&dnsbody[8]); + u16 numadd = ntohs(*(u16*)&dnsbody[10]); + + printf("DNS: ID=%04X, flags=%04X, Q=%d, A=%d, auth=%d, add=%d\n", + id, flags, numquestions, numanswers, numauth, numadd); + + // for now we only take 'simple' DNS requests + if (flags & 0x8000) return; + if (numquestions != 1 || numanswers != 0) return; + + u8 resp[1024]; + u8* out = &resp[0]; + + // ethernet + memcpy(out, &data[6], 6); out += 6; + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* resp_ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x11; // protocol (UDP) + *(u16*)out = 0; out += 2; // checksum + *(u32*)out = htonl(kDNSIP); out += 4; // source IP + *(u32*)out = htonl(srcip); out += 4; // destination IP + + // UDP + u8* resp_udpheader = out; + *(u16*)out = htons(53); out += 2; // source port + *(u16*)out = htons(srcport); out += 2; // destination port + *(u16*)out = 0; out += 2; // length + *(u16*)out = 0; out += 2; // checksum + + // DNS + u8* resp_body = out; + *(u16*)out = htons(id); out += 2; // ID + *(u16*)out = htons(0x8000); out += 2; // flags + *(u16*)out = htons(numquestions); out += 2; // num questions + *(u16*)out = htons(numquestions); out += 2; // num answers + *(u16*)out = 0; out += 2; // num authority + *(u16*)out = 0; out += 2; // num additional + + u32 curoffset = 12; + for (u16 i = 0; i < numquestions; i++) + { + if (curoffset >= (len-0x2A)) return; + + u8 bitlength = 0; + while ((bitlength = dnsbody[curoffset++]) != 0) + curoffset += bitlength; + + curoffset += 4; + } + + u32 qlen = curoffset-12; + if (qlen > 512) return; + memcpy(out, &dnsbody[12], qlen); out += qlen; + + curoffset = 12; + for (u16 i = 0; i < numquestions; i++) + { + // assemble the requested domain name + u8 bitlength = 0; + char domainname[256] = ""; int o = 0; + while ((bitlength = dnsbody[curoffset++]) != 0) + { + if ((o+bitlength) >= 255) + { + // welp. atleast try not to explode. + domainname[o++] = '\0'; + break; + } + + strncpy(&domainname[o], (const char *)&dnsbody[curoffset], bitlength); + o += bitlength; + + curoffset += bitlength; + if (dnsbody[curoffset] != 0) + domainname[o++] = '.'; + else + domainname[o++] = '\0'; + } + + u16 type = ntohs(*(u16*)&dnsbody[curoffset]); + u16 cls = ntohs(*(u16*)&dnsbody[curoffset+2]); + + printf("- q%d: %04X %04X %s", i, type, cls, domainname); + + // get answer + struct addrinfo dns_hint; + struct addrinfo* dns_res; + u32 addr_res; + + memset(&dns_hint, 0, sizeof(dns_hint)); + dns_hint.ai_family = AF_INET; // TODO: other address types (INET6, etc) + if (getaddrinfo(domainname, "0", &dns_hint, &dns_res) == 0) + { + struct addrinfo* p = dns_res; + while (p) + { + struct sockaddr_in* addr = (struct sockaddr_in*)p->ai_addr; + /*printf(" -> %d.%d.%d.%d", + addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2, + addr->sin_addr.S_un.S_un_b.s_b3, addr->sin_addr.S_un.S_un_b.s_b4);*/ + + //addr_res = addr->sin_addr.S_un.S_addr; + addr_res = *(u32*)&addr->sin_addr; + p = p->ai_next; + } + } + else + { + printf(" shat itself :("); + addr_res = 0; + } + + printf("\n"); + curoffset += 4; + + // TODO: betterer support + // (under which conditions does the C00C marker work?) + *(u16*)out = htons(0xC00C); out += 2; + *(u16*)out = htons(type); out += 2; + *(u16*)out = htons(cls); out += 2; + *(u32*)out = htonl(3600); out += 4; // TTL (hardcoded for now) + *(u16*)out = htons(4); out += 2; // address length + *(u32*)out = addr_res; out += 4; // address + } + + u32 framelen = (u32)(out - &resp[0]); + if (framelen & 1) { *out++ = 0; framelen++; } + FinishUDPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; +} + +void UDP_BuildIncomingFrame(UDPSocket* sock, u8* data, int len) +{ + u8 resp[2048]; + u8* out = &resp[0]; + + if (len > 1536) return; + + // ethernet + memcpy(out, Wifi::GetMAC(), 6); out += 6; // hurf + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* resp_ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x11; // protocol (UDP) + *(u16*)out = 0; out += 2; // checksum + memcpy(out, sock->DestIP, 4); out += 4; // source IP + *(u32*)out = htonl(kClientIP); out += 4; // destination IP + + // UDP + u8* resp_tcpheader = out; + *(u16*)out = htons(sock->DestPort); out += 2; // source port + *(u16*)out = htons(sock->SourcePort); out += 2; // destination port + *(u16*)out = htons(len+8); out += 2; // length of header+data + *(u16*)out = 0; out += 2; // checksum + + memcpy(out, data, len); out += len; + + u32 framelen = (u32)(out - &resp[0]); + FinishUDPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; +} + +void HandleUDPFrame(u8* data, int len) +{ + u8* ipheader = &data[0xE]; + u8* udpheader = &data[0x22]; + + // debug + /*for (int j = 0; j < len; j += 16) + { + int rem = len - j; + if (rem > 16) rem = 16; + for (int i = 0; i < rem; i++) + { + printf("%02X ", data[i+j]); + } + printf("\n"); + }*/ + + u16 srcport = ntohs(*(u16*)&udpheader[0]); + u16 dstport = ntohs(*(u16*)&udpheader[2]); + + int sockid = -1; + UDPSocket* sock; + for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++) + { + sock = &UDPSocketList[i]; + if (sock->Backend != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) && + sock->SourcePort == srcport && sock->DestPort == dstport) + { + sockid = i; + break; + } + } + + if (sockid == -1) + { + sockid = UDPSocketID; + sock = &UDPSocketList[sockid]; + + UDPSocketID++; + if (UDPSocketID >= (sizeof(UDPSocketList)/sizeof(UDPSocket))) + UDPSocketID = 0; + + if (sock->Backend != 0) + { + printf("LANMAGIC: closing previous UDP socket #%d\n", sockid); + closesocket(sock->Backend); + } + + sock->Backend = socket(AF_INET, SOCK_DGRAM, 0); + + memcpy(sock->DestIP, &ipheader[16], 4); + sock->SourcePort = srcport; + sock->DestPort = dstport; + + memset(&sock->BackendAddr, 0, sizeof(sock->BackendAddr)); + sock->BackendAddr.sin_family = AF_INET; + sock->BackendAddr.sin_port = htons(dstport); + memcpy(&sock->BackendAddr.sin_addr, &ipheader[16], 4); + /*if (bind(sock->Backend, (struct sockaddr*)&sock->BackendAddr, sizeof(sock->BackendAddr)) == -1) + { + printf("bind() shat itself :(\n"); + }*/ + + printf("LANMAGIC: opening UDP socket #%d to %d.%d.%d.%d:%d, srcport %d\n", + sockid, + ipheader[16], ipheader[17], ipheader[18], ipheader[19], + dstport, srcport); + } + + u16 udplen = ntohs(*(u16*)&udpheader[4]) - 8; + + printf("UDP: socket %d sending %d bytes\n", sockid, udplen); + sendto(sock->Backend, (char*)&udpheader[8], udplen, 0, + (struct sockaddr*)&sock->BackendAddr, sizeof(sock->BackendAddr)); +} + +void TCP_SYNACK(TCPSocket* sock, u8* data, int len) +{ + u8 resp[128]; + u8* out = &resp[0]; + + u8* ipheader = &data[0xE]; + u8* tcpheader = &data[0x22]; + + u32 seqnum = htonl(*(u32*)&tcpheader[4]); + seqnum++; + sock->AckNum = seqnum; + + //printf("SYNACK SEQ=%08X|%08X\n", sock->SeqNum, sock->AckNum); + + // ethernet + memcpy(out, &data[6], 6); out += 6; + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* resp_ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x06; // protocol (TCP) + *(u16*)out = 0; out += 2; // checksum + *(u32*)out = *(u32*)&ipheader[16]; out += 4; // source IP + *(u32*)out = *(u32*)&ipheader[12]; out += 4; // destination IP + + // TCP + u8* resp_tcpheader = out; + *(u16*)out = *(u16*)&tcpheader[2]; out += 2; // source port + *(u16*)out = *(u16*)&tcpheader[0]; out += 2; // destination port + *(u32*)out = htonl(sock->SeqNum); out += 4; sock->SeqNum++; // seq number + *(u32*)out = htonl(seqnum); out += 4; // ack seq number + *(u16*)out = htons(0x8012); out += 2; // flags (SYN+ACK) + *(u16*)out = htons(0x7000); out += 2; // window size (uuuh) + *(u16*)out = 0; out += 2; // checksum + *(u16*)out = 0; out += 2; // urgent pointer + + // TCP options + *out++ = 0x02; *out++ = 0x04; // max segment size + *(u16*)out = htons(0x05B4); out += 2; + *out++ = 0x01; + *out++ = 0x01; + *out++ = 0x04; *out++ = 0x02; // SACK permitted + *out++ = 0x01; + *out++ = 0x03; *out++ = 0x03; // window size + *out++ = 0x08; + + u32 framelen = (u32)(out - &resp[0]); + //if (framelen & 1) { *out++ = 0; framelen++; } + FinishTCPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; +} + +void TCP_ACK(TCPSocket* sock, bool fin) +{ + u8 resp[64]; + u8* out = &resp[0]; + + u16 flags = 0x5010; + if (fin) flags |= 0x0001; + + //printf("%sACK SEQ=%08X|%08X\n", fin?"FIN":" ", sock->SeqNum, sock->AckNum); + + // ethernet + memcpy(out, Wifi::GetMAC(), 6); out += 6; + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* resp_ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x06; // protocol (TCP) + *(u16*)out = 0; out += 2; // checksum + *(u32*)out = *(u32*)&sock->DestIP; out += 4; // source IP + *(u32*)out = htonl(kClientIP); out += 4; // destination IP + + // TCP + u8* resp_tcpheader = out; + *(u16*)out = htonl(sock->DestPort); out += 2; // source port + *(u16*)out = htonl(sock->SourcePort); out += 2; // destination port + *(u32*)out = htonl(sock->SeqNum); out += 4; // seq number + *(u32*)out = htonl(sock->AckNum); out += 4; // ack seq number + *(u16*)out = htons(flags); out += 2; // flags + *(u16*)out = htons(0x7000); out += 2; // window size (uuuh) + *(u16*)out = 0; out += 2; // checksum + *(u16*)out = 0; out += 2; // urgent pointer + + u32 framelen = (u32)(out - &resp[0]); + //if (framelen & 1) { *out++ = 0; framelen++; } + FinishTCPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; +} + +void TCP_BuildIncomingFrame(TCPSocket* sock, u8* data, int len) +{ + u8 resp[2048]; + u8* out = &resp[0]; + + if (len > 1536) return; +//printf("INCOMING SEQ=%08X|%08X\n", sock->SeqNum, sock->AckNum); + // ethernet + memcpy(out, Wifi::GetMAC(), 6); out += 6; // hurf + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0800); out += 2; + + // IP + u8* resp_ipheader = out; + *out++ = 0x45; + *out++ = 0x00; + *(u16*)out = 0; out += 2; // total length + *(u16*)out = htons(IPv4ID); out += 2; IPv4ID++; + *out++ = 0x00; + *out++ = 0x00; + *out++ = 0x80; // TTL + *out++ = 0x06; // protocol (TCP) + *(u16*)out = 0; out += 2; // checksum + memcpy(out, sock->DestIP, 4); out += 4; // source IP + *(u32*)out = htonl(kClientIP); out += 4; // destination IP + + // TCP + u8* resp_tcpheader = out; + *(u16*)out = htons(sock->DestPort); out += 2; // source port + *(u16*)out = htons(sock->SourcePort); out += 2; // destination port + *(u32*)out = htonl(sock->SeqNum); out += 4; // seq number + *(u32*)out = htonl(sock->AckNum); out += 4; // ack seq number + *(u16*)out = htons(0x5018); out += 2; // flags (ACK, PSH) + *(u16*)out = htons(0x7000); out += 2; // window size (uuuh) + *(u16*)out = 0; out += 2; // checksum + *(u16*)out = 0; out += 2; // urgent pointer + + memcpy(out, data, len); out += len; + + u32 framelen = (u32)(out - &resp[0]); + FinishTCPFrame(resp, framelen); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; + + sock->SeqNum += len; +} + +void HandleTCPFrame(u8* data, int len) +{ + u8* ipheader = &data[0xE]; + u8* tcpheader = &data[0x22]; + + u16 srcport = ntohs(*(u16*)&tcpheader[0]); + u16 dstport = ntohs(*(u16*)&tcpheader[2]); + u16 flags = ntohs(*(u16*)&tcpheader[12]); + + u32 tcpheaderlen = 4 * (flags >> 12); + u32 tcplen = ntohs(*(u16*)&ipheader[2]) - 0x14; + u32 tcpdatalen = tcplen - tcpheaderlen; + + /*printf("tcpflags=%04X header=%d data=%d seq=%08X|%08X\n", + flags, tcpheaderlen, tcpdatalen, + ntohl(*(u32*)&tcpheader[4]), + ntohl(*(u32*)&tcpheader[8]));*/ + + if (flags & 0x002) // SYN + { + int sockid = -1; + TCPSocket* sock; + for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++) + { + sock = &TCPSocketList[i]; + if (sock->Status != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) && + sock->SourcePort == srcport && sock->DestPort == dstport) + { + printf("LANMAGIC: duplicate TCP socket\n"); + sockid = i; + break; + } + } + + if (sockid == -1) + { + for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++) + { + sock = &TCPSocketList[i]; + if (sock->Status == 0) + { + sockid = i; + break; + } + } + } + + if (sockid == -1) + { + printf("LANMAGIC: !! TCP SOCKET LIST FULL\n"); + return; + } + + printf("LANMAGIC: opening TCP socket #%d to %d.%d.%d.%d:%d, srcport %d\n", + sockid, + ipheader[16], ipheader[17], ipheader[18], ipheader[19], + dstport, srcport); + + // keep track of it + sock->Status = 1; + memcpy(sock->DestIP, &ipheader[16], 4); + sock->DestPort = dstport; + sock->SourcePort = srcport; + sock->SeqNum = 0x13370000; + sock->AckNum = 0; + + // open backend socket + if (!sock->Backend) + { + sock->Backend = socket(AF_INET, SOCK_STREAM, 0); + } + + struct sockaddr_in conn_addr; + memset(&conn_addr, 0, sizeof(conn_addr)); + conn_addr.sin_family = AF_INET; + memcpy(&conn_addr.sin_addr, &ipheader[16], 4); + conn_addr.sin_port = htons(dstport); + if (connect(sock->Backend, (sockaddr*)&conn_addr, sizeof(conn_addr)) == -1) + { + printf("connect() shat itself :(\n"); + } + else + { + // acknowledge it + TCP_SYNACK(sock, data, len); + } + } + else + { + int sockid = -1; + TCPSocket* sock; + for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++) + { + sock = &TCPSocketList[i]; + if (sock->Status != 0 && !memcmp(&sock->DestIP, &ipheader[16], 4) && + sock->SourcePort == srcport && sock->DestPort == dstport) + { + sockid = i; + break; + } + } + + if (sockid == -1) + { + printf("LANMAGIC: bad TCP packet\n"); + return; + } + + // TODO: check those + u32 seqnum = ntohl(*(u32*)&tcpheader[4]); + u32 acknum = ntohl(*(u32*)&tcpheader[8]); + sock->SeqNum = acknum; + sock->AckNum = seqnum + tcpdatalen; + + // send data over the socket + if (tcpdatalen > 0) + { + u8* tcpdata = &tcpheader[tcpheaderlen]; + + printf("TCP: socket %d sending %d bytes (flags=%04X)\n", sockid, tcpdatalen, flags); + send(sock->Backend, (char*)tcpdata, tcpdatalen, 0); + + // kind of a hack, there + TCP_ACK(sock, false); + } + + if (flags & 0x001) // FIN + { + // TODO: timeout etc + printf("TCP: socket %d closing\n", sockid); + + sock->Status = 0; + closesocket(sock->Backend); + sock->Backend = 0; + } + } +} + +void HandleARPFrame(u8* data, int len) +{ + u16 protocol = ntohs(*(u16*)&data[0x10]); + if (protocol != 0x0800) return; + + u16 op = ntohs(*(u16*)&data[0x14]); + u32 targetip = ntohl(*(u32*)&data[0x26]); + + // TODO: handle ARP to the client + // this only handles ARP to the DHCP/router + + if (op == 1) + { + // opcode 1=req 2=reply + // sender MAC + // sender IP + // target MAC + // target IP + + const u8* targetmac; + if (targetip == kServerIP) targetmac = kServerMAC; + else if (targetip == kDNSIP) targetmac = kDNSMAC; + else return; + + u8 resp[64]; + u8* out = &resp[0]; + + // ethernet + memcpy(out, &data[6], 6); out += 6; + memcpy(out, kServerMAC, 6); out += 6; + *(u16*)out = htons(0x0806); out += 2; + + // ARP + *(u16*)out = htons(0x0001); out += 2; // hardware type + *(u16*)out = htons(0x0800); out += 2; // protocol + *out++ = 6; // MAC address size + *out++ = 4; // IP address size + *(u16*)out = htons(0x0002); out += 2; // opcode + memcpy(out, targetmac, 6); out += 6; + *(u32*)out = htonl(targetip); out += 4; + memcpy(out, &data[0x16], 6+4); out += 6+4; + + u32 framelen = (u32)(out - &resp[0]); + + // TODO: if there is already a packet queued, this will overwrite it + // that being said, this will only happen during DHCP setup, so probably + // not a big deal + + PacketLen = framelen; + memcpy(PacketBuffer, resp, PacketLen); + RXNum = 1; + } + else + { + printf("wat??\n"); + } +} + +void HandlePacket(u8* data, int len) +{ + u16 ethertype = ntohs(*(u16*)&data[0xC]); + + if (ethertype == 0x0800) // IPv4 + { + u8 protocol = data[0x17]; + if (protocol == 0x11) // UDP + { + u16 srcport = ntohs(*(u16*)&data[0x22]); + u16 dstport = ntohs(*(u16*)&data[0x24]); + if (srcport == 68 && dstport == 67) // DHCP + { + printf("LANMAGIC: DHCP packet\n"); + return HandleDHCPFrame(data, len); + } + else if (dstport == 53 && htonl(*(u32*)&data[0x1E]) == kDNSIP) // DNS + { + printf("LANMAGIC: DNS packet\n"); + return HandleDNSFrame(data, len); + } + + printf("LANMAGIC: UDP packet %d->%d\n", srcport, dstport); + return HandleUDPFrame(data, len); + } + else if (protocol == 0x06) // TCP + { + printf("LANMAGIC: TCP packet\n"); + return HandleTCPFrame(data, len); + } + else + printf("LANMAGIC: unsupported IP protocol %02X\n", protocol); + } + else if (ethertype == 0x0806) // ARP + { + printf("LANMAGIC: ARP packet\n"); + return HandleARPFrame(data, len); + } + else + printf("LANMAGIC: unsupported ethernet type %04X\n", ethertype); +} + +int SendPacket(u8* data, int len) +{ + if (len > 2048) + { + printf("LAN_SendPacket: error: packet too long (%d)\n", len); + return 0; + } + + HandlePacket(data, len); + return len; +} + +int RecvPacket(u8* data) +{ + int ret = 0; + if (RXNum > 0) + { + memcpy(data, PacketBuffer, PacketLen); + ret = PacketLen; + RXNum = 0; + } + + for (int i = 0; i < (sizeof(TCPSocketList)/sizeof(TCPSocket)); i++) + { + TCPSocket* sock = &TCPSocketList[i]; + if (sock->Status != 1) continue; + + fd_set fd; + struct timeval tv; + + FD_ZERO(&fd); + FD_SET(sock->Backend, &fd); + tv.tv_sec = 0; + tv.tv_usec = 0; + + if (!select(sock->Backend+1, &fd, 0, 0, &tv)) + { + continue; + } + + u8 recvbuf[1024]; + int recvlen = recv(sock->Backend, (char*)recvbuf, 1024, 0); + if (recvlen < 1) + { + if (recvlen == 0) + { + // socket has closed from the other side + printf("TCP: socket %d closed from other side\n", i); + sock->Status = 2; + TCP_ACK(sock, true); + } + continue; + } + + printf("TCP: socket %d receiving %d bytes\n", i, recvlen); + TCP_BuildIncomingFrame(sock, recvbuf, recvlen); + + // debug + /*for (int j = 0; j < recvlen; j += 16) + { + int rem = recvlen - j; + if (rem > 16) rem = 16; + for (int k = 0; k < rem; k++) + { + printf("%02X ", recvbuf[k+j]); + } + printf("\n"); + }*/ + + //recvlen = recv(sock->Backend, (char*)recvbuf, 1024, 0); + //if (recvlen == 0) printf("it closed immediately after\n"); + } + + for (int i = 0; i < (sizeof(UDPSocketList)/sizeof(UDPSocket)); i++) + { + UDPSocket* sock = &UDPSocketList[i]; + if (sock->Backend == 0) continue; + + fd_set fd; + struct timeval tv; + + FD_ZERO(&fd); + FD_SET(sock->Backend, &fd); + tv.tv_sec = 0; + tv.tv_usec = 0; + + if (!select(sock->Backend+1, &fd, 0, 0, &tv)) + { + continue; + } + + u8 recvbuf[1024]; + sockaddr_t fromAddr; + socklen_t fromLen = sizeof(sockaddr_t); + int recvlen = recvfrom(sock->Backend, (char*)recvbuf, 1024, 0, &fromAddr, &fromLen); + if (recvlen < 1) continue; + + if (fromAddr.sa_family != AF_INET) continue; + struct sockaddr_in* fromAddrIn = (struct sockaddr_in*)&fromAddr; + if (memcmp(&fromAddrIn->sin_addr, sock->DestIP, 4)) continue; + if (ntohs(fromAddrIn->sin_port) != sock->DestPort) continue; + + printf("UDP: socket %d receiving %d bytes\n", i, recvlen); + UDP_BuildIncomingFrame(sock, recvbuf, recvlen); + } + + return ret; +} + +} diff --git a/src/frontend/qt_sdl/LAN_Socket.h b/src/frontend/qt_sdl/LAN_Socket.h new file mode 100644 index 0000000..8453a5f --- /dev/null +++ b/src/frontend/qt_sdl/LAN_Socket.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 LAN_SOCKET_H +#define LAN_SOCKET_H + +#include "../types.h" + +namespace LAN_Socket +{ + +// + + +bool Init(); +void DeInit(); + +int SendPacket(u8* data, int len); +int RecvPacket(u8* data); + +} + +#endif // LAN_SOCKET_H diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.ui b/src/frontend/qt_sdl/WifiSettingsDialog.ui new file mode 100644 index 0000000..bfee1fd --- /dev/null +++ b/src/frontend/qt_sdl/WifiSettingsDialog.ui @@ -0,0 +1,165 @@ + + + WifiSettingsDialog + + + + 0 + 0 + 479 + 217 + + + + + 0 + 0 + + + + Wifi settings - melonDS + + + + QLayout::SetFixedSize + + + + + Local + + + + + + <html><head/><body><p>Enabling this allows (theoretically) playing local multiplayer games over a local network. It may or may not help make for a better connection in general.</p></body></html> + + + Bind socket to any address + + + + + + + + + + Online + + + + + + MAC address: + + + + + + + <html><head/><body><p>Direct mode directly routes network traffic to the host network. It is the most reliable, but requires an ethernet connection.</p><p><br/></p><p>Non-direct mode uses a layer of emulation to get around this, but is more prone to problems.</p></body></html> + + + Direct mode [TEXT PLACEHOLDER] + + + + + + + + 0 + 0 + + + + + 350 + 0 + + + + <html><head/><body><p>Selects the network adapter through which to route network traffic under direct mode.</p></body></html> + + + + + + + Network adapter: + + + + + + + IP address: + + + + + + + [PLACEHOLDER] + + + + + + + [PLACEHOLDER] + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + WifiSettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WifiSettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qt_sdl/pcap/bluetooth.h b/src/frontend/qt_sdl/pcap/bluetooth.h new file mode 100644 index 0000000..15dc5a8 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/bluetooth.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2006 Paolo Abeni (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * bluetooth data struct + * By Paolo Abeni + */ + +#ifndef lib_pcap_bluetooth_h +#define lib_pcap_bluetooth_h + +#include + +/* + * Header prepended libpcap to each bluetooth h4 frame, + * fields are in network byte order + */ +typedef struct _pcap_bluetooth_h4_header { + uint32_t direction; /* if first bit is set direction is incoming */ +} pcap_bluetooth_h4_header; + +/* + * Header prepended libpcap to each bluetooth linux monitor frame, + * fields are in network byte order + */ +typedef struct _pcap_bluetooth_linux_monitor_header { + uint16_t adapter_id; + uint16_t opcode; +} pcap_bluetooth_linux_monitor_header; + +#endif diff --git a/src/frontend/qt_sdl/pcap/bpf.h b/src/frontend/qt_sdl/pcap/bpf.h new file mode 100644 index 0000000..1a953a9 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/bpf.h @@ -0,0 +1,270 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + */ + +/* + * This is libpcap's cut-down version of bpf.h; it includes only + * the stuff needed for the code generator and the userland BPF + * interpreter, and the libpcap APIs for setting filters, etc.. + * + * "pcap-bpf.c" will include the native OS version, as it deals with + * the OS's BPF implementation. + * + * At least two programs found by Google Code Search explicitly includes + * (even though / includes it for you), + * so moving that stuff to would break the build for some + * programs. + */ + +/* + * If we've already included , don't re-define this stuff. + * We assume BSD-style multiple-include protection in , + * which is true of all but the oldest versions of FreeBSD and NetBSD, + * or Tru64 UNIX-style multiple-include protection (or, at least, + * Tru64 UNIX 5.x-style; I don't have earlier versions available to check), + * or AIX-style multiple-include protection (or, at least, AIX 5.x-style; + * I don't have earlier versions available to check), or QNX-style + * multiple-include protection (as per GitHub pull request #394). + * + * We do not check for BPF_MAJOR_VERSION, as that's defined by + * , which is directly or indirectly included in some + * programs that also include pcap.h, and doesn't + * define stuff we need. + * + * This also provides our own multiple-include protection. + */ +#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) +#define lib_pcap_bpf_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* BSD style release date */ +#define BPF_RELEASE 199606 + +#ifdef MSDOS /* must be 32-bit */ +typedef long bpf_int32; +typedef unsigned long bpf_u_int32; +#else +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +/* + * Alignment macros. BPF_WORDALIGN rounds up to the next + * even multiple of BPF_ALIGNMENT. + * + * Tcpdump's print-pflog.c uses this, so we define it here. + */ +#ifndef __NetBSD__ +#define BPF_ALIGNMENT sizeof(bpf_int32) +#else +#define BPF_ALIGNMENT sizeof(long) +#endif +#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) + +/* + * Structure for "pcap_compile()", "pcap_setfilter()", etc.. + */ +struct bpf_program { + u_int bf_len; + struct bpf_insn *bf_insns; +}; + +#include + +/* + * The instruction encodings. + * + * Please inform tcpdump-workers@lists.tcpdump.org if you use any + * of the reserved values, so that we can note that they're used + * (and perhaps implement it in the reference BPF implementation + * and encourage its implementation elsewhere). + */ + +/* + * The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000. + */ + +/* instruction classes */ +#define BPF_CLASS(code) ((code) & 0x07) +#define BPF_LD 0x00 +#define BPF_LDX 0x01 +#define BPF_ST 0x02 +#define BPF_STX 0x03 +#define BPF_ALU 0x04 +#define BPF_JMP 0x05 +#define BPF_RET 0x06 +#define BPF_MISC 0x07 + +/* ld/ldx fields */ +#define BPF_SIZE(code) ((code) & 0x18) +#define BPF_W 0x00 +#define BPF_H 0x08 +#define BPF_B 0x10 +/* 0x18 reserved; used by BSD/OS */ +#define BPF_MODE(code) ((code) & 0xe0) +#define BPF_IMM 0x00 +#define BPF_ABS 0x20 +#define BPF_IND 0x40 +#define BPF_MEM 0x60 +#define BPF_LEN 0x80 +#define BPF_MSH 0xa0 +/* 0xc0 reserved; used by BSD/OS */ +/* 0xe0 reserved; used by BSD/OS */ + +/* alu/jmp fields */ +#define BPF_OP(code) ((code) & 0xf0) +#define BPF_ADD 0x00 +#define BPF_SUB 0x10 +#define BPF_MUL 0x20 +#define BPF_DIV 0x30 +#define BPF_OR 0x40 +#define BPF_AND 0x50 +#define BPF_LSH 0x60 +#define BPF_RSH 0x70 +#define BPF_NEG 0x80 +#define BPF_MOD 0x90 +#define BPF_XOR 0xa0 +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ + +#define BPF_JA 0x00 +#define BPF_JEQ 0x10 +#define BPF_JGT 0x20 +#define BPF_JGE 0x30 +#define BPF_JSET 0x40 +/* 0x50 reserved; used on BSD/OS */ +/* 0x60 reserved */ +/* 0x70 reserved */ +/* 0x80 reserved */ +/* 0x90 reserved */ +/* 0xa0 reserved */ +/* 0xb0 reserved */ +/* 0xc0 reserved */ +/* 0xd0 reserved */ +/* 0xe0 reserved */ +/* 0xf0 reserved */ +#define BPF_SRC(code) ((code) & 0x08) +#define BPF_K 0x00 +#define BPF_X 0x08 + +/* ret - BPF_K and BPF_X also apply */ +#define BPF_RVAL(code) ((code) & 0x18) +#define BPF_A 0x10 +/* 0x18 reserved */ + +/* misc */ +#define BPF_MISCOP(code) ((code) & 0xf8) +#define BPF_TAX 0x00 +/* 0x08 reserved */ +/* 0x10 reserved */ +/* 0x18 reserved */ +/* #define BPF_COP 0x20 NetBSD "coprocessor" extensions */ +/* 0x28 reserved */ +/* 0x30 reserved */ +/* 0x38 reserved */ +/* #define BPF_COPX 0x40 NetBSD "coprocessor" extensions */ +/* also used on BSD/OS */ +/* 0x48 reserved */ +/* 0x50 reserved */ +/* 0x58 reserved */ +/* 0x60 reserved */ +/* 0x68 reserved */ +/* 0x70 reserved */ +/* 0x78 reserved */ +#define BPF_TXA 0x80 +/* 0x88 reserved */ +/* 0x90 reserved */ +/* 0x98 reserved */ +/* 0xa0 reserved */ +/* 0xa8 reserved */ +/* 0xb0 reserved */ +/* 0xb8 reserved */ +/* 0xc0 reserved; used on BSD/OS */ +/* 0xc8 reserved */ +/* 0xd0 reserved */ +/* 0xd8 reserved */ +/* 0xe0 reserved */ +/* 0xe8 reserved */ +/* 0xf0 reserved */ +/* 0xf8 reserved */ + +/* + * The instruction data structure. + */ +struct bpf_insn { + u_short code; + u_char jt; + u_char jf; + bpf_u_int32 k; +}; + +/* + * Auxiliary data, for use when interpreting a filter intended for the + * Linux kernel when the kernel rejects the filter (requiring us to + * run it in userland). It contains VLAN tag information. + */ +struct bpf_aux_data { + u_short vlan_tag_present; + u_short vlan_tag; +}; + +/* + * Macros for insn array initializers. + */ +#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } +#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } + +PCAP_API int bpf_validate(const struct bpf_insn *, int); +PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); + +/* + * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). + */ +#define BPF_MEMWORDS 16 + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) */ diff --git a/src/frontend/qt_sdl/pcap/can_socketcan.h b/src/frontend/qt_sdl/pcap/can_socketcan.h new file mode 100644 index 0000000..332d9ff --- /dev/null +++ b/src/frontend/qt_sdl/pcap/can_socketcan.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_can_socketcan_h +#define lib_pcap_can_socketcan_h + +#include + +/* + * SocketCAN header, as per Documentation/networking/can.txt in the + * Linux source. + */ +typedef struct { + uint32_t can_id; + uint8_t payload_length; + uint8_t pad; + uint8_t reserved1; + uint8_t reserved2; +} pcap_can_socketcan_hdr; + +#endif diff --git a/src/frontend/qt_sdl/pcap/compiler-tests.h b/src/frontend/qt_sdl/pcap/compiler-tests.h new file mode 100644 index 0000000..8876c67 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/compiler-tests.h @@ -0,0 +1,152 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_compiler_tests_h +#define lib_pcap_compiler_tests_h + + +/* + * This was introduced by Clang: + * + * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute + * + * in some version (which version?); it has been picked up by GCC 5.0. + */ +#ifndef __has_attribute + /* + * It's a macro, so you can check whether it's defined to check + * whether it's supported. + * + * If it's not, define it to always return 0, so that we move on to + * the fallback checks. + */ + #define __has_attribute(x) 0 +#endif + +/* + * Note that the C90 spec's "6.8.1 Conditional inclusion" and the + * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say: + * + * Prior to evaluation, macro invocations in the list of preprocessing + * tokens that will become the controlling constant expression are + * replaced (except for those macro names modified by the defined unary + * operator), just as in normal text. If the token "defined" is + * generated as a result of this replacement process or use of the + * "defined" unary operator does not match one of the two specified + * forms prior to macro replacement, the behavior is undefined. + * + * so you shouldn't use defined() in a #define that's used in #if or + * #elif. Some versions of Clang, for example, will warn about this. + * + * Instead, we check whether the pre-defined macros for particular + * compilers are defined and, if not, define the "is this version XXX + * or a later version of this compiler" macros as 0. + */ + +/* + * Check whether this is GCC major.minor or a later release, or some + * compiler that claims to be "just like GCC" of that version or a + * later release. + */ + +#if ! defined(__GNUC__) +#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 +#else +#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \ + (__GNUC__ > (major) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#endif + +/* + * Check whether this is Sun C/SunPro C/Oracle Studio major.minor + * or a later release. + * + * The version number in __SUNPRO_C is encoded in hex BCD, with the + * uppermost hex digit being the major version number, the next + * one or two hex digits being the minor version number, and + * the last digit being the patch version. + * + * It represents the *compiler* version, not the product version; + * see + * + * https://sourceforge.net/p/predef/wiki/Compilers/ + * + * for a partial mapping, which we assume continues for later + * 12.x product releases. + */ + +#if ! defined(__SUNPRO_C) +#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0 +#else +#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \ + (((minor) >= 10) ? \ + (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \ + (((major) << 8) | ((minor) << 4))) +#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \ + (__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor))) +#endif + +/* + * Check whether this is IBM XL C major.minor or a later release. + * + * The version number in __xlC__ has the major version in the + * upper 8 bits and the minor version in the lower 8 bits. + */ + +#if ! defined(__xlC__) +#define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0 +#else +#define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \ + (__xlC__ >= (((major) << 8) | (minor))) +#endif + +/* + * Check whether this is HP aC++/HP C major.minor or a later release. + * + * The version number in __HP_aCC is encoded in zero-padded decimal BCD, + * with the "A." stripped off, the uppermost two decimal digits being + * the major version number, the next two decimal digits being the minor + * version number, and the last two decimal digits being the patch version. + * (Strip off the A., remove the . between the major and minor version + * number, and add two digits of patch.) + */ + +#if ! defined(__HP_aCC) +#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0 +#else +#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \ + (__HP_aCC >= ((major)*10000 + (minor)*100)) +#endif + +#endif /* lib_pcap_funcattrs_h */ diff --git a/src/frontend/qt_sdl/pcap/dlt.h b/src/frontend/qt_sdl/pcap/dlt.h new file mode 100644 index 0000000..609bcaf --- /dev/null +++ b/src/frontend/qt_sdl/pcap/dlt.h @@ -0,0 +1,1389 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)bpf.h 7.1 (Berkeley) 5/7/91 + */ + +#ifndef lib_pcap_dlt_h +#define lib_pcap_dlt_h + +/* + * Link-layer header type codes. + * + * Do *NOT* add new values to this list without asking + * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run + * the risk of using a value that's already being used for some other + * purpose, and of having tools that read libpcap-format captures not + * being able to handle captures with your new DLT_ value, with no hope + * that they will ever be changed to do so (as that would destroy their + * ability to read captures using that value for that other purpose). + * + * See + * + * http://www.tcpdump.org/linktypes.html + * + * for detailed descriptions of some of these link-layer header types. + */ + +/* + * These are the types that are the same on all platforms, and that + * have been defined by for ages. + */ +#define DLT_NULL 0 /* BSD loopback encapsulation */ +#define DLT_EN10MB 1 /* Ethernet (10Mb) */ +#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ +#define DLT_AX25 3 /* Amateur Radio AX.25 */ +#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ +#define DLT_CHAOS 5 /* Chaos */ +#define DLT_IEEE802 6 /* 802.5 Token Ring */ +#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ +#define DLT_SLIP 8 /* Serial Line IP */ +#define DLT_PPP 9 /* Point-to-point Protocol */ +#define DLT_FDDI 10 /* FDDI */ + +/* + * These are types that are different on some platforms, and that + * have been defined by for ages. We use #ifdefs to + * detect the BSDs that define them differently from the traditional + * libpcap + * + * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, + * but I don't know what the right #define is for BSD/OS. + */ +#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ + +#ifdef __OpenBSD__ +#define DLT_RAW 14 /* raw IP */ +#else +#define DLT_RAW 12 /* raw IP */ +#endif + +/* + * Given that the only OS that currently generates BSD/OS SLIP or PPP + * is, well, BSD/OS, arguably everybody should have chosen its values + * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they + * didn't. So it goes. + */ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#ifndef DLT_SLIP_BSDOS +#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ +#endif +#else +#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ +#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ +#endif + +/* + * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. + * + * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG + * as 117 so that pflog captures would use a link-layer header type + * value that didn't collide with any other values. On all + * platforms other than OpenBSD, we defined DLT_PFLOG as 117, + * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. + * + * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. + * + * Don't use 17 for anything else. + */ + +/* + * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and + * Mac OS X; don't use it for anything else. (FreeBSD uses 121, + * which collides with DLT_HHDLC, even though it doesn't use 18 + * for anything and doesn't appear to have ever used it for anything.) + * + * We define it as 18 on those platforms; it is, unfortunately, used + * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC + * in general. As the packet format for it, like that for + * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, + * we don't support printing it in tcpdump except on OSes that + * have the relevant header files, so it's not that useful on + * other platforms. + */ +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) +#define DLT_PFSYNC 18 +#endif + +#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ + +/* + * Apparently Redback uses this for its SmartEdge 400/800. I hope + * nobody else decided to use it, too. + */ +#define DLT_REDBACK_SMARTEDGE 32 + +/* + * These values are defined by NetBSD; other platforms should refrain from + * using them for other purposes, so that NetBSD savefiles with link + * types of 50 or 51 can be read as this type on all platforms. + */ +#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ +#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ + +/* + * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses + * a link-layer type of 99 for the tcpdump it supplies. The link-layer + * header has 6 bytes of unknown data, something that appears to be an + * Ethernet type, and 36 bytes that appear to be 0 in at least one capture + * I've seen. + */ +#define DLT_SYMANTEC_FIREWALL 99 + +/* + * Values between 100 and 103 are used in capture file headers as + * link-layer header type LINKTYPE_ values corresponding to DLT_ types + * that differ between platforms; don't use those values for new DLT_ + * new types. + */ + +/* + * Values starting with 104 are used for newly-assigned link-layer + * header type values; for those link-layer header types, the DLT_ + * value returned by pcap_datalink() and passed to pcap_open_dead(), + * and the LINKTYPE_ value that appears in capture files, are the + * same. + * + * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is + * the highest such value. + */ +#define DLT_MATCHING_MIN 104 + +/* + * This value was defined by libpcap 0.5; platforms that have defined + * it with a different value should define it here with that value - + * a link type of 104 in a save file will be mapped to DLT_C_HDLC, + * whatever value that happens to be, so programs will correctly + * handle files with that link type regardless of the value of + * DLT_C_HDLC. + * + * The name DLT_C_HDLC was used by BSD/OS; we use that name for source + * compatibility with programs written for BSD/OS. + * + * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, + * for source compatibility with programs written for libpcap 0.5. + */ +#define DLT_C_HDLC 104 /* Cisco HDLC */ +#define DLT_CHDLC DLT_C_HDLC + +#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ + +/* + * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, + * except when it isn't. (I.e., sometimes it's just raw IP, and + * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, + * so that we don't have to worry about the link-layer header.) + */ + +/* + * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides + * with other values. + * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header + * (DLCI, etc.). + */ +#define DLT_FRELAY 107 + +/* + * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except + * that the AF_ type in the link-layer header is in network byte order. + * + * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so + * we don't use 12 for it in OSes other than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_LOOP 12 +#else +#define DLT_LOOP 108 +#endif + +/* + * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's + * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other + * than OpenBSD. + */ +#ifdef __OpenBSD__ +#define DLT_ENC 13 +#else +#define DLT_ENC 109 +#endif + +/* + * Values between 110 and 112 are reserved for use in capture file headers + * as link-layer types corresponding to DLT_ types that might differ + * between platforms; don't use those values for new DLT_ types + * other than the corresponding DLT_ types. + */ + +/* + * This is for Linux cooked sockets. + */ +#define DLT_LINUX_SLL 113 + +/* + * Apple LocalTalk hardware. + */ +#define DLT_LTALK 114 + +/* + * Acorn Econet. + */ +#define DLT_ECONET 115 + +/* + * Reserved for use with OpenBSD ipfilter. + */ +#define DLT_IPFILTER 116 + +/* + * OpenBSD DLT_PFLOG. + */ +#define DLT_PFLOG 117 + +/* + * Registered for Cisco-internal use. + */ +#define DLT_CISCO_IOS 118 + +/* + * For 802.11 cards using the Prism II chips, with a link-layer + * header including Prism monitor mode information plus an 802.11 + * header. + */ +#define DLT_PRISM_HEADER 119 + +/* + * Reserved for Aironet 802.11 cards, with an Aironet link-layer header + * (see Doug Ambrisko's FreeBSD patches). + */ +#define DLT_AIRONET_HEADER 120 + +/* + * Sigh. + * + * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as + * requested by Tomas Kukosa. + * + * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that + * assigned 121 as DLT_PFSYNC. In current versions, its libpcap + * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a + * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC + * dump files with 246 as the link-layer header type. (Earlier + * versions might not have done mapping, in which case they would + * have written them out with a link-layer header type of 121.) + * + * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; + * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would + * write out DLT_PFSYNC dump files with use 18 as the link-layer + * header type. + * + * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in + * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, + * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they + * should write out DLT_PFSYNC dump files with 246 as the link-layer + * header type. (Earlier versions might not have done mapping, + * in which case they'd work the same way OpenBSD does, writing + * them out with a link-layer header type of 18.) + * + * We'll define DLT_PFSYNC as: + * + * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; + * + * 121 on FreeBSD; + * + * 246 everywhere else. + * + * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; + * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC + * is out of luck. + * + * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that + * savefiles written using *this* code won't use 18 or 121 for PFSYNC, + * they'll all use 246. + * + * Code that uses pcap_datalink() to determine the link-layer header + * type of a savefile won't, when built and run on FreeBSD, be able + * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture + * files, as pcap_datalink() will give 121 for both of them. Code + * that doesn't, such as the code in Wireshark, will be able to + * distinguish between them. + * + * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., + * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, + * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's + * libpcap won't treat those files as DLT_PFSYNC files. + * + * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; + * this means they can read DLT_HHDLC files, if any exist, but won't + * treat pcap files written by any older versions of FreeBSD libpcap that + * didn't map to 246 as DLT_PFSYNC files. + */ +#ifdef __FreeBSD__ +#define DLT_PFSYNC 121 +#else +#define DLT_HHDLC 121 +#endif + +/* + * This is for RFC 2625 IP-over-Fibre Channel. + * + * This is not for use with raw Fibre Channel, where the link-layer + * header starts with a Fibre Channel frame header; it's for IP-over-FC, + * where the link-layer header starts with an RFC 2625 Network_Header + * field. + */ +#define DLT_IP_OVER_FC 122 + +/* + * This is for Full Frontal ATM on Solaris with SunATM, with a + * pseudo-header followed by an AALn PDU. + * + * There may be other forms of Full Frontal ATM on other OSes, + * with different pseudo-headers. + * + * If ATM software returns a pseudo-header with VPI/VCI information + * (and, ideally, packet type information, e.g. signalling, ILMI, + * LANE, LLC-multiplexed traffic, etc.), it should not use + * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump + * and the like don't have to infer the presence or absence of a + * pseudo-header and the form of the pseudo-header. + */ +#define DLT_SUNATM 123 /* Solaris+SunATM */ + +/* + * Reserved as per request from Kent Dahlgren + * for private use. + */ +#define DLT_RIO 124 /* RapidIO */ +#define DLT_PCI_EXP 125 /* PCI Express */ +#define DLT_AURORA 126 /* Xilinx Aurora link layer */ + +/* + * Header for 802.11 plus a number of bits of link-layer information + * including radio information, used by some recent BSD drivers as + * well as the madwifi Atheros driver for Linux. + */ +#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ + +/* + * Reserved for the TZSP encapsulation, as per request from + * Chris Waters + * TZSP is a generic encapsulation for any other link type, + * which includes a means to include meta-information + * with the packet, e.g. signal strength and channel + * for 802.11 packets. + */ +#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ + +/* + * BSD's ARCNET headers have the source host, destination host, + * and type at the beginning of the packet; that's what's handed + * up to userland via BPF. + * + * Linux's ARCNET headers, however, have a 2-byte offset field + * between the host IDs and the type; that's what's handed up + * to userland via PF_PACKET sockets. + * + * We therefore have to have separate DLT_ values for them. + */ +#define DLT_ARCNET_LINUX 129 /* ARCNET */ + +/* + * Juniper-private data link types, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MLPPP 130 +#define DLT_JUNIPER_MLFR 131 +#define DLT_JUNIPER_ES 132 +#define DLT_JUNIPER_GGSN 133 +#define DLT_JUNIPER_MFR 134 +#define DLT_JUNIPER_ATM2 135 +#define DLT_JUNIPER_SERVICES 136 +#define DLT_JUNIPER_ATM1 137 + +/* + * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund + * . The header that's presented is an Ethernet-like + * header: + * + * #define FIREWIRE_EUI64_LEN 8 + * struct firewire_header { + * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; + * u_char firewire_shost[FIREWIRE_EUI64_LEN]; + * u_short firewire_type; + * }; + * + * with "firewire_type" being an Ethernet type value, rather than, + * for example, raw GASP frames being handed up. + */ +#define DLT_APPLE_IP_OVER_IEEE1394 138 + +/* + * Various SS7 encapsulations, as per a request from Jeff Morriss + * and subsequent discussions. + */ +#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ +#define DLT_MTP2 140 /* MTP2, without pseudo-header */ +#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ +#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ + +/* + * DOCSIS MAC frames. + */ +#define DLT_DOCSIS 143 + +/* + * Linux-IrDA packets. Protocol defined at http://www.irda.org. + * Those packets include IrLAP headers and above (IrLMP...), but + * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy + * framing can be handled by the hardware and depend on the bitrate. + * This is exactly the format you would get capturing on a Linux-IrDA + * interface (irdaX), but not on a raw serial port. + * Note the capture is done in "Linux-cooked" mode, so each packet include + * a fake packet header (struct sll_header). This is because IrDA packet + * decoding is dependant on the direction of the packet (incomming or + * outgoing). + * When/if other platform implement IrDA capture, we may revisit the + * issue and define a real DLT_IRDA... + * Jean II + */ +#define DLT_LINUX_IRDA 144 + +/* + * Reserved for IBM SP switch and IBM Next Federation switch. + */ +#define DLT_IBM_SP 145 +#define DLT_IBM_SN 146 + +/* + * Reserved for private use. If you have some link-layer header type + * that you want to use within your organization, with the capture files + * using that link-layer header type not ever be sent outside your + * organization, you can use these values. + * + * No libpcap release will use these for any purpose, nor will any + * tcpdump release use them, either. + * + * Do *NOT* use these in capture files that you expect anybody not using + * your private versions of capture-file-reading tools to read; in + * particular, do *NOT* use them in products, otherwise you may find that + * people won't be able to use tcpdump, or snort, or Ethereal, or... to + * read capture files from your firewall/intrusion detection/traffic + * monitoring/etc. appliance, or whatever product uses that DLT_ value, + * and you may also find that the developers of those applications will + * not accept patches to let them read those files. + * + * Also, do not use them if somebody might send you a capture using them + * for *their* private type and tools using them for *your* private type + * would have to read them. + * + * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, + * as per the comment above, and use the type you're given. + */ +#define DLT_USER0 147 +#define DLT_USER1 148 +#define DLT_USER2 149 +#define DLT_USER3 150 +#define DLT_USER4 151 +#define DLT_USER5 152 +#define DLT_USER6 153 +#define DLT_USER7 154 +#define DLT_USER8 155 +#define DLT_USER9 156 +#define DLT_USER10 157 +#define DLT_USER11 158 +#define DLT_USER12 159 +#define DLT_USER13 160 +#define DLT_USER14 161 +#define DLT_USER15 162 + +/* + * For future use with 802.11 captures - defined by AbsoluteValue + * Systems to store a number of bits of link-layer information + * including radio information: + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt + * + * but it might be used by some non-AVS drivers now or in the + * future. + */ +#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, etc.. + */ +#define DLT_JUNIPER_MONITOR 164 + +/* + * BACnet MS/TP frames. + */ +#define DLT_BACNET_MS_TP 165 + +/* + * Another PPP variant as per request from Karsten Keil . + * + * This is used in some OSes to allow a kernel socket filter to distinguish + * between incoming and outgoing packets, on a socket intended to + * supply pppd with outgoing packets so it can do dial-on-demand and + * hangup-on-lack-of-demand; incoming packets are filtered out so they + * don't cause pppd to hold the connection up (you don't want random + * input packets such as port scans, packets from old lost connections, + * etc. to force the connection to stay up). + * + * The first byte of the PPP header (0xff03) is modified to accomodate + * the direction - 0x00 = IN, 0x01 = OUT. + */ +#define DLT_PPP_PPPD 166 + +/* + * Names for backwards compatibility with older versions of some PPP + * software; new software should use DLT_PPP_PPPD. + */ +#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD +#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_s are used + * for passing on chassis-internal metainformation such as + * QOS profiles, cookies, etc.. + */ +#define DLT_JUNIPER_PPPOE 167 +#define DLT_JUNIPER_PPPOE_ATM 168 + +#define DLT_GPRS_LLC 169 /* GPRS LLC */ +#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ +#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ + +/* + * Requested by Oolan Zimmer for use in Gcom's T1/E1 line + * monitoring equipment. + */ +#define DLT_GCOM_T1E1 172 +#define DLT_GCOM_SERIAL 173 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . The DLT_ is used + * for internal communication to Physical Interface Cards (PIC) + */ +#define DLT_JUNIPER_PIC_PEER 174 + +/* + * Link types requested by Gregor Maier of Endace + * Measurement Systems. They add an ERF header (see + * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of + * the link-layer header. + */ +#define DLT_ERF_ETH 175 /* Ethernet */ +#define DLT_ERF_POS 176 /* Packet-over-SONET */ + +/* + * Requested by Daniele Orlandi for raw LAPD + * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header + * includes additional information before the LAPD header, so it's + * not necessarily a generic LAPD header. + */ +#define DLT_LINUX_LAPD 177 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ are used for prepending meta-information + * like interface index, interface name + * before standard Ethernet, PPP, Frelay & C-HDLC Frames + */ +#define DLT_JUNIPER_ETHER 178 +#define DLT_JUNIPER_PPP 179 +#define DLT_JUNIPER_FRELAY 180 +#define DLT_JUNIPER_CHDLC 181 + +/* + * Multi Link Frame Relay (FRF.16) + */ +#define DLT_MFR 182 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * voice Adapter Card (PIC) + */ +#define DLT_JUNIPER_VP 183 + +/* + * Arinc 429 frames. + * DLT_ requested by Gianluca Varenni . + * Every frame contains a 32bit A429 label. + * More documentation on Arinc 429 can be found at + * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf + */ +#define DLT_A429 184 + +/* + * Arinc 653 Interpartition Communication messages. + * DLT_ requested by Gianluca Varenni . + * Please refer to the A653-1 standard for more information. + */ +#define DLT_A653_ICM 185 + +/* + * This used to be "USB packets, beginning with a USB setup header; + * requested by Paolo Abeni ." + * + * However, that header didn't work all that well - it left out some + * useful information - and was abandoned in favor of the DLT_USB_LINUX + * header. + * + * This is now used by FreeBSD for its BPF taps for USB; that has its + * own headers. So it is written, so it is done. + * + * For source-code compatibility, we also define DLT_USB to have this + * value. We do it numerically so that, if code that includes this + * file (directly or indirectly) also includes an OS header that also + * defines DLT_USB as 186, we don't get a redefinition warning. + * (NetBSD 7 does that.) + */ +#define DLT_USB_FREEBSD 186 +#define DLT_USB 186 + +/* + * Bluetooth HCI UART transport layer (part H:4); requested by + * Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4 187 + +/* + * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz + * . + */ +#define DLT_IEEE802_16_MAC_CPS 188 + +/* + * USB packets, beginning with a Linux USB header; requested by + * Paolo Abeni . + */ +#define DLT_USB_LINUX 189 + +/* + * Controller Area Network (CAN) v. 2.0B packets. + * DLT_ requested by Gianluca Varenni . + * Used to dump CAN packets coming from a CAN Vector board. + * More documentation on the CAN v2.0B frames can be found at + * http://www.can-cia.org/downloads/?269 + */ +#define DLT_CAN20B 190 + +/* + * IEEE 802.15.4, with address fields padded, as is done by Linux + * drivers; requested by Juergen Schimmer. + */ +#define DLT_IEEE802_15_4_LINUX 191 + +/* + * Per Packet Information encapsulated packets. + * DLT_ requested by Gianluca Varenni . + */ +#define DLT_PPI 192 + +/* + * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; + * requested by Charles Clancy. + */ +#define DLT_IEEE802_16_MAC_CPS_RADIO 193 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for internal communication with a + * integrated service module (ISM). + */ +#define DLT_JUNIPER_ISM 194 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing); requested by Mikko Saarnivala . + * For this one, we expect the FCS to be present at the end of the frame; + * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. + */ +#define DLT_IEEE802_15_4 195 + +/* + * Various link-layer types, with a pseudo-header, for SITA + * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). + */ +#define DLT_SITA 196 + +/* + * Various link-layer types, with a pseudo-header, for Endace DAG cards; + * encapsulates Endace ERF records. Requested by Stephen Donnelly + * . + */ +#define DLT_ERF 197 + +/* + * Special header prepended to Ethernet packets when capturing from a + * u10 Networks board. Requested by Phil Mulholland + * . + */ +#define DLT_RAIF1 198 + +/* + * IPMB packet for IPMI, beginning with the I2C slave address, followed + * by the netFn and LUN, etc.. Requested by Chanthy Toeung + * . + */ +#define DLT_IPMB 199 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + * The DLT_ is used for capturing data on a secure tunnel interface. + */ +#define DLT_JUNIPER_ST 200 + +/* + * Bluetooth HCI UART transport layer (part H:4), with pseudo-header + * that includes direction information; requested by Paolo Abeni. + */ +#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 + +/* + * AX.25 packet with a 1-byte KISS header; see + * + * http://www.ax25.net/kiss.htm + * + * as per Richard Stearn . + */ +#define DLT_AX25_KISS 202 + +/* + * LAPD packets from an ISDN channel, starting with the address field, + * with no pseudo-header. + * Requested by Varuna De Silva . + */ +#define DLT_LAPD 203 + +/* + * Variants of various link-layer headers, with a one-byte direction + * pseudo-header prepended - zero means "received by this host", + * non-zero (any non-zero value) means "sent by this host" - as per + * Will Barker . + */ +#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ +#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ +#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ +#define DLT_LAPB_WITH_DIR 207 /* LAPB */ + +/* + * 208 is reserved for an as-yet-unspecified proprietary link-layer + * type, as requested by Will Barker. + */ + +/* + * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman + * . + */ +#define DLT_IPMB_LINUX 209 + +/* + * FlexRay automotive bus - http://www.flexray.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_FLEXRAY 210 + +/* + * Media Oriented Systems Transport (MOST) bus for multimedia + * transport - http://www.mostcooperation.com/ - as requested + * by Hannes Kaelber . + */ +#define DLT_MOST 211 + +/* + * Local Interconnect Network (LIN) bus for vehicle networks - + * http://www.lin-subbus.org/ - as requested by Hannes Kaelber + * . + */ +#define DLT_LIN 212 + +/* + * X2E-private data link type used for serial line capture, + * as requested by Hannes Kaelber . + */ +#define DLT_X2E_SERIAL 213 + +/* + * X2E-private data link type used for the Xoraya data logger + * family, as requested by Hannes Kaelber . + */ +#define DLT_X2E_XORAYA 214 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), but with the PHY-level data for non-ASK PHYs (4 octets + * of 0 as preamble, one octet of SFD, one octet of frame length+ + * reserved bit, and then the MAC-layer data, starting with the + * frame control field). + * + * Requested by Max Filippov . + */ +#define DLT_IEEE802_15_4_NONASK_PHY 215 + +/* + * David Gibson requested this for + * captures from the Linux kernel /dev/input/eventN devices. This + * is used to communicate keystrokes and mouse movements from the + * Linux kernel to display systems, such as Xorg. + */ +#define DLT_LINUX_EVDEV 216 + +/* + * GSM Um and Abis interfaces, preceded by a "gsmtap" header. + * + * Requested by Harald Welte . + */ +#define DLT_GSMTAP_UM 217 +#define DLT_GSMTAP_ABIS 218 + +/* + * MPLS, with an MPLS label as the link-layer header. + * Requested by Michele Marchetto on behalf + * of OpenBSD. + */ +#define DLT_MPLS 219 + +/* + * USB packets, beginning with a Linux USB header, with the USB header + * padded to 64 bytes; required for memory-mapped access. + */ +#define DLT_USB_LINUX_MMAPPED 220 + +/* + * DECT packets, with a pseudo-header; requested by + * Matthias Wenzel . + */ +#define DLT_DECT 221 + +/* + * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" + * Date: Mon, 11 May 2009 11:18:30 -0500 + * + * DLT_AOS. We need it for AOS Space Data Link Protocol. + * I have already written dissectors for but need an OK from + * legal before I can submit a patch. + * + */ +#define DLT_AOS 222 + +/* + * Wireless HART (Highway Addressable Remote Transducer) + * From the HART Communication Foundation + * IES/PAS 62591 + * + * Requested by Sam Roberts . + */ +#define DLT_WIHART 223 + +/* + * Fibre Channel FC-2 frames, beginning with a Frame_Header. + * Requested by Kahou Lei . + */ +#define DLT_FC_2 224 + +/* + * Fibre Channel FC-2 frames, beginning with an encoding of the + * SOF, and ending with an encoding of the EOF. + * + * The encodings represent the frame delimiters as 4-byte sequences + * representing the corresponding ordered sets, with K28.5 + * represented as 0xBC, and the D symbols as the corresponding + * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, + * is represented as 0xBC 0xB5 0x55 0x55. + * + * Requested by Kahou Lei . + */ +#define DLT_FC_2_WITH_FRAME_DELIMS 225 + +/* + * Solaris ipnet pseudo-header; requested by Darren Reed . + * + * The pseudo-header starts with a one-byte version number; for version 2, + * the pseudo-header is: + * + * struct dl_ipnetinfo { + * uint8_t dli_version; + * uint8_t dli_family; + * uint16_t dli_htype; + * uint32_t dli_pktlen; + * uint32_t dli_ifindex; + * uint32_t dli_grifindex; + * uint32_t dli_zsrc; + * uint32_t dli_zdst; + * }; + * + * dli_version is 2 for the current version of the pseudo-header. + * + * dli_family is a Solaris address family value, so it's 2 for IPv4 + * and 26 for IPv6. + * + * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing + * packets, and 2 for packets arriving from another zone on the same + * machine. + * + * dli_pktlen is the length of the packet data following the pseudo-header + * (so the captured length minus dli_pktlen is the length of the + * pseudo-header, assuming the entire pseudo-header was captured). + * + * dli_ifindex is the interface index of the interface on which the + * packet arrived. + * + * dli_grifindex is the group interface index number (for IPMP interfaces). + * + * dli_zsrc is the zone identifier for the source of the packet. + * + * dli_zdst is the zone identifier for the destination of the packet. + * + * A zone number of 0 is the global zone; a zone number of 0xffffffff + * means that the packet arrived from another host on the network, not + * from another zone on the same machine. + * + * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates + * which of those it is. + */ +#define DLT_IPNET 226 + +/* + * CAN (Controller Area Network) frames, with a pseudo-header as supplied + * by Linux SocketCAN, and with multi-byte numerical fields in that header + * in big-endian byte order. + * + * See Documentation/networking/can.txt in the Linux source. + * + * Requested by Felix Obenhuber . + */ +#define DLT_CAN_SOCKETCAN 227 + +/* + * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies + * whether it's v4 or v6. Requested by Darren Reed . + */ +#define DLT_IPV4 228 +#define DLT_IPV6 229 + +/* + * IEEE 802.15.4, exactly as it appears in the spec (no padding, no + * nothing), and with no FCS at the end of the frame; requested by + * Jon Smirl . + */ +#define DLT_IEEE802_15_4_NOFCS 230 + +/* + * Raw D-Bus: + * + * http://www.freedesktop.org/wiki/Software/dbus + * + * messages: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages + * + * starting with the endianness flag, followed by the message type, etc., + * but without the authentication handshake before the message sequence: + * + * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol + * + * Requested by Martin Vidner . + */ +#define DLT_DBUS 231 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_VS 232 +#define DLT_JUNIPER_SRX_E2E 233 +#define DLT_JUNIPER_FIBRECHANNEL 234 + +/* + * DVB-CI (DVB Common Interface for communication between a PC Card + * module and a DVB receiver). See + * + * http://www.kaiser.cx/pcap-dvbci.html + * + * for the specification. + * + * Requested by Martin Kaiser . + */ +#define DLT_DVB_CI 235 + +/* + * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but + * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel + * . + */ +#define DLT_MUX27010 236 + +/* + * STANAG 5066 D_PDUs. Requested by M. Baris Demiray + * . + */ +#define DLT_STANAG_5066_D_PDU 237 + +/* + * Juniper-private data link type, as per request from + * Hannes Gredler . + */ +#define DLT_JUNIPER_ATM_CEMIC 238 + +/* + * NetFilter LOG messages + * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) + * + * Requested by Jakub Zawadzki + */ +#define DLT_NFLOG 239 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and always + * with the payload including the FCS, as supplied by their + * netANALYZER hardware and software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER 240 + +/* + * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type + * for Ethernet packets with a 4-byte pseudo-header and FCS and + * with the Ethernet header preceded by 7 bytes of preamble and + * 1 byte of SFD, as supplied by their netANALYZER hardware and + * software. + * + * Requested by Holger P. Frommer + */ +#define DLT_NETANALYZER_TRANSPARENT 241 + +/* + * IP-over-InfiniBand, as specified by RFC 4391. + * + * Requested by Petr Sumbera . + */ +#define DLT_IPOIB 242 + +/* + * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). + * + * Requested by Guy Martin . + */ +#define DLT_MPEG_2_TS 243 + +/* + * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as + * used by their ng40 protocol tester. + * + * Requested by Jens Grimmer . + */ +#define DLT_NG40 244 + +/* + * Pseudo-header giving adapter number and flags, followed by an NFC + * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, + * as specified by NFC Forum Logical Link Control Protocol Technical + * Specification LLCP 1.1. + * + * Requested by Mike Wakerly . + */ +#define DLT_NFC_LLCP 245 + +/* + * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. + * + * DLT_PFSYNC has different values on different platforms, and all of + * them collide with something used elsewhere. On platforms that + * don't already define it, define it as 246. + */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) +#define DLT_PFSYNC 246 +#endif + +/* + * Raw InfiniBand packets, starting with the Local Routing Header. + * + * Requested by Oren Kladnitsky . + */ +#define DLT_INFINIBAND 247 + +/* + * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). + * + * Requested by Michael Tuexen . + */ +#define DLT_SCTP 248 + +/* + * USB packets, beginning with a USBPcap header. + * + * Requested by Tomasz Mon + */ +#define DLT_USBPCAP 249 + +/* + * Schweitzer Engineering Laboratories "RTAC" product serial-line + * packets. + * + * Requested by Chris Bontje . + */ +#define DLT_RTAC_SERIAL 250 + +/* + * Bluetooth Low Energy air interface link-layer packets. + * + * Requested by Mike Kershaw . + */ +#define DLT_BLUETOOTH_LE_LL 251 + +/* + * DLT type for upper-protocol layer PDU saves from wireshark. + * + * the actual contents are determined by two TAGs stored with each + * packet: + * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the + * original packet. + * + * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector + * that can make sense of the data stored. + */ +#define DLT_WIRESHARK_UPPER_PDU 252 + +/* + * DLT type for the netlink protocol (nlmon devices). + */ +#define DLT_NETLINK 253 + +/* + * Bluetooth Linux Monitor headers for the BlueZ stack. + */ +#define DLT_BLUETOOTH_LINUX_MONITOR 254 + +/* + * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as + * captured by Ubertooth. + */ +#define DLT_BLUETOOTH_BREDR_BB 255 + +/* + * Bluetooth Low Energy link layer packets, as captured by Ubertooth. + */ +#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 + +/* + * PROFIBUS data link layer. + */ +#define DLT_PROFIBUS_DL 257 + +/* + * Apple's DLT_PKTAP headers. + * + * Sadly, the folks at Apple either had no clue that the DLT_USERn values + * are for internal use within an organization and partners only, and + * didn't know that the right way to get a link-layer header type is to + * ask tcpdump.org for one, or knew and didn't care, so they just + * used DLT_USER2, which causes problems for everything except for + * their version of tcpdump. + * + * So I'll just give them one; hopefully this will show up in a + * libpcap release in time for them to get this into 10.10 Big Sur + * or whatever Mavericks' successor is called. LINKTYPE_PKTAP + * will be 258 *even on OS X*; that is *intentional*, so that + * PKTAP files look the same on *all* OSes (different OSes can have + * different numerical values for a given DLT_, but *MUST NOT* have + * different values for what goes in a file, as files can be moved + * between OSes!). + * + * When capturing, on a system with a Darwin-based OS, on a device + * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this + * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, + * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, + * binary compatibility with Mavericks is preserved for programs using + * this version of libpcap. This does mean that if you were using + * DLT_USER2 for some capture device on OS X, you can't do so with + * this version of libpcap, just as you can't with Apple's libpcap - + * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't + * be able to distinguish between PKTAP and whatever you were using + * DLT_USER2 for. + * + * If the program saves the capture to a file using this version of + * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be + * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. + * That way, the file will *not* be a DLT_USER2 file. That means + * that the latest version of tcpdump, when built with this version + * of libpcap, and sufficiently recent versions of Wireshark will + * be able to read those files and interpret them correctly; however, + * Apple's version of tcpdump in OS X 10.9 won't be able to handle + * them. (Hopefully, Apple will pick up this version of libpcap, + * and the corresponding version of tcpdump, so that tcpdump will + * be able to handle the old LINKTYPE_USER2 captures *and* the new + * LINKTYPE_PKTAP captures.) + */ +#ifdef __APPLE__ +#define DLT_PKTAP DLT_USER2 +#else +#define DLT_PKTAP 258 +#endif + +/* + * Ethernet packets preceded by a header giving the last 6 octets + * of the preamble specified by 802.3-2012 Clause 65, section + * 65.1.3.2 "Transmit". + */ +#define DLT_EPON 259 + +/* + * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" + * in the PICMG HPM.2 specification. + */ +#define DLT_IPMI_HPM_2 260 + +/* + * per Joshua Wright , formats for Zwave captures. + */ +#define DLT_ZWAVE_R1_R2 261 +#define DLT_ZWAVE_R3 262 + +/* + * per Steve Karg , formats for Wattstopper + * Digital Lighting Management room bus serial protocol captures. + */ +#define DLT_WATTSTOPPER_DLM 263 + +/* + * ISO 14443 contactless smart card messages. + */ +#define DLT_ISO_14443 264 + +/* + * Radio data system (RDS) groups. IEC 62106. + * Per Jonathan Brucker . + */ +#define DLT_RDS 265 + +/* + * USB packets, beginning with a Darwin (macOS, etc.) header. + */ +#define DLT_USB_DARWIN 266 + +/* + * OpenBSD DLT_OPENFLOW. + */ +#define DLT_OPENFLOW 267 + +/* + * SDLC frames containing SNA PDUs. + */ +#define DLT_SDLC 268 + +/* + * per "Selvig, Bjorn" used for + * TI protocol sniffer. + */ +#define DLT_TI_LLN_SNIFFER 269 + +/* + * per: Erik de Jong for + * https://github.com/eriknl/LoRaTap/releases/tag/v0.1 + */ +#define DLT_LORATAP 270 + +/* + * per: Stefanha at gmail.com for + * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html + * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h + * for: http://qemu-project.org/Features/VirtioVsock + */ +#define DLT_VSOCK 271 + +/* + * Nordic Semiconductor Bluetooth LE sniffer. + */ +#define DLT_NORDIC_BLE 272 + +/* + * Excentis DOCSIS 3.1 RF sniffer (XRA-31) + * per: bruno.verstuyft at excentis.com + * http://www.xra31.com/xra-header + */ +#define DLT_DOCSIS31_XRA31 273 + +/* + * mPackets, as specified by IEEE 802.3br Figure 99-4, starting + * with the preamble and always ending with a CRC field. + */ +#define DLT_ETHERNET_MPACKET 274 + +/* + * In case the code that includes this file (directly or indirectly) + * has also included OS files that happen to define DLT_MATCHING_MAX, + * with a different value (perhaps because that OS hasn't picked up + * the latest version of our DLT definitions), we undefine the + * previous value of DLT_MATCHING_MAX. + */ +#ifdef DLT_MATCHING_MAX +#undef DLT_MATCHING_MAX +#endif +#define DLT_MATCHING_MAX 274 /* highest value in the "matching" range */ + +/* + * DLT and savefile link type values are split into a class and + * a member of that class. A class value of 0 indicates a regular + * DLT_/LINKTYPE_ value. + */ +#define DLT_CLASS(x) ((x) & 0x03ff0000) + +/* + * NetBSD-specific generic "raw" link type. The class value indicates + * that this is the generic raw type, and the lower 16 bits are the + * address family we're dealing with. Those values are NetBSD-specific; + * do not assume that they correspond to AF_ values for your operating + * system. + */ +#define DLT_CLASS_NETBSD_RAWAF 0x02240000 +#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) +#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) +#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) + +#endif /* !defined(lib_pcap_dlt_h) */ diff --git a/src/frontend/qt_sdl/pcap/funcattrs.h b/src/frontend/qt_sdl/pcap/funcattrs.h new file mode 100644 index 0000000..d1cc2bf --- /dev/null +++ b/src/frontend/qt_sdl/pcap/funcattrs.h @@ -0,0 +1,242 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_funcattrs_h +#define lib_pcap_funcattrs_h + +#include + +/* + * Attributes to apply to functions and their arguments, using various + * compiler-specific extensions. + */ + +/* + * PCAP_API_DEF must be used when defining *data* exported from + * libpcap. It can be used when defining *functions* exported + * from libpcap, but it doesn't have to be used there. It + * should not be used in declarations in headers. + * + * PCAP_API must be used when *declaring* data or functions + * exported from libpcap; PCAP_API_DEF won't work on all platforms. + */ + +#if defined(_WIN32) + /* + * For Windows: + * + * when building libpcap: + * + * if we're building it as a DLL, we have to declare API + * functions with __declspec(dllexport); + * + * if we're building it as a static library, we don't want + * to do so. + * + * when using libpcap: + * + * if we're using the DLL, calls to its functions are a + * little more efficient if they're declared with + * __declspec(dllimport); + * + * if we're not using the dll, we don't want to declare + * them that way. + * + * So: + * + * if pcap_EXPORTS is defined, we define PCAP_API_DEF as + * __declspec(dllexport); + * + * if PCAP_DLL is defined, we define PCAP_API_DEF as + * __declspec(dllimport); + * + * otherwise, we define PCAP_API_DEF as nothing. + */ + #if defined(pcap_EXPORTS) + /* + * We're compiling libpcap, so we should export functions in our + * API. + */ + #define PCAP_API_DEF __declspec(dllexport) + #elif defined(PCAP_DLL) + #define PCAP_API_DEF __declspec(dllimport) + #else + #define PCAP_API_DEF + #endif +#elif defined(MSDOS) + /* XXX - does this need special treatment? */ + #define PCAP_API_DEF +#else /* UN*X */ + #ifdef pcap_EXPORTS + /* + * We're compiling libpcap, so we should export functions in our API. + * The compiler might be configured not to export functions from a + * shared library by default, so we might have to explicitly mark + * functions as exported. + */ + #if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4) \ + || PCAP_IS_AT_LEAST_XL_C_VERSION(12,0) + /* + * GCC 3.4 or later, or some compiler asserting compatibility with + * GCC 3.4 or later, or XL C 13.0 or later, so we have + * __attribute__((visibility()). + */ + #define PCAP_API_DEF __attribute__((visibility("default"))) + #elif PCAP_IS_AT_LEAST_SUNC_VERSION(5,5) + /* + * Sun C 5.5 or later, so we have __global. + * (Sun C 5.9 and later also have __attribute__((visibility()), + * but there's no reason to prefer it with Sun C.) + */ + #define PCAP_API_DEF __global + #else + /* + * We don't have anything to say. + */ + #define PCAP_API_DEF + #endif + #else + /* + * We're not building libpcap. + */ + #define PCAP_API_DEF + #endif +#endif /* _WIN32/MSDOS/UN*X */ + +#define PCAP_API PCAP_API_DEF extern + +/* + * PCAP_NORETURN, before a function declaration, means "this function + * never returns". (It must go before the function declaration, e.g. + * "extern PCAP_NORETURN func(...)" rather than after the function + * declaration, as the MSVC version has to go before the declaration.) + */ +#if __has_attribute(noreturn) \ + || PCAP_IS_AT_LEAST_GNUC_VERSION(2,5) \ + || PCAP_IS_AT_LEAST_SUNC_VERSION(5,9) \ + || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ + || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) + /* + * Compiler with support for __attribute((noreturn)), or GCC 2.5 and + * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 + * and later (do any earlier versions of XL C support this?), or + * HP aCC A.06.10 and later. + */ + #define PCAP_NORETURN __attribute((noreturn)) +#elif defined(_MSC_VER) + /* + * MSVC. + */ + #define PCAP_NORETURN __declspec(noreturn) +#else + #define PCAP_NORETURN +#endif + +/* + * PCAP_PRINTFLIKE(x,y), after a function declaration, means "this function + * does printf-style formatting, with the xth argument being the format + * string and the yth argument being the first argument for the format + * string". + */ +#if __has_attribute(__format__) \ + || PCAP_IS_AT_LEAST_GNUC_VERSION(2,3) \ + || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ + || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) + /* + * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1 + * and later (do any earlier versions of XL C support this?), + * or HP aCC A.06.10 and later. + */ + #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) +#else + #define PCAP_PRINTFLIKE(x,y) +#endif + +/* + * PCAP_DEPRECATED(func, msg), after a function declaration, marks the + * function as deprecated. + * + * The first argument is the name of the function; the second argument is + * a string giving the warning message to use if the compiler supports that. + * + * (Thank you, Microsoft, for requiring the function name.) + */ +#if __has_attribute(deprecated) \ + || PCAP_IS_AT_LEAST_GNUC_VERSION(4,5) \ + || PCAP_IS_AT_LEAST_SUNC_VERSION(5,13) + /* + * Compiler that supports __has_attribute and __attribute__((deprecated)), + * or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later. + * + * Those support __attribute__((deprecated(msg))) (we assume, perhaps + * incorrectly, that anything that supports __has_attribute() is + * recent enough to support __attribute__((deprecated(msg)))). + */ + #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated(msg))) +#elif PCAP_IS_AT_LEAST_GNUC_VERSION(3,1) + /* + * GCC 3.1 through 4.4. + * + * Those support __attribute__((deprecated)) but not + * __attribute__((deprecated(msg))). + */ + #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated)) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1500)) && !defined(pcap_EXPORTS) + /* + * MSVC from Visual Studio 2008 or later, and we're not building + * libpcap itself. + * + * If we *are* building libpcap, we don't want this, as it'll warn + * us even if we *define* the function. + */ + #define PCAP_DEPRECATED(func, msg) __pragma(deprecated(func)) +#else + #define PCAP_DEPRECATED(func, msg) +#endif + +/* + * For flagging arguments as format strings in MSVC. + */ +#ifdef _MSC_VER + #include + #if _MSC_VER > 1400 + #define PCAP_FORMAT_STRING(p) _Printf_format_string_ p + #else + #define PCAP_FORMAT_STRING(p) __format_string p + #endif +#else + #define PCAP_FORMAT_STRING(p) p +#endif + +#endif /* lib_pcap_funcattrs_h */ diff --git a/src/frontend/qt_sdl/pcap/ipnet.h b/src/frontend/qt_sdl/pcap/ipnet.h new file mode 100644 index 0000000..5330847 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/ipnet.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ +#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ + +#define IPNET_OUTBOUND 1 +#define IPNET_INBOUND 2 diff --git a/src/frontend/qt_sdl/pcap/namedb.h b/src/frontend/qt_sdl/pcap/namedb.h new file mode 100644 index 0000000..73fb40a --- /dev/null +++ b/src/frontend/qt_sdl/pcap/namedb.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1994, 1996 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_namedb_h +#define lib_pcap_namedb_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * As returned by the pcap_next_etherent() + * XXX this stuff doesn't belong in this interface, but this + * library already must do name to address translation, so + * on systems that don't have support for /etc/ethers, we + * export these hooks since they're already being used by + * some applications (such as tcpdump) and already being + * marked as exported in some OSes offering libpcap (such + * as Debian). + */ +struct pcap_etherent { + u_char addr[6]; + char name[122]; +}; +#ifndef PCAP_ETHERS_FILE +#define PCAP_ETHERS_FILE "/etc/ethers" +#endif +PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *); +PCAP_API u_char *pcap_ether_hostton(const char*); +PCAP_API u_char *pcap_ether_aton(const char *); + +PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *); +#ifdef INET6 +PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *); +#endif +PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *); + +PCAP_API int pcap_nametoport(const char *, int *, int *); +PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *); +PCAP_API int pcap_nametoproto(const char *); +PCAP_API int pcap_nametoeproto(const char *); +PCAP_API int pcap_nametollc(const char *); +/* + * If a protocol is unknown, PROTO_UNDEF is returned. + * Also, pcap_nametoport() returns the protocol along with the port number. + * If there are ambiguous entried in /etc/services (i.e. domain + * can be either tcp or udp) PROTO_UNDEF is returned. + */ +#define PROTO_UNDEF -1 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/frontend/qt_sdl/pcap/nflog.h b/src/frontend/qt_sdl/pcap/nflog.h new file mode 100644 index 0000000..29a71d2 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/nflog.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Petar Alilovic, + * Faculty of Electrical Engineering and Computing, University of Zagreb + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef lib_pcap_nflog_h +#define lib_pcap_nflog_h + +#include + +/* + * Structure of an NFLOG header and TLV parts, as described at + * http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html + * + * The NFLOG header is big-endian. + * + * The TLV length and type are in host byte order. The value is either + * big-endian or is an array of bytes in some externally-specified byte + * order (text string, link-layer address, link-layer header, packet + * data, etc.). + */ +typedef struct nflog_hdr { + uint8_t nflog_family; /* address family */ + uint8_t nflog_version; /* version */ + uint16_t nflog_rid; /* resource ID */ +} nflog_hdr_t; + +typedef struct nflog_tlv { + uint16_t tlv_length; /* tlv length */ + uint16_t tlv_type; /* tlv type */ + /* value follows this */ +} nflog_tlv_t; + +typedef struct nflog_packet_hdr { + uint16_t hw_protocol; /* hw protocol */ + uint8_t hook; /* netfilter hook */ + uint8_t pad; /* padding to 32 bits */ +} nflog_packet_hdr_t; + +typedef struct nflog_hwaddr { + uint16_t hw_addrlen; /* address length */ + uint16_t pad; /* padding to 32-bit boundary */ + uint8_t hw_addr[8]; /* address, up to 8 bytes */ +} nflog_hwaddr_t; + +typedef struct nflog_timestamp { + uint64_t sec; + uint64_t usec; +} nflog_timestamp_t; + +/* + * TLV types. + */ +#define NFULA_PACKET_HDR 1 /* nflog_packet_hdr_t */ +#define NFULA_MARK 2 /* packet mark from skbuff */ +#define NFULA_TIMESTAMP 3 /* nflog_timestamp_t for skbuff's time stamp */ +#define NFULA_IFINDEX_INDEV 4 /* ifindex of device on which packet received (possibly bridge group) */ +#define NFULA_IFINDEX_OUTDEV 5 /* ifindex of device on which packet transmitted (possibly bridge group) */ +#define NFULA_IFINDEX_PHYSINDEV 6 /* ifindex of physical device on which packet received (not bridge group) */ +#define NFULA_IFINDEX_PHYSOUTDEV 7 /* ifindex of physical device on which packet transmitted (not bridge group) */ +#define NFULA_HWADDR 8 /* nflog_hwaddr_t for hardware address */ +#define NFULA_PAYLOAD 9 /* packet payload */ +#define NFULA_PREFIX 10 /* text string - null-terminated, count includes NUL */ +#define NFULA_UID 11 /* UID owning socket on which packet was sent/received */ +#define NFULA_SEQ 12 /* sequence number of packets on this NFLOG socket */ +#define NFULA_SEQ_GLOBAL 13 /* sequence number of pakets on all NFLOG sockets */ +#define NFULA_GID 14 /* GID owning socket on which packet was sent/received */ +#define NFULA_HWTYPE 15 /* ARPHRD_ type of skbuff's device */ +#define NFULA_HWHEADER 16 /* skbuff's MAC-layer header */ +#define NFULA_HWLEN 17 /* length of skbuff's MAC-layer header */ + +#endif diff --git a/src/frontend/qt_sdl/pcap/pcap-inttypes.h b/src/frontend/qt_sdl/pcap/pcap-inttypes.h new file mode 100644 index 0000000..af2c23c --- /dev/null +++ b/src/frontend/qt_sdl/pcap/pcap-inttypes.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) + * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef pcap_pcap_inttypes_h +#define pcap_pcap_inttypes_h + +/* + * Get the integer types and PRi[doux]64 values from C99 + * defined, by hook or by crook. + */ +#if defined(_MSC_VER) + /* + * Compiler is MSVC. + */ + #if _MSC_VER >= 1800 + /* + * VS 2013 or newer; we have . + */ + #include + #else + /* + * Earlier VS; we have to define this stuff ourselves. + */ + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef signed short int16_t; + typedef unsigned int uint32_t; + typedef signed int int32_t; + #ifdef _MSC_EXTENSIONS + typedef unsigned _int64 uint64_t; + typedef _int64 int64_t; + #else /* _MSC_EXTENSIONS */ + typedef unsigned long long uint64_t; + typedef long long int64_t; + #endif + #endif + + /* + * These may be defined by . + * + * XXX - for MSVC, we always want the _MSC_EXTENSIONS versions. + * What about other compilers? If, as the MinGW Web site says MinGW + * does, the other compilers just use Microsoft's run-time library, + * then they should probably use the _MSC_EXTENSIONS even if the + * compiler doesn't define _MSC_EXTENSIONS. + * + * XXX - we currently aren't using any of these, but this allows + * their use in the future. + */ + #ifndef PRId64 + #ifdef _MSC_EXTENSIONS + #define PRId64 "I64d" + #else + #define PRId64 "lld" + #endif + #endif /* PRId64 */ + + #ifndef PRIo64 + #ifdef _MSC_EXTENSIONS + #define PRIo64 "I64o" + #else + #define PRIo64 "llo" + #endif + #endif /* PRIo64 */ + + #ifndef PRIx64 + #ifdef _MSC_EXTENSIONS + #define PRIx64 "I64x" + #else + #define PRIx64 "llx" + #endif + #endif + + #ifndef PRIu64 + #ifdef _MSC_EXTENSIONS + #define PRIu64 "I64u" + #else + #define PRIu64 "llu" + #endif + #endif +#elif defined(__MINGW32__) || !defined(_WIN32) + /* + * Compiler is MinGW or target is UN*X or MS-DOS. Just use + * . + */ + #include +#endif + +#endif /* pcap/pcap-inttypes.h */ diff --git a/src/frontend/qt_sdl/pcap/pcap.h b/src/frontend/qt_sdl/pcap/pcap.h new file mode 100644 index 0000000..d32e2a9 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/pcap.h @@ -0,0 +1,966 @@ +/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Computer Systems + * Engineering Group at Lawrence Berkeley Laboratory. + * 4. Neither the name of the University nor of the Laboratory may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Remote packet capture mechanisms and extensions from WinPcap: + * + * Copyright (c) 2002 - 2003 + * NetGroup, Politecnico di Torino (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Politecnico di Torino nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef lib_pcap_pcap_h +#define lib_pcap_pcap_h + +#include + +#include + +#if defined(_WIN32) + #include /* u_int, u_char etc. */ + #include /* _get_osfhandle() */ +#elif defined(MSDOS) + #include /* u_int, u_char etc. */ + #include +#else /* UN*X */ + #include /* u_int, u_char etc. */ + #include +#endif /* _WIN32/MSDOS/UN*X */ + +#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Version number of the current version of the pcap file format. + * + * NOTE: this is *NOT* the version number of the libpcap library. + * To fetch the version information for the version of libpcap + * you're using, use pcap_lib_version(). + */ +#define PCAP_VERSION_MAJOR 2 +#define PCAP_VERSION_MINOR 4 + +#define PCAP_ERRBUF_SIZE 256 + +/* + * Compatibility for systems that have a bpf.h that + * predates the bpf typedefs for 64-bit support. + */ +#if BPF_RELEASE - 0 < 199406 +typedef int bpf_int32; +typedef u_int bpf_u_int32; +#endif + +typedef struct pcap pcap_t; +typedef struct pcap_dumper pcap_dumper_t; +typedef struct pcap_if pcap_if_t; +typedef struct pcap_addr pcap_addr_t; + +/* + * The first record in the file contains saved values for some + * of the flags used in the printout phases of tcpdump. + * Many fields here are 32 bit ints so compilers won't insert unwanted + * padding; these files need to be interchangeable across architectures. + * + * Do not change the layout of this structure, in any way (this includes + * changes that only affect the length of fields in this structure). + * + * Also, do not change the interpretation of any of the members of this + * structure, in any way (this includes using values other than + * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" + * field). + * + * Instead: + * + * introduce a new structure for the new format, if the layout + * of the structure changed; + * + * send mail to "tcpdump-workers@lists.tcpdump.org", requesting + * a new magic number for your new capture file format, and, when + * you get the new magic number, put it in "savefile.c"; + * + * use that magic number for save files with the changed file + * header; + * + * make the code in "savefile.c" capable of reading files with + * the old file header as well as files with the new file header + * (using the magic number to determine the header format). + * + * Then supply the changes by forking the branch at + * + * https://github.com/the-tcpdump-group/libpcap/issues + * + * and issuing a pull request, so that future versions of libpcap and + * programs that use it (such as tcpdump) will be able to read your new + * capture file format. + */ +struct pcap_file_header { + bpf_u_int32 magic; + u_short version_major; + u_short version_minor; + bpf_int32 thiszone; /* gmt to local correction */ + bpf_u_int32 sigfigs; /* accuracy of timestamps */ + bpf_u_int32 snaplen; /* max length saved portion of each pkt */ + bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ +}; + +/* + * Macros for the value returned by pcap_datalink_ext(). + * + * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro + * gives the FCS length of packets in the capture. + */ +#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) +#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) +#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) + +typedef enum { + PCAP_D_INOUT = 0, + PCAP_D_IN, + PCAP_D_OUT +} pcap_direction_t; + +/* + * Generic per-packet information, as supplied by libpcap. + * + * The time stamp can and should be a "struct timeval", regardless of + * whether your system supports 32-bit tv_sec in "struct timeval", + * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit + * and 64-bit applications. The on-disk format of savefiles uses 32-bit + * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit + * and 64-bit versions of libpcap, even if they're on the same platform, + * should supply the appropriate version of "struct timeval", even if + * that's not what the underlying packet capture mechanism supplies. + */ +struct pcap_pkthdr { + struct timeval ts; /* time stamp */ + bpf_u_int32 caplen; /* length of portion present */ + bpf_u_int32 len; /* length this packet (off wire) */ +}; + +/* + * As returned by the pcap_stats() + */ +struct pcap_stat { + u_int ps_recv; /* number of packets received */ + u_int ps_drop; /* number of packets dropped */ + u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */ +#ifdef _WIN32 + u_int ps_capt; /* number of packets that reach the application */ + u_int ps_sent; /* number of packets sent by the server on the network */ + u_int ps_netdrop; /* number of packets lost on the network */ +#endif /* _WIN32 */ +}; + +#ifdef MSDOS +/* + * As returned by the pcap_stats_ex() + */ +struct pcap_stat_ex { + u_long rx_packets; /* total packets received */ + u_long tx_packets; /* total packets transmitted */ + u_long rx_bytes; /* total bytes received */ + u_long tx_bytes; /* total bytes transmitted */ + u_long rx_errors; /* bad packets received */ + u_long tx_errors; /* packet transmit problems */ + u_long rx_dropped; /* no space in Rx buffers */ + u_long tx_dropped; /* no space available for Tx */ + u_long multicast; /* multicast packets received */ + u_long collisions; + + /* detailed rx_errors: */ + u_long rx_length_errors; + u_long rx_over_errors; /* receiver ring buff overflow */ + u_long rx_crc_errors; /* recv'd pkt with crc error */ + u_long rx_frame_errors; /* recv'd frame alignment error */ + u_long rx_fifo_errors; /* recv'r fifo overrun */ + u_long rx_missed_errors; /* recv'r missed packet */ + + /* detailed tx_errors */ + u_long tx_aborted_errors; + u_long tx_carrier_errors; + u_long tx_fifo_errors; + u_long tx_heartbeat_errors; + u_long tx_window_errors; + }; +#endif + +/* + * Item in a list of interfaces. + */ +struct pcap_if { + struct pcap_if *next; + char *name; /* name to hand to "pcap_open_live()" */ + char *description; /* textual description of interface, or NULL */ + struct pcap_addr *addresses; + bpf_u_int32 flags; /* PCAP_IF_ interface flags */ +}; + +#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ +#define PCAP_IF_UP 0x00000002 /* interface is up */ +#define PCAP_IF_RUNNING 0x00000004 /* interface is running */ + +/* + * Representation of an interface address. + */ +struct pcap_addr { + struct pcap_addr *next; + struct sockaddr *addr; /* address */ + struct sockaddr *netmask; /* netmask for that address */ + struct sockaddr *broadaddr; /* broadcast address for that address */ + struct sockaddr *dstaddr; /* P2P destination address for that address */ +}; + +typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, + const u_char *); + +/* + * Error codes for the pcap API. + * These will all be negative, so you can check for the success or + * failure of a call that returns these codes by checking for a + * negative value. + */ +#define PCAP_ERROR -1 /* generic error code */ +#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ +#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ +#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ +#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ +#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ +#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ +#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ +#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ +#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */ +#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */ +#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */ + +/* + * Warning codes for the pcap API. + * These will all be positive and non-zero, so they won't look like + * errors. + */ +#define PCAP_WARNING 1 /* generic warning code */ +#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ +#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */ + +/* + * Value to pass to pcap_compile() as the netmask if you don't know what + * the netmask is. + */ +#define PCAP_NETMASK_UNKNOWN 0xffffffff + +/* + * We're deprecating pcap_lookupdev() for various reasons (not + * thread-safe, can behave weirdly with WinPcap). Callers + * should use pcap_findalldevs() and use the first device. + */ +PCAP_API char *pcap_lookupdev(char *) +PCAP_DEPRECATED(pcap_lookupdev, "use 'pcap_findalldevs' and use the first device"); + +PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); + +PCAP_API pcap_t *pcap_create(const char *, char *); +PCAP_API int pcap_set_snaplen(pcap_t *, int); +PCAP_API int pcap_set_promisc(pcap_t *, int); +PCAP_API int pcap_can_set_rfmon(pcap_t *); +PCAP_API int pcap_set_rfmon(pcap_t *, int); +PCAP_API int pcap_set_timeout(pcap_t *, int); +PCAP_API int pcap_set_tstamp_type(pcap_t *, int); +PCAP_API int pcap_set_immediate_mode(pcap_t *, int); +PCAP_API int pcap_set_buffer_size(pcap_t *, int); +PCAP_API int pcap_set_tstamp_precision(pcap_t *, int); +PCAP_API int pcap_get_tstamp_precision(pcap_t *); +PCAP_API int pcap_activate(pcap_t *); + +PCAP_API int pcap_list_tstamp_types(pcap_t *, int **); +PCAP_API void pcap_free_tstamp_types(int *); +PCAP_API int pcap_tstamp_type_name_to_val(const char *); +PCAP_API const char *pcap_tstamp_type_val_to_name(int); +PCAP_API const char *pcap_tstamp_type_val_to_description(int); + +#ifdef __linux__ +PCAP_API int pcap_set_protocol(pcap_t *, int); +#endif + +/* + * Time stamp types. + * Not all systems and interfaces will necessarily support all of these. + * + * A system that supports PCAP_TSTAMP_HOST is offering time stamps + * provided by the host machine, rather than by the capture device, + * but not committing to any characteristics of the time stamp; + * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes. + * + * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine, + * that's low-precision but relatively cheap to fetch; it's normally done + * using the system clock, so it's normally synchronized with times you'd + * fetch from system calls. + * + * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine, + * that's high-precision; it might be more expensive to fetch. It might + * or might not be synchronized with the system clock, and might have + * problems with time stamps for packets received on different CPUs, + * depending on the platform. + * + * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the + * capture device; it's synchronized with the system clock. + * + * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by + * the capture device; it's not synchronized with the system clock. + * + * Note that time stamps synchronized with the system clock can go + * backwards, as the system clock can go backwards. If a clock is + * not in sync with the system clock, that could be because the + * system clock isn't keeping accurate time, because the other + * clock isn't keeping accurate time, or both. + * + * Note that host-provided time stamps generally correspond to the + * time when the time-stamping code sees the packet; this could + * be some unknown amount of time after the first or last bit of + * the packet is received by the network adapter, due to batching + * of interrupts for packet arrival, queueing delays, etc.. + */ +#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */ +#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */ +#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */ +#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */ +#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */ + +/* + * Time stamp resolution types. + * Not all systems and interfaces will necessarily support all of these + * resolutions when doing live captures; all of them can be requested + * when reading a savefile. + */ +#define PCAP_TSTAMP_PRECISION_MICRO 0 /* use timestamps with microsecond precision, default */ +#define PCAP_TSTAMP_PRECISION_NANO 1 /* use timestamps with nanosecond precision */ + +PCAP_API pcap_t *pcap_open_live(const char *, int, int, int, char *); +PCAP_API pcap_t *pcap_open_dead(int, int); +PCAP_API pcap_t *pcap_open_dead_with_tstamp_precision(int, int, u_int); +PCAP_API pcap_t *pcap_open_offline_with_tstamp_precision(const char *, u_int, char *); +PCAP_API pcap_t *pcap_open_offline(const char *, char *); +#ifdef _WIN32 + PCAP_API pcap_t *pcap_hopen_offline_with_tstamp_precision(intptr_t, u_int, char *); + PCAP_API pcap_t *pcap_hopen_offline(intptr_t, char *); + /* + * If we're building libpcap, these are internal routines in savefile.c, + * so we must not define them as macros. + * + * If we're not building libpcap, given that the version of the C runtime + * with which libpcap was built might be different from the version + * of the C runtime with which an application using libpcap was built, + * and that a FILE structure may differ between the two versions of the + * C runtime, calls to _fileno() must use the version of _fileno() in + * the C runtime used to open the FILE *, not the version in the C + * runtime with which libpcap was built. (Maybe once the Universal CRT + * rules the world, this will cease to be a problem.) + */ + #ifndef BUILDING_PCAP + #define pcap_fopen_offline_with_tstamp_precision(f,p,b) \ + pcap_hopen_offline_with_tstamp_precision(_get_osfhandle(_fileno(f)), p, b) + #define pcap_fopen_offline(f,b) \ + pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) + #endif +#else /*_WIN32*/ + PCAP_API pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *); + PCAP_API pcap_t *pcap_fopen_offline(FILE *, char *); +#endif /*_WIN32*/ + +PCAP_API void pcap_close(pcap_t *); +PCAP_API int pcap_loop(pcap_t *, int, pcap_handler, u_char *); +PCAP_API int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); +PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *); +PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); +PCAP_API void pcap_breakloop(pcap_t *); +PCAP_API int pcap_stats(pcap_t *, struct pcap_stat *); +PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *); +PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t); +PCAP_API int pcap_getnonblock(pcap_t *, char *); +PCAP_API int pcap_setnonblock(pcap_t *, int, char *); +PCAP_API int pcap_inject(pcap_t *, const void *, size_t); +PCAP_API int pcap_sendpacket(pcap_t *, const u_char *, int); +PCAP_API const char *pcap_statustostr(int); +PCAP_API const char *pcap_strerror(int); +PCAP_API char *pcap_geterr(pcap_t *); +PCAP_API void pcap_perror(pcap_t *, const char *); +PCAP_API int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, + bpf_u_int32); +PCAP_API int pcap_compile_nopcap(int, int, struct bpf_program *, + const char *, int, bpf_u_int32); +PCAP_API void pcap_freecode(struct bpf_program *); +PCAP_API int pcap_offline_filter(const struct bpf_program *, + const struct pcap_pkthdr *, const u_char *); +PCAP_API int pcap_datalink(pcap_t *); +PCAP_API int pcap_datalink_ext(pcap_t *); +PCAP_API int pcap_list_datalinks(pcap_t *, int **); +PCAP_API int pcap_set_datalink(pcap_t *, int); +PCAP_API void pcap_free_datalinks(int *); +PCAP_API int pcap_datalink_name_to_val(const char *); +PCAP_API const char *pcap_datalink_val_to_name(int); +PCAP_API const char *pcap_datalink_val_to_description(int); +PCAP_API int pcap_snapshot(pcap_t *); +PCAP_API int pcap_is_swapped(pcap_t *); +PCAP_API int pcap_major_version(pcap_t *); +PCAP_API int pcap_minor_version(pcap_t *); +PCAP_API int pcap_bufsize(pcap_t *); + +/* XXX */ +PCAP_API FILE *pcap_file(pcap_t *); +PCAP_API int pcap_fileno(pcap_t *); + +#ifdef _WIN32 + PCAP_API int pcap_wsockinit(void); +#endif + +PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); +PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); +PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *); +PCAP_API FILE *pcap_dump_file(pcap_dumper_t *); +PCAP_API long pcap_dump_ftell(pcap_dumper_t *); +PCAP_API int64_t pcap_dump_ftell64(pcap_dumper_t *); +PCAP_API int pcap_dump_flush(pcap_dumper_t *); +PCAP_API void pcap_dump_close(pcap_dumper_t *); +PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); + +PCAP_API int pcap_findalldevs(pcap_if_t **, char *); +PCAP_API void pcap_freealldevs(pcap_if_t *); + +/* + * We return a pointer to the version string, rather than exporting the + * version string directly. + * + * On at least some UNIXes, if you import data from a shared library into + * an program, the data is bound into the program binary, so if the string + * in the version of the library with which the program was linked isn't + * the same as the string in the version of the library with which the + * program is being run, various undesirable things may happen (warnings, + * the string being the one from the version of the library with which the + * program was linked, or even weirder things, such as the string being the + * one from the library but being truncated). + * + * On Windows, the string is constructed at run time. + */ +PCAP_API const char *pcap_lib_version(void); + +/* + * On at least some versions of NetBSD and QNX, we don't want to declare + * bpf_filter() here, as it's also be declared in , with a + * different signature, but, on other BSD-flavored UN*Xes, it's not + * declared in , so we *do* want to declare it here, so it's + * declared when we build pcap-bpf.c. + */ +#if !defined(__NetBSD__) && !defined(__QNX__) + PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); +#endif +PCAP_API int bpf_validate(const struct bpf_insn *f, int len); +PCAP_API char *bpf_image(const struct bpf_insn *, int); +PCAP_API void bpf_dump(const struct bpf_program *, int); + +#if defined(_WIN32) + + /* + * Win32 definitions + */ + + /*! + \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). + */ + struct pcap_send_queue + { + u_int maxlen; /* Maximum size of the queue, in bytes. This + variable contains the size of the buffer field. */ + u_int len; /* Current size of the queue, in bytes. */ + char *buffer; /* Buffer containing the packets to be sent. */ + }; + + typedef struct pcap_send_queue pcap_send_queue; + + /*! + \brief This typedef is a support for the pcap_get_airpcap_handle() function + */ + #if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) + #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ + typedef struct _AirpcapHandle *PAirpcapHandle; + #endif + + PCAP_API int pcap_setbuff(pcap_t *p, int dim); + PCAP_API int pcap_setmode(pcap_t *p, int mode); + PCAP_API int pcap_setmintocopy(pcap_t *p, int size); + + PCAP_API HANDLE pcap_getevent(pcap_t *p); + + PCAP_API int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *); + PCAP_API int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *); + + PCAP_API pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); + + PCAP_API void pcap_sendqueue_destroy(pcap_send_queue* queue); + + PCAP_API int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); + + PCAP_API u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); + + PCAP_API struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); + + PCAP_API int pcap_setuserbuffer(pcap_t *p, int size); + + PCAP_API int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); + + PCAP_API int pcap_live_dump_ended(pcap_t *p, int sync); + + PCAP_API int pcap_start_oem(char* err_str, int flags); + + PCAP_API PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); + + #define MODE_CAPT 0 + #define MODE_STAT 1 + #define MODE_MON 2 + +#elif defined(MSDOS) + + /* + * MS-DOS definitions + */ + + PCAP_API int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); + PCAP_API void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); + PCAP_API u_long pcap_mac_packets (void); + +#else /* UN*X */ + + /* + * UN*X definitions + */ + + PCAP_API int pcap_get_selectable_fd(pcap_t *); + +#endif /* _WIN32/MSDOS/UN*X */ + +/* + * Remote capture definitions. + * + * These routines are only present if libpcap has been configured to + * include remote capture support. + */ + +/* + * The maximum buffer size in which address, port, interface names are kept. + * + * In case the adapter name or such is larger than this value, it is truncated. + * This is not used by the user; however it must be aware that an hostname / interface + * name longer than this value will be truncated. + */ +#define PCAP_BUF_SIZE 1024 + +/* + * The type of input source, passed to pcap_open(). + */ +#define PCAP_SRC_FILE 2 /* local savefile */ +#define PCAP_SRC_IFLOCAL 3 /* local network interface */ +#define PCAP_SRC_IFREMOTE 4 /* interface on a remote host, using RPCAP */ + +/* + * The formats allowed by pcap_open() are the following: + * - file://path_and_filename [opens a local file] + * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] + * - rpcap://host/devicename [opens the selected device available on a remote host] + * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] + * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] + * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] + * + * The formats allowed by the pcap_findalldevs_ex() are the following: + * - file://folder/ [lists all the files in the given folder] + * - rpcap:// [lists all local adapters] + * - rpcap://host:port/ [lists the devices available on a remote host] + * + * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since + * IPv6 is fully supported, these are the allowed formats: + * + * - host (literal): e.g. host.foo.bar + * - host (numeric IPv4): e.g. 10.11.12.13 + * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] + * - host (numeric IPv6): e.g. [1:2:3::4] + * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') + * + * Here you find some allowed examples: + * - rpcap://host.foo.bar/devicename [everything literal, no port number] + * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] + * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] + * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] + * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] + * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] + * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] + * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] + */ + +/* + * URL schemes for capture source. + */ +/* + * This string indicates that the user wants to open a capture from a + * local file. + */ +#define PCAP_SRC_FILE_STRING "file://" +/* + * This string indicates that the user wants to open a capture from a + * network interface. This string does not necessarily involve the use + * of the RPCAP protocol. If the interface required resides on the local + * host, the RPCAP protocol is not involved and the local functions are used. + */ +#define PCAP_SRC_IF_STRING "rpcap://" + +/* + * Flags to pass to pcap_open(). + */ + +/* + * Specifies whether promiscuous mode is to be used. + */ +#define PCAP_OPENFLAG_PROMISCUOUS 0x00000001 + +/* + * Specifies, for an RPCAP capture, whether the data transfer (in + * case of a remote capture) has to be done with UDP protocol. + * + * If it is '1' if you want a UDP data connection, '0' if you want + * a TCP data connection; control connection is always TCP-based. + * A UDP connection is much lighter, but it does not guarantee that all + * the captured packets arrive to the client workstation. Moreover, + * it could be harmful in case of network congestion. + * This flag is meaningless if the source is not a remote interface. + * In that case, it is simply ignored. + */ +#define PCAP_OPENFLAG_DATATX_UDP 0x00000002 + +/* + * Specifies wheether the remote probe will capture its own generated + * traffic. + * + * In case the remote probe uses the same interface to capture traffic + * and to send data back to the caller, the captured traffic includes + * the RPCAP traffic as well. If this flag is turned on, the RPCAP + * traffic is excluded from the capture, so that the trace returned + * back to the collector is does not include this traffic. + * + * Has no effect on local interfaces or savefiles. + */ +#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 0x00000004 + +/* + * Specifies whether the local adapter will capture its own generated traffic. + * + * This flag tells the underlying capture driver to drop the packets + * that were sent by itself. This is useful when building applications + * such as bridges that should ignore the traffic they just sent. + * + * Supported only on Windows. + */ +#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 0x00000008 + +/* + * This flag configures the adapter for maximum responsiveness. + * + * In presence of a large value for nbytes, WinPcap waits for the arrival + * of several packets before copying the data to the user. This guarantees + * a low number of system calls, i.e. lower processor usage, i.e. better + * performance, which is good for applications like sniffers. If the user + * sets the PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will + * copy the packets as soon as the application is ready to receive them. + * This is suggested for real time applications (such as, for example, + * a bridge) that need the best responsiveness. + * + * The equivalent with pcap_create()/pcap_activate() is "immediate mode". + */ +#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 0x00000010 + +/* + * Remote authentication methods. + * These are used in the 'type' member of the pcap_rmtauth structure. + */ + +/* + * NULL authentication. + * + * The 'NULL' authentication has to be equal to 'zero', so that old + * applications can just put every field of struct pcap_rmtauth to zero, + * and it does work. + */ +#define RPCAP_RMTAUTH_NULL 0 +/* + * Username/password authentication. + * + * With this type of authentication, the RPCAP protocol will use the username/ + * password provided to authenticate the user on the remote machine. If the + * authentication is successful (and the user has the right to open network + * devices) the RPCAP connection will continue; otherwise it will be dropped. + * + * *******NOTE********: the username and password are sent over the network + * to the capture server *IN CLEAR TEXT*. Don't use this on a network + * that you don't completely control! (And be *really* careful in your + * definition of "completely"!) + */ +#define RPCAP_RMTAUTH_PWD 1 + +/* + * This structure keeps the information needed to autheticate the user + * on a remote machine. + * + * The remote machine can either grant or refuse the access according + * to the information provided. + * In case the NULL authentication is required, both 'username' and + * 'password' can be NULL pointers. + * + * This structure is meaningless if the source is not a remote interface; + * in that case, the functions which requires such a structure can accept + * a NULL pointer as well. + */ +struct pcap_rmtauth +{ + /* + * \brief Type of the authentication required. + * + * In order to provide maximum flexibility, we can support different types + * of authentication based on the value of this 'type' variable. The currently + * supported authentication methods are defined into the + * \link remote_auth_methods Remote Authentication Methods Section\endlink. + */ + int type; + /* + * \brief Zero-terminated string containing the username that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char *username; + /* + * \brief Zero-terminated string containing the password that has to be + * used on the remote machine for authentication. + * + * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication + * and it can be NULL. + */ + char *password; +}; + +/* + * This routine can open a savefile, a local device, or a device on + * a remote machine running an RPCAP server. + * + * For opening a savefile, the pcap_open_offline routines can be used, + * and will work just as well; code using them will work on more + * platforms than code using pcap_open() to open savefiles. + * + * For opening a local device, pcap_open_live() can be used; it supports + * most of the capabilities that pcap_open() supports, and code using it + * will work on more platforms than code using pcap_open(). pcap_create() + * and pcap_activate() can also be used; they support all capabilities + * that pcap_open() supports, except for the Windows-only + * PCAP_OPENFLAG_NOCAPTURE_LOCAL, and support additional capabilities. + * + * For opening a remote capture, pcap_open() is currently the only + * API available. + */ +PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags, + int read_timeout, struct pcap_rmtauth *auth, char *errbuf); +PCAP_API int pcap_createsrcstr(char *source, int type, const char *host, + const char *port, const char *name, char *errbuf); +PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host, + char *port, char *name, char *errbuf); + +/* + * This routine can scan a directory for savefiles, list local capture + * devices, or list capture devices on a remote machine running an RPCAP + * server. + * + * For scanning for savefiles, it can be used on both UN*X systems and + * Windows systems; for each directory entry it sees, it tries to open + * the file as a savefile using pcap_open_offline(), and only includes + * it in the list of files if the open succeeds, so it filters out + * files for which the user doesn't have read permission, as well as + * files that aren't valid savefiles readable by libpcap. + * + * For listing local capture devices, it's just a wrapper around + * pcap_findalldevs(); code using pcap_findalldevs() will work on more + * platforms than code using pcap_findalldevs_ex(). + * + * For listing remote capture devices, pcap_findalldevs_ex() is currently + * the only API available. + */ +PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, + pcap_if_t **alldevs, char *errbuf); + +/* + * Sampling methods. + * + * These allow pcap_loop(), pcap_dispatch(), pcap_next(), and pcap_next_ex() + * to see only a sample of packets, rather than all packets. + * + * Currently, they work only on Windows local captures. + */ + +/* + * Specifies that no sampling is to be done on the current capture. + * + * In this case, no sampling algorithms are applied to the current capture. + */ +#define PCAP_SAMP_NOSAMP 0 + +/* + * Specifies that only 1 out of N packets must be returned to the user. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates the + * number of packets (minus 1) that must be discarded before one packet got + * accepted. + * In other words, if 'value = 10', the first packet is returned to the + * caller, while the following 9 are discarded. + */ +#define PCAP_SAMP_1_EVERY_N 1 + +/* + * Specifies that we have to return 1 packet every N milliseconds. + * + * In this case, the 'value' field of the 'pcap_samp' structure indicates + * the 'waiting time' in milliseconds before one packet got accepted. + * In other words, if 'value = 10', the first packet is returned to the + * caller; the next returned one will be the first packet that arrives + * when 10ms have elapsed. + */ +#define PCAP_SAMP_FIRST_AFTER_N_MS 2 + +/* + * This structure defines the information related to sampling. + * + * In case the sampling is requested, the capturing device should read + * only a subset of the packets coming from the source. The returned packets + * depend on the sampling parameters. + * + * WARNING: The sampling process is applied *after* the filtering process. + * In other words, packets are filtered first, then the sampling process + * selects a subset of the 'filtered' packets and it returns them to the + * caller. + */ +struct pcap_samp +{ + /* + * Method used for sampling; see above. + */ + int method; + + /* + * This value depends on the sampling method defined. + * For its meaning, see above. + */ + int value; +}; + +/* + * New functions. + */ +PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p); + +/* + * RPCAP active mode. + */ + +/* Maximum length of an host name (needed for the RPCAP active mode) */ +#define RPCAP_HOSTLIST_SIZE 1024 + +/* + * Some minor differences between UN*X sockets and and Winsock sockets. + */ +#ifndef _WIN32 + /*! + * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's + * a file descriptor, and therefore a signed integer. + * We define SOCKET to be a signed integer on UN*X, so that it can + * be used on both platforms. + */ + #define SOCKET int + + /*! + * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET; + * in UN*X, it's -1. + * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on + * both platforms. + */ + #define INVALID_SOCKET -1 +#endif + +PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port, + const char *hostlist, char *connectinghost, + struct pcap_rmtauth *auth, char *errbuf); +PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size, + char *errbuf); +PCAP_API int pcap_remoteact_close(const char *host, char *errbuf); +PCAP_API void pcap_remoteact_cleanup(void); + +#ifdef __cplusplus +} +#endif + +#endif /* lib_pcap_pcap_h */ diff --git a/src/frontend/qt_sdl/pcap/sll.h b/src/frontend/qt_sdl/pcap/sll.h new file mode 100644 index 0000000..c4d0886 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/sll.h @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * For captures on Linux cooked sockets, we construct a fake header + * that includes: + * + * a 2-byte "packet type" which is one of: + * + * LINUX_SLL_HOST packet was sent to us + * LINUX_SLL_BROADCAST packet was broadcast + * LINUX_SLL_MULTICAST packet was multicast + * LINUX_SLL_OTHERHOST packet was sent to somebody else + * LINUX_SLL_OUTGOING packet was sent *by* us; + * + * a 2-byte Ethernet protocol field; + * + * a 2-byte link-layer type; + * + * a 2-byte link-layer address length; + * + * an 8-byte source link-layer address, whose actual length is + * specified by the previous value. + * + * All fields except for the link-layer address are in network byte order. + * + * DO NOT change the layout of this structure, or change any of the + * LINUX_SLL_ values below. If you must change the link-layer header + * for a "cooked" Linux capture, introduce a new DLT_ type (ask + * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it + * a value that collides with a value already being used), and use the + * new header in captures of that type, so that programs that can + * handle DLT_LINUX_SLL captures will continue to handle them correctly + * without any change, and so that capture files with different headers + * can be told apart and programs that read them can dissect the + * packets in them. + */ + +#ifndef lib_pcap_sll_h +#define lib_pcap_sll_h + +/* + * A DLT_LINUX_SLL fake link-layer header. + */ +#define SLL_HDR_LEN 16 /* total header length */ +#define SLL_ADDRLEN 8 /* length of address field */ + +#include + +struct sll_header { + uint16_t sll_pkttype; /* packet type */ + uint16_t sll_hatype; /* link-layer address type */ + uint16_t sll_halen; /* link-layer address length */ + uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ + uint16_t sll_protocol; /* protocol */ +}; + +/* + * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the + * PACKET_ values on Linux, but are defined here so that they're + * available even on systems other than Linux, and so that they + * don't change even if the PACKET_ values change. + */ +#define LINUX_SLL_HOST 0 +#define LINUX_SLL_BROADCAST 1 +#define LINUX_SLL_MULTICAST 2 +#define LINUX_SLL_OTHERHOST 3 +#define LINUX_SLL_OUTGOING 4 + +/* + * The LINUX_SLL_ values for "sll_protocol"; these correspond to the + * ETH_P_ values on Linux, but are defined here so that they're + * available even on systems other than Linux. We assume, for now, + * that the ETH_P_ values won't change in Linux; if they do, then: + * + * if we don't translate them in "pcap-linux.c", capture files + * won't necessarily be readable if captured on a system that + * defines ETH_P_ values that don't match these values; + * + * if we do translate them in "pcap-linux.c", that makes life + * unpleasant for the BPF code generator, as the values you test + * for in the kernel aren't the values that you test for when + * reading a capture file, so the fixup code run on BPF programs + * handed to the kernel ends up having to do more work. + * + * Add other values here as necessary, for handling packet types that + * might show up on non-Ethernet, non-802.x networks. (Not all the ones + * in the Linux "if_ether.h" will, I suspect, actually show up in + * captures.) + */ +#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ +#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ +#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */ +#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */ + +#endif diff --git a/src/frontend/qt_sdl/pcap/usb.h b/src/frontend/qt_sdl/pcap/usb.h new file mode 100644 index 0000000..e485ec8 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/usb.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2006 Paolo Abeni (Italy) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Basic USB data struct + * By Paolo Abeni + */ + +#ifndef lib_pcap_usb_h +#define lib_pcap_usb_h + +#include + +/* + * possible transfer mode + */ +#define URB_TRANSFER_IN 0x80 +#define URB_ISOCHRONOUS 0x0 +#define URB_INTERRUPT 0x1 +#define URB_CONTROL 0x2 +#define URB_BULK 0x3 + +/* + * possible event type + */ +#define URB_SUBMIT 'S' +#define URB_COMPLETE 'C' +#define URB_ERROR 'E' + +/* + * USB setup header as defined in USB specification. + * Appears at the front of each Control S-type packet in DLT_USB captures. + */ +typedef struct _usb_setup { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} pcap_usb_setup; + +/* + * Information from the URB for Isochronous transfers. + */ +typedef struct _iso_rec { + int32_t error_count; + int32_t numdesc; +} iso_rec; + +/* + * Header prepended by linux kernel to each event. + * Appears at the front of each packet in DLT_USB_LINUX captures. + */ +typedef struct _usb_header { + uint64_t id; + uint8_t event_type; + uint8_t transfer_type; + uint8_t endpoint_number; + uint8_t device_address; + uint16_t bus_id; + char setup_flag;/*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + uint32_t urb_len; + uint32_t data_len; /* amount of urb data really present in this event*/ + pcap_usb_setup setup; +} pcap_usb_header; + +/* + * Header prepended by linux kernel to each event for the 2.6.31 + * and later kernels; for the 2.6.21 through 2.6.30 kernels, the + * "iso_rec" information, and the fields starting with "interval" + * are zeroed-out padding fields. + * + * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures. + */ +typedef struct _usb_header_mmapped { + uint64_t id; + uint8_t event_type; + uint8_t transfer_type; + uint8_t endpoint_number; + uint8_t device_address; + uint16_t bus_id; + char setup_flag;/*if !=0 the urb setup header is not present*/ + char data_flag; /*if !=0 no urb data is present*/ + int64_t ts_sec; + int32_t ts_usec; + int32_t status; + uint32_t urb_len; + uint32_t data_len; /* amount of urb data really present in this event*/ + union { + pcap_usb_setup setup; + iso_rec iso; + } s; + int32_t interval; /* for Interrupt and Isochronous events */ + int32_t start_frame; /* for Isochronous events */ + uint32_t xfer_flags; /* copy of URB's transfer flags */ + uint32_t ndesc; /* number of isochronous descriptors */ +} pcap_usb_header_mmapped; + +/* + * Isochronous descriptors; for isochronous transfers there might be + * one or more of these at the beginning of the packet data. The + * number of descriptors is given by the "ndesc" field in the header; + * as indicated, in older kernels that don't put the descriptors at + * the beginning of the packet, that field is zeroed out, so that field + * can be trusted even in captures from older kernels. + */ +typedef struct _usb_isodesc { + int32_t status; + uint32_t offset; + uint32_t len; + uint8_t pad[4]; +} usb_isodesc; + +#endif diff --git a/src/frontend/qt_sdl/pcap/vlan.h b/src/frontend/qt_sdl/pcap/vlan.h new file mode 100644 index 0000000..b29dd73 --- /dev/null +++ b/src/frontend/qt_sdl/pcap/vlan.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lib_pcap_vlan_h +#define lib_pcap_vlan_h + +#include + +struct vlan_tag { + uint16_t vlan_tpid; /* ETH_P_8021Q */ + uint16_t vlan_tci; /* VLAN TCI */ +}; + +#define VLAN_TAG_LEN 4 + +#endif diff --git a/src/pcap/bluetooth.h b/src/pcap/bluetooth.h deleted file mode 100644 index 15dc5a8..0000000 --- a/src/pcap/bluetooth.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2006 Paolo Abeni (Italy) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * bluetooth data struct - * By Paolo Abeni - */ - -#ifndef lib_pcap_bluetooth_h -#define lib_pcap_bluetooth_h - -#include - -/* - * Header prepended libpcap to each bluetooth h4 frame, - * fields are in network byte order - */ -typedef struct _pcap_bluetooth_h4_header { - uint32_t direction; /* if first bit is set direction is incoming */ -} pcap_bluetooth_h4_header; - -/* - * Header prepended libpcap to each bluetooth linux monitor frame, - * fields are in network byte order - */ -typedef struct _pcap_bluetooth_linux_monitor_header { - uint16_t adapter_id; - uint16_t opcode; -} pcap_bluetooth_linux_monitor_header; - -#endif diff --git a/src/pcap/bpf.h b/src/pcap/bpf.h deleted file mode 100644 index 1a953a9..0000000 --- a/src/pcap/bpf.h +++ /dev/null @@ -1,270 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - */ - -/* - * This is libpcap's cut-down version of bpf.h; it includes only - * the stuff needed for the code generator and the userland BPF - * interpreter, and the libpcap APIs for setting filters, etc.. - * - * "pcap-bpf.c" will include the native OS version, as it deals with - * the OS's BPF implementation. - * - * At least two programs found by Google Code Search explicitly includes - * (even though / includes it for you), - * so moving that stuff to would break the build for some - * programs. - */ - -/* - * If we've already included , don't re-define this stuff. - * We assume BSD-style multiple-include protection in , - * which is true of all but the oldest versions of FreeBSD and NetBSD, - * or Tru64 UNIX-style multiple-include protection (or, at least, - * Tru64 UNIX 5.x-style; I don't have earlier versions available to check), - * or AIX-style multiple-include protection (or, at least, AIX 5.x-style; - * I don't have earlier versions available to check), or QNX-style - * multiple-include protection (as per GitHub pull request #394). - * - * We do not check for BPF_MAJOR_VERSION, as that's defined by - * , which is directly or indirectly included in some - * programs that also include pcap.h, and doesn't - * define stuff we need. - * - * This also provides our own multiple-include protection. - */ -#if !defined(_NET_BPF_H_) && !defined(_NET_BPF_H_INCLUDED) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) -#define lib_pcap_bpf_h - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* BSD style release date */ -#define BPF_RELEASE 199606 - -#ifdef MSDOS /* must be 32-bit */ -typedef long bpf_int32; -typedef unsigned long bpf_u_int32; -#else -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -/* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. - * - * Tcpdump's print-pflog.c uses this, so we define it here. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) - -/* - * Structure for "pcap_compile()", "pcap_setfilter()", etc.. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -#include - -/* - * The instruction encodings. - * - * Please inform tcpdump-workers@lists.tcpdump.org if you use any - * of the reserved values, so that we can note that they're used - * (and perhaps implement it in the reference BPF implementation - * and encourage its implementation elsewhere). - */ - -/* - * The upper 8 bits of the opcode aren't used. BSD/OS used 0x8000. - */ - -/* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 - -/* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -/* 0x18 reserved; used by BSD/OS */ -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 -/* 0xc0 reserved; used by BSD/OS */ -/* 0xe0 reserved; used by BSD/OS */ - -/* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_MOD 0x90 -#define BPF_XOR 0xa0 -/* 0xb0 reserved */ -/* 0xc0 reserved */ -/* 0xd0 reserved */ -/* 0xe0 reserved */ -/* 0xf0 reserved */ - -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -/* 0x50 reserved; used on BSD/OS */ -/* 0x60 reserved */ -/* 0x70 reserved */ -/* 0x80 reserved */ -/* 0x90 reserved */ -/* 0xa0 reserved */ -/* 0xb0 reserved */ -/* 0xc0 reserved */ -/* 0xd0 reserved */ -/* 0xe0 reserved */ -/* 0xf0 reserved */ -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 - -/* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 -/* 0x18 reserved */ - -/* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -/* 0x08 reserved */ -/* 0x10 reserved */ -/* 0x18 reserved */ -/* #define BPF_COP 0x20 NetBSD "coprocessor" extensions */ -/* 0x28 reserved */ -/* 0x30 reserved */ -/* 0x38 reserved */ -/* #define BPF_COPX 0x40 NetBSD "coprocessor" extensions */ -/* also used on BSD/OS */ -/* 0x48 reserved */ -/* 0x50 reserved */ -/* 0x58 reserved */ -/* 0x60 reserved */ -/* 0x68 reserved */ -/* 0x70 reserved */ -/* 0x78 reserved */ -#define BPF_TXA 0x80 -/* 0x88 reserved */ -/* 0x90 reserved */ -/* 0x98 reserved */ -/* 0xa0 reserved */ -/* 0xa8 reserved */ -/* 0xb0 reserved */ -/* 0xb8 reserved */ -/* 0xc0 reserved; used on BSD/OS */ -/* 0xc8 reserved */ -/* 0xd0 reserved */ -/* 0xd8 reserved */ -/* 0xe0 reserved */ -/* 0xe8 reserved */ -/* 0xf0 reserved */ -/* 0xf8 reserved */ - -/* - * The instruction data structure. - */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_u_int32 k; -}; - -/* - * Auxiliary data, for use when interpreting a filter intended for the - * Linux kernel when the kernel rejects the filter (requiring us to - * run it in userland). It contains VLAN tag information. - */ -struct bpf_aux_data { - u_short vlan_tag_present; - u_short vlan_tag; -}; - -/* - * Macros for insn array initializers. - */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } - -PCAP_API int bpf_validate(const struct bpf_insn *, int); -PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -extern u_int bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *); - -/* - * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). - */ -#define BPF_MEMWORDS 16 - -#ifdef __cplusplus -} -#endif - -#endif /* !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h) */ diff --git a/src/pcap/can_socketcan.h b/src/pcap/can_socketcan.h deleted file mode 100644 index 332d9ff..0000000 --- a/src/pcap/can_socketcan.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lib_pcap_can_socketcan_h -#define lib_pcap_can_socketcan_h - -#include - -/* - * SocketCAN header, as per Documentation/networking/can.txt in the - * Linux source. - */ -typedef struct { - uint32_t can_id; - uint8_t payload_length; - uint8_t pad; - uint8_t reserved1; - uint8_t reserved2; -} pcap_can_socketcan_hdr; - -#endif diff --git a/src/pcap/compiler-tests.h b/src/pcap/compiler-tests.h deleted file mode 100644 index 8876c67..0000000 --- a/src/pcap/compiler-tests.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lib_pcap_compiler_tests_h -#define lib_pcap_compiler_tests_h - - -/* - * This was introduced by Clang: - * - * http://clang.llvm.org/docs/LanguageExtensions.html#has-attribute - * - * in some version (which version?); it has been picked up by GCC 5.0. - */ -#ifndef __has_attribute - /* - * It's a macro, so you can check whether it's defined to check - * whether it's supported. - * - * If it's not, define it to always return 0, so that we move on to - * the fallback checks. - */ - #define __has_attribute(x) 0 -#endif - -/* - * Note that the C90 spec's "6.8.1 Conditional inclusion" and the - * C99 spec's and C11 spec's "6.10.1 Conditional inclusion" say: - * - * Prior to evaluation, macro invocations in the list of preprocessing - * tokens that will become the controlling constant expression are - * replaced (except for those macro names modified by the defined unary - * operator), just as in normal text. If the token "defined" is - * generated as a result of this replacement process or use of the - * "defined" unary operator does not match one of the two specified - * forms prior to macro replacement, the behavior is undefined. - * - * so you shouldn't use defined() in a #define that's used in #if or - * #elif. Some versions of Clang, for example, will warn about this. - * - * Instead, we check whether the pre-defined macros for particular - * compilers are defined and, if not, define the "is this version XXX - * or a later version of this compiler" macros as 0. - */ - -/* - * Check whether this is GCC major.minor or a later release, or some - * compiler that claims to be "just like GCC" of that version or a - * later release. - */ - -#if ! defined(__GNUC__) -#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) 0 -#else -#define PCAP_IS_AT_LEAST_GNUC_VERSION(major, minor) \ - (__GNUC__ > (major) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) -#endif - -/* - * Check whether this is Sun C/SunPro C/Oracle Studio major.minor - * or a later release. - * - * The version number in __SUNPRO_C is encoded in hex BCD, with the - * uppermost hex digit being the major version number, the next - * one or two hex digits being the minor version number, and - * the last digit being the patch version. - * - * It represents the *compiler* version, not the product version; - * see - * - * https://sourceforge.net/p/predef/wiki/Compilers/ - * - * for a partial mapping, which we assume continues for later - * 12.x product releases. - */ - -#if ! defined(__SUNPRO_C) -#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) 0 -#else -#define PCAP_SUNPRO_VERSION_TO_BCD(major, minor) \ - (((minor) >= 10) ? \ - (((major) << 12) | (((minor)/10) << 8) | (((minor)%10) << 4)) : \ - (((major) << 8) | ((minor) << 4))) -#define PCAP_IS_AT_LEAST_SUNC_VERSION(major,minor) \ - (__SUNPRO_C >= PCAP_SUNPRO_VERSION_TO_BCD((major), (minor))) -#endif - -/* - * Check whether this is IBM XL C major.minor or a later release. - * - * The version number in __xlC__ has the major version in the - * upper 8 bits and the minor version in the lower 8 bits. - */ - -#if ! defined(__xlC__) -#define PCAP_IS_AT_LEAST_XL_C_VERSION(major,minor) 0 -#else -#define PCAP_IS_AT_LEAST_XL_C_VERSION(major, minor) \ - (__xlC__ >= (((major) << 8) | (minor))) -#endif - -/* - * Check whether this is HP aC++/HP C major.minor or a later release. - * - * The version number in __HP_aCC is encoded in zero-padded decimal BCD, - * with the "A." stripped off, the uppermost two decimal digits being - * the major version number, the next two decimal digits being the minor - * version number, and the last two decimal digits being the patch version. - * (Strip off the A., remove the . between the major and minor version - * number, and add two digits of patch.) - */ - -#if ! defined(__HP_aCC) -#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) 0 -#else -#define PCAP_IS_AT_LEAST_HP_C_VERSION(major,minor) \ - (__HP_aCC >= ((major)*10000 + (minor)*100)) -#endif - -#endif /* lib_pcap_funcattrs_h */ diff --git a/src/pcap/dlt.h b/src/pcap/dlt.h deleted file mode 100644 index 609bcaf..0000000 --- a/src/pcap/dlt.h +++ /dev/null @@ -1,1389 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - */ - -#ifndef lib_pcap_dlt_h -#define lib_pcap_dlt_h - -/* - * Link-layer header type codes. - * - * Do *NOT* add new values to this list without asking - * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run - * the risk of using a value that's already being used for some other - * purpose, and of having tools that read libpcap-format captures not - * being able to handle captures with your new DLT_ value, with no hope - * that they will ever be changed to do so (as that would destroy their - * ability to read captures using that value for that other purpose). - * - * See - * - * http://www.tcpdump.org/linktypes.html - * - * for detailed descriptions of some of these link-layer header types. - */ - -/* - * These are the types that are the same on all platforms, and that - * have been defined by for ages. - */ -#define DLT_NULL 0 /* BSD loopback encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* 802.5 Token Ring */ -#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are types that are different on some platforms, and that - * have been defined by for ages. We use #ifdefs to - * detect the BSDs that define them differently from the traditional - * libpcap - * - * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS, - * but I don't know what the right #define is for BSD/OS. - */ -#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */ - -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif - -/* - * Given that the only OS that currently generates BSD/OS SLIP or PPP - * is, well, BSD/OS, arguably everybody should have chosen its values - * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they - * didn't. So it goes. - */ -#if defined(__NetBSD__) || defined(__FreeBSD__) -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -/* - * 17 was used for DLT_PFLOG in OpenBSD; it no longer is. - * - * It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG - * as 117 so that pflog captures would use a link-layer header type - * value that didn't collide with any other values. On all - * platforms other than OpenBSD, we defined DLT_PFLOG as 117, - * and we mapped between LINKTYPE_PFLOG and DLT_PFLOG. - * - * OpenBSD eventually switched to using 117 for DLT_PFLOG as well. - * - * Don't use 17 for anything else. - */ - -/* - * 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and - * Mac OS X; don't use it for anything else. (FreeBSD uses 121, - * which collides with DLT_HHDLC, even though it doesn't use 18 - * for anything and doesn't appear to have ever used it for anything.) - * - * We define it as 18 on those platforms; it is, unfortunately, used - * for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC - * in general. As the packet format for it, like that for - * DLT_PFLOG, is not only OS-dependent but OS-version-dependent, - * we don't support printing it in tcpdump except on OSes that - * have the relevant header files, so it's not that useful on - * other platforms. - */ -#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__) -#define DLT_PFSYNC 18 -#endif - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * Apparently Redback uses this for its SmartEdge 400/800. I hope - * nobody else decided to use it, too. - */ -#define DLT_REDBACK_SMARTEDGE 32 - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses - * a link-layer type of 99 for the tcpdump it supplies. The link-layer - * header has 6 bytes of unknown data, something that appears to be an - * Ethernet type, and 36 bytes that appear to be 0 in at least one capture - * I've seen. - */ -#define DLT_SYMANTEC_FIREWALL 99 - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer header type LINKTYPE_ values corresponding to DLT_ types - * that differ between platforms; don't use those values for new DLT_ - * new types. - */ - -/* - * Values starting with 104 are used for newly-assigned link-layer - * header type values; for those link-layer header types, the DLT_ - * value returned by pcap_datalink() and passed to pcap_open_dead(), - * and the LINKTYPE_ value that appears in capture files, are the - * same. - * - * DLT_MATCHING_MIN is the lowest such value; DLT_MATCHING_MAX is - * the highest such value. - */ -#define DLT_MATCHING_MIN 104 - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW, - * except when it isn't. (I.e., sometimes it's just raw IP, and - * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL, - * so that we don't have to worry about the link-layer header.) - */ - -/* - * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides - * with other values. - * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header - * (DLCI, etc.). - */ -#define DLT_FRELAY 107 - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so - * we don't use 12 for it in OSes other than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_LOOP 12 -#else -#define DLT_LOOP 108 -#endif - -/* - * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's - * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other - * than OpenBSD. - */ -#ifdef __OpenBSD__ -#define DLT_ENC 13 -#else -#define DLT_ENC 109 -#endif - -/* - * Values between 110 and 112 are reserved for use in capture file headers - * as link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ types - * other than the corresponding DLT_ types. - */ - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * OpenBSD DLT_PFLOG. - */ -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * For 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Sigh. - * - * 121 was reserved for Siemens HiPath HDLC on 2002-01-25, as - * requested by Tomas Kukosa. - * - * On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that - * assigned 121 as DLT_PFSYNC. In current versions, its libpcap - * does DLT_ <-> LINKTYPE_ mapping, mapping DLT_PFSYNC to a - * LINKTYPE_PFSYNC value of 246, so it should write out DLT_PFSYNC - * dump files with 246 as the link-layer header type. (Earlier - * versions might not have done mapping, in which case they would - * have written them out with a link-layer header type of 121.) - * - * OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC; - * its libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would - * write out DLT_PFSYNC dump files with use 18 as the link-layer - * header type. - * - * NetBSD, DragonFly BSD, and Darwin also use 18 for DLT_PFSYNC; in - * current versions, their libpcaps do DLT_ <-> LINKTYPE_ mapping, - * mapping DLT_PFSYNC to a LINKTYPE_PFSYNC value of 246, so they - * should write out DLT_PFSYNC dump files with 246 as the link-layer - * header type. (Earlier versions might not have done mapping, - * in which case they'd work the same way OpenBSD does, writing - * them out with a link-layer header type of 18.) - * - * We'll define DLT_PFSYNC as: - * - * 18 on NetBSD, OpenBSD, DragonFly BSD, and Darwin; - * - * 121 on FreeBSD; - * - * 246 everywhere else. - * - * We'll define DLT_HHDLC as 121 on everything except for FreeBSD; - * anybody who wants to compile, on FreeBSD, code that uses DLT_HHDLC - * is out of luck. - * - * We'll define LINKTYPE_PFSYNC as 246 on *all* platforms, so that - * savefiles written using *this* code won't use 18 or 121 for PFSYNC, - * they'll all use 246. - * - * Code that uses pcap_datalink() to determine the link-layer header - * type of a savefile won't, when built and run on FreeBSD, be able - * to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC capture - * files, as pcap_datalink() will give 121 for both of them. Code - * that doesn't, such as the code in Wireshark, will be able to - * distinguish between them. - * - * FreeBSD's libpcap won't map a link-layer header type of 18 - i.e., - * DLT_PFSYNC files from OpenBSD and possibly older versions of NetBSD, - * DragonFly BSD, and OS X - to DLT_PFSYNC, so code built with FreeBSD's - * libpcap won't treat those files as DLT_PFSYNC files. - * - * Other libpcaps won't map a link-layer header type of 121 to DLT_PFSYNC; - * this means they can read DLT_HHDLC files, if any exist, but won't - * treat pcap files written by any older versions of FreeBSD libpcap that - * didn't map to 246 as DLT_PFSYNC files. - */ -#ifdef __FreeBSD__ -#define DLT_PFSYNC 121 -#else -#define DLT_HHDLC 121 -#endif - -/* - * This is for RFC 2625 IP-over-Fibre Channel. - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * This is for Full Frontal ATM on Solaris with SunATM, with a - * pseudo-header followed by an AALn PDU. - * - * There may be other forms of Full Frontal ATM on other OSes, - * with different pseudo-headers. - * - * If ATM software returns a pseudo-header with VPI/VCI information - * (and, ideally, packet type information, e.g. signalling, ILMI, - * LANE, LLC-multiplexed traffic, etc.), it should not use - * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump - * and the like don't have to infer the presence or absence of a - * pseudo-header and the form of the pseudo-header. - */ -#define DLT_SUNATM 123 /* Solaris+SunATM */ - -/* - * Reserved as per request from Kent Dahlgren - * for private use. - */ -#define DLT_RIO 124 /* RapidIO */ -#define DLT_PCI_EXP 125 /* PCI Express */ -#define DLT_AURORA 126 /* Xilinx Aurora link layer */ - -/* - * Header for 802.11 plus a number of bits of link-layer information - * including radio information, used by some recent BSD drivers as - * well as the madwifi Atheros driver for Linux. - */ -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */ - -/* - * Reserved for the TZSP encapsulation, as per request from - * Chris Waters - * TZSP is a generic encapsulation for any other link type, - * which includes a means to include meta-information - * with the packet, e.g. signal strength and channel - * for 802.11 packets. - */ -#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */ - -/* - * BSD's ARCNET headers have the source host, destination host, - * and type at the beginning of the packet; that's what's handed - * up to userland via BPF. - * - * Linux's ARCNET headers, however, have a 2-byte offset field - * between the host IDs and the type; that's what's handed up - * to userland via PF_PACKET sockets. - * - * We therefore have to have separate DLT_ values for them. - */ -#define DLT_ARCNET_LINUX 129 /* ARCNET */ - -/* - * Juniper-private data link types, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MLPPP 130 -#define DLT_JUNIPER_MLFR 131 -#define DLT_JUNIPER_ES 132 -#define DLT_JUNIPER_GGSN 133 -#define DLT_JUNIPER_MFR 134 -#define DLT_JUNIPER_ATM2 135 -#define DLT_JUNIPER_SERVICES 136 -#define DLT_JUNIPER_ATM1 137 - -/* - * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund - * . The header that's presented is an Ethernet-like - * header: - * - * #define FIREWIRE_EUI64_LEN 8 - * struct firewire_header { - * u_char firewire_dhost[FIREWIRE_EUI64_LEN]; - * u_char firewire_shost[FIREWIRE_EUI64_LEN]; - * u_short firewire_type; - * }; - * - * with "firewire_type" being an Ethernet type value, rather than, - * for example, raw GASP frames being handed up. - */ -#define DLT_APPLE_IP_OVER_IEEE1394 138 - -/* - * Various SS7 encapsulations, as per a request from Jeff Morriss - * and subsequent discussions. - */ -#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */ -#define DLT_MTP2 140 /* MTP2, without pseudo-header */ -#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */ -#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */ - -/* - * DOCSIS MAC frames. - */ -#define DLT_DOCSIS 143 - -/* - * Linux-IrDA packets. Protocol defined at http://www.irda.org. - * Those packets include IrLAP headers and above (IrLMP...), but - * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy - * framing can be handled by the hardware and depend on the bitrate. - * This is exactly the format you would get capturing on a Linux-IrDA - * interface (irdaX), but not on a raw serial port. - * Note the capture is done in "Linux-cooked" mode, so each packet include - * a fake packet header (struct sll_header). This is because IrDA packet - * decoding is dependant on the direction of the packet (incomming or - * outgoing). - * When/if other platform implement IrDA capture, we may revisit the - * issue and define a real DLT_IRDA... - * Jean II - */ -#define DLT_LINUX_IRDA 144 - -/* - * Reserved for IBM SP switch and IBM Next Federation switch. - */ -#define DLT_IBM_SP 145 -#define DLT_IBM_SN 146 - -/* - * Reserved for private use. If you have some link-layer header type - * that you want to use within your organization, with the capture files - * using that link-layer header type not ever be sent outside your - * organization, you can use these values. - * - * No libpcap release will use these for any purpose, nor will any - * tcpdump release use them, either. - * - * Do *NOT* use these in capture files that you expect anybody not using - * your private versions of capture-file-reading tools to read; in - * particular, do *NOT* use them in products, otherwise you may find that - * people won't be able to use tcpdump, or snort, or Ethereal, or... to - * read capture files from your firewall/intrusion detection/traffic - * monitoring/etc. appliance, or whatever product uses that DLT_ value, - * and you may also find that the developers of those applications will - * not accept patches to let them read those files. - * - * Also, do not use them if somebody might send you a capture using them - * for *their* private type and tools using them for *your* private type - * would have to read them. - * - * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value, - * as per the comment above, and use the type you're given. - */ -#define DLT_USER0 147 -#define DLT_USER1 148 -#define DLT_USER2 149 -#define DLT_USER3 150 -#define DLT_USER4 151 -#define DLT_USER5 152 -#define DLT_USER6 153 -#define DLT_USER7 154 -#define DLT_USER8 155 -#define DLT_USER9 156 -#define DLT_USER10 157 -#define DLT_USER11 158 -#define DLT_USER12 159 -#define DLT_USER13 160 -#define DLT_USER14 161 -#define DLT_USER15 162 - -/* - * For future use with 802.11 captures - defined by AbsoluteValue - * Systems to store a number of bits of link-layer information - * including radio information: - * - * http://www.shaftnet.org/~pizza/software/capturefrm.txt - * - * but it might be used by some non-AVS drivers now or in the - * future. - */ -#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */ - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, etc.. - */ -#define DLT_JUNIPER_MONITOR 164 - -/* - * BACnet MS/TP frames. - */ -#define DLT_BACNET_MS_TP 165 - -/* - * Another PPP variant as per request from Karsten Keil . - * - * This is used in some OSes to allow a kernel socket filter to distinguish - * between incoming and outgoing packets, on a socket intended to - * supply pppd with outgoing packets so it can do dial-on-demand and - * hangup-on-lack-of-demand; incoming packets are filtered out so they - * don't cause pppd to hold the connection up (you don't want random - * input packets such as port scans, packets from old lost connections, - * etc. to force the connection to stay up). - * - * The first byte of the PPP header (0xff03) is modified to accomodate - * the direction - 0x00 = IN, 0x01 = OUT. - */ -#define DLT_PPP_PPPD 166 - -/* - * Names for backwards compatibility with older versions of some PPP - * software; new software should use DLT_PPP_PPPD. - */ -#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD -#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_s are used - * for passing on chassis-internal metainformation such as - * QOS profiles, cookies, etc.. - */ -#define DLT_JUNIPER_PPPOE 167 -#define DLT_JUNIPER_PPPOE_ATM 168 - -#define DLT_GPRS_LLC 169 /* GPRS LLC */ -#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */ -#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */ - -/* - * Requested by Oolan Zimmer for use in Gcom's T1/E1 line - * monitoring equipment. - */ -#define DLT_GCOM_T1E1 172 -#define DLT_GCOM_SERIAL 173 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . The DLT_ is used - * for internal communication to Physical Interface Cards (PIC) - */ -#define DLT_JUNIPER_PIC_PEER 174 - -/* - * Link types requested by Gregor Maier of Endace - * Measurement Systems. They add an ERF header (see - * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of - * the link-layer header. - */ -#define DLT_ERF_ETH 175 /* Ethernet */ -#define DLT_ERF_POS 176 /* Packet-over-SONET */ - -/* - * Requested by Daniele Orlandi for raw LAPD - * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header - * includes additional information before the LAPD header, so it's - * not necessarily a generic LAPD header. - */ -#define DLT_LINUX_LAPD 177 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ are used for prepending meta-information - * like interface index, interface name - * before standard Ethernet, PPP, Frelay & C-HDLC Frames - */ -#define DLT_JUNIPER_ETHER 178 -#define DLT_JUNIPER_PPP 179 -#define DLT_JUNIPER_FRELAY 180 -#define DLT_JUNIPER_CHDLC 181 - -/* - * Multi Link Frame Relay (FRF.16) - */ -#define DLT_MFR 182 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * voice Adapter Card (PIC) - */ -#define DLT_JUNIPER_VP 183 - -/* - * Arinc 429 frames. - * DLT_ requested by Gianluca Varenni . - * Every frame contains a 32bit A429 label. - * More documentation on Arinc 429 can be found at - * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf - */ -#define DLT_A429 184 - -/* - * Arinc 653 Interpartition Communication messages. - * DLT_ requested by Gianluca Varenni . - * Please refer to the A653-1 standard for more information. - */ -#define DLT_A653_ICM 185 - -/* - * This used to be "USB packets, beginning with a USB setup header; - * requested by Paolo Abeni ." - * - * However, that header didn't work all that well - it left out some - * useful information - and was abandoned in favor of the DLT_USB_LINUX - * header. - * - * This is now used by FreeBSD for its BPF taps for USB; that has its - * own headers. So it is written, so it is done. - * - * For source-code compatibility, we also define DLT_USB to have this - * value. We do it numerically so that, if code that includes this - * file (directly or indirectly) also includes an OS header that also - * defines DLT_USB as 186, we don't get a redefinition warning. - * (NetBSD 7 does that.) - */ -#define DLT_USB_FREEBSD 186 -#define DLT_USB 186 - -/* - * Bluetooth HCI UART transport layer (part H:4); requested by - * Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4 187 - -/* - * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz - * . - */ -#define DLT_IEEE802_16_MAC_CPS 188 - -/* - * USB packets, beginning with a Linux USB header; requested by - * Paolo Abeni . - */ -#define DLT_USB_LINUX 189 - -/* - * Controller Area Network (CAN) v. 2.0B packets. - * DLT_ requested by Gianluca Varenni . - * Used to dump CAN packets coming from a CAN Vector board. - * More documentation on the CAN v2.0B frames can be found at - * http://www.can-cia.org/downloads/?269 - */ -#define DLT_CAN20B 190 - -/* - * IEEE 802.15.4, with address fields padded, as is done by Linux - * drivers; requested by Juergen Schimmer. - */ -#define DLT_IEEE802_15_4_LINUX 191 - -/* - * Per Packet Information encapsulated packets. - * DLT_ requested by Gianluca Varenni . - */ -#define DLT_PPI 192 - -/* - * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header; - * requested by Charles Clancy. - */ -#define DLT_IEEE802_16_MAC_CPS_RADIO 193 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for internal communication with a - * integrated service module (ISM). - */ -#define DLT_JUNIPER_ISM 194 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing); requested by Mikko Saarnivala . - * For this one, we expect the FCS to be present at the end of the frame; - * if the frame has no FCS, DLT_IEEE802_15_4_NOFCS should be used. - */ -#define DLT_IEEE802_15_4 195 - -/* - * Various link-layer types, with a pseudo-header, for SITA - * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com). - */ -#define DLT_SITA 196 - -/* - * Various link-layer types, with a pseudo-header, for Endace DAG cards; - * encapsulates Endace ERF records. Requested by Stephen Donnelly - * . - */ -#define DLT_ERF 197 - -/* - * Special header prepended to Ethernet packets when capturing from a - * u10 Networks board. Requested by Phil Mulholland - * . - */ -#define DLT_RAIF1 198 - -/* - * IPMB packet for IPMI, beginning with the I2C slave address, followed - * by the netFn and LUN, etc.. Requested by Chanthy Toeung - * . - */ -#define DLT_IPMB 199 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - * The DLT_ is used for capturing data on a secure tunnel interface. - */ -#define DLT_JUNIPER_ST 200 - -/* - * Bluetooth HCI UART transport layer (part H:4), with pseudo-header - * that includes direction information; requested by Paolo Abeni. - */ -#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201 - -/* - * AX.25 packet with a 1-byte KISS header; see - * - * http://www.ax25.net/kiss.htm - * - * as per Richard Stearn . - */ -#define DLT_AX25_KISS 202 - -/* - * LAPD packets from an ISDN channel, starting with the address field, - * with no pseudo-header. - * Requested by Varuna De Silva . - */ -#define DLT_LAPD 203 - -/* - * Variants of various link-layer headers, with a one-byte direction - * pseudo-header prepended - zero means "received by this host", - * non-zero (any non-zero value) means "sent by this host" - as per - * Will Barker . - */ -#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */ -#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */ -#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */ -#define DLT_LAPB_WITH_DIR 207 /* LAPB */ - -/* - * 208 is reserved for an as-yet-unspecified proprietary link-layer - * type, as requested by Will Barker. - */ - -/* - * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman - * . - */ -#define DLT_IPMB_LINUX 209 - -/* - * FlexRay automotive bus - http://www.flexray.com/ - as requested - * by Hannes Kaelber . - */ -#define DLT_FLEXRAY 210 - -/* - * Media Oriented Systems Transport (MOST) bus for multimedia - * transport - http://www.mostcooperation.com/ - as requested - * by Hannes Kaelber . - */ -#define DLT_MOST 211 - -/* - * Local Interconnect Network (LIN) bus for vehicle networks - - * http://www.lin-subbus.org/ - as requested by Hannes Kaelber - * . - */ -#define DLT_LIN 212 - -/* - * X2E-private data link type used for serial line capture, - * as requested by Hannes Kaelber . - */ -#define DLT_X2E_SERIAL 213 - -/* - * X2E-private data link type used for the Xoraya data logger - * family, as requested by Hannes Kaelber . - */ -#define DLT_X2E_XORAYA 214 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), but with the PHY-level data for non-ASK PHYs (4 octets - * of 0 as preamble, one octet of SFD, one octet of frame length+ - * reserved bit, and then the MAC-layer data, starting with the - * frame control field). - * - * Requested by Max Filippov . - */ -#define DLT_IEEE802_15_4_NONASK_PHY 215 - -/* - * David Gibson requested this for - * captures from the Linux kernel /dev/input/eventN devices. This - * is used to communicate keystrokes and mouse movements from the - * Linux kernel to display systems, such as Xorg. - */ -#define DLT_LINUX_EVDEV 216 - -/* - * GSM Um and Abis interfaces, preceded by a "gsmtap" header. - * - * Requested by Harald Welte . - */ -#define DLT_GSMTAP_UM 217 -#define DLT_GSMTAP_ABIS 218 - -/* - * MPLS, with an MPLS label as the link-layer header. - * Requested by Michele Marchetto on behalf - * of OpenBSD. - */ -#define DLT_MPLS 219 - -/* - * USB packets, beginning with a Linux USB header, with the USB header - * padded to 64 bytes; required for memory-mapped access. - */ -#define DLT_USB_LINUX_MMAPPED 220 - -/* - * DECT packets, with a pseudo-header; requested by - * Matthias Wenzel . - */ -#define DLT_DECT 221 - -/* - * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" - * Date: Mon, 11 May 2009 11:18:30 -0500 - * - * DLT_AOS. We need it for AOS Space Data Link Protocol. - * I have already written dissectors for but need an OK from - * legal before I can submit a patch. - * - */ -#define DLT_AOS 222 - -/* - * Wireless HART (Highway Addressable Remote Transducer) - * From the HART Communication Foundation - * IES/PAS 62591 - * - * Requested by Sam Roberts . - */ -#define DLT_WIHART 223 - -/* - * Fibre Channel FC-2 frames, beginning with a Frame_Header. - * Requested by Kahou Lei . - */ -#define DLT_FC_2 224 - -/* - * Fibre Channel FC-2 frames, beginning with an encoding of the - * SOF, and ending with an encoding of the EOF. - * - * The encodings represent the frame delimiters as 4-byte sequences - * representing the corresponding ordered sets, with K28.5 - * represented as 0xBC, and the D symbols as the corresponding - * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2, - * is represented as 0xBC 0xB5 0x55 0x55. - * - * Requested by Kahou Lei . - */ -#define DLT_FC_2_WITH_FRAME_DELIMS 225 - -/* - * Solaris ipnet pseudo-header; requested by Darren Reed . - * - * The pseudo-header starts with a one-byte version number; for version 2, - * the pseudo-header is: - * - * struct dl_ipnetinfo { - * uint8_t dli_version; - * uint8_t dli_family; - * uint16_t dli_htype; - * uint32_t dli_pktlen; - * uint32_t dli_ifindex; - * uint32_t dli_grifindex; - * uint32_t dli_zsrc; - * uint32_t dli_zdst; - * }; - * - * dli_version is 2 for the current version of the pseudo-header. - * - * dli_family is a Solaris address family value, so it's 2 for IPv4 - * and 26 for IPv6. - * - * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing - * packets, and 2 for packets arriving from another zone on the same - * machine. - * - * dli_pktlen is the length of the packet data following the pseudo-header - * (so the captured length minus dli_pktlen is the length of the - * pseudo-header, assuming the entire pseudo-header was captured). - * - * dli_ifindex is the interface index of the interface on which the - * packet arrived. - * - * dli_grifindex is the group interface index number (for IPMP interfaces). - * - * dli_zsrc is the zone identifier for the source of the packet. - * - * dli_zdst is the zone identifier for the destination of the packet. - * - * A zone number of 0 is the global zone; a zone number of 0xffffffff - * means that the packet arrived from another host on the network, not - * from another zone on the same machine. - * - * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates - * which of those it is. - */ -#define DLT_IPNET 226 - -/* - * CAN (Controller Area Network) frames, with a pseudo-header as supplied - * by Linux SocketCAN, and with multi-byte numerical fields in that header - * in big-endian byte order. - * - * See Documentation/networking/can.txt in the Linux source. - * - * Requested by Felix Obenhuber . - */ -#define DLT_CAN_SOCKETCAN 227 - -/* - * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies - * whether it's v4 or v6. Requested by Darren Reed . - */ -#define DLT_IPV4 228 -#define DLT_IPV6 229 - -/* - * IEEE 802.15.4, exactly as it appears in the spec (no padding, no - * nothing), and with no FCS at the end of the frame; requested by - * Jon Smirl . - */ -#define DLT_IEEE802_15_4_NOFCS 230 - -/* - * Raw D-Bus: - * - * http://www.freedesktop.org/wiki/Software/dbus - * - * messages: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages - * - * starting with the endianness flag, followed by the message type, etc., - * but without the authentication handshake before the message sequence: - * - * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol - * - * Requested by Martin Vidner . - */ -#define DLT_DBUS 231 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - */ -#define DLT_JUNIPER_VS 232 -#define DLT_JUNIPER_SRX_E2E 233 -#define DLT_JUNIPER_FIBRECHANNEL 234 - -/* - * DVB-CI (DVB Common Interface for communication between a PC Card - * module and a DVB receiver). See - * - * http://www.kaiser.cx/pcap-dvbci.html - * - * for the specification. - * - * Requested by Martin Kaiser . - */ -#define DLT_DVB_CI 235 - -/* - * Variant of 3GPP TS 27.010 multiplexing protocol (similar to, but - * *not* the same as, 27.010). Requested by Hans-Christoph Schemmel - * . - */ -#define DLT_MUX27010 236 - -/* - * STANAG 5066 D_PDUs. Requested by M. Baris Demiray - * . - */ -#define DLT_STANAG_5066_D_PDU 237 - -/* - * Juniper-private data link type, as per request from - * Hannes Gredler . - */ -#define DLT_JUNIPER_ATM_CEMIC 238 - -/* - * NetFilter LOG messages - * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets) - * - * Requested by Jakub Zawadzki - */ -#define DLT_NFLOG 239 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and always - * with the payload including the FCS, as supplied by their - * netANALYZER hardware and software. - * - * Requested by Holger P. Frommer - */ -#define DLT_NETANALYZER 240 - -/* - * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type - * for Ethernet packets with a 4-byte pseudo-header and FCS and - * with the Ethernet header preceded by 7 bytes of preamble and - * 1 byte of SFD, as supplied by their netANALYZER hardware and - * software. - * - * Requested by Holger P. Frommer - */ -#define DLT_NETANALYZER_TRANSPARENT 241 - -/* - * IP-over-InfiniBand, as specified by RFC 4391. - * - * Requested by Petr Sumbera . - */ -#define DLT_IPOIB 242 - -/* - * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0). - * - * Requested by Guy Martin . - */ -#define DLT_MPEG_2_TS 243 - -/* - * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as - * used by their ng40 protocol tester. - * - * Requested by Jens Grimmer . - */ -#define DLT_NG40 244 - -/* - * Pseudo-header giving adapter number and flags, followed by an NFC - * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU, - * as specified by NFC Forum Logical Link Control Protocol Technical - * Specification LLCP 1.1. - * - * Requested by Mike Wakerly . - */ -#define DLT_NFC_LLCP 245 - -/* - * 246 is used as LINKTYPE_PFSYNC; do not use it for any other purpose. - * - * DLT_PFSYNC has different values on different platforms, and all of - * them collide with something used elsewhere. On platforms that - * don't already define it, define it as 246. - */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__) -#define DLT_PFSYNC 246 -#endif - -/* - * Raw InfiniBand packets, starting with the Local Routing Header. - * - * Requested by Oren Kladnitsky . - */ -#define DLT_INFINIBAND 247 - -/* - * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6). - * - * Requested by Michael Tuexen . - */ -#define DLT_SCTP 248 - -/* - * USB packets, beginning with a USBPcap header. - * - * Requested by Tomasz Mon - */ -#define DLT_USBPCAP 249 - -/* - * Schweitzer Engineering Laboratories "RTAC" product serial-line - * packets. - * - * Requested by Chris Bontje . - */ -#define DLT_RTAC_SERIAL 250 - -/* - * Bluetooth Low Energy air interface link-layer packets. - * - * Requested by Mike Kershaw . - */ -#define DLT_BLUETOOTH_LE_LL 251 - -/* - * DLT type for upper-protocol layer PDU saves from wireshark. - * - * the actual contents are determined by two TAGs stored with each - * packet: - * EXP_PDU_TAG_LINKTYPE the link type (LINKTYPE_ value) of the - * original packet. - * - * EXP_PDU_TAG_PROTO_NAME the name of the wireshark dissector - * that can make sense of the data stored. - */ -#define DLT_WIRESHARK_UPPER_PDU 252 - -/* - * DLT type for the netlink protocol (nlmon devices). - */ -#define DLT_NETLINK 253 - -/* - * Bluetooth Linux Monitor headers for the BlueZ stack. - */ -#define DLT_BLUETOOTH_LINUX_MONITOR 254 - -/* - * Bluetooth Basic Rate/Enhanced Data Rate baseband packets, as - * captured by Ubertooth. - */ -#define DLT_BLUETOOTH_BREDR_BB 255 - -/* - * Bluetooth Low Energy link layer packets, as captured by Ubertooth. - */ -#define DLT_BLUETOOTH_LE_LL_WITH_PHDR 256 - -/* - * PROFIBUS data link layer. - */ -#define DLT_PROFIBUS_DL 257 - -/* - * Apple's DLT_PKTAP headers. - * - * Sadly, the folks at Apple either had no clue that the DLT_USERn values - * are for internal use within an organization and partners only, and - * didn't know that the right way to get a link-layer header type is to - * ask tcpdump.org for one, or knew and didn't care, so they just - * used DLT_USER2, which causes problems for everything except for - * their version of tcpdump. - * - * So I'll just give them one; hopefully this will show up in a - * libpcap release in time for them to get this into 10.10 Big Sur - * or whatever Mavericks' successor is called. LINKTYPE_PKTAP - * will be 258 *even on OS X*; that is *intentional*, so that - * PKTAP files look the same on *all* OSes (different OSes can have - * different numerical values for a given DLT_, but *MUST NOT* have - * different values for what goes in a file, as files can be moved - * between OSes!). - * - * When capturing, on a system with a Darwin-based OS, on a device - * that returns 149 (DLT_USER2 and Apple's DLT_PKTAP) with this - * version of libpcap, the DLT_ value for the pcap_t will be DLT_PKTAP, - * and that will continue to be DLT_USER2 on Darwin-based OSes. That way, - * binary compatibility with Mavericks is preserved for programs using - * this version of libpcap. This does mean that if you were using - * DLT_USER2 for some capture device on OS X, you can't do so with - * this version of libpcap, just as you can't with Apple's libpcap - - * on OS X, they define DLT_PKTAP to be DLT_USER2, so programs won't - * be able to distinguish between PKTAP and whatever you were using - * DLT_USER2 for. - * - * If the program saves the capture to a file using this version of - * libpcap's pcap_dump code, the LINKTYPE_ value in the file will be - * LINKTYPE_PKTAP, which will be 258, even on Darwin-based OSes. - * That way, the file will *not* be a DLT_USER2 file. That means - * that the latest version of tcpdump, when built with this version - * of libpcap, and sufficiently recent versions of Wireshark will - * be able to read those files and interpret them correctly; however, - * Apple's version of tcpdump in OS X 10.9 won't be able to handle - * them. (Hopefully, Apple will pick up this version of libpcap, - * and the corresponding version of tcpdump, so that tcpdump will - * be able to handle the old LINKTYPE_USER2 captures *and* the new - * LINKTYPE_PKTAP captures.) - */ -#ifdef __APPLE__ -#define DLT_PKTAP DLT_USER2 -#else -#define DLT_PKTAP 258 -#endif - -/* - * Ethernet packets preceded by a header giving the last 6 octets - * of the preamble specified by 802.3-2012 Clause 65, section - * 65.1.3.2 "Transmit". - */ -#define DLT_EPON 259 - -/* - * IPMI trace packets, as specified by Table 3-20 "Trace Data Block Format" - * in the PICMG HPM.2 specification. - */ -#define DLT_IPMI_HPM_2 260 - -/* - * per Joshua Wright , formats for Zwave captures. - */ -#define DLT_ZWAVE_R1_R2 261 -#define DLT_ZWAVE_R3 262 - -/* - * per Steve Karg , formats for Wattstopper - * Digital Lighting Management room bus serial protocol captures. - */ -#define DLT_WATTSTOPPER_DLM 263 - -/* - * ISO 14443 contactless smart card messages. - */ -#define DLT_ISO_14443 264 - -/* - * Radio data system (RDS) groups. IEC 62106. - * Per Jonathan Brucker . - */ -#define DLT_RDS 265 - -/* - * USB packets, beginning with a Darwin (macOS, etc.) header. - */ -#define DLT_USB_DARWIN 266 - -/* - * OpenBSD DLT_OPENFLOW. - */ -#define DLT_OPENFLOW 267 - -/* - * SDLC frames containing SNA PDUs. - */ -#define DLT_SDLC 268 - -/* - * per "Selvig, Bjorn" used for - * TI protocol sniffer. - */ -#define DLT_TI_LLN_SNIFFER 269 - -/* - * per: Erik de Jong for - * https://github.com/eriknl/LoRaTap/releases/tag/v0.1 - */ -#define DLT_LORATAP 270 - -/* - * per: Stefanha at gmail.com for - * http://lists.sandelman.ca/pipermail/tcpdump-workers/2017-May/000772.html - * and: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/vsockmon.h - * for: http://qemu-project.org/Features/VirtioVsock - */ -#define DLT_VSOCK 271 - -/* - * Nordic Semiconductor Bluetooth LE sniffer. - */ -#define DLT_NORDIC_BLE 272 - -/* - * Excentis DOCSIS 3.1 RF sniffer (XRA-31) - * per: bruno.verstuyft at excentis.com - * http://www.xra31.com/xra-header - */ -#define DLT_DOCSIS31_XRA31 273 - -/* - * mPackets, as specified by IEEE 802.3br Figure 99-4, starting - * with the preamble and always ending with a CRC field. - */ -#define DLT_ETHERNET_MPACKET 274 - -/* - * In case the code that includes this file (directly or indirectly) - * has also included OS files that happen to define DLT_MATCHING_MAX, - * with a different value (perhaps because that OS hasn't picked up - * the latest version of our DLT definitions), we undefine the - * previous value of DLT_MATCHING_MAX. - */ -#ifdef DLT_MATCHING_MAX -#undef DLT_MATCHING_MAX -#endif -#define DLT_MATCHING_MAX 274 /* highest value in the "matching" range */ - -/* - * DLT and savefile link type values are split into a class and - * a member of that class. A class value of 0 indicates a regular - * DLT_/LINKTYPE_ value. - */ -#define DLT_CLASS(x) ((x) & 0x03ff0000) - -/* - * NetBSD-specific generic "raw" link type. The class value indicates - * that this is the generic raw type, and the lower 16 bits are the - * address family we're dealing with. Those values are NetBSD-specific; - * do not assume that they correspond to AF_ values for your operating - * system. - */ -#define DLT_CLASS_NETBSD_RAWAF 0x02240000 -#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af)) -#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff) -#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF) - -#endif /* !defined(lib_pcap_dlt_h) */ diff --git a/src/pcap/funcattrs.h b/src/pcap/funcattrs.h deleted file mode 100644 index d1cc2bf..0000000 --- a/src/pcap/funcattrs.h +++ /dev/null @@ -1,242 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lib_pcap_funcattrs_h -#define lib_pcap_funcattrs_h - -#include - -/* - * Attributes to apply to functions and their arguments, using various - * compiler-specific extensions. - */ - -/* - * PCAP_API_DEF must be used when defining *data* exported from - * libpcap. It can be used when defining *functions* exported - * from libpcap, but it doesn't have to be used there. It - * should not be used in declarations in headers. - * - * PCAP_API must be used when *declaring* data or functions - * exported from libpcap; PCAP_API_DEF won't work on all platforms. - */ - -#if defined(_WIN32) - /* - * For Windows: - * - * when building libpcap: - * - * if we're building it as a DLL, we have to declare API - * functions with __declspec(dllexport); - * - * if we're building it as a static library, we don't want - * to do so. - * - * when using libpcap: - * - * if we're using the DLL, calls to its functions are a - * little more efficient if they're declared with - * __declspec(dllimport); - * - * if we're not using the dll, we don't want to declare - * them that way. - * - * So: - * - * if pcap_EXPORTS is defined, we define PCAP_API_DEF as - * __declspec(dllexport); - * - * if PCAP_DLL is defined, we define PCAP_API_DEF as - * __declspec(dllimport); - * - * otherwise, we define PCAP_API_DEF as nothing. - */ - #if defined(pcap_EXPORTS) - /* - * We're compiling libpcap, so we should export functions in our - * API. - */ - #define PCAP_API_DEF __declspec(dllexport) - #elif defined(PCAP_DLL) - #define PCAP_API_DEF __declspec(dllimport) - #else - #define PCAP_API_DEF - #endif -#elif defined(MSDOS) - /* XXX - does this need special treatment? */ - #define PCAP_API_DEF -#else /* UN*X */ - #ifdef pcap_EXPORTS - /* - * We're compiling libpcap, so we should export functions in our API. - * The compiler might be configured not to export functions from a - * shared library by default, so we might have to explicitly mark - * functions as exported. - */ - #if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4) \ - || PCAP_IS_AT_LEAST_XL_C_VERSION(12,0) - /* - * GCC 3.4 or later, or some compiler asserting compatibility with - * GCC 3.4 or later, or XL C 13.0 or later, so we have - * __attribute__((visibility()). - */ - #define PCAP_API_DEF __attribute__((visibility("default"))) - #elif PCAP_IS_AT_LEAST_SUNC_VERSION(5,5) - /* - * Sun C 5.5 or later, so we have __global. - * (Sun C 5.9 and later also have __attribute__((visibility()), - * but there's no reason to prefer it with Sun C.) - */ - #define PCAP_API_DEF __global - #else - /* - * We don't have anything to say. - */ - #define PCAP_API_DEF - #endif - #else - /* - * We're not building libpcap. - */ - #define PCAP_API_DEF - #endif -#endif /* _WIN32/MSDOS/UN*X */ - -#define PCAP_API PCAP_API_DEF extern - -/* - * PCAP_NORETURN, before a function declaration, means "this function - * never returns". (It must go before the function declaration, e.g. - * "extern PCAP_NORETURN func(...)" rather than after the function - * declaration, as the MSVC version has to go before the declaration.) - */ -#if __has_attribute(noreturn) \ - || PCAP_IS_AT_LEAST_GNUC_VERSION(2,5) \ - || PCAP_IS_AT_LEAST_SUNC_VERSION(5,9) \ - || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ - || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) - /* - * Compiler with support for __attribute((noreturn)), or GCC 2.5 and - * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 - * and later (do any earlier versions of XL C support this?), or - * HP aCC A.06.10 and later. - */ - #define PCAP_NORETURN __attribute((noreturn)) -#elif defined(_MSC_VER) - /* - * MSVC. - */ - #define PCAP_NORETURN __declspec(noreturn) -#else - #define PCAP_NORETURN -#endif - -/* - * PCAP_PRINTFLIKE(x,y), after a function declaration, means "this function - * does printf-style formatting, with the xth argument being the format - * string and the yth argument being the first argument for the format - * string". - */ -#if __has_attribute(__format__) \ - || PCAP_IS_AT_LEAST_GNUC_VERSION(2,3) \ - || PCAP_IS_AT_LEAST_XL_C_VERSION(10,1) \ - || PCAP_IS_AT_LEAST_HP_C_VERSION(6,10) - /* - * Compiler with support for it, or GCC 2.3 and later, or IBM XL C 10.1 - * and later (do any earlier versions of XL C support this?), - * or HP aCC A.06.10 and later. - */ - #define PCAP_PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) -#else - #define PCAP_PRINTFLIKE(x,y) -#endif - -/* - * PCAP_DEPRECATED(func, msg), after a function declaration, marks the - * function as deprecated. - * - * The first argument is the name of the function; the second argument is - * a string giving the warning message to use if the compiler supports that. - * - * (Thank you, Microsoft, for requiring the function name.) - */ -#if __has_attribute(deprecated) \ - || PCAP_IS_AT_LEAST_GNUC_VERSION(4,5) \ - || PCAP_IS_AT_LEAST_SUNC_VERSION(5,13) - /* - * Compiler that supports __has_attribute and __attribute__((deprecated)), - * or GCC 4.5 and later, or Sun/Oracle C 12.4 (Sun C 5.13) or later. - * - * Those support __attribute__((deprecated(msg))) (we assume, perhaps - * incorrectly, that anything that supports __has_attribute() is - * recent enough to support __attribute__((deprecated(msg)))). - */ - #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated(msg))) -#elif PCAP_IS_AT_LEAST_GNUC_VERSION(3,1) - /* - * GCC 3.1 through 4.4. - * - * Those support __attribute__((deprecated)) but not - * __attribute__((deprecated(msg))). - */ - #define PCAP_DEPRECATED(func, msg) __attribute__((deprecated)) -#elif (defined(_MSC_VER) && (_MSC_VER >= 1500)) && !defined(pcap_EXPORTS) - /* - * MSVC from Visual Studio 2008 or later, and we're not building - * libpcap itself. - * - * If we *are* building libpcap, we don't want this, as it'll warn - * us even if we *define* the function. - */ - #define PCAP_DEPRECATED(func, msg) __pragma(deprecated(func)) -#else - #define PCAP_DEPRECATED(func, msg) -#endif - -/* - * For flagging arguments as format strings in MSVC. - */ -#ifdef _MSC_VER - #include - #if _MSC_VER > 1400 - #define PCAP_FORMAT_STRING(p) _Printf_format_string_ p - #else - #define PCAP_FORMAT_STRING(p) __format_string p - #endif -#else - #define PCAP_FORMAT_STRING(p) p -#endif - -#endif /* lib_pcap_funcattrs_h */ diff --git a/src/pcap/ipnet.h b/src/pcap/ipnet.h deleted file mode 100644 index 5330847..0000000 --- a/src/pcap/ipnet.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */ -#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */ - -#define IPNET_OUTBOUND 1 -#define IPNET_INBOUND 2 diff --git a/src/pcap/namedb.h b/src/pcap/namedb.h deleted file mode 100644 index 73fb40a..0000000 --- a/src/pcap/namedb.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 1994, 1996 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lib_pcap_namedb_h -#define lib_pcap_namedb_h - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * As returned by the pcap_next_etherent() - * XXX this stuff doesn't belong in this interface, but this - * library already must do name to address translation, so - * on systems that don't have support for /etc/ethers, we - * export these hooks since they're already being used by - * some applications (such as tcpdump) and already being - * marked as exported in some OSes offering libpcap (such - * as Debian). - */ -struct pcap_etherent { - u_char addr[6]; - char name[122]; -}; -#ifndef PCAP_ETHERS_FILE -#define PCAP_ETHERS_FILE "/etc/ethers" -#endif -PCAP_API struct pcap_etherent *pcap_next_etherent(FILE *); -PCAP_API u_char *pcap_ether_hostton(const char*); -PCAP_API u_char *pcap_ether_aton(const char *); - -PCAP_API bpf_u_int32 **pcap_nametoaddr(const char *); -#ifdef INET6 -PCAP_API struct addrinfo *pcap_nametoaddrinfo(const char *); -#endif -PCAP_API bpf_u_int32 pcap_nametonetaddr(const char *); - -PCAP_API int pcap_nametoport(const char *, int *, int *); -PCAP_API int pcap_nametoportrange(const char *, int *, int *, int *); -PCAP_API int pcap_nametoproto(const char *); -PCAP_API int pcap_nametoeproto(const char *); -PCAP_API int pcap_nametollc(const char *); -/* - * If a protocol is unknown, PROTO_UNDEF is returned. - * Also, pcap_nametoport() returns the protocol along with the port number. - * If there are ambiguous entried in /etc/services (i.e. domain - * can be either tcp or udp) PROTO_UNDEF is returned. - */ -#define PROTO_UNDEF -1 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/pcap/nflog.h b/src/pcap/nflog.h deleted file mode 100644 index 29a71d2..0000000 --- a/src/pcap/nflog.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2013, Petar Alilovic, - * Faculty of Electrical Engineering and Computing, University of Zagreb - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -#ifndef lib_pcap_nflog_h -#define lib_pcap_nflog_h - -#include - -/* - * Structure of an NFLOG header and TLV parts, as described at - * http://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html - * - * The NFLOG header is big-endian. - * - * The TLV length and type are in host byte order. The value is either - * big-endian or is an array of bytes in some externally-specified byte - * order (text string, link-layer address, link-layer header, packet - * data, etc.). - */ -typedef struct nflog_hdr { - uint8_t nflog_family; /* address family */ - uint8_t nflog_version; /* version */ - uint16_t nflog_rid; /* resource ID */ -} nflog_hdr_t; - -typedef struct nflog_tlv { - uint16_t tlv_length; /* tlv length */ - uint16_t tlv_type; /* tlv type */ - /* value follows this */ -} nflog_tlv_t; - -typedef struct nflog_packet_hdr { - uint16_t hw_protocol; /* hw protocol */ - uint8_t hook; /* netfilter hook */ - uint8_t pad; /* padding to 32 bits */ -} nflog_packet_hdr_t; - -typedef struct nflog_hwaddr { - uint16_t hw_addrlen; /* address length */ - uint16_t pad; /* padding to 32-bit boundary */ - uint8_t hw_addr[8]; /* address, up to 8 bytes */ -} nflog_hwaddr_t; - -typedef struct nflog_timestamp { - uint64_t sec; - uint64_t usec; -} nflog_timestamp_t; - -/* - * TLV types. - */ -#define NFULA_PACKET_HDR 1 /* nflog_packet_hdr_t */ -#define NFULA_MARK 2 /* packet mark from skbuff */ -#define NFULA_TIMESTAMP 3 /* nflog_timestamp_t for skbuff's time stamp */ -#define NFULA_IFINDEX_INDEV 4 /* ifindex of device on which packet received (possibly bridge group) */ -#define NFULA_IFINDEX_OUTDEV 5 /* ifindex of device on which packet transmitted (possibly bridge group) */ -#define NFULA_IFINDEX_PHYSINDEV 6 /* ifindex of physical device on which packet received (not bridge group) */ -#define NFULA_IFINDEX_PHYSOUTDEV 7 /* ifindex of physical device on which packet transmitted (not bridge group) */ -#define NFULA_HWADDR 8 /* nflog_hwaddr_t for hardware address */ -#define NFULA_PAYLOAD 9 /* packet payload */ -#define NFULA_PREFIX 10 /* text string - null-terminated, count includes NUL */ -#define NFULA_UID 11 /* UID owning socket on which packet was sent/received */ -#define NFULA_SEQ 12 /* sequence number of packets on this NFLOG socket */ -#define NFULA_SEQ_GLOBAL 13 /* sequence number of pakets on all NFLOG sockets */ -#define NFULA_GID 14 /* GID owning socket on which packet was sent/received */ -#define NFULA_HWTYPE 15 /* ARPHRD_ type of skbuff's device */ -#define NFULA_HWHEADER 16 /* skbuff's MAC-layer header */ -#define NFULA_HWLEN 17 /* length of skbuff's MAC-layer header */ - -#endif diff --git a/src/pcap/pcap-inttypes.h b/src/pcap/pcap-inttypes.h deleted file mode 100644 index af2c23c..0000000 --- a/src/pcap/pcap-inttypes.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) - * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef pcap_pcap_inttypes_h -#define pcap_pcap_inttypes_h - -/* - * Get the integer types and PRi[doux]64 values from C99 - * defined, by hook or by crook. - */ -#if defined(_MSC_VER) - /* - * Compiler is MSVC. - */ - #if _MSC_VER >= 1800 - /* - * VS 2013 or newer; we have . - */ - #include - #else - /* - * Earlier VS; we have to define this stuff ourselves. - */ - typedef unsigned char uint8_t; - typedef signed char int8_t; - typedef unsigned short uint16_t; - typedef signed short int16_t; - typedef unsigned int uint32_t; - typedef signed int int32_t; - #ifdef _MSC_EXTENSIONS - typedef unsigned _int64 uint64_t; - typedef _int64 int64_t; - #else /* _MSC_EXTENSIONS */ - typedef unsigned long long uint64_t; - typedef long long int64_t; - #endif - #endif - - /* - * These may be defined by . - * - * XXX - for MSVC, we always want the _MSC_EXTENSIONS versions. - * What about other compilers? If, as the MinGW Web site says MinGW - * does, the other compilers just use Microsoft's run-time library, - * then they should probably use the _MSC_EXTENSIONS even if the - * compiler doesn't define _MSC_EXTENSIONS. - * - * XXX - we currently aren't using any of these, but this allows - * their use in the future. - */ - #ifndef PRId64 - #ifdef _MSC_EXTENSIONS - #define PRId64 "I64d" - #else - #define PRId64 "lld" - #endif - #endif /* PRId64 */ - - #ifndef PRIo64 - #ifdef _MSC_EXTENSIONS - #define PRIo64 "I64o" - #else - #define PRIo64 "llo" - #endif - #endif /* PRIo64 */ - - #ifndef PRIx64 - #ifdef _MSC_EXTENSIONS - #define PRIx64 "I64x" - #else - #define PRIx64 "llx" - #endif - #endif - - #ifndef PRIu64 - #ifdef _MSC_EXTENSIONS - #define PRIu64 "I64u" - #else - #define PRIu64 "llu" - #endif - #endif -#elif defined(__MINGW32__) || !defined(_WIN32) - /* - * Compiler is MinGW or target is UN*X or MS-DOS. Just use - * . - */ - #include -#endif - -#endif /* pcap/pcap-inttypes.h */ diff --git a/src/pcap/pcap.h b/src/pcap/pcap.h deleted file mode 100644 index d32e2a9..0000000 --- a/src/pcap/pcap.h +++ /dev/null @@ -1,966 +0,0 @@ -/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ -/* - * Copyright (c) 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Computer Systems - * Engineering Group at Lawrence Berkeley Laboratory. - * 4. Neither the name of the University nor of the Laboratory may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Remote packet capture mechanisms and extensions from WinPcap: - * - * Copyright (c) 2002 - 2003 - * NetGroup, Politecnico di Torino (Italy) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef lib_pcap_pcap_h -#define lib_pcap_pcap_h - -#include - -#include - -#if defined(_WIN32) - #include /* u_int, u_char etc. */ - #include /* _get_osfhandle() */ -#elif defined(MSDOS) - #include /* u_int, u_char etc. */ - #include -#else /* UN*X */ - #include /* u_int, u_char etc. */ - #include -#endif /* _WIN32/MSDOS/UN*X */ - -#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H -#include -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Version number of the current version of the pcap file format. - * - * NOTE: this is *NOT* the version number of the libpcap library. - * To fetch the version information for the version of libpcap - * you're using, use pcap_lib_version(). - */ -#define PCAP_VERSION_MAJOR 2 -#define PCAP_VERSION_MINOR 4 - -#define PCAP_ERRBUF_SIZE 256 - -/* - * Compatibility for systems that have a bpf.h that - * predates the bpf typedefs for 64-bit support. - */ -#if BPF_RELEASE - 0 < 199406 -typedef int bpf_int32; -typedef u_int bpf_u_int32; -#endif - -typedef struct pcap pcap_t; -typedef struct pcap_dumper pcap_dumper_t; -typedef struct pcap_if pcap_if_t; -typedef struct pcap_addr pcap_addr_t; - -/* - * The first record in the file contains saved values for some - * of the flags used in the printout phases of tcpdump. - * Many fields here are 32 bit ints so compilers won't insert unwanted - * padding; these files need to be interchangeable across architectures. - * - * Do not change the layout of this structure, in any way (this includes - * changes that only affect the length of fields in this structure). - * - * Also, do not change the interpretation of any of the members of this - * structure, in any way (this includes using values other than - * LINKTYPE_ values, as defined in "savefile.c", in the "linktype" - * field). - * - * Instead: - * - * introduce a new structure for the new format, if the layout - * of the structure changed; - * - * send mail to "tcpdump-workers@lists.tcpdump.org", requesting - * a new magic number for your new capture file format, and, when - * you get the new magic number, put it in "savefile.c"; - * - * use that magic number for save files with the changed file - * header; - * - * make the code in "savefile.c" capable of reading files with - * the old file header as well as files with the new file header - * (using the magic number to determine the header format). - * - * Then supply the changes by forking the branch at - * - * https://github.com/the-tcpdump-group/libpcap/issues - * - * and issuing a pull request, so that future versions of libpcap and - * programs that use it (such as tcpdump) will be able to read your new - * capture file format. - */ -struct pcap_file_header { - bpf_u_int32 magic; - u_short version_major; - u_short version_minor; - bpf_int32 thiszone; /* gmt to local correction */ - bpf_u_int32 sigfigs; /* accuracy of timestamps */ - bpf_u_int32 snaplen; /* max length saved portion of each pkt */ - bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */ -}; - -/* - * Macros for the value returned by pcap_datalink_ext(). - * - * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro - * gives the FCS length of packets in the capture. - */ -#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000) -#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28) -#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000) - -typedef enum { - PCAP_D_INOUT = 0, - PCAP_D_IN, - PCAP_D_OUT -} pcap_direction_t; - -/* - * Generic per-packet information, as supplied by libpcap. - * - * The time stamp can and should be a "struct timeval", regardless of - * whether your system supports 32-bit tv_sec in "struct timeval", - * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit - * and 64-bit applications. The on-disk format of savefiles uses 32-bit - * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit - * and 64-bit versions of libpcap, even if they're on the same platform, - * should supply the appropriate version of "struct timeval", even if - * that's not what the underlying packet capture mechanism supplies. - */ -struct pcap_pkthdr { - struct timeval ts; /* time stamp */ - bpf_u_int32 caplen; /* length of portion present */ - bpf_u_int32 len; /* length this packet (off wire) */ -}; - -/* - * As returned by the pcap_stats() - */ -struct pcap_stat { - u_int ps_recv; /* number of packets received */ - u_int ps_drop; /* number of packets dropped */ - u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */ -#ifdef _WIN32 - u_int ps_capt; /* number of packets that reach the application */ - u_int ps_sent; /* number of packets sent by the server on the network */ - u_int ps_netdrop; /* number of packets lost on the network */ -#endif /* _WIN32 */ -}; - -#ifdef MSDOS -/* - * As returned by the pcap_stats_ex() - */ -struct pcap_stat_ex { - u_long rx_packets; /* total packets received */ - u_long tx_packets; /* total packets transmitted */ - u_long rx_bytes; /* total bytes received */ - u_long tx_bytes; /* total bytes transmitted */ - u_long rx_errors; /* bad packets received */ - u_long tx_errors; /* packet transmit problems */ - u_long rx_dropped; /* no space in Rx buffers */ - u_long tx_dropped; /* no space available for Tx */ - u_long multicast; /* multicast packets received */ - u_long collisions; - - /* detailed rx_errors: */ - u_long rx_length_errors; - u_long rx_over_errors; /* receiver ring buff overflow */ - u_long rx_crc_errors; /* recv'd pkt with crc error */ - u_long rx_frame_errors; /* recv'd frame alignment error */ - u_long rx_fifo_errors; /* recv'r fifo overrun */ - u_long rx_missed_errors; /* recv'r missed packet */ - - /* detailed tx_errors */ - u_long tx_aborted_errors; - u_long tx_carrier_errors; - u_long tx_fifo_errors; - u_long tx_heartbeat_errors; - u_long tx_window_errors; - }; -#endif - -/* - * Item in a list of interfaces. - */ -struct pcap_if { - struct pcap_if *next; - char *name; /* name to hand to "pcap_open_live()" */ - char *description; /* textual description of interface, or NULL */ - struct pcap_addr *addresses; - bpf_u_int32 flags; /* PCAP_IF_ interface flags */ -}; - -#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */ -#define PCAP_IF_UP 0x00000002 /* interface is up */ -#define PCAP_IF_RUNNING 0x00000004 /* interface is running */ - -/* - * Representation of an interface address. - */ -struct pcap_addr { - struct pcap_addr *next; - struct sockaddr *addr; /* address */ - struct sockaddr *netmask; /* netmask for that address */ - struct sockaddr *broadaddr; /* broadcast address for that address */ - struct sockaddr *dstaddr; /* P2P destination address for that address */ -}; - -typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, - const u_char *); - -/* - * Error codes for the pcap API. - * These will all be negative, so you can check for the success or - * failure of a call that returns these codes by checking for a - * negative value. - */ -#define PCAP_ERROR -1 /* generic error code */ -#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */ -#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */ -#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */ -#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */ -#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */ -#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ -#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ -#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ -#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */ -#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */ -#define PCAP_ERROR_TSTAMP_PRECISION_NOTSUP -12 /* the requested time stamp precision is not supported */ - -/* - * Warning codes for the pcap API. - * These will all be positive and non-zero, so they won't look like - * errors. - */ -#define PCAP_WARNING 1 /* generic warning code */ -#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */ -#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */ - -/* - * Value to pass to pcap_compile() as the netmask if you don't know what - * the netmask is. - */ -#define PCAP_NETMASK_UNKNOWN 0xffffffff - -/* - * We're deprecating pcap_lookupdev() for various reasons (not - * thread-safe, can behave weirdly with WinPcap). Callers - * should use pcap_findalldevs() and use the first device. - */ -PCAP_API char *pcap_lookupdev(char *) -PCAP_DEPRECATED(pcap_lookupdev, "use 'pcap_findalldevs' and use the first device"); - -PCAP_API int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *); - -PCAP_API pcap_t *pcap_create(const char *, char *); -PCAP_API int pcap_set_snaplen(pcap_t *, int); -PCAP_API int pcap_set_promisc(pcap_t *, int); -PCAP_API int pcap_can_set_rfmon(pcap_t *); -PCAP_API int pcap_set_rfmon(pcap_t *, int); -PCAP_API int pcap_set_timeout(pcap_t *, int); -PCAP_API int pcap_set_tstamp_type(pcap_t *, int); -PCAP_API int pcap_set_immediate_mode(pcap_t *, int); -PCAP_API int pcap_set_buffer_size(pcap_t *, int); -PCAP_API int pcap_set_tstamp_precision(pcap_t *, int); -PCAP_API int pcap_get_tstamp_precision(pcap_t *); -PCAP_API int pcap_activate(pcap_t *); - -PCAP_API int pcap_list_tstamp_types(pcap_t *, int **); -PCAP_API void pcap_free_tstamp_types(int *); -PCAP_API int pcap_tstamp_type_name_to_val(const char *); -PCAP_API const char *pcap_tstamp_type_val_to_name(int); -PCAP_API const char *pcap_tstamp_type_val_to_description(int); - -#ifdef __linux__ -PCAP_API int pcap_set_protocol(pcap_t *, int); -#endif - -/* - * Time stamp types. - * Not all systems and interfaces will necessarily support all of these. - * - * A system that supports PCAP_TSTAMP_HOST is offering time stamps - * provided by the host machine, rather than by the capture device, - * but not committing to any characteristics of the time stamp; - * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes. - * - * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine, - * that's low-precision but relatively cheap to fetch; it's normally done - * using the system clock, so it's normally synchronized with times you'd - * fetch from system calls. - * - * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine, - * that's high-precision; it might be more expensive to fetch. It might - * or might not be synchronized with the system clock, and might have - * problems with time stamps for packets received on different CPUs, - * depending on the platform. - * - * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the - * capture device; it's synchronized with the system clock. - * - * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by - * the capture device; it's not synchronized with the system clock. - * - * Note that time stamps synchronized with the system clock can go - * backwards, as the system clock can go backwards. If a clock is - * not in sync with the system clock, that could be because the - * system clock isn't keeping accurate time, because the other - * clock isn't keeping accurate time, or both. - * - * Note that host-provided time stamps generally correspond to the - * time when the time-stamping code sees the packet; this could - * be some unknown amount of time after the first or last bit of - * the packet is received by the network adapter, due to batching - * of interrupts for packet arrival, queueing delays, etc.. - */ -#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */ -#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */ -#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */ -#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */ -#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */ - -/* - * Time stamp resolution types. - * Not all systems and interfaces will necessarily support all of these - * resolutions when doing live captures; all of them can be requested - * when reading a savefile. - */ -#define PCAP_TSTAMP_PRECISION_MICRO 0 /* use timestamps with microsecond precision, default */ -#define PCAP_TSTAMP_PRECISION_NANO 1 /* use timestamps with nanosecond precision */ - -PCAP_API pcap_t *pcap_open_live(const char *, int, int, int, char *); -PCAP_API pcap_t *pcap_open_dead(int, int); -PCAP_API pcap_t *pcap_open_dead_with_tstamp_precision(int, int, u_int); -PCAP_API pcap_t *pcap_open_offline_with_tstamp_precision(const char *, u_int, char *); -PCAP_API pcap_t *pcap_open_offline(const char *, char *); -#ifdef _WIN32 - PCAP_API pcap_t *pcap_hopen_offline_with_tstamp_precision(intptr_t, u_int, char *); - PCAP_API pcap_t *pcap_hopen_offline(intptr_t, char *); - /* - * If we're building libpcap, these are internal routines in savefile.c, - * so we must not define them as macros. - * - * If we're not building libpcap, given that the version of the C runtime - * with which libpcap was built might be different from the version - * of the C runtime with which an application using libpcap was built, - * and that a FILE structure may differ between the two versions of the - * C runtime, calls to _fileno() must use the version of _fileno() in - * the C runtime used to open the FILE *, not the version in the C - * runtime with which libpcap was built. (Maybe once the Universal CRT - * rules the world, this will cease to be a problem.) - */ - #ifndef BUILDING_PCAP - #define pcap_fopen_offline_with_tstamp_precision(f,p,b) \ - pcap_hopen_offline_with_tstamp_precision(_get_osfhandle(_fileno(f)), p, b) - #define pcap_fopen_offline(f,b) \ - pcap_hopen_offline(_get_osfhandle(_fileno(f)), b) - #endif -#else /*_WIN32*/ - PCAP_API pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *); - PCAP_API pcap_t *pcap_fopen_offline(FILE *, char *); -#endif /*_WIN32*/ - -PCAP_API void pcap_close(pcap_t *); -PCAP_API int pcap_loop(pcap_t *, int, pcap_handler, u_char *); -PCAP_API int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); -PCAP_API const u_char *pcap_next(pcap_t *, struct pcap_pkthdr *); -PCAP_API int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **); -PCAP_API void pcap_breakloop(pcap_t *); -PCAP_API int pcap_stats(pcap_t *, struct pcap_stat *); -PCAP_API int pcap_setfilter(pcap_t *, struct bpf_program *); -PCAP_API int pcap_setdirection(pcap_t *, pcap_direction_t); -PCAP_API int pcap_getnonblock(pcap_t *, char *); -PCAP_API int pcap_setnonblock(pcap_t *, int, char *); -PCAP_API int pcap_inject(pcap_t *, const void *, size_t); -PCAP_API int pcap_sendpacket(pcap_t *, const u_char *, int); -PCAP_API const char *pcap_statustostr(int); -PCAP_API const char *pcap_strerror(int); -PCAP_API char *pcap_geterr(pcap_t *); -PCAP_API void pcap_perror(pcap_t *, const char *); -PCAP_API int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, - bpf_u_int32); -PCAP_API int pcap_compile_nopcap(int, int, struct bpf_program *, - const char *, int, bpf_u_int32); -PCAP_API void pcap_freecode(struct bpf_program *); -PCAP_API int pcap_offline_filter(const struct bpf_program *, - const struct pcap_pkthdr *, const u_char *); -PCAP_API int pcap_datalink(pcap_t *); -PCAP_API int pcap_datalink_ext(pcap_t *); -PCAP_API int pcap_list_datalinks(pcap_t *, int **); -PCAP_API int pcap_set_datalink(pcap_t *, int); -PCAP_API void pcap_free_datalinks(int *); -PCAP_API int pcap_datalink_name_to_val(const char *); -PCAP_API const char *pcap_datalink_val_to_name(int); -PCAP_API const char *pcap_datalink_val_to_description(int); -PCAP_API int pcap_snapshot(pcap_t *); -PCAP_API int pcap_is_swapped(pcap_t *); -PCAP_API int pcap_major_version(pcap_t *); -PCAP_API int pcap_minor_version(pcap_t *); -PCAP_API int pcap_bufsize(pcap_t *); - -/* XXX */ -PCAP_API FILE *pcap_file(pcap_t *); -PCAP_API int pcap_fileno(pcap_t *); - -#ifdef _WIN32 - PCAP_API int pcap_wsockinit(void); -#endif - -PCAP_API pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); -PCAP_API pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp); -PCAP_API pcap_dumper_t *pcap_dump_open_append(pcap_t *, const char *); -PCAP_API FILE *pcap_dump_file(pcap_dumper_t *); -PCAP_API long pcap_dump_ftell(pcap_dumper_t *); -PCAP_API int64_t pcap_dump_ftell64(pcap_dumper_t *); -PCAP_API int pcap_dump_flush(pcap_dumper_t *); -PCAP_API void pcap_dump_close(pcap_dumper_t *); -PCAP_API void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); - -PCAP_API int pcap_findalldevs(pcap_if_t **, char *); -PCAP_API void pcap_freealldevs(pcap_if_t *); - -/* - * We return a pointer to the version string, rather than exporting the - * version string directly. - * - * On at least some UNIXes, if you import data from a shared library into - * an program, the data is bound into the program binary, so if the string - * in the version of the library with which the program was linked isn't - * the same as the string in the version of the library with which the - * program is being run, various undesirable things may happen (warnings, - * the string being the one from the version of the library with which the - * program was linked, or even weirder things, such as the string being the - * one from the library but being truncated). - * - * On Windows, the string is constructed at run time. - */ -PCAP_API const char *pcap_lib_version(void); - -/* - * On at least some versions of NetBSD and QNX, we don't want to declare - * bpf_filter() here, as it's also be declared in , with a - * different signature, but, on other BSD-flavored UN*Xes, it's not - * declared in , so we *do* want to declare it here, so it's - * declared when we build pcap-bpf.c. - */ -#if !defined(__NetBSD__) && !defined(__QNX__) - PCAP_API u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int); -#endif -PCAP_API int bpf_validate(const struct bpf_insn *f, int len); -PCAP_API char *bpf_image(const struct bpf_insn *, int); -PCAP_API void bpf_dump(const struct bpf_program *, int); - -#if defined(_WIN32) - - /* - * Win32 definitions - */ - - /*! - \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit(). - */ - struct pcap_send_queue - { - u_int maxlen; /* Maximum size of the queue, in bytes. This - variable contains the size of the buffer field. */ - u_int len; /* Current size of the queue, in bytes. */ - char *buffer; /* Buffer containing the packets to be sent. */ - }; - - typedef struct pcap_send_queue pcap_send_queue; - - /*! - \brief This typedef is a support for the pcap_get_airpcap_handle() function - */ - #if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_) - #define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ - typedef struct _AirpcapHandle *PAirpcapHandle; - #endif - - PCAP_API int pcap_setbuff(pcap_t *p, int dim); - PCAP_API int pcap_setmode(pcap_t *p, int mode); - PCAP_API int pcap_setmintocopy(pcap_t *p, int size); - - PCAP_API HANDLE pcap_getevent(pcap_t *p); - - PCAP_API int pcap_oid_get_request(pcap_t *, bpf_u_int32, void *, size_t *); - PCAP_API int pcap_oid_set_request(pcap_t *, bpf_u_int32, const void *, size_t *); - - PCAP_API pcap_send_queue* pcap_sendqueue_alloc(u_int memsize); - - PCAP_API void pcap_sendqueue_destroy(pcap_send_queue* queue); - - PCAP_API int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data); - - PCAP_API u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync); - - PCAP_API struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size); - - PCAP_API int pcap_setuserbuffer(pcap_t *p, int size); - - PCAP_API int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks); - - PCAP_API int pcap_live_dump_ended(pcap_t *p, int sync); - - PCAP_API int pcap_start_oem(char* err_str, int flags); - - PCAP_API PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p); - - #define MODE_CAPT 0 - #define MODE_STAT 1 - #define MODE_MON 2 - -#elif defined(MSDOS) - - /* - * MS-DOS definitions - */ - - PCAP_API int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *); - PCAP_API void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait); - PCAP_API u_long pcap_mac_packets (void); - -#else /* UN*X */ - - /* - * UN*X definitions - */ - - PCAP_API int pcap_get_selectable_fd(pcap_t *); - -#endif /* _WIN32/MSDOS/UN*X */ - -/* - * Remote capture definitions. - * - * These routines are only present if libpcap has been configured to - * include remote capture support. - */ - -/* - * The maximum buffer size in which address, port, interface names are kept. - * - * In case the adapter name or such is larger than this value, it is truncated. - * This is not used by the user; however it must be aware that an hostname / interface - * name longer than this value will be truncated. - */ -#define PCAP_BUF_SIZE 1024 - -/* - * The type of input source, passed to pcap_open(). - */ -#define PCAP_SRC_FILE 2 /* local savefile */ -#define PCAP_SRC_IFLOCAL 3 /* local network interface */ -#define PCAP_SRC_IFREMOTE 4 /* interface on a remote host, using RPCAP */ - -/* - * The formats allowed by pcap_open() are the following: - * - file://path_and_filename [opens a local file] - * - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol] - * - rpcap://host/devicename [opens the selected device available on a remote host] - * - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP] - * - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged] - * - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged] - * - * The formats allowed by the pcap_findalldevs_ex() are the following: - * - file://folder/ [lists all the files in the given folder] - * - rpcap:// [lists all local adapters] - * - rpcap://host:port/ [lists the devices available on a remote host] - * - * Referring to the 'host' and 'port' parameters, they can be either numeric or literal. Since - * IPv6 is fully supported, these are the allowed formats: - * - * - host (literal): e.g. host.foo.bar - * - host (numeric IPv4): e.g. 10.11.12.13 - * - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13] - * - host (numeric IPv6): e.g. [1:2:3::4] - * - port: can be either numeric (e.g. '80') or literal (e.g. 'http') - * - * Here you find some allowed examples: - * - rpcap://host.foo.bar/devicename [everything literal, no port number] - * - rpcap://host.foo.bar:1234/devicename [everything literal, with port number] - * - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number] - * - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number] - * - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number] - * - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number] - * - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number] - * - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number] - */ - -/* - * URL schemes for capture source. - */ -/* - * This string indicates that the user wants to open a capture from a - * local file. - */ -#define PCAP_SRC_FILE_STRING "file://" -/* - * This string indicates that the user wants to open a capture from a - * network interface. This string does not necessarily involve the use - * of the RPCAP protocol. If the interface required resides on the local - * host, the RPCAP protocol is not involved and the local functions are used. - */ -#define PCAP_SRC_IF_STRING "rpcap://" - -/* - * Flags to pass to pcap_open(). - */ - -/* - * Specifies whether promiscuous mode is to be used. - */ -#define PCAP_OPENFLAG_PROMISCUOUS 0x00000001 - -/* - * Specifies, for an RPCAP capture, whether the data transfer (in - * case of a remote capture) has to be done with UDP protocol. - * - * If it is '1' if you want a UDP data connection, '0' if you want - * a TCP data connection; control connection is always TCP-based. - * A UDP connection is much lighter, but it does not guarantee that all - * the captured packets arrive to the client workstation. Moreover, - * it could be harmful in case of network congestion. - * This flag is meaningless if the source is not a remote interface. - * In that case, it is simply ignored. - */ -#define PCAP_OPENFLAG_DATATX_UDP 0x00000002 - -/* - * Specifies wheether the remote probe will capture its own generated - * traffic. - * - * In case the remote probe uses the same interface to capture traffic - * and to send data back to the caller, the captured traffic includes - * the RPCAP traffic as well. If this flag is turned on, the RPCAP - * traffic is excluded from the capture, so that the trace returned - * back to the collector is does not include this traffic. - * - * Has no effect on local interfaces or savefiles. - */ -#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 0x00000004 - -/* - * Specifies whether the local adapter will capture its own generated traffic. - * - * This flag tells the underlying capture driver to drop the packets - * that were sent by itself. This is useful when building applications - * such as bridges that should ignore the traffic they just sent. - * - * Supported only on Windows. - */ -#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 0x00000008 - -/* - * This flag configures the adapter for maximum responsiveness. - * - * In presence of a large value for nbytes, WinPcap waits for the arrival - * of several packets before copying the data to the user. This guarantees - * a low number of system calls, i.e. lower processor usage, i.e. better - * performance, which is good for applications like sniffers. If the user - * sets the PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will - * copy the packets as soon as the application is ready to receive them. - * This is suggested for real time applications (such as, for example, - * a bridge) that need the best responsiveness. - * - * The equivalent with pcap_create()/pcap_activate() is "immediate mode". - */ -#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 0x00000010 - -/* - * Remote authentication methods. - * These are used in the 'type' member of the pcap_rmtauth structure. - */ - -/* - * NULL authentication. - * - * The 'NULL' authentication has to be equal to 'zero', so that old - * applications can just put every field of struct pcap_rmtauth to zero, - * and it does work. - */ -#define RPCAP_RMTAUTH_NULL 0 -/* - * Username/password authentication. - * - * With this type of authentication, the RPCAP protocol will use the username/ - * password provided to authenticate the user on the remote machine. If the - * authentication is successful (and the user has the right to open network - * devices) the RPCAP connection will continue; otherwise it will be dropped. - * - * *******NOTE********: the username and password are sent over the network - * to the capture server *IN CLEAR TEXT*. Don't use this on a network - * that you don't completely control! (And be *really* careful in your - * definition of "completely"!) - */ -#define RPCAP_RMTAUTH_PWD 1 - -/* - * This structure keeps the information needed to autheticate the user - * on a remote machine. - * - * The remote machine can either grant or refuse the access according - * to the information provided. - * In case the NULL authentication is required, both 'username' and - * 'password' can be NULL pointers. - * - * This structure is meaningless if the source is not a remote interface; - * in that case, the functions which requires such a structure can accept - * a NULL pointer as well. - */ -struct pcap_rmtauth -{ - /* - * \brief Type of the authentication required. - * - * In order to provide maximum flexibility, we can support different types - * of authentication based on the value of this 'type' variable. The currently - * supported authentication methods are defined into the - * \link remote_auth_methods Remote Authentication Methods Section\endlink. - */ - int type; - /* - * \brief Zero-terminated string containing the username that has to be - * used on the remote machine for authentication. - * - * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - * and it can be NULL. - */ - char *username; - /* - * \brief Zero-terminated string containing the password that has to be - * used on the remote machine for authentication. - * - * This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication - * and it can be NULL. - */ - char *password; -}; - -/* - * This routine can open a savefile, a local device, or a device on - * a remote machine running an RPCAP server. - * - * For opening a savefile, the pcap_open_offline routines can be used, - * and will work just as well; code using them will work on more - * platforms than code using pcap_open() to open savefiles. - * - * For opening a local device, pcap_open_live() can be used; it supports - * most of the capabilities that pcap_open() supports, and code using it - * will work on more platforms than code using pcap_open(). pcap_create() - * and pcap_activate() can also be used; they support all capabilities - * that pcap_open() supports, except for the Windows-only - * PCAP_OPENFLAG_NOCAPTURE_LOCAL, and support additional capabilities. - * - * For opening a remote capture, pcap_open() is currently the only - * API available. - */ -PCAP_API pcap_t *pcap_open(const char *source, int snaplen, int flags, - int read_timeout, struct pcap_rmtauth *auth, char *errbuf); -PCAP_API int pcap_createsrcstr(char *source, int type, const char *host, - const char *port, const char *name, char *errbuf); -PCAP_API int pcap_parsesrcstr(const char *source, int *type, char *host, - char *port, char *name, char *errbuf); - -/* - * This routine can scan a directory for savefiles, list local capture - * devices, or list capture devices on a remote machine running an RPCAP - * server. - * - * For scanning for savefiles, it can be used on both UN*X systems and - * Windows systems; for each directory entry it sees, it tries to open - * the file as a savefile using pcap_open_offline(), and only includes - * it in the list of files if the open succeeds, so it filters out - * files for which the user doesn't have read permission, as well as - * files that aren't valid savefiles readable by libpcap. - * - * For listing local capture devices, it's just a wrapper around - * pcap_findalldevs(); code using pcap_findalldevs() will work on more - * platforms than code using pcap_findalldevs_ex(). - * - * For listing remote capture devices, pcap_findalldevs_ex() is currently - * the only API available. - */ -PCAP_API int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, - pcap_if_t **alldevs, char *errbuf); - -/* - * Sampling methods. - * - * These allow pcap_loop(), pcap_dispatch(), pcap_next(), and pcap_next_ex() - * to see only a sample of packets, rather than all packets. - * - * Currently, they work only on Windows local captures. - */ - -/* - * Specifies that no sampling is to be done on the current capture. - * - * In this case, no sampling algorithms are applied to the current capture. - */ -#define PCAP_SAMP_NOSAMP 0 - -/* - * Specifies that only 1 out of N packets must be returned to the user. - * - * In this case, the 'value' field of the 'pcap_samp' structure indicates the - * number of packets (minus 1) that must be discarded before one packet got - * accepted. - * In other words, if 'value = 10', the first packet is returned to the - * caller, while the following 9 are discarded. - */ -#define PCAP_SAMP_1_EVERY_N 1 - -/* - * Specifies that we have to return 1 packet every N milliseconds. - * - * In this case, the 'value' field of the 'pcap_samp' structure indicates - * the 'waiting time' in milliseconds before one packet got accepted. - * In other words, if 'value = 10', the first packet is returned to the - * caller; the next returned one will be the first packet that arrives - * when 10ms have elapsed. - */ -#define PCAP_SAMP_FIRST_AFTER_N_MS 2 - -/* - * This structure defines the information related to sampling. - * - * In case the sampling is requested, the capturing device should read - * only a subset of the packets coming from the source. The returned packets - * depend on the sampling parameters. - * - * WARNING: The sampling process is applied *after* the filtering process. - * In other words, packets are filtered first, then the sampling process - * selects a subset of the 'filtered' packets and it returns them to the - * caller. - */ -struct pcap_samp -{ - /* - * Method used for sampling; see above. - */ - int method; - - /* - * This value depends on the sampling method defined. - * For its meaning, see above. - */ - int value; -}; - -/* - * New functions. - */ -PCAP_API struct pcap_samp *pcap_setsampling(pcap_t *p); - -/* - * RPCAP active mode. - */ - -/* Maximum length of an host name (needed for the RPCAP active mode) */ -#define RPCAP_HOSTLIST_SIZE 1024 - -/* - * Some minor differences between UN*X sockets and and Winsock sockets. - */ -#ifndef _WIN32 - /*! - * \brief In Winsock, a socket handle is of type SOCKET; in UN*X, it's - * a file descriptor, and therefore a signed integer. - * We define SOCKET to be a signed integer on UN*X, so that it can - * be used on both platforms. - */ - #define SOCKET int - - /*! - * \brief In Winsock, the error return if socket() fails is INVALID_SOCKET; - * in UN*X, it's -1. - * We define INVALID_SOCKET to be -1 on UN*X, so that it can be used on - * both platforms. - */ - #define INVALID_SOCKET -1 -#endif - -PCAP_API SOCKET pcap_remoteact_accept(const char *address, const char *port, - const char *hostlist, char *connectinghost, - struct pcap_rmtauth *auth, char *errbuf); -PCAP_API int pcap_remoteact_list(char *hostlist, char sep, int size, - char *errbuf); -PCAP_API int pcap_remoteact_close(const char *host, char *errbuf); -PCAP_API void pcap_remoteact_cleanup(void); - -#ifdef __cplusplus -} -#endif - -#endif /* lib_pcap_pcap_h */ diff --git a/src/pcap/sll.h b/src/pcap/sll.h deleted file mode 100644 index c4d0886..0000000 --- a/src/pcap/sll.h +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * For captures on Linux cooked sockets, we construct a fake header - * that includes: - * - * a 2-byte "packet type" which is one of: - * - * LINUX_SLL_HOST packet was sent to us - * LINUX_SLL_BROADCAST packet was broadcast - * LINUX_SLL_MULTICAST packet was multicast - * LINUX_SLL_OTHERHOST packet was sent to somebody else - * LINUX_SLL_OUTGOING packet was sent *by* us; - * - * a 2-byte Ethernet protocol field; - * - * a 2-byte link-layer type; - * - * a 2-byte link-layer address length; - * - * an 8-byte source link-layer address, whose actual length is - * specified by the previous value. - * - * All fields except for the link-layer address are in network byte order. - * - * DO NOT change the layout of this structure, or change any of the - * LINUX_SLL_ values below. If you must change the link-layer header - * for a "cooked" Linux capture, introduce a new DLT_ type (ask - * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it - * a value that collides with a value already being used), and use the - * new header in captures of that type, so that programs that can - * handle DLT_LINUX_SLL captures will continue to handle them correctly - * without any change, and so that capture files with different headers - * can be told apart and programs that read them can dissect the - * packets in them. - */ - -#ifndef lib_pcap_sll_h -#define lib_pcap_sll_h - -/* - * A DLT_LINUX_SLL fake link-layer header. - */ -#define SLL_HDR_LEN 16 /* total header length */ -#define SLL_ADDRLEN 8 /* length of address field */ - -#include - -struct sll_header { - uint16_t sll_pkttype; /* packet type */ - uint16_t sll_hatype; /* link-layer address type */ - uint16_t sll_halen; /* link-layer address length */ - uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */ - uint16_t sll_protocol; /* protocol */ -}; - -/* - * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the - * PACKET_ values on Linux, but are defined here so that they're - * available even on systems other than Linux, and so that they - * don't change even if the PACKET_ values change. - */ -#define LINUX_SLL_HOST 0 -#define LINUX_SLL_BROADCAST 1 -#define LINUX_SLL_MULTICAST 2 -#define LINUX_SLL_OTHERHOST 3 -#define LINUX_SLL_OUTGOING 4 - -/* - * The LINUX_SLL_ values for "sll_protocol"; these correspond to the - * ETH_P_ values on Linux, but are defined here so that they're - * available even on systems other than Linux. We assume, for now, - * that the ETH_P_ values won't change in Linux; if they do, then: - * - * if we don't translate them in "pcap-linux.c", capture files - * won't necessarily be readable if captured on a system that - * defines ETH_P_ values that don't match these values; - * - * if we do translate them in "pcap-linux.c", that makes life - * unpleasant for the BPF code generator, as the values you test - * for in the kernel aren't the values that you test for when - * reading a capture file, so the fixup code run on BPF programs - * handed to the kernel ends up having to do more work. - * - * Add other values here as necessary, for handling packet types that - * might show up on non-Ethernet, non-802.x networks. (Not all the ones - * in the Linux "if_ether.h" will, I suspect, actually show up in - * captures.) - */ -#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */ -#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */ -#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */ -#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */ - -#endif diff --git a/src/pcap/usb.h b/src/pcap/usb.h deleted file mode 100644 index e485ec8..0000000 --- a/src/pcap/usb.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2006 Paolo Abeni (Italy) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Basic USB data struct - * By Paolo Abeni - */ - -#ifndef lib_pcap_usb_h -#define lib_pcap_usb_h - -#include - -/* - * possible transfer mode - */ -#define URB_TRANSFER_IN 0x80 -#define URB_ISOCHRONOUS 0x0 -#define URB_INTERRUPT 0x1 -#define URB_CONTROL 0x2 -#define URB_BULK 0x3 - -/* - * possible event type - */ -#define URB_SUBMIT 'S' -#define URB_COMPLETE 'C' -#define URB_ERROR 'E' - -/* - * USB setup header as defined in USB specification. - * Appears at the front of each Control S-type packet in DLT_USB captures. - */ -typedef struct _usb_setup { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; -} pcap_usb_setup; - -/* - * Information from the URB for Isochronous transfers. - */ -typedef struct _iso_rec { - int32_t error_count; - int32_t numdesc; -} iso_rec; - -/* - * Header prepended by linux kernel to each event. - * Appears at the front of each packet in DLT_USB_LINUX captures. - */ -typedef struct _usb_header { - uint64_t id; - uint8_t event_type; - uint8_t transfer_type; - uint8_t endpoint_number; - uint8_t device_address; - uint16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - uint32_t urb_len; - uint32_t data_len; /* amount of urb data really present in this event*/ - pcap_usb_setup setup; -} pcap_usb_header; - -/* - * Header prepended by linux kernel to each event for the 2.6.31 - * and later kernels; for the 2.6.21 through 2.6.30 kernels, the - * "iso_rec" information, and the fields starting with "interval" - * are zeroed-out padding fields. - * - * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures. - */ -typedef struct _usb_header_mmapped { - uint64_t id; - uint8_t event_type; - uint8_t transfer_type; - uint8_t endpoint_number; - uint8_t device_address; - uint16_t bus_id; - char setup_flag;/*if !=0 the urb setup header is not present*/ - char data_flag; /*if !=0 no urb data is present*/ - int64_t ts_sec; - int32_t ts_usec; - int32_t status; - uint32_t urb_len; - uint32_t data_len; /* amount of urb data really present in this event*/ - union { - pcap_usb_setup setup; - iso_rec iso; - } s; - int32_t interval; /* for Interrupt and Isochronous events */ - int32_t start_frame; /* for Isochronous events */ - uint32_t xfer_flags; /* copy of URB's transfer flags */ - uint32_t ndesc; /* number of isochronous descriptors */ -} pcap_usb_header_mmapped; - -/* - * Isochronous descriptors; for isochronous transfers there might be - * one or more of these at the beginning of the packet data. The - * number of descriptors is given by the "ndesc" field in the header; - * as indicated, in older kernels that don't put the descriptors at - * the beginning of the packet, that field is zeroed out, so that field - * can be trusted even in captures from older kernels. - */ -typedef struct _usb_isodesc { - int32_t status; - uint32_t offset; - uint32_t len; - uint8_t pad[4]; -} usb_isodesc; - -#endif diff --git a/src/pcap/vlan.h b/src/pcap/vlan.h deleted file mode 100644 index b29dd73..0000000 --- a/src/pcap/vlan.h +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lib_pcap_vlan_h -#define lib_pcap_vlan_h - -#include - -struct vlan_tag { - uint16_t vlan_tpid; /* ETH_P_8021Q */ - uint16_t vlan_tci; /* VLAN TCI */ -}; - -#define VLAN_TAG_LEN 4 - -#endif -- 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') 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') 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 935f121025d6736207adb7d17851fb54ea0f767d Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 29 May 2020 21:03:46 +0200 Subject: * add options for static linking * make the vsync checkbox and shit work to some extent (they don't actually function tho) --- CMakeLists.txt | 7 ++++++- src/frontend/qt_sdl/CMakeLists.txt | 28 +++++++++++++++++++++++----- src/frontend/qt_sdl/VideoSettingsDialog.cpp | 15 +++++++++++++++ src/frontend/qt_sdl/VideoSettingsDialog.h | 3 +++ 4 files changed, 47 insertions(+), 6 deletions(-) (limited to 'src/frontend') diff --git a/CMakeLists.txt b/CMakeLists.txt index e640a48..0309725 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) project(melonDS) -if(NOT CMAKE_BUILD_TYPE) +if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() @@ -20,6 +20,7 @@ endif() if (CMAKE_BUILD_TYPE STREQUAL Release) add_compile_options(-O3) + add_link_options(-s) endif() add_compile_options(-fno-pic) @@ -27,6 +28,10 @@ add_link_options(-no-pie) option(BUILD_QT_SDL "Build Qt/SDL frontend" ON) +if (WIN32) + option(BUILD_STATIC "Statically link dependencies" OFF) +endif() + add_subdirectory(src) if (BUILD_QT_SDL) diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index dbc1e3a..8992b50 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -30,9 +30,15 @@ if (WIN32) set(CMAKE_RC_COMPILE_OBJECT " -i -o ") endif() -find_package(Qt5 COMPONENTS Core REQUIRED) -find_package(Qt5 COMPONENTS Gui REQUIRED) -find_package(Qt5 COMPONENTS Widgets REQUIRED) +if (BUILD_STATIC AND QT5_STATIC_DIR) + set(QT5_STATIC_BASE ${QT5_STATIC_DIR}/lib/cmake/Qt5) + set(Qt5_DIR ${QT5_STATIC_BASE}) + set(Qt5Core_DIR ${QT5_STATIC_BASE}Core) + set(Qt5Gui_DIR ${QT5_STATIC_BASE}Gui) + set(Qt5Widgets_DIR ${QT5_STATIC_BASE}Widgets) +endif() + +find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) @@ -46,7 +52,13 @@ 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}) +target_link_libraries(melonDS core) + +if (BUILD_STATIC) + target_link_libraries(melonDS -static ${SDL2_LIBRARIES}) +else() + target_link_libraries(melonDS ${SDL2_LIBRARIES}) +endif() if (UNIX) option(UNIX_PORTABLE "Make a portable build that looks for its configuration in the current directory" OFF) @@ -77,7 +89,13 @@ if (UNIX) target_sources(melonDS PUBLIC melon_grc.c) elseif (WIN32) target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc") - target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 Qt5::Core Qt5::Gui Qt5::Widgets) + + target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32) + if (BUILD_STATIC) + target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets z zstd) + else() + target_link_libraries(melonDS Qt5::Core Qt5::Gui Qt5::Widgets) + endif() endif () install(FILES ../../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.cpp b/src/frontend/qt_sdl/VideoSettingsDialog.cpp index efb5051..ba433c3 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.cpp +++ b/src/frontend/qt_sdl/VideoSettingsDialog.cpp @@ -60,6 +60,9 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui( 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::ScreenVSync) + ui->sbVSyncInterval->setEnabled(false); + if (Config::_3DRenderer == 0) { ui->cbGLDisplay->setEnabled(true); @@ -136,6 +139,18 @@ void VideoSettingsDialog::on_cbGLDisplay_stateChanged(int state) emit updateVideoSettings(old_gl != new_gl); } +void VideoSettingsDialog::on_cbVSync_stateChanged(int state) +{ + bool vsync = (state != 0); + ui->sbVSyncInterval->setEnabled(vsync); + Config::ScreenVSync = vsync; +} + +void VideoSettingsDialog::on_sbVSyncInterval_valueChanged(int val) +{ + Config::ScreenVSyncInterval = val; +} + void VideoSettingsDialog::on_cbSoftwareThreaded_stateChanged(int state) { Config::Threaded3D = (state != 0); diff --git a/src/frontend/qt_sdl/VideoSettingsDialog.h b/src/frontend/qt_sdl/VideoSettingsDialog.h index 2f6d17c..2311d4d 100644 --- a/src/frontend/qt_sdl/VideoSettingsDialog.h +++ b/src/frontend/qt_sdl/VideoSettingsDialog.h @@ -60,6 +60,9 @@ private slots: void onChange3DRenderer(int renderer); void on_cbGLDisplay_stateChanged(int state); + void on_cbVSync_stateChanged(int state); + void on_sbVSyncInterval_valueChanged(int val); + void on_cbxGLResolution_currentIndexChanged(int idx); void on_cbSoftwareThreaded_stateChanged(int state); -- cgit v1.2.3 From d3dd7bd9880bfd6a5b65f263272742105620ccb3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 29 May 2020 21:19:18 +0200 Subject: get rid of console in release builds --- src/frontend/qt_sdl/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/frontend') diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 8992b50..37a8ff1 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -47,7 +47,12 @@ set(CMAKE_AUTORCC ON) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2) -add_executable(melonDS ${SOURCES_QT_SDL}) +if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release)) + add_executable(melonDS WIN32 ${SOURCES_QT_SDL}) +else() + add_executable(melonDS ${SOURCES_QT_SDL}) +endif() + 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}/..") -- 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') 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') 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