This commit is contained in:
DepressedTWM 2026-08-18 20:22:54 +04:00
parent 526330f3c8
commit 6127f1d25c
12 changed files with 416 additions and 233 deletions

View file

@ -416,10 +416,11 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION_STRING="${VERSION_STR
find_package(PkgConfig REQUIRED)
find_package(ZLIB REQUIRED)
find_package(SDL3 CONFIG)
find_package(SDL3_image CONFIG)
find_package(SDL3_mixer CONFIG REQUIRED)
find_package(SDL3_ttf CONFIG)
find_package(SDL3 CONFIG REQUIRED)
find_package(SDL3_image CONFIG REQUIRED)
find_package(SDL3_mixer CONFIG REQUIRED REQUIRED)
find_package(SDL3_ttf CONFIG REQUIRED)
find_package(SDL3_net CONFIG REQUIRED)
find_package(Boost REQUIRED COMPONENTS program_options chrono)
find_package(PhysFS)
find_path(PIXMAN_INCLUDE_DIR NAMES pixman.h PATH_SUFFIXES pixman-1)
@ -432,10 +433,10 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE ${DEFINES})
target_include_directories(${PROJECT_NAME} PRIVATE src include ${PIXMAN_INCLUDE_DIR} ${SIGC2_INCLUDE_DIRS}
${Ruby_INCLUDE_DIRS} Boost::boost ${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS} SDL3_mixer::SDL3_mixer)
${ZLIB_INCLUDE_DIRS} SDL3_mixer::SDL3_mixer SDL3_net::SDL3_net)
target_link_libraries(${PROJECT_NAME} PRIVATE SDL3::SDL3 SDL3_image::SDL3_image
SDL3_mixer::SDL3_mixer SDL3_ttf::SDL3_ttf
SDL3_mixer::SDL3_mixer SDL3_ttf::SDL3_ttf SDL3_net::SDL3_net
physfs ${PIXMAN_LIBRARY} ${SIGC2_LIBRARIES} ${PLATFORM_LIBRARIES}
${Ruby_LIBRARIES} Boost::boost Boost::chrono ${Boost_LIBRARIES}
ZLIB::ZLIB ${PLATFORM_LIBS})

View file

