#include "TessesFramework/Common.hpp" #include "TessesFramework/Streams/NetworkStream.hpp" #include "TessesFramework/Lazy.hpp" #include #include #include #include #if defined(TESSESFRAMEWORK_ENABLE_SQLITE) extern "C" { #include "Serialization/sqlite/sqlite3.h" } #if defined(GEKKO) || defined(__SWITCH__) || defined(__PS2__) extern "C" { sqlite3_vfs *sqlite3_demovfs(); } #endif #endif #if defined(_WIN32) #include #undef min #include #elif defined(__SWITCH__) extern "C" { #include } #elif defined(GEKKO) #include #include #include #include #include #if defined(HW_RVL) #if defined(TESSESFRAMEWORK_USE_WII_SOCKET) #include #endif #include #endif static void *xfb = NULL; static GXRModeObj *rmode = NULL; #endif #if defined(TESSESFRAMEWORK_ENABLE_THREADING) #include "TessesFramework/Threading/Mutex.hpp" #endif #if defined(TESSESFRAMEWORK_ENABLE_SDL2) #include #include #include #include "TessesFramework/SDL2/GUI.hpp" #endif namespace Tesses::Framework { EventList OnItteraton; #if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__)) namespace Threading { extern void JoinAllThreads(); extern void LookForFinishedThreads(); } #endif volatile static bool isRunningSig=true; volatile static std::atomic isRunning; volatile static std::atomic gaming_console_events=true; #if defined(TESSESFRAMEWORK_ENABLE_THREADING) Threading::Mutex invokings_mtx; std::queue> invokings; #endif void TF_Invoke(std::function cb) { #if defined(TESSESFRAMEWORK_ENABLE_THREADING) invokings_mtx.Lock(); invokings.push(cb); invokings_mtx.Unlock(); #else cb(); #endif } void TF_ConnectToSelf(uint16_t port) { Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false); } bool TF_IsRunning() { return isRunning; } static void _sigInt(int c) { isRunningSig=false; #if defined(TESSESFRAMEWORK_ENABLE_SDL2) SDL_Event quitEvent; quitEvent.type = SDL_QUIT; SDL_PushEvent(&quitEvent); #endif } void TF_RunEventLoop() { while(isRunning) { TF_RunEventLoopItteration(); } } #if defined(__SWITCH__) bool initedConsole=false; PadState default_pad; #endif uint64_t ittr=0; void TF_RunEventLoopItteration() { OnItteraton.Invoke(ittr++); #if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__)) Tesses::Framework::Threading::LookForFinishedThreads(); #endif #if defined(TESSESFRAMEWORK_ENABLE_THREADING) invokings_mtx.Lock(); auto invokes = invokings; invokings_mtx.Unlock(); while(!invokes.empty()) { invokes.front()(); invokes.pop(); } #endif if(!isRunningSig) isRunning=false; #if defined(GEKKO) if(gaming_console_events) { PAD_ScanPads(); if(PAD_ButtonsDown(0) & PAD_BUTTON_START) isRunning=false; } #elif defined(__SWITCH__) if(gaming_console_events) { if(!appletMainLoop()) isRunning=false; padUpdate(&default_pad); u64 kDown = padGetButtonsDown(&default_pad); if (kDown & HidNpadButton_Plus) isRunning=false; if(initedConsole) consoleUpdate(NULL); } #endif #if defined(_WIN32) MSG winMSG; if (PeekMessage(&winMSG, NULL, WM_QUIT, WM_QUIT, 1)) { isRunning = false; } #endif #if defined(TESSESFRAMEWORK_ENABLE_SDL2) Tesses::Framework::SDL2::gui.Update(); #endif } void TF_SetIsRunning(bool _isRunning) { isRunning = _isRunning; } void TF_Quit() { isRunning=false; #if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__)) Tesses::Framework::Threading::JoinAllThreads(); #endif #if defined(TESSESFRAMEWORK_ENABLE_SDL2) SDL_Quit(); Tesses::Framework::SDL2::gui.CloseWindows(); #endif } void TF_Init() { #if defined(TESSESFRAMEWORK_ENABLE_SQLITE) sqlite3_initialize(); #if defined(GEKKO) || defined(__SWITCH__) || defined(__PS2__) sqlite3_vfs_register(sqlite3_demovfs(),1); #endif #endif #if defined(TESSESFRAMEWORK_ENABLE_SDL2) //SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS,"1"); SDL_Init(SDL_INIT_EVERYTHING); TTF_Init(); int r = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP #if !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__) | IMG_INIT_JXL |IMG_INIT_AVIF #endif ; if(IMG_Init( r ) != r) { std::cout << "IMG_Init: " << IMG_GetError() << std::endl; } #endif tzset(); #if defined(_WIN32) system(" "); signal(SIGINT, _sigInt); signal(SIGTERM, _sigInt); #endif isRunning=true; #if defined(_WIN32) WSADATA wsaData; int iResult; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); return; } #elif defined(GEKKO) fatInitDefault(); VIDEO_Init(); PAD_Init(); #if defined(HW_RVL) #if defined(TESSESFRAMEWORK_USE_WII_SOCKET) wiisocket_init(); #endif WPAD_Init(); #endif #elif defined(__SWITCH__) padConfigureInput(1, HidNpadStyleSet_NpadStandard); padInitializeDefault(&default_pad); socketInitializeDefault(); // Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller) #else signal(SIGPIPE,SIG_IGN); signal(SIGINT,_sigInt); signal(SIGTERM, _sigInt); #endif } bool TF_GetConsoleEventsEnabled() { return gaming_console_events; } void TF_SetConsoleEventsEnabled(bool flag) { gaming_console_events=flag; } void TF_InitConsole() { #if defined(GEKKO) rmode = VIDEO_GetPreferredMode(NULL); // Allocate memory for the display in the uncached region xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); // Initialise the console, required for printf console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ); //SYS_STDIO_Report(true); // Set up the video registers with the chosen mode VIDEO_Configure(rmode); // Tell the video hardware where our display memory is VIDEO_SetNextFramebuffer(xfb); // Make the display visible VIDEO_SetBlack(false); // Flush the video register changes to the hardware VIDEO_Flush(); // Wait for Video setup to complete VIDEO_WaitVSync(); if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); // The console understands VT terminal escape codes // This positions the cursor on row 2, column 0 // we can use variables for this with format codes too // e.g. printf ("\x1b[%d;%dH", row, column ); printf("\x1b[2;0H"); #elif defined(__SWITCH__) consoleInit(NULL); initedConsole=true; #endif } void TF_InitWithConsole() { TF_Init(); TF_InitConsole(); #if defined(TESSESFRAMEWORK_LOGTOFILE) printf("Enabled Logging\n"); #endif } #if defined(TESSESFRAMEWORK_LOGTOFILE) #if defined(TESSESFRAMEWORK_ENABLE_THREADING) Tesses::Framework::Threading::Mutex log_mtx; #endif void TF_Log(std::string txtToLog) { #if defined(TESSESFRAMEWORK_ENABLE_THREADING) log_mtx.Lock(); #endif FILE* f = fopen("TF_Log.log","a"); fprintf(f,"%s\n",txtToLog.c_str()); fclose(f); #if defined(TESSESFRAMEWORK_ENABLE_THREADING) log_mtx.Unlock(); #endif } #endif }