mkxp-sunshine/binding-mri/screen-binding.cpp

80 lines
2.1 KiB
C++

#include "etc.h"
#include "binding-util.h"
#include "binding-types.h"
#include "debugwriter.h"
#include "config.h"
#include "sharedstate.h"
#include "pipe.h"
static Pipe ipc;
static void start(){
ipc.open("oneshot-pipe", Pipe::Write);
// Create process
#if defined _WIN32
WCHAR path[MAX_PATH];
WCHAR gameFolder[MAX_PATH];
MultiByteToWideChar(CP_UTF8, 0, shState->config().gameFolder.c_str(), -1, gameFolder, MAX_PATH);
GetModuleFileNameW(NULL, path, MAX_PATH);
STARTUPINFOW si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
std::wstring argString = std::wstring(L"oneshot.exe \"--gameFolder=") + gameFolder + L"\" --screenMode=true";
WCHAR *args = new WCHAR[argString.size() + 1];
memcpy(args, argString.c_str(), (argString.size() + 1) * sizeof(WCHAR));
CreateProcessW(path, args, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
delete [] args;
#else
#if defined __linux
char path[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", path, PATH_MAX);
if (len == -1)
rb_raise(rb_eRuntimeError, "Cannot determine path of running executable");
std::string exename = std::string(path, len);
#else
#endif
pid_t pid = fork();
if (pid == 0) {
execl(exename.c_str(), "oneshot",
(std::string("--gameFolder=") + shState->config().gameFolder).c_str(), "--screenMode=true", NULL);
exit(1);
}
#endif
ipc.connect();
}
RB_METHOD(screenStart){
RB_UNUSED_PARAM;
start();
return Qnil;
}
RB_METHOD(screenFinish){
RB_UNUSED_PARAM;
ipc.write("END", sizeof("END"));
ipc.close();
return Qnil;
}
RB_METHOD(screenSet){
RB_UNUSED_PARAM;
const char *imageName;
rb_get_args(argc, argv, "z", &imageName RB_ARG_END);
if (!ipc.isOpen())
start();
ipc.write(imageName, strlen(imageName) + 1);
return Qnil;
}
void screenBindingInit(){
printf("[screenBindingInit] Initializing Screen binding\n");
VALUE module = rb_define_module("Screen");
_rb_define_module_function(module, "start", screenStart);
_rb_define_module_function(module, "finish", screenFinish);
_rb_define_module_function(module, "set", screenSet);
printf("[screenBindingInit] Done\n");
}