@ -4,145 +4,48 @@
#include "debugwriter.h"
#include "i18n.h"
#include "define.h"
//OS-Specific code
#if defined _WIN32
#define OS_W32
#elif unix_like
#define LINUX
#ifdef __APPLE__
#define OS_OSX
#else
#define OS_LINUX
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef __linux__
#include <sys/inotify.h>
#endif
#include <unistd.h>
#include <cstdio>
#include <pwd.h>
#include <string>
#endif
#include <SDL3/SDL.h>
#include <SDL3/SDL.h>
#include <SDL3_net/SDL_net.h>
#define BUFFER_SIZE 256
void SendRaw(const char *address, int port, const char *raw){
NET_Address *addr = NET_ResolveHostname(address);
if (!addr) {
Debug() << "Failed to resolve " << address << " : " << SDL_GetError();
return;
}
static SDL_Thread *thread = NULL;
static SDL_Mutex *mutex = NULL;
static volatile char lang_buffer[BUFFER_SIZE];
static volatile char message_buffer[BUFFER_SIZE];
static volatile bool active = false;
static volatile int message_len = 0;
if (NET_WaitUntilResolved(addr, -1) == NET_FAILURE) {
Debug() << "NET_FAILURE " << address << " : " << SDL_GetError();
return;
}
#ifdef unix_like
static std::string PIPE_PATH = std::string(getpwuid(getuid())->pw_dir) + "/.oneshot-pipe";
static volatile int out_pipe = -1;
void cleanup_pipe(){
unlink(PIPE_PATH.c_str());
remove(PIPE_PATH.c_str());
}
#endif
NET_StreamSocket *socket = NET_CreateClient(addr, port, 0);
if (!socket) {
Debug() << "Failed to create connection: " << SDL_GetError();
return;
}
int server_thread(void *data){
(void)data;
#if defined OS_W32
HANDLE pipe = CreateNamedPipeW(L"\\\\.\\pipe\\oneshot-journal-to-game",
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUFFER_SIZE,
BUFFER_SIZE,
0,
NULL);
for (;;) {
ConnectNamedPipe(pipe, NULL);
SDL_LockMutex(mutex);
DWORD written;
WriteFile(pipe, (const void*)message_buffer, BUFFER_SIZE, &written, NULL);
active = true;
SDL_UnlockMutex(mutex);
FlushFileBuffers(pipe);
DisconnectNamedPipe(pipe);
}
CloseHandle(pipe);
#else
if (access(PIPE_PATH.c_str(), F_OK) != -1){
out_pipe = open(PIPE_PATH.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
SDL_LockMutex(mutex);
active = true;
if (message_len > 0){
if (write(out_pipe, (char*)message_buffer, message_len) == -1){
#ifdef DEBUG
Debug() << "[journal-binding>server_thread()]Failure writing to journal's pipe!";
#endif
}
}
SDL_UnlockMutex(mutex);
}
return 0;
#endif
if (NET_WaitUntilConnected(socket, -1) == NET_FAILURE) {
Debug() << "Failed to connect to " << address << ":" << port << " " << SDL_GetError();
NET_DestroyStreamSocket(socket);
return;
}
int length = (int)SDL_strlen(raw);
if (!NET_WriteToStreamSocket(socket, raw, length)) {
Debug() << "Failed to send: " << SDL_GetError();
} else if (NET_WaitUntilStreamSocketDrained(socket, -1) < 0) {
Debug() << "Error: " << SDL_GetError();
}
NET_DestroyStreamSocket(socket);
}
RB_METHOD(journalSet){
RB_UNUSED_PARAM;
const char *name;
rb_get_args(argc, argv, "z", &name RB_ARG_END);
// Record message
SDL_LockMutex(mutex);
message_len = SDL_strlen(name);
strcpy((char*)message_buffer, name);
if (message_len > 0) {
// in the case where journal is being sent empty string
// do not append the language suffix, because empty string
// is the signifier to terminate the journal
strcpy((char*)message_buffer + message_len, (char*)lang_buffer);
message_len += SDL_strlen((char*)lang_buffer);
}
SDL_UnlockMutex(mutex);
#if defined _WIN32
HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\oneshot-game-to-journal",
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (pipe != INVALID_HANDLE_VALUE) {
active = true;
DWORD written;
WriteFile(pipe, (const void*)message_buffer, BUFFER_SIZE, &written, NULL);
FlushFileBuffers(pipe);
CloseHandle(pipe);
}
if (thread == NULL) {
thread = SDL_CreateThread(server_thread, "journal", NULL);
}
#else
// Clean up connection thread
if (thread != NULL && out_pipe != -1) {
SDL_WaitThread(thread, NULL);
thread = NULL;
}
// Attempt to send it over the tubes
if (out_pipe != -1) {
// We have a connection, so send it over
if (write(out_pipe, (char*)message_buffer, message_len) <= 0) {
// In the case of an error, close
close(out_pipe);
out_pipe = -1;
}
}
if (out_pipe == -1) {
// We don't have a pipe open, so spawn the connection thread
thread = SDL_CreateThread(server_thread, "journal", NULL);
}
#endif
return Qnil;
}
@ -150,25 +53,19 @@ RB_METHOD(journalSetLang){
RB_UNUSED_PARAM;
const char *lang;
rb_get_args(argc, argv, "z", &lang RB_ARG_END);
strcpy((char*)lang_buffer+1, lang);
loadLocale(lang);
printf(lang);
return Qnil;
}
RB_METHOD(journalActive){
RB_UNUSED_PARAM;
return active ? Qtrue : Qfalse;
return Qfalse;
}
void journalBindingInit(){
mutex = SDL_CreateMutex();
SDL_memset((char*)lang_buffer, 0, BUFFER_SIZE);
lang_buffer[0] = '_';
#ifdef unix_like
mkfifo(PIPE_PATH.c_str(), 0666);
atexit(cleanup_pipe);
#endif
if (!NET_Init()) {
Debug() << "NET_Init() failed: " << SDL_GetError();
}
VALUE module = rb_define_module("Journal");
_rb_define_module_function(module, "set", journalSet);
_rb_define_module_function(module, "active?", journalActive);

View file

@ -66,3 +66,4 @@ Added X11 Window Managers support
GNOME support fixed
Fixed small defect on cg_wake5
Added ModLoader loading screen
Added [Function():string number] debug information in logs

View file

@ -41,7 +41,7 @@ foreach(item ${EMBEDDED_INPUT})
endforeach()
source_group("Embedded Source" FILES ${EMBEDDED_INPUT} ${EMBEDDED_SOURCE})
add_executable(${PROJECT_NAME} ${EMBEDDED_SOURCE} main.c)
add_executable(${PROJECT_NAME} ${EMBEDDED_SOURCE} main.cpp debugwriter.h)
find_package(SDL3 CONFIG REQUIRED)
find_package(SDL3_image CONFIG REQUIRED)
find_package(SDL3_net CONFIG REQUIRED)

71
journal/SDL/debugwriter.h Normal file
View file

@ -0,0 +1,71 @@
/*
** debugwriter.h
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version.
**
** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEBUGWRITER_H
#define DEBUGWRITER_H
#include <iostream>
#include <sstream>
#include <vector>
#ifdef __ANDROID__
#include <android/SDL_log.h>
#elif __EMSCRIPTEN__
#include <emscripten/console.h>
#endif
class Debug{
public:
Debug(){
buf << std::boolalpha;
}
template<typename T>
Debug &operator<<(const T &t){
buf << t;
buf << " ";
return *this;
}
template<typename T>
Debug &operator<<(const std::vector<T> &v){
for (size_t i = 0; i < v.size(); ++i)
buf << v[i] << " ";
return *this;
}
~Debug(){
#ifdef __ANDROID__
__android_log_write(ANDROID_LOG_DEBUG, "sunshine", buf.str().c_str());
#elif __EMSCRIPTEN__
emscripten_console_log(buf.str().c_str());
#else
std::cout << buf.str() << "\n";
#endif
}
private:
std::stringstream buf;
};
#endif // DEBUGWRITER_H

View file

@ -1,75 +0,0 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_log.h>
#include "icon.png.xxd"
#include "default.png.xxd"
char image[256] = "default"
int LoadImage(SDL_Renderer* ren){
if(image == "default"){
SDL_Surface* img = IMG_Load_IO(SDL_IOFromConstMem(assets_the_modded_machine_png, assets_the_modded_machine_png_len), true);
}else{
}
}
int main(int argc, char* argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* win = SDL_CreateWindow("SDL3 Image",640, 480, 0);
if (win == NULL) {
SDL_Log("SDL_CreateWindow Error: %s", SDL_GetError());
SDL_Quit();
return 1;
}
SDL_Renderer* ren = SDL_CreateRenderer(win, NULL);
if (ren == NULL) {
SDL_Log("SDL_CreateRenderer Error: %s", SDL_GetError());
SDL_DestroyWindow(win);
SDL_Quit();
return 1;
}
SDL_Surface* bmp = SDL_LoadBMP("lettuce.bmp");
if (bmp == NULL) {
SDL_Log("Image loading Error: %s", SDL_GetError());
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 1;
}
SDL_Texture* tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_DestroySurface(bmp);
if (tex == NULL) {
std::cerr << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 1;
}
SDL_Event e;
bool quit = false;
while (!quit) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) {
quit = true;
}
}
SDL_RenderClear(ren);
SDL_RenderTexture(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}

279
journal/SDL/main.cpp Normal file
View file

@ -0,0 +1,279 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_stdinc.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_net/SDL_net.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_thread.h>
#include <string>
#include <iostream>
#include <fstream>
#include <filesystem>
#include "debugwriter.h"
#include "icon.png.xxd"
#include "default.png.xxd"
static bool quit = false;
static char is_changed = false;
static char image[256] = "default";
static char image_full_path[1024] = "default";
static char gamedir_path[256] = "";
static char address[64] = "127.0.0.1";
Uint16 server_port = 23821;
static void trim_crlf_inplace(char* s) {
if (!s) return;
size_t n = SDL_strlen(s);
while (n > 0 && (s[n - 1] == '\r' || s[n - 1] == '\n')) {
s[n - 1] = '\0';
n--;
}
}
static int network_thread(void* /*data*/) {
NET_Address* server_addr = NET_ResolveHostname("127.0.0.1");
if (!server_addr || (NET_WaitUntilResolved(server_addr, -1) != NET_SUCCESS)) {
if (server_addr) { NET_UnrefAddress(server_addr); }
return 1;
}
NET_Server* server = NET_CreateServer(server_addr, server_port, 0);
if (!server) {
SDL_Log("Failed to create server: %s", SDL_GetError());
return 1;
}
SDL_Log("Port %d!", (int)server_port);
int num_vsockets = 1;
void* vsockets[128];
SDL_zeroa(vsockets);
vsockets[0] = server;
int wait_timeout_ms = quit ? 10 : 50;
while (!quit && NET_WaitUntilInputAvailable(vsockets, num_vsockets, wait_timeout_ms) >= 0) {
NET_StreamSocket* streamsocket = nullptr;
if (NET_AcceptClient(server, &streamsocket)) {
if (!quit && streamsocket) {
SDL_Log("New connection from %s!", NET_GetAddressString(NET_GetStreamSocketAddress(streamsocket)));
if (num_vsockets >= (int)(SDL_arraysize(vsockets) - 1)) {
SDL_Log(" (too many connections, though, so dropping immediately.)");
NET_DestroyStreamSocket(streamsocket);
} else {
vsockets[num_vsockets++] = streamsocket;
}
} else if (streamsocket) {
NET_DestroyStreamSocket(streamsocket);
}
}
for (int i = 1; i < num_vsockets; i++) {
if (quit) break;
bool kill_socket = false;
streamsocket = (NET_StreamSocket*)vsockets[i];
if (!streamsocket) {
continue;
}
char buffer[1024];
const int br = NET_ReadFromStreamSocket(
streamsocket, buffer, (int)sizeof(buffer) - 1
);
if (br < 0) {
kill_socket = true;
} else if (br > 0) {
buffer[br] = '\0';
trim_crlf_inplace(buffer);
if (buffer[0] != '\0') {
if (SDL_snprintf(image, sizeof(image), "%s", buffer) >= 0) {
is_changed = true;
} else {
Debug() << "SDL_snprintf error";
}
}
kill_socket = true;
}
if (kill_socket) {
SDL_Log("Dropping connection to '%s'", NET_GetAddressString(NET_GetStreamSocketAddress(streamsocket)));
NET_DestroyStreamSocket(streamsocket);
vsockets[i] = nullptr;
if (i < (num_vsockets - 1)) {
SDL_memmove(&vsockets[i], &vsockets[i + 1], sizeof(vsockets[0]) * ((num_vsockets - i) - 1));
}
num_vsockets--;
i--;
}
}
}
for (int i = 1; i < num_vsockets; i++) {
if (vsockets[i]) {
NET_DestroyStreamSocket((NET_StreamSocket*)vsockets[i]);
vsockets[i] = nullptr;
}
}
NET_DestroyServer(server);
return 0;
}
int main(int argc, char* argv[]) {
// get game dir path
std::ifstream file(std::filesystem::temp_directory_path() / "sunshine");
if (file.is_open()) {
std::string filePath;
std::getline(file, filePath);
SDL_strlcpy(gamedir_path, filePath.c_str(), sizeof(gamedir_path) - 1);
gamedir_path[sizeof(gamedir_path) - 1] = '\0';
file.close();
} else {
Debug() << "Unable to open file";
}
Debug() << gamedir_path;
for (int i = 1; i < argc; i++) {
const char* arg = argv[i];
if ((SDL_strcmp(arg, "--port") == 0) && (i < (argc - 1))) {
server_port = (Uint16)SDL_atoi(argv[++i]);
}
if ((SDL_strcmp(arg, "--addr") == 0) && (i < (argc - 1))) {
strncpy(address, argv[++i], sizeof(address) - 1);
address[sizeof(address) - 1] = '\0';
}
if ((SDL_strcmp(arg, "--game-path") == 0) && (i < (argc - 1))) {
strncpy(gamedir_path, argv[++i], sizeof(gamedir_path) - 1);
gamedir_path[sizeof(gamedir_path) - 1] = '\0';
}
}
// initialization
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
Debug() << "SDL_Init failed: " << SDL_GetError();
return 1;
}
if (!NET_Init()) {
Debug() << "NET_Init failed: " << SDL_GetError();
SDL_Quit();
return 1;
}
// window / renderer
SDL_Window* win = SDL_CreateWindow("_______", 800, 600, SDL_WINDOW_TRANSPARENT);
if (win == NULL) {
Debug() << "SDL_CreateWindow Error: " << SDL_GetError();
NET_Quit();
SDL_Quit();
return 1;
}
SDL_Renderer* ren = SDL_CreateRenderer(win, NULL);
if (ren == NULL) {
Debug() << "SDL_CreateRenderer Error: " << SDL_GetError();
SDL_DestroyWindow(win);
NET_Quit();
SDL_Quit();
return 1;
}
// default image texture
SDL_Surface* img0 = IMG_Load_IO(SDL_IOFromConstMem(assets_default_png, assets_default_png_len), true);
if (!img0) {
Debug() << "IMG_Load_IO default failed: " << SDL_GetError();
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
NET_Quit();
SDL_Quit();
return 1;
}
SDL_Texture* tex = SDL_CreateTextureFromSurface(ren, img0);
SDL_DestroySurface(img0);
if (tex == NULL) {
Debug() << "SDL_CreateTextureFromSurface Error: " << SDL_GetError();
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
NET_Quit();
SDL_Quit();
return 1;
}
// start network thread
SDL_Thread* network_thread_pointer = SDL_CreateThread(network_thread, "network", NULL);
if (!network_thread_pointer) {
Debug() << "SDL_CreateThread failed";
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
NET_Quit();
SDL_Quit();
return 1;
}
SDL_Event e;
while (!quit) {
while (SDL_PollEvent(&e)) {
if (e.type == SDL_EVENT_QUIT) {
quit = true;
}else if(e.type == SDL_EVENT_WINDOW_DESTROYED){
quit = true;
}
}
if (is_changed) {
char local_image[256];
SDL_strlcpy(local_image, image, sizeof(local_image));
SDL_Texture* new_tex = nullptr;
if (SDL_strcmp(local_image, "default") == 0) {
SDL_Surface* img = IMG_Load_IO(SDL_IOFromConstMem(assets_default_png, assets_default_png_len), true);
if (!img) {
Debug() << "IMG_Load_IO default failed: " << SDL_GetError();
} else {
new_tex = SDL_CreateTextureFromSurface(ren, img);
SDL_DestroySurface(img);
if (!new_tex) {
Debug() << "SDL_CreateTextureFromSurface Error: " << SDL_GetError();
}
}
} else {
if (SDL_snprintf(image_full_path, sizeof(image_full_path), "%s/%s", gamedir_path, local_image) < 0) {
Debug() << "SDL_snprintf error";
} else {
SDL_Surface* img = IMG_Load(image_full_path);
if (!img) {
Debug() << "Image loading Error: " << SDL_GetError();
} else {
new_tex = SDL_CreateTextureFromSurface(ren, img);
SDL_DestroySurface(img);
if (!new_tex) {
Debug() << "SDL_CreateTextureFromSurface Error: " << SDL_GetError();
}
}
}
}
if (new_tex) {
SDL_DestroyTexture(tex);
tex = new_tex;
}
is_changed = false;
}
SDL_RenderClear(ren);
SDL_RenderTexture(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(16);
}
SDL_WaitThread(network_thread_pointer, NULL);
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
NET_Quit();
SDL_Quit();
return 0;
}

View file

@ -55,7 +55,7 @@ module Settings
:debug_picture_names => false,
:debug_lightmap => false,
:SDL_HINT_SHUTDOWN_DBUS_ON_QUIT => false,
:profiler => false,
:profiler => false,
}
reset_controls!
end

View file

@ -94,7 +94,9 @@ void Config::read(int argc, char *argv[]){
PO_DESC(Windows_AllocConsole, bool, false) \
PO_DESC(Modloader.use_default_save_path, bool, false) \
PO_DESC(pancakes, bool, false) \
PO_DESC(SecurityEngine, bool, true)
PO_DESC(SecurityEngine, bool, true) \
PO_DESC(journal_address, std::string, "127.0.0.1") \
PO_DESC(journal_port, int, 23821)
// Not gonna take your shit boost
#define GUARD_ALL( SDL_exp ) try { SDL_exp } catch(...) {}

View file

@ -58,23 +58,23 @@ struct Config{
std::string iconPath;
std::string wallpaperMode;
std::string journal_address;
int journal_port;
struct{
int sourceCount;
} SE;
struct{
std::string ModsDirPath;
bool use_default_save_path;
std::string ModsDirPath;
bool use_default_save_path;
} Modloader;
bool useScriptNames;
std::string customScript;
std::vector<std::string> rtps;
std::vector<std::string> fontSubs;
std::vector<std::string> rubyLoadpaths;
/* Game INI contents */
struct {

View file

@ -26,6 +26,7 @@
#include <sstream>
#include <vector>
#include <ruby.h>
#include <source_location>
#include "meow.h"
#undef vsnprintf
#undef snprintf
@ -38,8 +39,8 @@
class Debug{
public:
Debug(){
buf << std::boolalpha;
explicit Debug(const std::source_location location = std::source_location::current()) : location(location){
buf << std::boolalpha;
}
template<typename T>
@ -65,18 +66,21 @@ public:
}
~Debug(){
std::ostringstream result;
result << "[" << location.line() << ":" << location.function_name() << "] " << buf.str();
#ifdef __ANDROID__
__android_log_write(ANDROID_LOG_DEBUG, "sunshine", buf.str().c_str());
__android_log_write(ANDROID_LOG_DEBUG, "sunshine", result.str().c_str());
#elif __EMSCRIPTEN__
emscripten_console_log(buf.str().c_str());
emscripten_console_log(result.str().c_str());
#else
logs.push_back(buf.str());
std::cout << buf.str() << "\n";
logs.push_back(result.str());
std::cout << result.str() << "\n";
#endif
}
private:
std::stringstream buf;
std::source_location location;
};
#endif // DEBUGWRITER_H

View file

@ -76,6 +76,9 @@ void ModLoader(Config conf, SDL_Window* win){
}
SDL_Thread* render_thread_pointer = SDL_CreateThread(renderer_thread, "ModRenderer", win);
if (!render_thread_pointer) {
//TODO: Error handling
}
std::vector<std::string> mod_list = {};
try {
// 1.check if any zip(mod) file, 2. calculate sha256 hash of zip(mod) files 3.mount mod via PhysFS