mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-27 08:45:00 +01:00
Move more platform code to UiContext
This commit is contained in:
@@ -86,23 +86,6 @@ typedef struct rct2_time {
|
||||
uint8 second;
|
||||
} rct2_time;
|
||||
|
||||
typedef struct openrct2_cursor {
|
||||
sint32 x, y;
|
||||
uint8 left, middle, right, any;
|
||||
sint32 wheel;
|
||||
sint32 old;
|
||||
bool touch, touchIsDouble;
|
||||
uint32 touchDownTimestamp;
|
||||
} openrct2_cursor;
|
||||
|
||||
enum {
|
||||
CURSOR_UP = 0,
|
||||
CURSOR_DOWN = 1,
|
||||
CURSOR_CHANGED = 2,
|
||||
CURSOR_RELEASED = CURSOR_UP | CURSOR_CHANGED,
|
||||
CURSOR_PRESSED = CURSOR_DOWN | CURSOR_CHANGED,
|
||||
};
|
||||
|
||||
typedef enum {FD_OPEN, FD_SAVE} filedialog_type;
|
||||
|
||||
typedef struct file_dialog_desc {
|
||||
@@ -116,44 +99,18 @@ typedef struct file_dialog_desc {
|
||||
} filters[8];
|
||||
} file_dialog_desc;
|
||||
|
||||
extern openrct2_cursor gCursorState;
|
||||
extern const uint8 *gKeysState;
|
||||
extern uint8 *gKeysPressed;
|
||||
extern uint32 gLastKeyPressed;
|
||||
|
||||
extern textinputbuffer gTextInput;
|
||||
extern bool gTextInputCompositionActive;
|
||||
extern utf8 gTextInputComposition[32];
|
||||
extern sint32 gTextInputCompositionStart;
|
||||
extern sint32 gTextInputCompositionLength;
|
||||
|
||||
extern sint32 gResolutionsAllowAnyAspectRatio;
|
||||
extern sint32 gNumResolutions;
|
||||
extern resolution_t *gResolutions;
|
||||
extern SDL_Window *gWindow;
|
||||
|
||||
extern SDL_Color gPalette[256];
|
||||
|
||||
extern bool gSteamOverlayActive;
|
||||
|
||||
// Platform shared definitions
|
||||
void platform_update_fullscreen_resolutions();
|
||||
void platform_get_closest_resolution(sint32 inWidth, sint32 inHeight, sint32 *outWidth, sint32 *outHeight);
|
||||
void platform_init();
|
||||
void platform_draw();
|
||||
void platform_draw_require_end();
|
||||
void platform_free();
|
||||
void platform_trigger_resize();
|
||||
void platform_update_palette(const uint8 *colours, sint32 start_index, sint32 num_colours);
|
||||
void platform_set_fullscreen_mode(sint32 mode);
|
||||
void platform_toggle_windowed_mode();
|
||||
void platform_set_cursor(uint8 cursor);
|
||||
void platform_refresh_video();
|
||||
void platform_process_messages();
|
||||
sint32 platform_scancode_to_rct_keycode(sint32 sdl_key);
|
||||
void platform_start_text_input(utf8 *buffer, sint32 max_length);
|
||||
void platform_stop_text_input();
|
||||
bool platform_is_input_active();
|
||||
void platform_get_date_utc(rct2_date *out_date);
|
||||
void platform_get_time_utc(rct2_time *out_time);
|
||||
void platform_get_date_local(rct2_date *out_date);
|
||||
@@ -183,11 +140,6 @@ sint32 platform_get_drives();
|
||||
bool platform_file_copy(const utf8 *srcPath, const utf8 *dstPath, bool overwrite);
|
||||
bool platform_file_move(const utf8 *srcPath, const utf8 *dstPath);
|
||||
bool platform_file_delete(const utf8 *path);
|
||||
void platform_hide_cursor();
|
||||
void platform_show_cursor();
|
||||
void platform_get_cursor_position(sint32 *x, sint32 *y);
|
||||
void platform_get_cursor_position_scaled(sint32 *x, sint32 *y);
|
||||
void platform_set_cursor_position(sint32 x, sint32 y);
|
||||
uint32 platform_get_ticks();
|
||||
void platform_sleep(uint32 ms);
|
||||
void platform_resolve_user_data_path();
|
||||
|
||||
@@ -49,21 +49,6 @@
|
||||
|
||||
typedef void(*update_palette_func)(const uint8*, sint32, sint32);
|
||||
|
||||
openrct2_cursor gCursorState;
|
||||
const uint8 *gKeysState;
|
||||
uint8 *gKeysPressed;
|
||||
uint32 gLastKeyPressed;
|
||||
textinputbuffer gTextInput;
|
||||
|
||||
bool gTextInputCompositionActive;
|
||||
utf8 gTextInputComposition[32];
|
||||
sint32 gTextInputCompositionStart;
|
||||
sint32 gTextInputCompositionLength;
|
||||
|
||||
sint32 gNumResolutions = 0;
|
||||
resolution_t *gResolutions = NULL;
|
||||
sint32 gResolutionsAllowAnyAspectRatio = 0;
|
||||
|
||||
SDL_Window *gWindow = NULL;
|
||||
SDL_Renderer *gRenderer = NULL;
|
||||
SDL_Texture *gBufferTexture = NULL;
|
||||
@@ -147,277 +132,6 @@ void platform_update_palette(const uint8* colours, sint32 start_index, sint32 nu
|
||||
}
|
||||
}
|
||||
|
||||
void platform_process_messages()
|
||||
{
|
||||
SDL_Event e;
|
||||
|
||||
gLastKeyPressed = 0;
|
||||
// gCursorState.wheel = 0;
|
||||
gCursorState.left &= ~CURSOR_CHANGED;
|
||||
gCursorState.middle &= ~CURSOR_CHANGED;
|
||||
gCursorState.right &= ~CURSOR_CHANGED;
|
||||
gCursorState.old = 0;
|
||||
gCursorState.touch = false;
|
||||
|
||||
while (SDL_PollEvent(&e)) {
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
// rct2_finish();
|
||||
rct2_quit();
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
// HACK: Fix #2158, OpenRCT2 does not draw if it does not think that the window is
|
||||
// visible - due a bug in SDL2.0.3 this hack is required if the
|
||||
// window is maximised, minimised and then restored again.
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||
if (SDL_GetWindowFlags(gWindow) & SDL_WINDOW_MAXIMIZED) {
|
||||
SDL_RestoreWindow(gWindow);
|
||||
SDL_MaximizeWindow(gWindow);
|
||||
}
|
||||
if ((SDL_GetWindowFlags(gWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
SDL_RestoreWindow(gWindow);
|
||||
SDL_SetWindowFullscreen(gWindow, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||
platform_resize(e.window.data1, e.window.data2);
|
||||
if (gConfigSound.audio_focus && gConfigSound.sound_enabled) {
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
|
||||
Mixer_SetVolume(1);
|
||||
}
|
||||
if (e.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||
Mixer_SetVolume(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
gCursorState.x = (sint32)(e.motion.x / gConfigGeneral.window_scale);
|
||||
gCursorState.y = (sint32)(e.motion.y / gConfigGeneral.window_scale);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (gConsoleOpen) {
|
||||
console_scroll(e.wheel.y);
|
||||
break;
|
||||
}
|
||||
gCursorState.wheel += e.wheel.y * 128;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
sint32 x = (sint32)(e.button.x / gConfigGeneral.window_scale);
|
||||
sint32 y = (sint32)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
gCursorState.left = CURSOR_PRESSED;
|
||||
gCursorState.old = 1;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
gCursorState.middle = CURSOR_PRESSED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
gCursorState.right = CURSOR_PRESSED;
|
||||
gCursorState.old = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
sint32 x = (sint32)(e.button.x / gConfigGeneral.window_scale);
|
||||
sint32 y = (sint32)(e.button.y / gConfigGeneral.window_scale);
|
||||
switch (e.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
gCursorState.left = CURSOR_RELEASED;
|
||||
gCursorState.old = 3;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
gCursorState.middle = CURSOR_RELEASED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
gCursorState.right = CURSOR_RELEASED;
|
||||
gCursorState.old = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Apple sends touchscreen events for trackpads, so ignore these events on macOS
|
||||
#ifndef __MACOSX__
|
||||
case SDL_FINGERMOTION:
|
||||
gCursorState.x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
gCursorState.y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
sint32 x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
sint32 y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
|
||||
gCursorState.touchIsDouble = (!gCursorState.touchIsDouble
|
||||
&& e.tfinger.timestamp - gCursorState.touchDownTimestamp < TOUCH_DOUBLE_TIMEOUT);
|
||||
|
||||
if (gCursorState.touchIsDouble) {
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
gCursorState.right = CURSOR_PRESSED;
|
||||
gCursorState.old = 2;
|
||||
} else {
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
gCursorState.left = CURSOR_PRESSED;
|
||||
gCursorState.old = 1;
|
||||
}
|
||||
gCursorState.touch = true;
|
||||
gCursorState.touchDownTimestamp = e.tfinger.timestamp;
|
||||
break;
|
||||
}
|
||||
case SDL_FINGERUP:
|
||||
{
|
||||
sint32 x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
sint32 y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
|
||||
if (gCursorState.touchIsDouble) {
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
gCursorState.left = CURSOR_RELEASED;
|
||||
gCursorState.old = 4;
|
||||
} else {
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
gCursorState.left = CURSOR_RELEASED;
|
||||
gCursorState.old = 3;
|
||||
}
|
||||
gCursorState.touch = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SDL_KEYDOWN:
|
||||
if (gTextInputCompositionActive) break;
|
||||
|
||||
if (e.key.keysym.sym == SDLK_KP_ENTER){
|
||||
// Map Keypad enter to regular enter.
|
||||
e.key.keysym.scancode = SDL_SCANCODE_RETURN;
|
||||
}
|
||||
|
||||
gLastKeyPressed = e.key.keysym.sym;
|
||||
gKeysPressed[e.key.keysym.scancode] = 1;
|
||||
|
||||
// Text input
|
||||
if (gTextInput.buffer == NULL) break;
|
||||
|
||||
// Clear the input on <CTRL>Backspace (Windows/Linux) or <MOD>Backspace (macOS)
|
||||
if (e.key.keysym.sym == SDLK_BACKSPACE && (e.key.keysym.mod & KEYBOARD_PRIMARY_MODIFIER)) {
|
||||
textinputbuffer_clear(&gTextInput);
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
|
||||
// If backspace and we have input text with a cursor position none zero
|
||||
if (e.key.keysym.sym == SDLK_BACKSPACE) {
|
||||
if (gTextInput.selection_offset > 0) {
|
||||
size_t endOffset = gTextInput.selection_offset;
|
||||
textinputbuffer_cursor_left(&gTextInput);
|
||||
gTextInput.selection_size = endOffset - gTextInput.selection_offset;
|
||||
textinputbuffer_remove_selected(&gTextInput);
|
||||
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_HOME) {
|
||||
textinputbuffer_cursor_home(&gTextInput);
|
||||
console_refresh_caret();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_END) {
|
||||
textinputbuffer_cursor_end(&gTextInput);
|
||||
console_refresh_caret();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_DELETE) {
|
||||
size_t startOffset = gTextInput.selection_offset;
|
||||
textinputbuffer_cursor_right(&gTextInput);
|
||||
gTextInput.selection_size = gTextInput.selection_offset - startOffset;
|
||||
gTextInput.selection_offset = startOffset;
|
||||
textinputbuffer_remove_selected(&gTextInput);
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_RETURN) {
|
||||
window_cancel_textbox();
|
||||
}
|
||||
if (e.key.keysym.sym == SDLK_LEFT) {
|
||||
textinputbuffer_cursor_left(&gTextInput);
|
||||
console_refresh_caret();
|
||||
}
|
||||
else if (e.key.keysym.sym == SDLK_RIGHT) {
|
||||
textinputbuffer_cursor_right(&gTextInput);
|
||||
console_refresh_caret();
|
||||
}
|
||||
else if (e.key.keysym.sym == SDLK_v && (SDL_GetModState() & KEYBOARD_PRIMARY_MODIFIER)) {
|
||||
if (SDL_HasClipboardText()) {
|
||||
utf8* text = SDL_GetClipboardText();
|
||||
|
||||
utf8_remove_formatting(text, false);
|
||||
textinputbuffer_insert(&gTextInput, text);
|
||||
|
||||
SDL_free(text);
|
||||
|
||||
window_update_textbox();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_MULTIGESTURE:
|
||||
if (e.mgesture.numFingers == 2) {
|
||||
if (e.mgesture.timestamp > _lastGestureTimestamp + 1000)
|
||||
_gestureRadius = 0;
|
||||
_lastGestureTimestamp = e.mgesture.timestamp;
|
||||
_gestureRadius += e.mgesture.dDist;
|
||||
|
||||
// Zoom gesture
|
||||
const sint32 tolerance = 128;
|
||||
sint32 gesturePixels = (sint32)(_gestureRadius * gScreenWidth);
|
||||
if (abs(gesturePixels) > tolerance) {
|
||||
_gestureRadius = 0;
|
||||
main_window_zoom(gesturePixels > 0, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
// When inputting Korean characters, `e.edit.length` is always Zero.
|
||||
safe_strcpy(gTextInputComposition, e.edit.text, sizeof(gTextInputComposition));
|
||||
gTextInputCompositionStart = e.edit.start;
|
||||
gTextInputCompositionLength = e.edit.length;
|
||||
gTextInputCompositionActive = ((e.edit.length != 0 || strlen(e.edit.text) != 0) && gTextInputComposition[0] != 0);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
// will receive an `SDL_TEXTINPUT` event when a composition is committed.
|
||||
// so, set gTextInputCompositionActive to false.
|
||||
gTextInputCompositionActive = false;
|
||||
|
||||
if (gTextInput.buffer == NULL) break;
|
||||
|
||||
// HACK ` will close console, so don't input any text
|
||||
if (e.text.text[0] == '`' && gConsoleOpen) {
|
||||
break;
|
||||
}
|
||||
|
||||
utf8* newText = e.text.text;
|
||||
|
||||
utf8_remove_formatting(newText, false);
|
||||
textinputbuffer_insert(&gTextInput, newText);
|
||||
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gCursorState.any = gCursorState.left | gCursorState.middle | gCursorState.right;
|
||||
|
||||
// Updates the state of the keys
|
||||
sint32 numKeys = 256;
|
||||
gKeysState = SDL_GetKeyboardState(&numKeys);
|
||||
}
|
||||
|
||||
void platform_init()
|
||||
{
|
||||
gKeysPressed = malloc(sizeof(uint8) * 256);
|
||||
@@ -450,56 +164,6 @@ void platform_free()
|
||||
free(gKeysPressed);
|
||||
}
|
||||
|
||||
void platform_start_text_input(utf8* buffer, sint32 max_length)
|
||||
{
|
||||
// TODO This doesn't work, and position could be improved to where text entry is
|
||||
SDL_Rect rect = { 10, 10, 100, 100 };
|
||||
SDL_SetTextInputRect(&rect);
|
||||
|
||||
SDL_StartTextInput();
|
||||
|
||||
textinputbuffer_init(&gTextInput, buffer, max_length);
|
||||
}
|
||||
|
||||
bool platform_is_input_active()
|
||||
{
|
||||
return SDL_IsTextInputActive() && gTextInput.buffer != NULL;
|
||||
}
|
||||
|
||||
void platform_stop_text_input()
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
gTextInput.buffer = NULL;
|
||||
gTextInputCompositionActive = false;
|
||||
}
|
||||
|
||||
void platform_set_fullscreen_mode(sint32 mode)
|
||||
{
|
||||
sint32 width, height;
|
||||
|
||||
mode = _fullscreen_modes[mode];
|
||||
|
||||
// HACK Changing window size when in fullscreen usually has no effect
|
||||
if (mode == SDL_WINDOW_FULLSCREEN)
|
||||
SDL_SetWindowFullscreen(gWindow, 0);
|
||||
|
||||
// Set window size
|
||||
if (mode == SDL_WINDOW_FULLSCREEN) {
|
||||
platform_update_fullscreen_resolutions();
|
||||
platform_get_closest_resolution(gConfigGeneral.fullscreen_width, gConfigGeneral.fullscreen_height, &width, &height);
|
||||
SDL_SetWindowSize(gWindow, width, height);
|
||||
} else if (mode == 0) {
|
||||
SDL_SetWindowSize(gWindow, gConfigGeneral.window_width, gConfigGeneral.window_height);
|
||||
}
|
||||
|
||||
if (SDL_SetWindowFullscreen(gWindow, mode)) {
|
||||
log_fatal("SDL_SetWindowFullscreen %s", SDL_GetError());
|
||||
exit(1);
|
||||
|
||||
// TODO try another display mode rather than just exiting the game
|
||||
}
|
||||
}
|
||||
|
||||
void platform_toggle_windowed_mode()
|
||||
{
|
||||
sint32 targetMode = gConfigGeneral.fullscreen_mode == 0 ? 2 : 0;
|
||||
@@ -519,35 +183,6 @@ void platform_refresh_video()
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
void platform_hide_cursor()
|
||||
{
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
void platform_show_cursor()
|
||||
{
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
|
||||
void platform_get_cursor_position(sint32 *x, sint32 *y)
|
||||
{
|
||||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
||||
void platform_get_cursor_position_scaled(sint32 *x, sint32 *y)
|
||||
{
|
||||
platform_get_cursor_position(x, y);
|
||||
|
||||
// Compensate for window scaling.
|
||||
*x = (sint32) ceilf(*x / gConfigGeneral.window_scale);
|
||||
*y = (sint32) ceilf(*y / gConfigGeneral.window_scale);
|
||||
}
|
||||
|
||||
void platform_set_cursor_position(sint32 x, sint32 y)
|
||||
{
|
||||
SDL_WarpMouseInWindow(NULL, x, y);
|
||||
}
|
||||
|
||||
uint32 platform_get_ticks()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
Reference in New Issue
Block a user