mirror of https://github.com/OpenRCT2/OpenRCT2.git
Move more platform code to UiContext
This commit is contained in:
parent
5885cb646f
commit
f736e8ff96
|
@ -0,0 +1,300 @@
|
|||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include <SDL.h>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
#include <openrct2/core/String.hpp>
|
||||
#include <openrct2/localisation/localisation.h>
|
||||
#include "TextComposition.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <openrct2/interface/console.h>
|
||||
#include <openrct2/interface/window.h>
|
||||
}
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
bool TextComposition::IsActive()
|
||||
{
|
||||
return SDL_IsTextInputActive() && _session.Buffer != nullptr;
|
||||
}
|
||||
|
||||
const TextInputSession * TextComposition::Start(utf8 * buffer, size_t bufferSize)
|
||||
{
|
||||
Guard::ArgumentNotNull(buffer);
|
||||
|
||||
// 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();
|
||||
|
||||
_session.Buffer = buffer;
|
||||
_session.BufferSize = bufferSize - 1;
|
||||
_session.Size = strlen(buffer);
|
||||
_session.SelectionStart = _session.Size;
|
||||
_session.SelectionSize = 0;
|
||||
RecalculateLength();
|
||||
return &_session;
|
||||
}
|
||||
|
||||
void TextComposition::Stop()
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
_session.Buffer = nullptr;
|
||||
_imeActive = false;
|
||||
}
|
||||
|
||||
void TextComposition::HandleMessage(const SDL_Event * e)
|
||||
{
|
||||
switch (e->type) {
|
||||
case SDL_TEXTEDITING:
|
||||
// When inputting Korean characters, `edit.length` is always zero
|
||||
String::Set(_imeBuffer, sizeof(_imeBuffer), e->edit.text);
|
||||
_imeStart = e->edit.start;
|
||||
_imeLength = e->edit.length;
|
||||
_imeActive = ((e->edit.length != 0 || String::SizeOf(e->edit.text) != 0) && _imeBuffer[0] != '\0');
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
// will receive an `SDL_TEXTINPUT` event when a composition is committed
|
||||
_imeActive = false;
|
||||
if (_session.Buffer != nullptr)
|
||||
{
|
||||
// HACK ` will close console, so don't input any text
|
||||
if (e->text.text[0] == '`' && gConsoleOpen) {
|
||||
break;
|
||||
}
|
||||
|
||||
utf8 * newText = String::Duplicate(e->text.text);
|
||||
utf8_remove_formatting(newText, false);
|
||||
Insert(newText);
|
||||
Memory::Free(newText);
|
||||
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
if (_imeActive)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
uint16 modifier = e->key.keysym.mod;
|
||||
SDL_Keycode key = e->key.keysym.sym;
|
||||
if (key == SDLK_KP_ENTER)
|
||||
{
|
||||
// Map Keypad enter to regular enter.
|
||||
key = SDLK_RETURN;
|
||||
}
|
||||
|
||||
// _lastKeyPressed = e.key.keysym.sym;
|
||||
// _keysPressed[e.key.keysym.scancode] = 1;
|
||||
|
||||
// Text input
|
||||
if (_session.Buffer == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the input on <CTRL>Backspace (Windows/Linux) or <MOD>Backspace (macOS)
|
||||
if (key == SDLK_BACKSPACE && (modifier & KEYBOARD_PRIMARY_MODIFIER))
|
||||
{
|
||||
Clear();
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case SDLK_BACKSPACE:
|
||||
// If backspace and we have input text with a cursor position none zero
|
||||
if (_session.SelectionStart > 0)
|
||||
{
|
||||
size_t endOffset = _session.SelectionStart;
|
||||
CursorLeft();
|
||||
_session.SelectionSize = endOffset - _session.SelectionStart;
|
||||
Delete();
|
||||
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
case SDLK_HOME:
|
||||
CursorHome();
|
||||
console_refresh_caret();
|
||||
break;
|
||||
case SDLK_END:
|
||||
CursorEnd();
|
||||
console_refresh_caret();
|
||||
break;
|
||||
case SDLK_DELETE:
|
||||
{
|
||||
size_t startOffset = _session.SelectionStart;
|
||||
CursorRight();
|
||||
_session.SelectionSize = _session.SelectionStart - startOffset;
|
||||
_session.SelectionStart = startOffset;
|
||||
Delete();
|
||||
console_refresh_caret();
|
||||
window_update_textbox();
|
||||
break;
|
||||
}
|
||||
case SDLK_RETURN:
|
||||
window_cancel_textbox();
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
CursorLeft();
|
||||
console_refresh_caret();
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
CursorRight();
|
||||
console_refresh_caret();
|
||||
break;
|
||||
case SDLK_v:
|
||||
if ((modifier & KEYBOARD_PRIMARY_MODIFIER) && SDL_HasClipboardText())
|
||||
{
|
||||
utf8 * text = SDL_GetClipboardText();
|
||||
utf8_remove_formatting(text, false);
|
||||
Insert(text);
|
||||
SDL_free(text);
|
||||
window_update_textbox();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::CursorHome()
|
||||
{
|
||||
_session.SelectionStart = 0;
|
||||
}
|
||||
|
||||
void TextComposition::CursorEnd()
|
||||
{
|
||||
_session.SelectionStart = _session.SelectionSize;
|
||||
}
|
||||
|
||||
void TextComposition::CursorLeft()
|
||||
{
|
||||
size_t selectionOffset = _session.SelectionStart;
|
||||
if (selectionOffset > 0)
|
||||
{
|
||||
const utf8 * ch = _session.Buffer + selectionOffset;
|
||||
do
|
||||
{
|
||||
ch--;
|
||||
selectionOffset--;
|
||||
}
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset > 0);
|
||||
|
||||
_session.SelectionStart = selectionOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::CursorRight()
|
||||
{
|
||||
size_t selectionOffset = _session.SelectionStart;
|
||||
size_t selectionMaxOffset = _session.Size;
|
||||
if (selectionOffset < selectionMaxOffset)
|
||||
{
|
||||
const utf8 * ch = _session.Buffer + _session.SelectionStart;
|
||||
do
|
||||
{
|
||||
ch++;
|
||||
selectionOffset++;
|
||||
}
|
||||
while (!utf8_is_codepoint_start(ch) && selectionOffset < selectionMaxOffset);
|
||||
|
||||
_session.SelectionSize = Math::Max<size_t>(0, _session.SelectionSize - (selectionOffset - _session.SelectionStart));
|
||||
_session.SelectionStart = selectionOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::Insert(const utf8 * text)
|
||||
{
|
||||
const utf8 * ch = text;
|
||||
uint32 codepoint;
|
||||
while ((codepoint = utf8_get_next(ch, &ch)) != 0)
|
||||
{
|
||||
InsertCodepoint(codepoint);
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::InsertCodepoint(codepoint_t codepoint)
|
||||
{
|
||||
size_t codepointLength = utf8_get_codepoint_length(codepoint);
|
||||
size_t remainingSize = _session.BufferSize - _session.Size;
|
||||
if (codepointLength <= remainingSize)
|
||||
{
|
||||
utf8 * buffer = (utf8 *)_session.Buffer;
|
||||
utf8 * insertPtr = buffer + _session.SelectionStart;
|
||||
if (_session.SelectionStart < _session.Size)
|
||||
{
|
||||
// Shift bytes (including null terminator) right to make room for new codepoint
|
||||
utf8 * targetShiftPtr = insertPtr + codepointLength;
|
||||
size_t shiftSize = _session.Size - _session.SelectionStart + 1;
|
||||
memmove(targetShiftPtr, insertPtr, shiftSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Character is appended onto the end, so set byte after it to null terminator
|
||||
buffer[_session.Size + codepointLength] = 0;
|
||||
}
|
||||
|
||||
utf8_write_codepoint(insertPtr, codepoint);
|
||||
_session.SelectionStart += codepointLength;
|
||||
_session.Size += codepointLength;
|
||||
_session.Length++;
|
||||
}
|
||||
}
|
||||
|
||||
void TextComposition::Clear()
|
||||
{
|
||||
utf8 * buffer = (utf8 *)_session.Buffer;
|
||||
buffer[0] = 0;
|
||||
_session.Size = 0;
|
||||
_session.Length = 0;
|
||||
_session.SelectionStart = 0;
|
||||
_session.SelectionSize = 0;
|
||||
}
|
||||
|
||||
void TextComposition::Delete()
|
||||
{
|
||||
utf8 * buffer = (utf8 *)_session.Buffer;
|
||||
utf8 * targetShiftPtr = buffer + _session.SelectionStart;
|
||||
utf8 * sourceShiftPtr = targetShiftPtr + _session.SelectionSize;
|
||||
size_t shiftSize = _session.SelectionSize - _session.SelectionStart - _session.SelectionSize + 1;
|
||||
memmove(targetShiftPtr, sourceShiftPtr, shiftSize);
|
||||
_session.SelectionSize = 0;
|
||||
RecalculateLength();
|
||||
}
|
||||
|
||||
void TextComposition::RecalculateLength()
|
||||
{
|
||||
_session.Size = String::SizeOf(_session.Buffer);
|
||||
_session.Length = String::LengthOf(_session.Buffer);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
|
||||
union SDL_Event;
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
namespace Ui
|
||||
{
|
||||
/**
|
||||
* Represents a
|
||||
*/
|
||||
class TextComposition
|
||||
{
|
||||
private:
|
||||
TextInputSession _session = { 0 };
|
||||
|
||||
bool _imeActive = false;
|
||||
sint32 _imeStart = 0;
|
||||
sint32 _imeLength = 0;
|
||||
utf8 _imeBuffer[32] = { 0 };
|
||||
|
||||
public:
|
||||
bool IsActive();
|
||||
const TextInputSession * TextComposition::Start(utf8 * buffer, size_t bufferSize);
|
||||
void Stop();
|
||||
void HandleMessage(const SDL_Event * e);
|
||||
|
||||
private:
|
||||
void CursorHome();
|
||||
void CursorEnd();
|
||||
void CursorLeft();
|
||||
void CursorRight();
|
||||
void Insert(const utf8 * text);
|
||||
void InsertCodepoint(codepoint_t codepoint);
|
||||
void Clear();
|
||||
void Delete();
|
||||
void RecalculateLength();
|
||||
};
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
#include <openrct2/audio/AudioMixer.h>
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/drawing/IDrawingEngine.h>
|
||||
|
@ -26,15 +27,31 @@
|
|||
#include <openrct2/Version.h>
|
||||
#include "CursorRepository.h"
|
||||
#include "drawing/engines/DrawingEngines.h"
|
||||
#include "TextComposition.h"
|
||||
#include "UiContext.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <openrct2/interface/console.h>
|
||||
#include <openrct2/input.h>
|
||||
}
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// macOS uses COMMAND rather than CTRL for many keyboard shortcuts
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI
|
||||
#else
|
||||
#define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL
|
||||
#endif
|
||||
|
||||
class UiContext : public IUiContext
|
||||
{
|
||||
private:
|
||||
constexpr static uint32 TOUCH_DOUBLE_TIMEOUT = 300;
|
||||
|
||||
IPlatformUiContext * const _platformUiContext;
|
||||
|
||||
CursorRepository _cursorRepository;
|
||||
|
@ -48,6 +65,15 @@ private:
|
|||
|
||||
bool _steamOverlayActive = false;
|
||||
|
||||
// Input
|
||||
TextComposition _textComposition;
|
||||
CursorState _cursorState;
|
||||
uint32 _lastKeyPressed;
|
||||
const uint8 * _keysState;
|
||||
uint8 * _keysPressed;
|
||||
uint32 _lastGestureTimestamp;
|
||||
float _gestureRadius;
|
||||
|
||||
public:
|
||||
UiContext(IPlatformUiContext * platformUiContext)
|
||||
: _platformUiContext(platformUiContext)
|
||||
|
@ -60,16 +86,6 @@ public:
|
|||
}
|
||||
|
||||
// Window
|
||||
CURSOR_ID GetCursor() override
|
||||
{
|
||||
return _cursorRepository.GetCurrentCursor();
|
||||
}
|
||||
|
||||
void SetCursor(CURSOR_ID cursor) override
|
||||
{
|
||||
_cursorRepository.SetCurrentCursor(cursor);
|
||||
}
|
||||
|
||||
void * GetWindow() override
|
||||
{
|
||||
return _window;
|
||||
|
@ -122,6 +138,52 @@ public:
|
|||
return _fsResolutions;
|
||||
}
|
||||
|
||||
bool IsSteamOverlayActive() override
|
||||
{
|
||||
return _steamOverlayActive;
|
||||
}
|
||||
|
||||
// Input
|
||||
const CursorState * GetCursorState() override
|
||||
{
|
||||
return &_cursorState;
|
||||
}
|
||||
|
||||
const uint8 * GetKeysState() override
|
||||
{
|
||||
return _keysState;
|
||||
}
|
||||
|
||||
const uint8 * GetKeysPressed() override
|
||||
{
|
||||
return _keysPressed;
|
||||
}
|
||||
|
||||
CURSOR_ID GetCursor() override
|
||||
{
|
||||
return _cursorRepository.GetCurrentCursor();
|
||||
}
|
||||
|
||||
void SetCursor(CURSOR_ID cursor) override
|
||||
{
|
||||
_cursorRepository.SetCurrentCursor(cursor);
|
||||
}
|
||||
|
||||
void SetCursorVisible(bool value) override
|
||||
{
|
||||
SDL_ShowCursor(value ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
|
||||
void GetCursorPosition(sint32 * x, sint32 * y) override
|
||||
{
|
||||
SDL_GetMouseState(x, y);
|
||||
}
|
||||
|
||||
void SetCursorPosition(sint32 x, sint32 y) override
|
||||
{
|
||||
SDL_WarpMouseInWindow(nullptr, x, y);
|
||||
}
|
||||
|
||||
// Drawing
|
||||
IDrawingEngine * CreateDrawingEngine(DRAWING_ENGINE_TYPE type) override
|
||||
{
|
||||
|
@ -140,9 +202,215 @@ public:
|
|||
}
|
||||
|
||||
// Text input
|
||||
bool IsTextInputActive() override { return false; }
|
||||
const TextInputSession * StartTextInput(utf8 * buffer, sint32 bufferSize) override { return nullptr; }
|
||||
void StopTextInput() override { }
|
||||
bool IsTextInputActive() override
|
||||
{
|
||||
return _textComposition.IsActive();
|
||||
}
|
||||
|
||||
const TextInputSession * StartTextInput(utf8 * buffer, size_t bufferSize) override
|
||||
{
|
||||
return _textComposition.Start(buffer, bufferSize);
|
||||
}
|
||||
|
||||
void StopTextInput() override
|
||||
{
|
||||
_textComposition.Stop();
|
||||
}
|
||||
|
||||
void ProcessMessages()
|
||||
{
|
||||
_lastKeyPressed = 0;
|
||||
_cursorState.left &= ~CURSOR_CHANGED;
|
||||
_cursorState.middle &= ~CURSOR_CHANGED;
|
||||
_cursorState.right &= ~CURSOR_CHANGED;
|
||||
_cursorState.old = 0;
|
||||
_cursorState.touch = false;
|
||||
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e))
|
||||
{
|
||||
switch (e.type) {
|
||||
case SDL_QUIT:
|
||||
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 SDL 2.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(_window) & SDL_WINDOW_MAXIMIZED)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_MaximizeWindow(_window);
|
||||
}
|
||||
if ((SDL_GetWindowFlags(_window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
SDL_RestoreWindow(_window);
|
||||
SDL_SetWindowFullscreen(_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
||||
{
|
||||
OnResize(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:
|
||||
_cursorState.x = (sint32)(e.motion.x / gConfigGeneral.window_scale);
|
||||
_cursorState.y = (sint32)(e.motion.y / gConfigGeneral.window_scale);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (gConsoleOpen)
|
||||
{
|
||||
console_scroll(e.wheel.y);
|
||||
break;
|
||||
}
|
||||
_cursorState.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);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_PRESSED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.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);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
_cursorState.middle = CURSOR_RELEASED;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.right = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Apple sends touchscreen events for trackpads, so ignore these events on macOS
|
||||
#ifndef __MACOSX__
|
||||
case SDL_FINGERMOTION:
|
||||
_cursorState.x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
_cursorState.y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
break;
|
||||
case SDL_FINGERDOWN:
|
||||
{
|
||||
sint32 x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
sint32 y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
|
||||
_cursorState.touchIsDouble = (!_cursorState.touchIsDouble &&
|
||||
e.tfinger.timestamp - _cursorState.touchDownTimestamp < TOUCH_DOUBLE_TIMEOUT);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_PRESS, x, y);
|
||||
_cursorState.right = CURSOR_PRESSED;
|
||||
_cursorState.old = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_LEFT_PRESS, x, y);
|
||||
_cursorState.left = CURSOR_PRESSED;
|
||||
_cursorState.old = 1;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
_cursorState.touchDownTimestamp = e.tfinger.timestamp;
|
||||
break;
|
||||
}
|
||||
case SDL_FINGERUP:
|
||||
{
|
||||
sint32 x = (sint32)(e.tfinger.x * gScreenWidth);
|
||||
sint32 y = (sint32)(e.tfinger.y * gScreenHeight);
|
||||
|
||||
if (_cursorState.touchIsDouble)
|
||||
{
|
||||
store_mouse_input(MOUSE_STATE_RIGHT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 4;
|
||||
}
|
||||
else {
|
||||
store_mouse_input(MOUSE_STATE_LEFT_RELEASE, x, y);
|
||||
_cursorState.left = CURSOR_RELEASED;
|
||||
_cursorState.old = 3;
|
||||
}
|
||||
_cursorState.touch = true;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SDL_KEYDOWN:
|
||||
_textComposition.HandleMessage(&e);
|
||||
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
|
||||
constexpr sint32 tolerance = 128;
|
||||
sint32 gesturePixels = (sint32)(_gestureRadius * gScreenWidth);
|
||||
if (abs(gesturePixels) > tolerance)
|
||||
{
|
||||
_gestureRadius = 0;
|
||||
main_window_zoom(gesturePixels > 0, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_TEXTEDITING:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
_textComposition.HandleMessage(&e);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_cursorState.any = _cursorState.left | _cursorState.middle | _cursorState.right;
|
||||
|
||||
// Updates the state of the keys
|
||||
sint32 numKeys = 256;
|
||||
_keysState = SDL_GetKeyboardState(&numKeys);
|
||||
}
|
||||
|
||||
private:
|
||||
void CreateWindow()
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#pragma endregion
|
||||
|
||||
#include <openrct2/config/Config.h>
|
||||
#include <openrct2/Context.h>
|
||||
#include <openrct2/ui/UiContext.h>
|
||||
#include <openrct2/core/Guard.hpp>
|
||||
#include <openrct2/core/Math.hpp>
|
||||
#include <openrct2/core/Memory.hpp>
|
||||
|
@ -37,6 +39,7 @@ extern "C"
|
|||
#include <openrct2/drawing/lightfx.h>
|
||||
}
|
||||
|
||||
using namespace OpenRCT2;
|
||||
using namespace OpenRCT2::Drawing;
|
||||
|
||||
class SoftwareDrawingEngine;
|
||||
|
@ -730,14 +733,15 @@ private:
|
|||
}
|
||||
SDL_RenderCopy(_sdlRenderer, _screenTexture, nullptr, nullptr);
|
||||
|
||||
if (gSteamOverlayActive && gConfigGeneral.steam_overlay_pause)
|
||||
bool isSteamOverlayActive = GetContext()->GetUiContext()->IsSteamOverlayActive();
|
||||
if (isSteamOverlayActive && gConfigGeneral.steam_overlay_pause)
|
||||
{
|
||||
OverlayPreRenderCheck();
|
||||
}
|
||||
|
||||
SDL_RenderPresent(_sdlRenderer);
|
||||
|
||||
if (gSteamOverlayActive && gConfigGeneral.steam_overlay_pause)
|
||||
if (isSteamOverlayActive && gConfigGeneral.steam_overlay_pause)
|
||||
{
|
||||
OverlayPostRenderCheck();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<ClCompile Include="drawing\engines\opengl\SwapFramebuffer.cpp" />
|
||||
<ClCompile Include="drawing\engines\opengl\TextureCache.cpp" />
|
||||
<ClCompile Include="drawing\engines\SoftwareDrawingEngine.cpp" />
|
||||
<ClCompile Include="TextComposition.cpp" />
|
||||
<ClCompile Include="Ui.cpp" />
|
||||
<ClCompile Include="UiContext.cpp" />
|
||||
<ClCompile Include="UiContext.Win32.cpp" />
|
||||
|
@ -53,6 +54,7 @@
|
|||
<ClInclude Include="drawing\engines\opengl\OpenGLShaderProgram.h" />
|
||||
<ClInclude Include="drawing\engines\opengl\SwapFramebuffer.h" />
|
||||
<ClInclude Include="drawing\engines\opengl\TextureCache.h" />
|
||||
<ClInclude Include="TextComposition.h" />
|
||||
<ClInclude Include="UiContext.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#pragma endregion
|
||||
|
||||
#include <exception>
|
||||
#include "config/Config.h"
|
||||
#include "Context.h"
|
||||
#include "OpenRCT2.h"
|
||||
#include "ui/UiContext.h"
|
||||
|
@ -88,4 +89,63 @@ extern "C"
|
|||
{
|
||||
GetContext()->GetUiContext()->SetCursor((CURSOR_ID)cursor);
|
||||
}
|
||||
|
||||
void context_hide_cursor()
|
||||
{
|
||||
GetContext()->GetUiContext()->SetCursorVisible(false);
|
||||
}
|
||||
|
||||
void context_show_cursor()
|
||||
{
|
||||
GetContext()->GetUiContext()->SetCursorVisible(true);
|
||||
}
|
||||
|
||||
void context_get_cursor_position(sint32 * x, sint32 * y)
|
||||
{
|
||||
GetContext()->GetUiContext()->GetCursorPosition(x, y);
|
||||
}
|
||||
|
||||
void context_get_cursor_position_scaled(sint32 * x, sint32 * y)
|
||||
{
|
||||
context_get_cursor_position(x, y);
|
||||
|
||||
// Compensate for window scaling.
|
||||
*x = (sint32)ceilf(*x / gConfigGeneral.window_scale);
|
||||
*y = (sint32)ceilf(*y / gConfigGeneral.window_scale);
|
||||
}
|
||||
|
||||
void context_set_cursor_position(sint32 x, sint32 y)
|
||||
{
|
||||
GetContext()->GetUiContext()->SetCursorPosition(x, y);
|
||||
}
|
||||
|
||||
const CursorState * context_get_cursor_state()
|
||||
{
|
||||
return GetContext()->GetUiContext()->GetCursorState();
|
||||
}
|
||||
|
||||
const uint8 * context_get_keys_state()
|
||||
{
|
||||
return GetContext()->GetUiContext()->GetKeysState();
|
||||
}
|
||||
|
||||
const uint8 * context_get_keys_pressed()
|
||||
{
|
||||
return GetContext()->GetUiContext()->GetKeysPressed();
|
||||
}
|
||||
|
||||
void context_start_text_input(utf8 * buffer, size_t maxLength)
|
||||
{
|
||||
GetContext()->GetUiContext()->StartTextInput(buffer, maxLength);
|
||||
}
|
||||
|
||||
void context_stop_text_input()
|
||||
{
|
||||
GetContext()->GetUiContext()->StopTextInput();
|
||||
}
|
||||
|
||||
bool context_is_input_active()
|
||||
{
|
||||
return GetContext()->GetUiContext()->IsTextInputActive();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,25 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
typedef struct CursorState
|
||||
{
|
||||
sint32 x, y;
|
||||
uint8 left, middle, right, any;
|
||||
sint32 wheel;
|
||||
sint32 old;
|
||||
bool touch, touchIsDouble;
|
||||
uint32 touchDownTimestamp;
|
||||
} CursorState;
|
||||
|
||||
enum
|
||||
{
|
||||
CURSOR_UP = 0,
|
||||
CURSOR_DOWN = 1,
|
||||
CURSOR_CHANGED = 2,
|
||||
CURSOR_RELEASED = CURSOR_UP | CURSOR_CHANGED,
|
||||
CURSOR_PRESSED = CURSOR_DOWN | CURSOR_CHANGED,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace OpenRCT2
|
||||
|
@ -45,11 +64,23 @@ namespace OpenRCT2
|
|||
|
||||
#endif // __cplusplus
|
||||
|
||||
#if __cplusplus
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void context_setcurrentcursor(sint32 cursor);
|
||||
#if __cplusplus
|
||||
void context_hide_cursor();
|
||||
void context_show_cursor();
|
||||
void context_get_cursor_position(sint32 * x, sint32 * y);
|
||||
void context_get_cursor_position_scaled(sint32 * x, sint32 * y);
|
||||
void context_set_cursor_position(sint32 x, sint32 y);
|
||||
const CursorState * context_get_cursor_state();
|
||||
const uint8 * context_get_keys_state();
|
||||
const uint8 * context_get_keys_pressed();
|
||||
void context_start_text_input(utf8 * buffer, size_t maxLength);
|
||||
void context_stop_text_input();
|
||||
bool context_is_input_active();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Context.h"
|
||||
#include "ui/UiContext.h"
|
||||
#include "core/Console.hpp"
|
||||
#include "core/File.h"
|
||||
#include "core/FileStream.hpp"
|
||||
|
@ -463,7 +465,7 @@ namespace OpenRCT2
|
|||
{
|
||||
_lastTick = currentTick;
|
||||
}
|
||||
platform_process_messages();
|
||||
GetContext()->GetUiContext()->ProcessMessages();
|
||||
rct2_update();
|
||||
if (!_isWindowMinimised)
|
||||
{
|
||||
|
@ -486,7 +488,7 @@ namespace OpenRCT2
|
|||
_uncapTick = currentTick - UPDATE_TIME_MS - 1;
|
||||
}
|
||||
|
||||
platform_process_messages();
|
||||
GetContext()->GetUiContext()->ProcessMessages();
|
||||
|
||||
while (_uncapTick <= currentTick && currentTick - _uncapTick > UPDATE_TIME_MS)
|
||||
{
|
||||
|
|
|
@ -690,3 +690,19 @@ void Mixer_SetVolume(float volume)
|
|||
gMixer->SetVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
sint32 DStoMixerVolume(sint32 volume)
|
||||
{
|
||||
return (sint32)(SDL_MIX_MAXVOLUME * (SDL_pow(10, (float)volume / 2000)));
|
||||
}
|
||||
|
||||
float DStoMixerPan(sint32 pan)
|
||||
{
|
||||
return (((float)pan + -DSBPAN_LEFT) / DSBPAN_RIGHT) / 2;
|
||||
}
|
||||
|
||||
double DStoMixerRate(sint32 frequency)
|
||||
{
|
||||
return (double)frequency / 22050;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,6 @@
|
|||
|
||||
#include "../common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "../platform/platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#define MIXER_LOOP_NONE 0
|
||||
#define MIXER_LOOP_INFINITE -1
|
||||
|
||||
|
@ -89,9 +78,9 @@ void Mixer_Channel_SetGroup(void* channel, sint32 group);
|
|||
void* Mixer_Play_Music(sint32 pathId, sint32 loop, sint32 streaming);
|
||||
void Mixer_SetVolume(float volume);
|
||||
|
||||
static inline sint32 DStoMixerVolume(sint32 volume) { return (sint32)(SDL_MIX_MAXVOLUME * (SDL_pow(10, (float)volume / 2000))); }
|
||||
static inline float DStoMixerPan(sint32 pan) { return (((float)pan + -DSBPAN_LEFT) / DSBPAN_RIGHT) / 2; }
|
||||
static inline double DStoMixerRate(sint32 frequency) { return (double)frequency / 22050; }
|
||||
sint32 DStoMixerVolume(sint32 volume);
|
||||
float DStoMixerPan(sint32 pan);
|
||||
double DStoMixerRate(sint32 frequency);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -159,8 +159,9 @@ static sint32 game_get_next_input(sint32 *x, sint32 *y)
|
|||
{
|
||||
rct_mouse_data *input = get_mouse_input();
|
||||
if (input == NULL) {
|
||||
*x = gCursorState.x;
|
||||
*y = gCursorState.y;
|
||||
const CursorState * cursorState = context_get_cursor_state();
|
||||
*x = cursorState->x;
|
||||
*y = cursorState->y;
|
||||
return 0;
|
||||
} else {
|
||||
*x = input->x;
|
||||
|
@ -200,7 +201,7 @@ static void input_scroll_drag_begin(sint32 x, sint32 y, rct_window* w, rct_widge
|
|||
_ticksSinceDragStart = 0;
|
||||
|
||||
_dragScrollIndex = window_get_scroll_data_index(w, widgetIndex);
|
||||
platform_hide_cursor();
|
||||
context_hide_cursor();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,7 +242,7 @@ static void input_scroll_drag_continue(sint32 x, sint32 y, rct_window* w)
|
|||
sint32 fixedCursorPositionX = (sint32) ceilf(gInputDragLastX * gConfigGeneral.window_scale);
|
||||
sint32 fixedCursorPositionY = (sint32) ceilf(gInputDragLastY * gConfigGeneral.window_scale);
|
||||
|
||||
platform_set_cursor_position(fixedCursorPositionX, fixedCursorPositionY);
|
||||
context_set_cursor_position(fixedCursorPositionX, fixedCursorPositionY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -252,7 +253,7 @@ static void input_scroll_right(sint32 x, sint32 y, sint32 state)
|
|||
{
|
||||
rct_window* w = window_find_by_number(_dragWidget.window_classification, _dragWidget.window_number);
|
||||
if (w == NULL) {
|
||||
platform_show_cursor();
|
||||
context_show_cursor();
|
||||
_inputState = INPUT_STATE_RESET;
|
||||
return;
|
||||
}
|
||||
|
@ -267,7 +268,7 @@ static void input_scroll_right(sint32 x, sint32 y, sint32 state)
|
|||
break;
|
||||
case MOUSE_STATE_RIGHT_RELEASE:
|
||||
_inputState = INPUT_STATE_RESET;
|
||||
platform_show_cursor();
|
||||
context_show_cursor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -502,8 +503,8 @@ static void input_viewport_drag_begin(rct_window *w, sint32 x, sint32 y)
|
|||
_dragWidget.window_classification = w->classification;
|
||||
_dragWidget.window_number = w->number;
|
||||
_ticksSinceDragStart = 0;
|
||||
platform_get_cursor_position(&gInputDragLastX, &gInputDragLastY);
|
||||
platform_hide_cursor();
|
||||
context_get_cursor_position(&gInputDragLastX, &gInputDragLastY);
|
||||
context_hide_cursor();
|
||||
|
||||
// gInputFlags |= INPUT_FLAG_5;
|
||||
}
|
||||
|
@ -514,7 +515,7 @@ static void input_viewport_drag_continue()
|
|||
rct_window *w;
|
||||
rct_viewport *viewport;
|
||||
|
||||
platform_get_cursor_position(&newDragX, &newDragY);
|
||||
context_get_cursor_position(&newDragX, &newDragY);
|
||||
|
||||
dx = newDragX - gInputDragLastX;
|
||||
dy = newDragY - gInputDragLastY;
|
||||
|
@ -530,7 +531,7 @@ static void input_viewport_drag_continue()
|
|||
viewport = w->viewport;
|
||||
_ticksSinceDragStart += gTicksSinceLastUpdate;
|
||||
if (viewport == NULL) {
|
||||
platform_show_cursor();
|
||||
context_show_cursor();
|
||||
_inputState = INPUT_STATE_RESET;
|
||||
} else if (dx != 0 || dy != 0) {
|
||||
if (!(w->flags & WF_NO_SCROLLING)) {
|
||||
|
@ -552,13 +553,13 @@ static void input_viewport_drag_continue()
|
|||
}
|
||||
}
|
||||
|
||||
platform_set_cursor_position(gInputDragLastX, gInputDragLastY);
|
||||
context_set_cursor_position(gInputDragLastX, gInputDragLastY);
|
||||
}
|
||||
|
||||
static void input_viewport_drag_end()
|
||||
{
|
||||
_inputState = INPUT_STATE_RESET;
|
||||
platform_show_cursor();
|
||||
context_show_cursor();
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
@ -1411,14 +1412,15 @@ void title_handle_keyboard_input()
|
|||
if (!gConsoleOpen) {
|
||||
// Handle modifier keys and key scrolling
|
||||
gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE;
|
||||
if (gKeysState[SDL_SCANCODE_LSHIFT] || gKeysState[SDL_SCANCODE_RSHIFT])
|
||||
const uint8 * keysState = context_get_keys_state();
|
||||
if (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT])
|
||||
gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_SHIFT_Z;
|
||||
if (gKeysState[SDL_SCANCODE_LCTRL] || gKeysState[SDL_SCANCODE_RCTRL])
|
||||
if (keysState[SDL_SCANCODE_LCTRL] || keysState[SDL_SCANCODE_RCTRL])
|
||||
gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_COPY_Z;
|
||||
if (gKeysState[SDL_SCANCODE_LALT] || gKeysState[SDL_SCANCODE_RALT])
|
||||
if (keysState[SDL_SCANCODE_LALT] || keysState[SDL_SCANCODE_RALT])
|
||||
gInputPlaceObjectModifier |= 4;
|
||||
#ifdef __MACOSX__
|
||||
if (gKeysState[SDL_SCANCODE_LGUI] || gKeysState[SDL_SCANCODE_RGUI]) {
|
||||
if (keysState[SDL_SCANCODE_LGUI] || keysState[SDL_SCANCODE_RGUI]) {
|
||||
gInputPlaceObjectModifier |= 8;
|
||||
}
|
||||
#endif
|
||||
|
@ -1430,7 +1432,7 @@ void title_handle_keyboard_input()
|
|||
|
||||
// Reserve backtick for console
|
||||
if (key == SDL_SCANCODE_GRAVE) {
|
||||
if ((gConfigGeneral.debugging_tools && !platform_is_input_active()) || gConsoleOpen) {
|
||||
if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || gConsoleOpen) {
|
||||
window_cancel_textbox();
|
||||
console_toggle();
|
||||
}
|
||||
|
@ -1476,17 +1478,18 @@ void game_handle_keyboard_input()
|
|||
|
||||
// Handle modifier keys and key scrolling
|
||||
gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE;
|
||||
if (gKeysState[SDL_SCANCODE_LSHIFT] || gKeysState[SDL_SCANCODE_RSHIFT]) {
|
||||
const uint8 * keysState = context_get_keys_state();
|
||||
if (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT]) {
|
||||
gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_SHIFT_Z;
|
||||
}
|
||||
if (gKeysState[SDL_SCANCODE_LCTRL] || gKeysState[SDL_SCANCODE_RCTRL]) {
|
||||
if (keysState[SDL_SCANCODE_LCTRL] || keysState[SDL_SCANCODE_RCTRL]) {
|
||||
gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_COPY_Z;
|
||||
}
|
||||
if (gKeysState[SDL_SCANCODE_LALT] || gKeysState[SDL_SCANCODE_RALT]) {
|
||||
if (keysState[SDL_SCANCODE_LALT] || keysState[SDL_SCANCODE_RALT]) {
|
||||
gInputPlaceObjectModifier |= 4;
|
||||
}
|
||||
#ifdef __MACOSX__
|
||||
if (gKeysState[SDL_SCANCODE_LGUI] || gKeysState[SDL_SCANCODE_RGUI]) {
|
||||
if (keysState[SDL_SCANCODE_LGUI] || keysState[SDL_SCANCODE_RGUI]) {
|
||||
gInputPlaceObjectModifier |= 8;
|
||||
}
|
||||
#endif
|
||||
|
@ -1501,7 +1504,7 @@ void game_handle_keyboard_input()
|
|||
|
||||
// Reserve backtick for console
|
||||
if (key == SDL_SCANCODE_GRAVE) {
|
||||
if ((gConfigGeneral.debugging_tools && !platform_is_input_active()) || gConsoleOpen) {
|
||||
if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || gConsoleOpen) {
|
||||
window_cancel_textbox();
|
||||
console_toggle();
|
||||
}
|
||||
|
@ -1536,10 +1539,10 @@ void game_handle_keyboard_input()
|
|||
*/
|
||||
sint32 get_next_key()
|
||||
{
|
||||
sint32 i;
|
||||
for (i = 0; i < 221; i++) {
|
||||
if (gKeysPressed[i]) {
|
||||
gKeysPressed[i] = 0;
|
||||
uint8 * keysPressed = (uint8 *)context_get_keys_pressed();
|
||||
for (sint32 i = 0; i < 221; i++) {
|
||||
if (keysPressed[i]) {
|
||||
keysPressed[i] = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -1617,15 +1620,16 @@ void game_handle_edge_scroll()
|
|||
scrollY = 0;
|
||||
|
||||
// Scroll left / right
|
||||
if (gCursorState.x == 0)
|
||||
const CursorState * cursorState = context_get_cursor_state();
|
||||
if (cursorState->x == 0)
|
||||
scrollX = -1;
|
||||
else if (gCursorState.x >= gScreenWidth - 1)
|
||||
else if (cursorState->x >= gScreenWidth - 1)
|
||||
scrollX = 1;
|
||||
|
||||
// Scroll up / down
|
||||
if (gCursorState.y == 0)
|
||||
if (cursorState->y == 0)
|
||||
scrollY = -1;
|
||||
else if (gCursorState.y >= gScreenHeight - 1)
|
||||
else if (cursorState->y >= gScreenHeight - 1)
|
||||
scrollY = 1;
|
||||
|
||||
// Scroll viewport
|
||||
|
@ -1661,25 +1665,26 @@ void game_handle_key_scroll()
|
|||
scrollX = 0;
|
||||
scrollY = 0;
|
||||
|
||||
const uint8 * keysState = context_get_keys_state();
|
||||
for (sint32 shortcutId = SHORTCUT_SCROLL_MAP_UP; shortcutId <= SHORTCUT_SCROLL_MAP_RIGHT; shortcutId++) {
|
||||
uint16 shortcutKey = gShortcutKeys[shortcutId];
|
||||
uint8 scancode = shortcutKey & 0xFF;
|
||||
|
||||
if (shortcutKey == 0xFFFF) continue;
|
||||
if (!gKeysState[scancode]) continue;
|
||||
if (!keysState[scancode]) continue;
|
||||
|
||||
if (shortcutKey & SHIFT) {
|
||||
if (!gKeysState[SDL_SCANCODE_LSHIFT] && !gKeysState[SDL_SCANCODE_RSHIFT]) continue;
|
||||
if (!keysState[SDL_SCANCODE_LSHIFT] && !keysState[SDL_SCANCODE_RSHIFT]) continue;
|
||||
}
|
||||
if (shortcutKey & CTRL) {
|
||||
if (!gKeysState[SDL_SCANCODE_LCTRL] && !gKeysState[SDL_SCANCODE_RCTRL]) continue;
|
||||
if (!keysState[SDL_SCANCODE_LCTRL] && !keysState[SDL_SCANCODE_RCTRL]) continue;
|
||||
}
|
||||
if (shortcutKey & ALT) {
|
||||
if (!gKeysState[SDL_SCANCODE_LALT] && !gKeysState[SDL_SCANCODE_RALT]) continue;
|
||||
if (!keysState[SDL_SCANCODE_LALT] && !keysState[SDL_SCANCODE_RALT]) continue;
|
||||
}
|
||||
#ifdef __MACOSX__
|
||||
if (shortcutKey & CMD) {
|
||||
if (!gKeysState[SDL_SCANCODE_LGUI] && !gKeysState[SDL_SCANCODE_RGUI]) continue;
|
||||
if (!keysState[SDL_SCANCODE_LGUI] && !keysState[SDL_SCANCODE_RGUI]) continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "../audio/audio.h"
|
||||
#include "../audio/AudioMixer.h"
|
||||
#include "../Context.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../network/network.h"
|
||||
|
@ -44,13 +45,13 @@ static void chat_clear_input();
|
|||
void chat_open()
|
||||
{
|
||||
gChatOpen = true;
|
||||
platform_start_text_input(_chatCurrentLine, sizeof(_chatCurrentLine));
|
||||
context_start_text_input(_chatCurrentLine, sizeof(_chatCurrentLine));
|
||||
}
|
||||
|
||||
void chat_close()
|
||||
{
|
||||
gChatOpen = false;
|
||||
platform_stop_text_input();
|
||||
context_stop_text_input();
|
||||
}
|
||||
|
||||
void chat_toggle()
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <SDL_scancode.h>
|
||||
|
||||
#include "../config/Config.h"
|
||||
#include "../Context.h"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../game.h"
|
||||
#include "../input.h"
|
||||
|
@ -91,14 +92,14 @@ void console_open()
|
|||
_consoleScrollPos = 0;
|
||||
console_refresh_caret();
|
||||
console_update_scroll();
|
||||
platform_start_text_input(_consoleCurrentLine, sizeof(_consoleCurrentLine));
|
||||
context_start_text_input(_consoleCurrentLine, sizeof(_consoleCurrentLine));
|
||||
}
|
||||
|
||||
void console_close()
|
||||
{
|
||||
gConsoleOpen = false;
|
||||
console_invalidate();
|
||||
platform_stop_text_input();
|
||||
context_stop_text_input();
|
||||
}
|
||||
|
||||
void console_toggle()
|
||||
|
@ -412,7 +413,7 @@ static void console_clear_input()
|
|||
{
|
||||
_consoleCurrentLine[0] = 0;
|
||||
if (gConsoleOpen) {
|
||||
platform_start_text_input(_consoleCurrentLine, sizeof(_consoleCurrentLine));
|
||||
context_start_text_input(_consoleCurrentLine, sizeof(_consoleCurrentLine));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#pragma endregion
|
||||
|
||||
#include "../audio/audio.h"
|
||||
#include "../Context.h"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../editor.h"
|
||||
|
@ -295,7 +296,7 @@ static bool window_other_wheel_input(rct_window *w, rct_widgetindex widgetIndex,
|
|||
static void window_all_wheel_input()
|
||||
{
|
||||
// Get wheel value
|
||||
sint32 raw = gCursorState.wheel;
|
||||
sint32 raw = context_get_cursor_state()->wheel;
|
||||
sint32 wheel = 0;
|
||||
while (1) {
|
||||
raw -= 120;
|
||||
|
@ -311,14 +312,17 @@ static void window_all_wheel_input()
|
|||
wheel += 17;
|
||||
}
|
||||
raw -= 120;
|
||||
gCursorState.wheel = raw;
|
||||
|
||||
// TODO do something about this hack
|
||||
CursorState * cursorState = (CursorState *)context_get_cursor_state();
|
||||
cursorState->wheel = raw;
|
||||
|
||||
if (wheel == 0)
|
||||
return;
|
||||
|
||||
// Check window cursor is over
|
||||
if (!(input_test_flag(INPUT_FLAG_5))) {
|
||||
rct_window *w = window_find_from_point(gCursorState.x, gCursorState.y);
|
||||
rct_window *w = window_find_from_point(cursorState->x, cursorState->y);
|
||||
if (w != NULL) {
|
||||
// Check if main window
|
||||
if (w->classification == WC_MAIN_WINDOW || w->classification == WC_VIEWPORT) {
|
||||
|
@ -327,7 +331,7 @@ static void window_all_wheel_input()
|
|||
}
|
||||
|
||||
// Check scroll view, cursor is over
|
||||
rct_widgetindex widgetIndex = window_find_widget_from_point(w, gCursorState.x, gCursorState.y);
|
||||
rct_widgetindex widgetIndex = window_find_widget_from_point(w, cursorState->x, cursorState->y);
|
||||
if (widgetIndex != -1) {
|
||||
rct_widget *widget = &w->widgets[widgetIndex];
|
||||
if (widget->type == WWT_SCROLL) {
|
||||
|
@ -1471,7 +1475,7 @@ void window_viewport_get_map_coords_by_cursor(rct_window *w, sint16 *map_x, sint
|
|||
{
|
||||
// Get mouse position to offset against.
|
||||
sint32 mouse_x, mouse_y;
|
||||
platform_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
context_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
|
||||
// Compute map coordinate by mouse position.
|
||||
get_map_coordinates_from_pos(mouse_x, mouse_y, VIEWPORT_INTERACTION_MASK_NONE, map_x, map_y, NULL, NULL, NULL);
|
||||
|
@ -1499,7 +1503,7 @@ void window_viewport_centre_tile_around_cursor(rct_window *w, sint16 map_x, sint
|
|||
|
||||
// Get mouse position to offset against.
|
||||
sint32 mouse_x, mouse_y;
|
||||
platform_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
context_get_cursor_position_scaled(&mouse_x, &mouse_y);
|
||||
|
||||
// Rebase mouse position onto centre of window, and compensate for zoom level.
|
||||
sint32 rebased_x = ((w->width >> 1) - mouse_x) * (1 << w->viewport->zoom),
|
||||
|
@ -2507,7 +2511,7 @@ void window_start_textbox(rct_window *call_w, rct_widgetindex call_widget, rct_s
|
|||
// from crashing the game.
|
||||
gTextBoxInput[maxLength - 1] = '\0';
|
||||
|
||||
platform_start_text_input(gTextBoxInput, maxLength);
|
||||
context_start_text_input(gTextBoxInput, maxLength);
|
||||
}
|
||||
|
||||
void window_cancel_textbox()
|
||||
|
@ -2520,7 +2524,7 @@ void window_cancel_textbox()
|
|||
window_event_textinput_call(w, gCurrentTextBox.widget_index, NULL);
|
||||
gCurrentTextBox.window.classification = WC_NULL;
|
||||
gCurrentTextBox.window.number = 0;
|
||||
platform_stop_text_input();
|
||||
context_stop_text_input();
|
||||
gUsingWidgetTextBox = false;
|
||||
widget_invalidate(w, gCurrentTextBox.widget_index);
|
||||
gCurrentTextBox.widget_index = WWT_LAST;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "audio/audio.h"
|
||||
#include "audio/AudioMixer.h"
|
||||
#include "Context.h"
|
||||
#include "drawing/drawing.h"
|
||||
#include "intro.h"
|
||||
#include "rct2.h"
|
||||
|
@ -221,7 +222,7 @@ void intro_draw(rct_drawpixelinfo *dpi)
|
|||
|
||||
static void screen_intro_process_mouse_input()
|
||||
{
|
||||
if (gCursorState.any == CURSOR_PRESSED) {
|
||||
if (context_get_cursor_state()->any == CURSOR_PRESSED) {
|
||||
screen_intro_skip_part();
|
||||
}
|
||||
}
|
||||
|
@ -232,8 +233,12 @@ static void screen_intro_process_mouse_input()
|
|||
*/
|
||||
static void screen_intro_process_keyboard_input()
|
||||
{
|
||||
if (gLastKeyPressed != 0) {
|
||||
screen_intro_skip_part();
|
||||
const uint8 * keys = context_get_keys_state();
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (keys[i] != 0) {
|
||||
screen_intro_skip_part();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "../common.h"
|
||||
#include "../interface/Cursors.h"
|
||||
|
||||
struct CursorState;
|
||||
|
||||
namespace OpenRCT2
|
||||
{
|
||||
namespace Drawing
|
||||
|
@ -42,7 +44,7 @@ namespace OpenRCT2
|
|||
const utf8 * Buffer; // UTF-8 stream
|
||||
size_t BufferSize; // Maximum number of bytes (excluding null terminator)
|
||||
size_t Size; // Number of bytes (excluding null terminator)
|
||||
uint32 Length; // Number of codepoints
|
||||
size_t Length; // Number of codepoints
|
||||
size_t SelectionStart; // Selection start, in bytes
|
||||
size_t SelectionSize; // Selection length in bytes
|
||||
};
|
||||
|
@ -83,21 +85,30 @@ namespace OpenRCT2
|
|||
virtual ~IUiContext() = default;
|
||||
|
||||
// Window
|
||||
virtual CURSOR_ID GetCursor() abstract;
|
||||
virtual void SetCursor(CURSOR_ID cursor) abstract;
|
||||
virtual void * GetWindow() abstract;
|
||||
virtual sint32 GetWidth() abstract;
|
||||
virtual sint32 GetHeight() abstract;
|
||||
virtual void SetFullscreenMode(FULLSCREEN_MODE mode) abstract;
|
||||
|
||||
virtual std::vector<Resolution> GetFullscreenResolutions() abstract;
|
||||
virtual bool IsSteamOverlayActive() abstract;
|
||||
virtual void ProcessMessages() abstract;
|
||||
|
||||
// Input
|
||||
virtual const CursorState * GetCursorState() abstract;
|
||||
virtual CURSOR_ID GetCursor() abstract;
|
||||
virtual void SetCursor(CURSOR_ID cursor) abstract;
|
||||
virtual void SetCursorVisible(bool value) abstract;
|
||||
virtual void GetCursorPosition(sint32 * x, sint32 * y) abstract;
|
||||
virtual void SetCursorPosition(sint32 x, sint32 y) abstract;
|
||||
virtual const uint8 * GetKeysState() abstract;
|
||||
virtual const uint8 * GetKeysPressed() abstract;
|
||||
|
||||
// Drawing
|
||||
virtual Drawing::IDrawingEngine * CreateDrawingEngine(Drawing::DRAWING_ENGINE_TYPE type) abstract;
|
||||
|
||||
// Text input
|
||||
virtual bool IsTextInputActive() abstract;
|
||||
virtual const TextInputSession * StartTextInput(utf8 * buffer, sint32 bufferSize) abstract;
|
||||
virtual const TextInputSession * StartTextInput(utf8 * buffer, size_t bufferSize) abstract;
|
||||
virtual void StopTextInput() abstract;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue