mkxp/src/eventthread.h

253 lines
4.3 KiB
C
Raw Normal View History

2013-09-01 14:27:21 +00:00
/*
** eventthread.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 EVENTTHREAD_H
#define EVENTTHREAD_H
#include "config.h"
#include "etc-internal.h"
#include "sdl-util.h"
#include "keybindings.h"
2013-09-01 14:27:21 +00:00
#include <SDL_scancode.h>
#include <SDL_joystick.h>
#include <SDL_mouse.h>
#include <SDL_mutex.h>
2013-09-01 14:27:21 +00:00
#include <string>
2013-09-01 14:27:21 +00:00
#include <stdint.h>
2013-09-01 14:27:21 +00:00
struct RGSSThreadData;
typedef struct ALCdevice_struct ALCdevice;
2013-09-01 14:27:21 +00:00
struct SDL_Window;
class EventThread
{
public:
static uint8_t keyStates[SDL_NUM_SCANCODES];
2013-09-01 14:27:21 +00:00
struct JoyState
{
2014-12-31 15:39:28 +00:00
int axes[256];
uint8_t hats[256];
bool buttons[256];
2013-09-01 14:27:21 +00:00
};
static JoyState joyState;
struct MouseState
{
int x, y;
bool inWindow;
bool buttons[32];
2013-09-01 14:27:21 +00:00
};
static MouseState mouseState;
static bool allocUserEvents();
2013-09-01 14:27:21 +00:00
EventThread();
void process(RGSSThreadData &rtData);
void cleanup();
/* Called from RGSS thread */
2013-09-01 14:27:21 +00:00
void requestFullscreenMode(bool mode);
void requestWindowResize(int width, int height);
void requestShowCursor(bool mode);
2013-09-01 14:27:21 +00:00
void requestTerminate();
bool getFullscreen() const;
bool getShowCursor() const;
2013-09-01 14:27:21 +00:00
void showMessageBox(const char *body, int flags = 0);
/* RGSS thread calls this once per frame */
void notifyFrame();
2013-09-01 14:27:21 +00:00
private:
void resetInputStates();
2013-09-01 14:27:21 +00:00
void setFullscreen(SDL_Window *, bool mode);
void updateCursorState(bool inWindow);
2013-09-01 14:27:21 +00:00
bool fullscreen;
bool showCursor;
AtomicFlag msgBoxDone;
struct
{
uint64_t lastFrame;
uint64_t displayCounter;
bool displaying;
bool immInitFlag;
bool immFiniFlag;
double acc;
uint32_t accDiv;
} fps;
2013-09-01 14:27:21 +00:00
};
2013-10-06 05:11:03 +00:00
/* Used to asynchronously inform the RGSS thread
2013-09-04 10:09:09 +00:00
* about window size changes */
2013-09-01 14:27:21 +00:00
struct WindowSizeNotify
{
SDL_mutex *mutex;
AtomicFlag changed;
int w, h;
2013-09-01 14:27:21 +00:00
WindowSizeNotify()
{
mutex = SDL_CreateMutex();
w = h = 0;
}
~WindowSizeNotify()
{
SDL_DestroyMutex(mutex);
}
/* Done from the sending side */
void notifyChange(int w, int h)
{
SDL_LockMutex(mutex);
this->w = w;
this->h = h;
changed.set();
2013-09-01 14:27:21 +00:00
SDL_UnlockMutex(mutex);
}
/* Done from the receiving side */
bool pollChange(int *w, int *h)
{
if (!changed)
2013-09-01 14:27:21 +00:00
return false;
SDL_LockMutex(mutex);
*w = this->w;
*h = this->h;
changed.clear();
2013-09-01 14:27:21 +00:00
SDL_UnlockMutex(mutex);
return true;
}
};
struct BindingNotify
{
BindingNotify()
{
mut = SDL_CreateMutex();
}
~BindingNotify()
{
SDL_DestroyMutex(mut);
}
bool poll(BDescVec &out) const
{
if (!changed)
return false;
SDL_LockMutex(mut);
out = data;
changed.clear();
SDL_UnlockMutex(mut);
return true;
}
void get(BDescVec &out) const
{
SDL_LockMutex(mut);
out = data;
SDL_UnlockMutex(mut);
}
void post(const BDescVec &d)
{
SDL_LockMutex(mut);
changed.set();
data = d;
SDL_UnlockMutex(mut);
}
private:
SDL_mutex *mut;
BDescVec data;
mutable AtomicFlag changed;
};
2013-09-01 14:27:21 +00:00
struct RGSSThreadData
{
2013-10-06 05:11:03 +00:00
/* Main thread sets this to request RGSS thread to terminate */
AtomicFlag rqTerm;
2013-10-06 05:11:03 +00:00
/* In response, RGSS thread sets this to confirm
2013-09-01 14:27:21 +00:00
* that it received the request and isn't stuck */
AtomicFlag rqTermAck;
/* Set when F12 is pressed */
AtomicFlag rqReset;
/* Set when F12 is released */
AtomicFlag rqResetFinish;
2013-09-01 14:27:21 +00:00
EventThread *ethread;
WindowSizeNotify windowSizeMsg;
BindingNotify bindingUpdateMsg;
2013-09-01 14:27:21 +00:00
const char *argv0;
SDL_Window *window;
ALCdevice *alcDev;
2013-09-01 14:27:21 +00:00
Vec2 sizeResoRatio;
2013-09-23 08:39:16 +00:00
Vec2i screenOffset;
2013-09-01 14:27:21 +00:00
Config config;
std::string rgssErrorMsg;
2013-09-01 14:27:21 +00:00
RGSSThreadData(EventThread *ethread,
2014-01-01 23:17:31 +00:00
const char *argv0,
SDL_Window *window,
ALCdevice *alcDev,
2014-01-01 23:17:31 +00:00
const Config& newconf)
: ethread(ethread),
2013-09-01 14:27:21 +00:00
argv0(argv0),
window(window),
alcDev(alcDev),
sizeResoRatio(1, 1),
config(newconf)
2013-09-01 14:27:21 +00:00
{}
};
#endif // EVENTTHREAD_H