diff --git a/AsyncManager.cpp b/AsyncManager.cpp index d3433e8..cb82ae5 100644 --- a/AsyncManager.cpp +++ b/AsyncManager.cpp @@ -24,91 +24,89 @@ void AsyncManager::cleanFutureMap(SockFutureMap& map) { } void AsyncManager::run() { - while (!stopping && runtime.cooperate()) { - // We should stop once there is nothing left to do - if (sockReads.empty() && sockWrites.empty()) [[unlikely]] { - break; - } - - // We need to keep track of the highest fd for socket() - int maxFd = 0; - - // Create except FD set - fd_set exceptFds; - FD_ZERO(&exceptFds); - - // Create write FD set - fd_set writeFds; - FD_ZERO(&writeFds); - for (const auto& [fd, cb] : sockWrites) { - FD_SET(fd, &writeFds); - FD_SET(fd, &exceptFds); - if (fd > maxFd) { - maxFd = fd; - } - } - - // Create read FD set - fd_set readFds; - FD_ZERO(&readFds); - for (const auto& [fd, cb] : sockReads) { - FD_SET(fd, &readFds); - FD_SET(fd, &exceptFds); - if (fd > maxFd) { - maxFd = fd; - } - } - - // Specify timeout - timeval tv{ - .tv_sec = 0, - .tv_usec = 250000 - }; - - // select() until there is data - bool error = false; - if (select(maxFd+1, &readFds, &writeFds, &exceptFds, &tv) < 0) { - FD_ZERO(&readFds); - FD_ZERO(&writeFds); - error = true; - } - - // Execution queue - std::vector> execQueue; - - // Collect all write futures - for (auto& [fd, future] : sockWrites) { - if (FD_ISSET(fd, &writeFds)) { - // Socket is ready for writing - execQueue.push_back({future, false}); - } - if (FD_ISSET(fd, &exceptFds) || error) [[unlikely]] { - // An exception happened in the socket - execQueue.push_back({future, true}); - } - } - - // Collect all read futures - for (auto& [fd, future] : sockReads) { - if (FD_ISSET(fd, &readFds)) { - // Socket is ready for reading - execQueue.push_back({future, false}); - } - if (FD_ISSET(fd, &exceptFds) || error) [[unlikely]] { - // An exception happened in the socket - execQueue.push_back({future, true}); - } - } - - // Set futures - for (auto& [future, value] : execQueue) { - future->set(value?AsyncResult::Error:AsyncResult::Success); - future = nullptr; - } - - // Clean future maps - cleanFutureMap(sockWrites); - cleanFutureMap(sockReads); + // We should stop once there is nothing left to do + if (sockReads.empty() && sockWrites.empty()) [[unlikely]] { + stopping = true; + return; } - stopping = false; + + // We need to keep track of the highest fd for socket() + int maxFd = 0; + + // Create except FD set + fd_set exceptFds; + FD_ZERO(&exceptFds); + + // Create write FD set + fd_set writeFds; + FD_ZERO(&writeFds); + for (const auto& [fd, cb] : sockWrites) { + FD_SET(fd, &writeFds); + FD_SET(fd, &exceptFds); + if (fd > maxFd) { + maxFd = fd; + } + } + + // Create read FD set + fd_set readFds; + FD_ZERO(&readFds); + for (const auto& [fd, cb] : sockReads) { + FD_SET(fd, &readFds); + FD_SET(fd, &exceptFds); + if (fd > maxFd) { + maxFd = fd; + } + } + + // Specify timeout + timeval tv{ + .tv_sec = 0, + .tv_usec = 250000 + }; + + // select() until there is data + bool error = false; + if (select(maxFd+1, &readFds, &writeFds, &exceptFds, &tv) < 0) { + FD_ZERO(&readFds); + FD_ZERO(&writeFds); + error = true; + } + + // Execution queue + std::vector> execQueue; + + // Collect all write futures + for (auto& [fd, future] : sockWrites) { + if (FD_ISSET(fd, &writeFds)) { + // Socket is ready for writing + execQueue.push_back({future, false}); + } + if (FD_ISSET(fd, &exceptFds) || error) [[unlikely]] { + // An exception happened in the socket + execQueue.push_back({future, true}); + } + } + + // Collect all read futures + for (auto& [fd, future] : sockReads) { + if (FD_ISSET(fd, &readFds)) { + // Socket is ready for reading + execQueue.push_back({future, false}); + } + if (FD_ISSET(fd, &exceptFds) || error) [[unlikely]] { + // An exception happened in the socket + execQueue.push_back({future, true}); + } + } + + // Set futures + for (auto& [future, value] : execQueue) { + future->set(value?AsyncResult::Error:AsyncResult::Success); + future = nullptr; + } + + // Clean future maps + cleanFutureMap(sockWrites); + cleanFutureMap(sockReads); } diff --git a/AsyncManager.hpp b/AsyncManager.hpp index 3b5b240..44a9fd6 100644 --- a/AsyncManager.hpp +++ b/AsyncManager.hpp @@ -38,6 +38,9 @@ public: AsyncManager(const AsyncManager&) = delete; AsyncManager(AsyncManager&&) = delete; + bool shouldRun() const { + return !stopping && runtime.cooperate(); + } void run(); void stop() { stopping = true; diff --git a/CMakeLists.txt b/CMakeLists.txt index ff24ae8..f6f6660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -project(llama.any LANGUAGES CXX) +project(llama.nds LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -12,21 +12,16 @@ add_executable(llama Receiver.hpp Receiver.cpp Sender.hpp Sender.cpp AsyncManager.hpp AsyncManager.cpp + font.h font.c + NDSUI.hpp NDSUI.cpp Runtime.cpp Runtime.hpp basic-coro/AwaitableTask.hpp basic-coro/SingleEvent.hpp basic-coro/SingleEvent.cpp ) target_compile_definitions(llama PUBLIC PLATFORM="${CMAKE_SYSTEM_NAME}") -if (CMAKE_SYSTEM_NAME STREQUAL Nintendo3DS) - target_compile_definitions(llama PUBLIC PLATFORM_3DS) -elseif (CMAKE_SYSTEM_NAME STREQUAL NintendoDS) +if (CMAKE_SYSTEM_NAME STREQUAL NintendoDS) target_compile_definitions(llama PUBLIC PLATFORM_DS) target_link_libraries(llama PUBLIC dswifi9 nds9) -elseif (CMAKE_SYSTEM_NAME STREQUAL Linux) - target_compile_definitions(llama PUBLIC PLATFORM_LINUX) -elseif (CMAKE_SYSTEM_NAME STREQUAL Windows) - target_compile_definitions(llama PUBLIC PLATFORM_WINDOWS) - target_link_libraries(llama PUBLIC Ws2_32) else() message(SEND_ERROR "${CMAKE_SYSTEM_NAME} is not a supported platform!") endif() diff --git a/Client.cpp b/Client.cpp index 5060a60..b7eb3dc 100644 --- a/Client.cpp +++ b/Client.cpp @@ -17,27 +17,9 @@ void Client::fetchAddr(const std::string& addr, unsigned port) { -# ifdef HAS_ADDRINFO - // Set up hints - addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; //TODO: Care about IPv6 - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_CANONNAME; - - // Get port as C string - char portStr[7]; - sprintf(portStr, "%u", port); - - // Get addrinfo - auto error = getaddrinfo(addr.c_str(), portStr, &hints, &addrInfo); - auto bad = addrInfo == nullptr; -# else addrInfo = gethostbyname(addr.c_str()); auto error = errno; auto bad = addrInfo == nullptr || addrInfo->h_addr_list[0] == nullptr; -# endif // Check for error if (bad) { @@ -55,12 +37,6 @@ Client::Client(const std::string& addr, unsigned port, AsyncManager& asyncManage // Fetch address fetchAddr(addr, port); -# ifdef HAS_ADDRINFO - // Connect to server - if (connect(*connection, addrInfo->ai_addr, addrInfo->ai_addrlen) != 0) [[unlikely]] { - throw Exception("Connection has been refused"); - } -# else // Connect to server struct sockaddr_in sain; sain.sin_family = AF_INET; @@ -69,7 +45,6 @@ Client::Client(const std::string& addr, unsigned port, AsyncManager& asyncManage if (connect(*connection, reinterpret_cast(&sain), sizeof(sain)) != 0) [[unlikely]] { throw Exception("Connection has been declined"); } -# endif } basiccoro::AwaitableTask Client::ask(std::string_view prompt, const std::function (unsigned progress)>& on_progress, const std::function (std::string_view token)>& on_token) { diff --git a/Client.hpp b/Client.hpp index 2311f53..e8d7efe 100644 --- a/Client.hpp +++ b/Client.hpp @@ -28,13 +28,8 @@ class Client AsyncManager& aMan; int fd = -1; -# ifdef HAS_ADDRINFO - addrinfo -# else bool sent = false; - hostent -# endif - *addrInfo; // Can't be null unless request has already been sent + hostent *addrInfo; // Can't be null unless request has already been sent std::unique_ptr> connection; diff --git a/NDSUI.cpp b/NDSUI.cpp new file mode 100644 index 0000000..1b6710d --- /dev/null +++ b/NDSUI.cpp @@ -0,0 +1,215 @@ +#include "NDSUI.hpp" +#include "font.h" + +#include +#include +#include +#include +#include + +#define SCREEN_BORDER_PADDING 4 +#define FONT_PADDING 1 +#define INPUT_LINE_HEIGHT (FONT_HEIGHT+FONT_PADDING) + + +NDSUI *NDSUI::currentInstance; + + + +consteval +unsigned NDSUI::calcMaxCharsInLine(unsigned int width) { + return width / (FONT_WIDTH + FONT_PADDING); +} +consteval +unsigned NDSUI::calcMaxLinesInRow(unsigned height) { + return height / (FONT_HEIGHT + FONT_PADDING); +} + +void NDSUI::kbCallback(int key) { + if (key > 0) currentInstance->handleInput(static_cast(key)); +} + +consteval +Box2D NDSUI::calcMessageLogDimensions() { + return { + {SCREEN_BORDER_PADDING, 0}, + {SCREEN_WIDTH-SCREEN_BORDER_PADDING, SCREEN_HEIGHT-(SCREEN_BORDER_PADDING*2)-INPUT_LINE_HEIGHT} + }; +} +void NDSUI::renderMessageLog() { + constexpr Box2D boxDims = calcMessageLogDimensions(); + + // Draw box + glBoxFilled(boxDims.topLeft.x, boxDims.topLeft.y, boxDims.bottomRight.x, boxDims.bottomRight.y, RGB15(6, 2, 14)); + + // Log messages renderer + auto renderLine = [this, y = int(boxDims.bottomRight.y - FONT_PADDING - FONT_HEIGHT), boxDims] (std::string_view line) mutable { + print(line, {boxDims.topLeft.x + FONT_PADDING, unsigned(y)}, RGB15(28, 28, 28)); + y -= FONT_PADDING + FONT_HEIGHT; + if (y < 0) { + throw std::exception(); // Stop rendering any more lines + } + }; + + // Display line by line + try { + for (auto message = messages.rbegin(); message != messages.rend(); message++) { + const auto& lines = message->getLines(); + for (auto line = lines.rbegin(); line != lines.rend(); line++) { + renderLine(*line); + } + } + } catch (...) {} +} + +consteval +Box2D NDSUI::calcInputLineDimensions() { + return { + {SCREEN_BORDER_PADDING, SCREEN_HEIGHT-SCREEN_BORDER_PADDING-INPUT_LINE_HEIGHT}, + {SCREEN_WIDTH-SCREEN_BORDER_PADDING, SCREEN_HEIGHT-SCREEN_BORDER_PADDING} + }; +} +void NDSUI::renderInputLine() { + constexpr Box2D boxDims = calcInputLineDimensions(); + constexpr Position2D textTopLeft{boxDims.topLeft.x+FONT_PADDING, boxDims.topLeft.y+FONT_PADDING}; + + // Draw box + glBoxFilled(boxDims.topLeft.x, boxDims.topLeft.y, boxDims.bottomRight.x, boxDims.bottomRight.y, RGB15(13, 8, 3)); + + // Measure amount of character that fit in + constexpr auto maxChars = calcMaxCharsInLine(boxDims.bottomRight.x - boxDims.topLeft.x); + + // Mease amount of characters that don't fit in + unsigned startIdx = 0; + if (inputLineBufHead > maxChars) { + startIdx = inputLineBufHead - maxChars; + } + + // Get that amount of characters + print(&inputLineBuf[startIdx], textTopLeft, RGB15(28, 28, 28)); +} + +bool NDSUI::printChar(const char character, Position2D *topleftpos, const int color) { + const bool *fontChar = font_get_character(character); + int x = 0; + int y = 0; + unsigned no = 0; + for (const bool *thispixel = fontChar; ; thispixel++) { + if (x == FONT_WIDTH) { + x = 0; + y++; + } if (y == FONT_HEIGHT) { + break; + } if (*thispixel) { + // Calculate spareout + unsigned spareout = font_pixels / 500; + // Skip pixel for spareout + if (!(no++ % spareout)) { + // Draw pixel with melonDS fallback for debug builds + # ifdef NDEBUG + glPutPixel(topleftpos->x + x, topleftpos->y + y, color); + # else + glBoxFilled(topleftpos->x + x, topleftpos->y + y, topleftpos->x + x, topleftpos->y + y, color); + # endif + font_pixels++; + } + } + x++; + } + return fontChar != fontBitmapUnk; +} + +void NDSUI::print(std::string_view str, Position2D topleftpos, const int color) { + for (const char c : str) { + printChar(c, &topleftpos, color); + topleftpos.x += FONT_WIDTH + FONT_PADDING; + } +} + +void NDSUI::handleInput(char c) { + //TODO: Check length + switch (c) { + case '\b': { + // Remove character if not at start + if (inputLineBufHead != 0) { + inputLineBuf[--inputLineBufHead] = '\0'; + } + } break; + case '\n': { + if (userInputHandler && inputLineBuf[0]) { + auto msg = createLogMessage("User", inputLineBuf.data()); + addLogMessage(std::move(msg)); + userInputHandler->set(inputLineBuf.data()); + resetInputLine(); + //userInputHandler = nullptr; + } + } break; + default: { + // Add character if not at end + if (inputLineBufHead != inputLineBuf.size() - 1) { + inputLineBuf[inputLineBufHead] = c; + inputLineBuf[++inputLineBufHead] = '\0'; + } + } + } +} + +NDSUI::NDSUI() { + resetInputLine(); + glScreen2D(); + auto swkbd = keyboardDemoInit(); + swkbd->OnKeyReleased = kbCallback; + keyboardShow(); +} + +void NDSUI::run() { + currentInstance = this; + font_pixels = 0; + // Update keyboard + keyboardUpdate(); + // Draw + glBegin2D(); { + renderInputLine(); + renderMessageLog(); + } glEnd2D(); + // Apply changes + glFlush(0); + swiWaitForVBlank(); +} + +LineWrappedString NDSUI::createLogMessage(const char *username, std::string_view message) { + // Do line-wrapping, create and return Message instance + return LineWrappedString(" "+std::string(username)+"\n"+std::string(message)+"\n", calcMaxCharsInLine(calcMessageLogDimensions().width())); +} + +void LineWrappedString::split(std::string_view str, unsigned maxCharsPerLine) { + lines.clear(); + const char *currStrStart = str.data(); + const char *strEnd = str.data() + str.size(); + for (size_t currStrLen = 0; ;) { + const char& c = currStrStart[currStrLen]; + bool brk = false; + bool next = false; + bool minusOne = false; + if (c == '\n') { + next = true; + minusOne = true; + } else if (&c == strEnd) { + next = true; + brk = true; + minusOne = true; + } else if (currStrLen > maxCharsPerLine) { + next = true; + } + + if (next) { + lines.push_back({currStrStart, currStrLen}); + if (brk) break; + + currStrStart += currStrLen + minusOne; + currStrLen = 0; + } else { + currStrLen++; + } + } +} diff --git a/NDSUI.hpp b/NDSUI.hpp new file mode 100644 index 0000000..e42e9c4 --- /dev/null +++ b/NDSUI.hpp @@ -0,0 +1,111 @@ +#ifndef NDSUI_HPP +#define NDSUI_HPP +#include "basic-coro/AwaitableTask.hpp" +#include "basic-coro/SingleEvent.hpp" + +#include +#include +#include +#include +#include + + +class LineWrappedString { + unsigned maxCharsPerLine; + std::vector lines; + + void split(std::string_view, unsigned maxCharsPerLine); + +public: + LineWrappedString(std::string_view str, unsigned maxCharsPerLine) : maxCharsPerLine(maxCharsPerLine) { + split(str, maxCharsPerLine); + } + LineWrappedString(const LineWrappedString& o) : maxCharsPerLine(o.maxCharsPerLine), lines(o.lines) {} + LineWrappedString(LineWrappedString&& o) : maxCharsPerLine(o.maxCharsPerLine), lines(std::move(o.lines)) {} + + auto& operator=(LineWrappedString&& o) { + maxCharsPerLine = o.maxCharsPerLine; + lines = std::move(o.lines); + return *this; + } + auto& operator=(const LineWrappedString& o) { + maxCharsPerLine = o.maxCharsPerLine; + lines = o.lines; + return *this; + } + + const std::vector& getLines() const { + return lines; + } +}; + +struct Position2D { + unsigned x, y; +}; +struct Box2D { + Position2D topLeft, bottomRight; + + constexpr + unsigned height() const { + return bottomRight.y - topLeft.y; + } + constexpr + unsigned width() const { + return bottomRight.x - topLeft.x; + } +}; + +class NDSUI { + static NDSUI *currentInstance; // Currently updating instance + std::array inputLineBuf; + unsigned inputLineBufHead = 0; + std::vector messages; + std::unique_ptr> userInputHandler = nullptr; + size_t font_pixels; + + static void kbCallback(int key); + + static consteval + Box2D calcInputLineDimensions(); + static consteval + Box2D calcMessageLogDimensions(); + + void renderMessageLog(); + void renderInputLine(); + + static consteval + unsigned calcMaxCharsInLine(unsigned width); + static consteval + unsigned calcMaxLinesInRow(unsigned height); + + bool printChar(const char character, Position2D *topleftpos, const int color); + void print(std::string_view str, Position2D topleftpos, const int color); + + void handleInput(char); + + void resetInputLine() { + inputLineBufHead = 0; + inputLineBuf[0] = '\0'; + } + +public: + NDSUI(); + + bool shouldRun() const { + return userInputHandler != nullptr; + } + void run(); + + auto& addLogMessage(LineWrappedString &&msg) { + return messages.emplace_back(std::move(msg)); + } + + basiccoro::AwaitableTask readLine() { + userInputHandler = std::make_unique::type>(); + co_return co_await *userInputHandler; + } + + static + LineWrappedString createLogMessage(const char *username, std::string_view message); +}; +#endif // NDSUI_HPP diff --git a/Receiver.cpp b/Receiver.cpp index e027016..a8652f2 100644 --- a/Receiver.cpp +++ b/Receiver.cpp @@ -3,6 +3,7 @@ #include #include #ifndef PLATFORM_WINDOWS +# include # include #else # include diff --git a/Runtime.cpp b/Runtime.cpp index ff6f100..e69de29 100644 --- a/Runtime.cpp +++ b/Runtime.cpp @@ -1,47 +0,0 @@ -#include "Runtime.hpp" - -#ifdef PLATFORM_3DS -#include -#include - -#include -#include <3ds.h> - - - -void Runtime::customTerminate() noexcept { - // Get error message - std::string message; - try { - std::rethrow_exception(std::current_exception()); - } catch (const std::exception& e) { - message = e.what(); - } catch (...) { - message = "Unknown"; - } - // Display error - errorConf conf = { - .type = ERROR_TEXT_WORD_WRAP, - .errorCode = errno, - .upperScreenFlag = ERROR_NORMAL, - .useLanguage = CFG_LANGUAGE_EN, - .Text = {L'I', L'N', L'V', L'A', L'L', L'I', L'D', L'\0'}, - .homeButton = true, - .softwareReset = false, - .appJump = false, - .returnCode = ERROR_UNKNOWN, - .eulaVersion = 0 - }; - errorText(&conf, ("An exception was thrown but never handled:\n\n"+message).c_str()); - errorDisp(&conf); - // Exit - aptExit(); - socExit(); - gfxExit(); - exit(-errno); -} -#elif PLATFORM_DS -void Runtime::kbCallback(int key) { - if (key > 0) printf("%c", key); -} -#endif diff --git a/Runtime.hpp b/Runtime.hpp index b4f4a17..feca2f2 100644 --- a/Runtime.hpp +++ b/Runtime.hpp @@ -1,77 +1,5 @@ #ifndef _RUNTIME_HPP #define _RUNTIME_HPP - -#ifdef PLATFORM_3DS -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include <3ds.h> - - -class Runtime { - u32 *SOC_buffer = NULL; - constexpr static auto SOC_ALIGN = 0x1000, - SOC_BUFFERSIZE = 0x100000; - - [[noreturn]] static void customTerminate() noexcept; - -public: - Runtime() { - std::set_terminate(customTerminate); - gfxInitDefault(); - consoleInit(GFX_TOP, NULL); - aptInit(); - SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE); - auto ret = socInit(SOC_buffer, SOC_BUFFERSIZE); - if (ret != 0) { - throw std::runtime_error("socInit() = "+std::to_string((unsigned int)ret)); - } - } - Runtime(Runtime&) = delete; - Runtime(const Runtime&) = delete; - Runtime(Runtime&&) = delete; - ~Runtime() { - aptSetHomeAllowed(false); - std::cout << std::flush; - std::cerr << std::flush; - std::clog << std::endl << "Runtime destroyed." << std::endl; - std::clog << "Press START to exit" << std::flush; - for (u32 kDown; !(hidKeysDown() & KEY_START) && cooperate(); hidScanInput()) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - } - aptExit(); - socExit(); - gfxExit(); - } - - static inline - bool cooperate() noexcept { - return aptMainLoop(); - } - - static const char *readInput(const char *hint) { - static SwkbdState swkbd; - static char swkbd_buf[2048]; - // Read input - memset(swkbd_buf, 0, sizeof(swkbd_buf)); - swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 3, sizeof(swkbd_buf)); - swkbdSetHintText(&swkbd, hint); - swkbdInputText(&swkbd, swkbd_buf, sizeof(swkbd_buf)); - // Return input as string - return swkbd_buf; - } - - static void clearScreen() { - consoleClear(); - } -}; -#elif PLATFORM_DS #include #include #include @@ -85,12 +13,14 @@ public: class Runtime { - static void kbCallback(int key); - Keyboard *swkbd; public: Runtime() { + // Configure displays + videoSetMode(MODE_0_3D); + lcdMainOnTop(); + // Initialize console consoleDemoInit(); @@ -99,10 +29,6 @@ public: if (!Wifi_InitDefault(WFC_CONNECT)) { throw std::runtime_error("Failed to enable WiFi"); } - - // Initialize keyboard - swkbd = keyboardDemoInit(); - swkbd->OnKeyPressed = kbCallback; } Runtime(Runtime&) = delete; Runtime(const Runtime&) = delete; @@ -126,114 +52,6 @@ public: consoleClear(); } }; -#elif PLATFORM_LINUX -#include -#include -#include -#include -#include -#include - - -class Runtime { - static inline bool stopping = false; - static inline void handler(int signo, siginfo_t *info, void *context) { - stopping = true; - } - -public: - Runtime() { - struct sigaction act = { 0 }; - act.sa_flags = SA_SIGINFO; - act.sa_sigaction = handler; - for (int sig : {SIGTERM, SIGINT, SIGQUIT, SIGHUP}) { - if (sigaction(sig, &act, nullptr) < 0) { - throw std::runtime_error("sigaction() = "+std::string(strerror(errno))); - } - } - } - Runtime(Runtime&) = delete; - Runtime(const Runtime&) = delete; - Runtime(Runtime&&) = delete; - ~Runtime() { - std::cout << std::flush; - std::cerr << std::flush; - std::clog << std::endl << "Runtime destroyed." << std::endl; - } - - static inline bool cooperate() noexcept { - // Linux runs threads preemptively, no need to actually cooperate - return !stopping; - } - - static const char *readInput(const char *hint) { - static std::string content; - std::cout << hint << ": "; - std::getline(std::cin, content); - return content.c_str(); - } - - static void clearScreen() { - std::cout << "\033[H\033[2J\033[3J"; - } -}; -#elif PLATFORM_WINDOWS -#include -#include -#include -#include - - - -class Runtime { -public: - Runtime() { - WSADATA wsaData; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - throw std::runtime_error("Failed to initialize WinSock"); - } - } - Runtime(Runtime&) = delete; - Runtime(const Runtime&) = delete; - Runtime(Runtime&&) = delete; - ~Runtime() { - std::cout << std::flush; - std::cerr << std::flush; - std::clog << std::endl << "Runtime destroyed." << std::endl; - WSACleanup(); - } - - static constexpr bool cooperate() noexcept { - // Windows runs threads preemptively, no need to cooperate. - // No signals to handle either, Windows doesn't support them. - return true; - } - - static const char *readInput(const char *hint) { - static std::string content; - std::cout << hint << ": "; - std::getline(std::cin, content); - return content.c_str(); - } - - static void clearScreen() { - system("cls"); - } -}; -#endif -#endif - -#if !(defined(PLATFORM_WINDOWS) || defined(PLATFORM_DS)) -# define MSG_FLAGS_OR_ZERO(...) __VA_ARGS__ -#else -# define MSG_FLAGS_OR_ZERO(...) 0 -#endif - -#ifdef PLATFORM_DS -# define IPPROTO_TCP 0 -#endif - -#ifndef PLATFORM_DS -# define HAS_ADDRINFO +#define IPPROTO_TCP 0 #endif diff --git a/Sender.cpp b/Sender.cpp index 539ba77..03a5b3c 100644 --- a/Sender.cpp +++ b/Sender.cpp @@ -4,6 +4,7 @@ #include #ifndef PLATFORM_WINDOWS +# include # include #else # include @@ -25,5 +26,5 @@ basiccoro::AwaitableTask Sender::Simple::write(const std::byte *dat } // Write - co_return (send(fd, reinterpret_cast(data), size, MSG_FLAGS_OR_ZERO(MSG_NOSIGNAL | (int(moreData)*MSG_MORE))) < 0)?AsyncResult::Error:AsyncResult::Success; + co_return (send(fd, reinterpret_cast(data), size, 0) < 0)?AsyncResult::Error:AsyncResult::Success; } diff --git a/font.c b/font.c new file mode 100644 index 0000000..5154f3f --- /dev/null +++ b/font.c @@ -0,0 +1,1760 @@ +#include +#include "font.h" + +// Same data as the Linux kernel uses, extracted from the PC VGA font. +const bool fontBitmap[] = { + // 32 0x20 ' ' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 33 0x21 '!' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 34 0x22 '"' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 35 0x23 '#' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 36 0x24 '$' + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 37 0x25 '%' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 38 0x26 '&' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 39 0x27 ''' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 40 0x28 '(' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 41 0x29 ')' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 42 0x2a '*' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 43 0x2b '+' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 44 0x2c ',' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 45 0x2d '-' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 46 0x2e '.' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 47 0x2f '/' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 48 0x30 '0' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 49 0x31 '1' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 50 0x32 '2' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 51 0x33 '3' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 52 0x34 '4' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 53 0x35 '5' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 54 0x36 '6' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 55 0x37 '7' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 56 0x38 '8' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 57 0x39 '9' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 58 0x3a ':' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 59 0x3b ';' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 60 0x3c '<' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 61 0x3d '=' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 62 0x3e '>' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 63 0x3f '?' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 64 0x40 '@' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 65 0x41 'A' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 66 0x42 'B' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 67 0x43 'C' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 68 0x44 'D' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 69 0x45 'E' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 70 0x46 'F' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 71 0x47 'G' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 72 0x48 'H' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 73 0x49 'I' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 74 0x4a 'J' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 75 0x4b 'K' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 76 0x4c 'L' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 77 0x4d 'M' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 78 0x4e 'N' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 79 0x4f 'O' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 80 0x50 'P' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 81 0x51 'Q' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 82 0x52 'R' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 83 0x53 'S' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 84 0x54 'T' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 0, 1, 1, 0, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 85 0x55 'U' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 86 0x56 'V' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 87 0x57 'W' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 0, 1, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 88 0x58 'X' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 89 0x59 'Y' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 90 0x5a 'Z' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 91 0x5b '[' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 92 0x5c '\' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 93 0x5d ']' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 94 0x5e '^' + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 95 0x5f '_' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 96 0x60 '`' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 97 0x61 'a' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 98 0x62 'b' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 99 0x63 'c' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 100 0x64 'd' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 101 0x65 'e' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 102 0x66 'f' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 1, 1, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 103 0x67 'g' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 104 0x68 'h' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 105 0x69 'i' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 106 0x6a 'j' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 107 0x6b 'k' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 1, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 108 0x6c 'l' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 109 0x6d 'm' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 11, 0 0x6e 'n' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 11, 1 0x6f 'o' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 112 0x70 'p' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 113 0x71 'q' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 114 0x72 'r' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 115 0x73 's' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 116 0x74 't' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 117 0x75 'u' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 118 0x76 'v' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 119 0x77 'w' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 120 0x78 'x' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 121 0x79 'y' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 122 0x7a 'z' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 123 0x7b '{' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 124 0x7c '|' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 125 0x7d '}' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 126 0x7e '~' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 1, 1, 0, + 1, 1, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 127 0x7f '' + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 0, 0, 0, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; +const bool fontBitmapUnk[] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 0, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, +}; + + +const bool *font_get_character(char character) { + if (character < 0x20) { + return fontBitmapUnk; + } + character -= 0x20; + return &fontBitmap[character * FONT_SIZE]; +} diff --git a/font.h b/font.h new file mode 100644 index 0000000..21971c5 --- /dev/null +++ b/font.h @@ -0,0 +1,13 @@ +#include +#define FONT_HEIGHT 16 +#define FONT_WIDTH 8 +#define FONT_SIZE FONT_HEIGHT * FONT_WIDTH + +#ifdef __cplusplus +extern "C" { +#endif +extern const bool fontBitmapUnk[FONT_SIZE]; +const bool *font_get_character(const char character); +#ifdef __cplusplus +} +#endif diff --git a/font_ugly.h b/font_ugly.h new file mode 100644 index 0000000..160847e --- /dev/null +++ b/font_ugly.h @@ -0,0 +1,765 @@ +#include +#define FONT_HEIGHT 8 +#define FONT_WIDTH 4 +#define FONT_SIZE FONT_HEIGHT * FONT_WIDTH + + +const bool font_space[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +}; +const bool font_unk[] = { + 1, 1, 1, 1, + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 1, 0, 1, + 1, 1, 1, 1, +}; + +const bool font_digit_1[] = { + 0, 0, 0, 1, + 0, 1, 1, 1, + 1, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, +}; +const bool font_digit_2[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 1, 1, +}; +const bool font_digit_3[] = { + 1, 1, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 1, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_digit_4[] = { + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0, + 1, 0, 1, 0, + 1, 1, 1, 1, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, +}; +const bool font_digit_5[] = { + 1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_digit_6[] = { + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_digit_7[] = { + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 1, 0, 0, 0, +}; +const bool font_digit_8[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_digit_9[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_digit_0[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; + +const bool font_letter_a[] = { + 0, 0, 0, 0, + 1, 1, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_b[] = { + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_c[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 1, 1, +}; + +const bool font_letter_d[] = { + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_e[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 1, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 0, 0, + 0, 1, 1, 0, +}; +const bool font_letter_f[] = { + 0, 0, 1, 1, + 0, 1, 0, 0, + 0, 1, 0, 0, + 1, 1, 1, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, +}; +const bool font_letter_g[] = { + 0, 0, 0, 0, + 0, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_h[] = { + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_i[] = { + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, +}; +const bool font_letter_j[] = { + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 1, 0, 1, 0, + 0, 1, 0, 0, +}; +const bool font_letter_k[] = { + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 0, 1, 0, + 1, 1, 0, 0, + 1, 0, 1, 0, + 1, 0, 0, 1, +}; +const bool font_letter_l[] = { + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 1, + 0, 0, 1, 0, +}; +const bool font_letter_m[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 1, 1, + 1, 0, 1, 1, +}; +const bool font_letter_n[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_o[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_p[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, +}; +const bool font_letter_q[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, +}; +const bool font_letter_r[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, +}; +const bool font_letter_s[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 1, 1, + 1, 0, 0, 0, + 0, 1, 1, 0, + 0, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_letter_t[] = { + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 1, 1, 1, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 1, +}; +const bool font_letter_u[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_v[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, +}; + +const bool font_letter_w[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 1, 1, 0, +}; +const bool font_letter_x[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1, +}; +const bool font_letter_y[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, +}; +const bool font_letter_z[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 1, 0, 0, + 1, 1, 1, 1, +}; +const bool font_letter_A[] = { + 0, 0, 0, 0, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_B[] = { + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_letter_C[] = { + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 1, 1, +}; +const bool font_letter_D[] = { + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_letter_E[] = { + 1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, +}; +const bool font_letter_F[] = { + 1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, +}; +const bool font_letter_G[] = { + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_H[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_I[] = { + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, +}; +const bool font_letter_J[] = { + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_K[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 1, 0, + 1, 1, 0, 0, + 1, 0, 0, 0, + 1, 1, 0, 0, + 1, 0, 1, 0, + 1, 0, 0, 1, +}; +const bool font_letter_L[] = { + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 1, 1, 1, +}; +const bool font_letter_M[] = { + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_N[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 0, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 1, 0, 1, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_O[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_P[] = { + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, +}; +const bool font_letter_Q[] = { + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 0, 1, + 1, 0, 1, 1, + 0, 1, 1, 1, +}; +const bool font_letter_R[] = { + 1, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 0, + 1, 1, 0, 0, + 1, 0, 1, 0, + 1, 0, 0, 1, +}; +const bool font_letter_S[] = { + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 0, + 1, 0, 0, 0, + 0, 1, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, + 1, 1, 1, 0, +}; +const bool font_letter_T[] = { + 1, 1, 1, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, +}; +const bool font_letter_U[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, +}; +const bool font_letter_V[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 0, 1, 1, 0, +}; +const bool font_letter_W[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, +}; +const bool font_letter_X[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 0, + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, +}; +const bool font_letter_Y[] = { + 1, 0, 0, 1, + 1, 0, 0, 1, + 1, 0, 0, 1, + 0, 1, 1, 0, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 1, +}; +const bool font_letter_Z[] = { + 1, 1, 1, 1, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 0, 1, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 1, 1, 0, 0, + 1, 1, 1, 1, +}; + +const bool font_special_dot[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 0, 0, +}; +const bool font_special_colon[] = { + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 0, 0, +}; +const bool font_special_exclaimationmark[] = { + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 1, 0, 0, +}; + + +/* + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, +*/ +const bool *font_get_character(const char character) { + const bool *res = font_unk; + switch(character) { + case 'a': res = font_letter_a; break; + case 'b': res = font_letter_b; break; + case 'c': res = font_letter_c; break; + case 'd': res = font_letter_d; break; + case 'e': res = font_letter_e; break; + case 'f': res = font_letter_f; break; + case 'g': res = font_letter_g; break; + case 'h': res = font_letter_h; break; + case 'i': res = font_letter_i; break; + case 'j': res = font_letter_j; break; + case 'k': res = font_letter_k; break; + case 'l': res = font_letter_l; break; + case 'm': res = font_letter_m; break; + case 'n': res = font_letter_n; break; + case 'o': res = font_letter_o; break; + case 'p': res = font_letter_p; break; + case 'q': res = font_letter_q; break; + case 'r': res = font_letter_r; break; + case 's': res = font_letter_s; break; + case 't': res = font_letter_t; break; + case 'u': res = font_letter_u; break; + case 'v': res = font_letter_v; break; + case 'w': res = font_letter_w; break; + case 'x': res = font_letter_x; break; + case 'y': res = font_letter_y; break; + case 'z': res = font_letter_z; break; + case 'A': res = font_letter_A; break; + case 'B': res = font_letter_B; break; + case 'C': res = font_letter_C; break; + case 'D': res = font_letter_D; break; + case 'E': res = font_letter_E; break; + case 'F': res = font_letter_F; break; + case 'G': res = font_letter_G; break; + case 'H': res = font_letter_H; break; + case 'I': res = font_letter_I; break; + case 'J': res = font_letter_J; break; + case 'K': res = font_letter_K; break; + case 'L': res = font_letter_L; break; + case 'M': res = font_letter_M; break; + case 'N': res = font_letter_N; break; + case 'O': res = font_letter_O; break; + case 'P': res = font_letter_P; break; + case 'Q': res = font_letter_Q; break; + case 'R': res = font_letter_R; break; + case 'S': res = font_letter_S; break; + case 'T': res = font_letter_T; break; + case 'U': res = font_letter_U; break; + case 'V': res = font_letter_V; break; + case 'W': res = font_letter_W; break; + case 'X': res = font_letter_X; break; + case 'Y': res = font_letter_Y; break; + case 'Z': res = font_letter_Z; break; + case ' ': res = font_space; break; + case '1': res = font_digit_1; break; + case '2': res = font_digit_2; break; + case '3': res = font_digit_3; break; + case '4': res = font_digit_4; break; + case '5': res = font_digit_5; break; + case '6': res = font_digit_6; break; + case '7': res = font_digit_7; break; + case '8': res = font_digit_8; break; + case '9': res = font_digit_9; break; + case '0': res = font_digit_0; break; + case '.': res = font_special_dot; break; + case ':': res = font_special_colon; break; + case '!': res = font_special_exclaimationmark; break; + } + return res; +} diff --git a/main.cpp b/main.cpp index ebaf237..48577c4 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,4 @@ +#include "NDSUI.hpp" #include "Runtime.hpp" #include "AsyncManager.hpp" #include "Client.hpp" @@ -13,49 +14,57 @@ void on_progress(float progress) { std::cout << unsigned(progress) << '\r' << std::flush; } -basiccoro::AwaitableTask async_main(Runtime& rt, AsyncManager &aMan) { +basiccoro::AwaitableTask async_main(Runtime& rt, AsyncManager &aMan, NDSUI& ui) { // Ask for server address - const std::string addr = rt.readInput("Server address"); + ui.addLogMessage(ui.createLogMessage("System", "Please type in the address of the server.")); + const std::string addr = co_await ui.readLine(); // Create client Client client(addr, 99181, aMan); + // Greet the user + ui.addLogMessage(ui.createLogMessage("Bot", "Hey! How can I help you today?")); + // Connection loop for (;; rt.cooperate()) { // Read prompt - const auto prompt = rt.readInput("Prompt"); - - // Clear screen - rt.clearScreen(); + const auto prompt = co_await ui.readLine(); // Display prompt - std::cout << "Prompt: " << prompt << std::endl; + auto& msg = ui.addLogMessage(ui.createLogMessage("Bot", "Initializing...")); // Run inference - co_await client.ask(prompt, [&rt] (float progress) -> basiccoro::AwaitableTask { - std::cout << unsigned(progress) << "%\r" << std::flush; + std::string result; + co_await client.ask(prompt, [&msg, &ui] (unsigned progress) -> basiccoro::AwaitableTask { + msg = ui.createLogMessage("Bot", (std::to_string(progress)+"%")); co_return; - }, [&rt] (std::string_view token) -> basiccoro::AwaitableTask { - std::cout << token << std::flush; + }, [&result, &msg, &ui] (std::string_view token) -> basiccoro::AwaitableTask { + result.append(token); + msg = ui.createLogMessage("Bot", result+"..."); co_return; }); + msg = ui.createLogMessage("Bot", result); std::cout << "\n"; } } int main() { Runtime rt; + NDSUI ui; AsyncManager aMan(rt); // Print header - std::cout << "llama.any running on " PLATFORM ".\n" + std::cout << "llama.nds running on " PLATFORM ".\n" "\n"; // Start async main() - async_main(rt, aMan); + async_main(rt, aMan, ui); // Start async manager - aMan.run(); + while (aMan.shouldRun() || ui.shouldRun()) { + ui.run(); + aMan.run(); + } return 0; }