mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 13:29:54 +00:00
Journal screen stuff
This commit is contained in:
parent
a0c9e2eeff
commit
0dc872bcea
9 changed files with 352 additions and 4 deletions
|
|
@ -73,6 +73,7 @@ void graphicsBindingInit();
|
|||
|
||||
void fileIntBindingInit();
|
||||
|
||||
void screenBindingInit();
|
||||
void oneshotBindingInit();
|
||||
void steamBindingInit();
|
||||
|
||||
|
|
@ -104,6 +105,7 @@ static void mriBindingInit()
|
|||
graphicsBindingInit();
|
||||
|
||||
fileIntBindingInit();
|
||||
screenBindingInit();
|
||||
oneshotBindingInit();
|
||||
steamBindingInit();
|
||||
|
||||
|
|
|
|||
84
binding-mri/screen-binding.cpp
Normal file
84
binding-mri/screen-binding.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#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
|
||||
#ifdef _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
|
||||
#ifdef 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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
7
mkxp.pro
7
mkxp.pro
|
|
@ -153,7 +153,8 @@ HEADERS += \
|
|||
src/audiostream.h \
|
||||
src/rgssad.h \
|
||||
src/sdl-util.h \
|
||||
src/oneshot.h
|
||||
src/oneshot.h \
|
||||
src/pipe.h
|
||||
|
||||
SOURCES += \
|
||||
src/main.cpp \
|
||||
|
|
@ -194,7 +195,9 @@ SOURCES += \
|
|||
src/vorbissource.cpp \
|
||||
src/oneshot.cpp \
|
||||
binding-mri/steam-binding.cpp \
|
||||
src/xdg-user-dir-lookup.c
|
||||
src/xdg-user-dir-lookup.c \
|
||||
src/screen.cpp \
|
||||
binding-mri/screen-binding.cpp
|
||||
|
||||
STEAM {
|
||||
HEADERS += src/steam.h steamshim/steamshim_child.h
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ begin
|
|||
|
||||
# Prepare for transition
|
||||
Graphics.freeze
|
||||
#$debug = false
|
||||
$demo = false
|
||||
$GDC = false
|
||||
# Make scene object (title screen)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ void Config::read(int argc, char *argv[])
|
|||
{
|
||||
#define PO_DESC_ALL \
|
||||
PO_DESC(debugMode, bool, false) \
|
||||
PO_DESC(screenMode, bool, false) \
|
||||
PO_DESC(printFPS, bool, false) \
|
||||
PO_DESC(fullscreen, bool, false) \
|
||||
PO_DESC(fixedAspectRatio, bool, true) \
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct Config
|
|||
int rgssVersion;
|
||||
|
||||
bool debugMode;
|
||||
bool screenMode;
|
||||
bool printFPS;
|
||||
|
||||
bool fullscreen;
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ int rgssThreadFun(void *userdata)
|
|||
static void showInitError(const std::string &msg)
|
||||
{
|
||||
Debug() << msg;
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "mkxp", msg.c_str(), 0);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OneShot", msg.c_str(), 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -212,6 +212,10 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern int screenMain(Config &conf);
|
||||
if (conf.screenMode)
|
||||
return screenMain(conf);
|
||||
|
||||
int imgFlags = IMG_INIT_PNG;
|
||||
if (IMG_Init(imgFlags) != imgFlags)
|
||||
{
|
||||
|
|
|
|||
148
src/pipe.h
Normal file
148
src/pipe.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#ifndef PIPE_H
|
||||
#define PIPE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
class Pipe
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
Write,
|
||||
Read,
|
||||
} Mode;
|
||||
|
||||
Pipe()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
handle = NULL;
|
||||
#else
|
||||
fd = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Pipe(const char *name_, Mode mode_)
|
||||
{
|
||||
open(name_, mode_);
|
||||
}
|
||||
|
||||
~Pipe()
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (mode == Write)
|
||||
unlink(filename.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void open(const char *name_, Mode mode_)
|
||||
{
|
||||
name = name_;
|
||||
mode = mode_;
|
||||
#ifdef _WIN32
|
||||
filename = std::string("\\\\.\\pipe\\") + name;
|
||||
#else
|
||||
filename = std::string(P_tmpdir) + "/" + name;
|
||||
#endif
|
||||
|
||||
if (mode == Read)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
handle = CreateFileA(
|
||||
filename.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
#else
|
||||
fd = ::open(filename.c_str(), O_RDONLY | O_NONBLOCK);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
handle = CreateNamedPipeA(
|
||||
filename.c_str(),
|
||||
PIPE_ACCESS_OUTBOUND,
|
||||
PIPE_TYPE_BYTE,
|
||||
PIPE_UNLIMITED_INSTANCES,
|
||||
256, 0, 0, NULL);
|
||||
#else
|
||||
mkfifo(filename.c_str(), 0666);
|
||||
fd = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void connect()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ConnectNamedPipe(handle, NULL);
|
||||
#else
|
||||
fd = ::open(filename.c_str(), O_WRONLY);
|
||||
#endif
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CloseHandle(handle);
|
||||
handle = NULL;
|
||||
#else
|
||||
::close(fd);
|
||||
fd = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool read(char *buf)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OVERLAPPED overlapped;
|
||||
memset(&overlapped, 0, sizeof(overlapped));
|
||||
if (!ReadFile(handle, buf, 1, NULL, &overlapped))
|
||||
{
|
||||
if (GetLastError() == ERROR_IO_PENDING)
|
||||
CancelIo(handle);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return ::read(fd, buf, 1) == 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void write(const char *buf, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WriteFile(handle, buf, size, NULL, NULL);
|
||||
#else
|
||||
::write(fd, buf, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isOpen()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return handle != NULL;
|
||||
#else
|
||||
return fd != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::string filename;
|
||||
Mode mode;
|
||||
#ifdef _WIN32
|
||||
HANDLE handle;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // PIPE_H
|
||||
106
src/screen.cpp
Normal file
106
src/screen.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_shape.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
#define FPS 60
|
||||
#define DEFAULT_WIDTH 320
|
||||
#define DEFAULT_HEIGHT 240
|
||||
|
||||
#include "config.h"
|
||||
#include "debugwriter.h"
|
||||
#include "pipe.h"
|
||||
|
||||
static void showInitError(const std::string &msg)
|
||||
{
|
||||
Debug() << msg;
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OneShot", msg.c_str(), 0);
|
||||
}
|
||||
|
||||
static bool readMessage(Pipe &ipc, char *buf, size_t size)
|
||||
{
|
||||
size_t index = 0;
|
||||
while (index < size - 1) {
|
||||
if (ipc.read(buf + index)) {
|
||||
++index;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[index] = 0;
|
||||
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
int screenMain(Config &conf)
|
||||
{
|
||||
const SDL_Color colorKey = {0x00, 0xFF, 0x00, 0xFF};
|
||||
const SDL_Color black = {0x00, 0x00, 0x00, 0xFF};
|
||||
|
||||
Pipe ipc("oneshot-pipe", Pipe::Read);
|
||||
|
||||
int imgFlags = IMG_INIT_PNG;
|
||||
if (IMG_Init(imgFlags) != imgFlags)
|
||||
{
|
||||
showInitError(std::string("Error initializing SDL_image: ") + SDL_GetError());
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Window *win;
|
||||
win = SDL_CreateShapedWindow("The Journal",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT, 0);
|
||||
|
||||
if (!win)
|
||||
{
|
||||
showInitError(std::string("Error creating window: ") + SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_WindowShapeMode shapeMode;
|
||||
shapeMode.mode = ShapeModeColorKey;
|
||||
shapeMode.parameters.colorKey = colorKey;
|
||||
|
||||
SDL_Surface *shape = SDL_CreateRGBSurface(0, DEFAULT_WIDTH, DEFAULT_HEIGHT, 8, 0, 0, 0, 0);
|
||||
SDL_SetPaletteColors(shape->format->palette, &black, 0, 1);
|
||||
|
||||
char messageBuf[256];
|
||||
|
||||
unsigned int ticks = SDL_GetTicks();
|
||||
for (;;) {
|
||||
// Handle events
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Change shape
|
||||
if (readMessage(ipc, messageBuf, sizeof(messageBuf))) {
|
||||
if (strcmp(messageBuf, "END") == 0)
|
||||
break;
|
||||
std::string imgname = conf.gameFolder + "/Journal/" + messageBuf + ".png";
|
||||
SDL_FreeSurface(shape);
|
||||
if ((shape = IMG_Load(imgname.c_str())) == NULL)
|
||||
break;
|
||||
SDL_SetWindowSize(win, shape->w, shape->h);
|
||||
SDL_SetWindowShape(win, shape, &shapeMode);
|
||||
}
|
||||
|
||||
// Redraw
|
||||
SDL_BlitSurface(shape, NULL, SDL_GetWindowSurface(win), NULL);
|
||||
SDL_UpdateWindowSurface(win);
|
||||
|
||||
// Regulate framerate
|
||||
unsigned int ticksDelta = SDL_GetTicks() - ticks;
|
||||
if (ticksDelta < 1000 / FPS)
|
||||
SDL_Delay(1000 / FPS - ticksDelta);
|
||||
ticks = SDL_GetTicks();
|
||||
}
|
||||
|
||||
SDL_FreeSurface(shape);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue