Journal screen stuff

This commit is contained in:
Mathew Velasquez 2016-09-30 19:21:47 -04:00
parent a0c9e2eeff
commit 0dc872bcea
9 changed files with 352 additions and 4 deletions

View file

@ -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();

View 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);
}

View file

@ -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

View file

@ -19,7 +19,6 @@ begin
# Prepare for transition
Graphics.freeze
#$debug = false
$demo = false
$GDC = false
# Make scene object (title screen)

View file

@ -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) \

View file

@ -30,6 +30,7 @@ struct Config
int rgssVersion;
bool debugMode;
bool screenMode;
bool printFPS;
bool fullscreen;

View file

@ -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
View 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
View 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;
}