mirror of
https://gitlab.com/niansa/llama_any.git
synced 2025-03-06 20:48:27 +01:00
244 lines
6 KiB
C++
244 lines
6 KiB
C++
#ifndef _RUNTIME_HPP
|
|
#define _RUNTIME_HPP
|
|
|
|
#ifdef PLATFORM_3DS
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
#include <cstring>
|
|
#include <malloc.h>
|
|
#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 <iostream>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <exception>
|
|
#include <stdexcept>
|
|
#include <malloc.h>
|
|
#include <nds.h>
|
|
#include <dswifi9.h>
|
|
|
|
|
|
class Runtime {
|
|
static void kbCallback(int key);
|
|
|
|
Keyboard *swkbd;
|
|
|
|
public:
|
|
Runtime() {
|
|
// Configure video
|
|
videoSetMode(MODE_0_2D);
|
|
lcdMainOnBottom();
|
|
|
|
// Initialize console
|
|
consoleDemoInit();
|
|
|
|
// Initialize WiFi
|
|
std::cout << "Connecting via WFC data" << std::endl;
|
|
if (!Wifi_InitDefault(WFC_CONNECT)) {
|
|
throw std::runtime_error("Failed to enable WiFi");
|
|
}
|
|
|
|
// Initialize keyboard
|
|
swkbd = keyboardGetDefault();
|
|
swkbd = keyboardInit(swkbd, 3, BgType_Text4bpp, BgSize_T_256x512, swkbd->mapBase, swkbd->tileBase, true, true);
|
|
swkbd->OnKeyPressed = kbCallback;
|
|
}
|
|
Runtime(Runtime&) = delete;
|
|
Runtime(const Runtime&) = delete;
|
|
Runtime(Runtime&&) = delete;
|
|
~Runtime() {}
|
|
|
|
static inline
|
|
bool cooperate() noexcept {
|
|
// The Nintendo DS does not support multitasking
|
|
return true;
|
|
}
|
|
|
|
static const char *readInput(const char *hint) {
|
|
std::cout << hint << ": " << std::flush;
|
|
static std::string outstr;
|
|
std::getline(std::cin, outstr);
|
|
return outstr.c_str();
|
|
}
|
|
|
|
static void clearScreen() {
|
|
consoleClear();
|
|
}
|
|
};
|
|
#elif PLATFORM_LINUX
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <mutex>
|
|
#include <cstring>
|
|
#include <csignal>
|
|
#include <cerrno>
|
|
|
|
|
|
|
|
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 <iostream>
|
|
#include <mutex>
|
|
#include <stdexcept>
|
|
#include <winsock2.h>
|
|
|
|
|
|
|
|
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
|
|
#endif
|