mirror of
https://github.com/fallout2-ce/fallout2-ce.git
synced 2026-07-27 16:47:11 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bbbc98065 | ||
|
|
b0b08ed14e | ||
|
|
5b8281922d |
+46
-8
@@ -48,6 +48,8 @@ static void buildNormalizedQwertyKeys();
|
||||
static void _GNW95_process_key(KeyboardData* data);
|
||||
static int inputGetHookMouseButton(int sdlButton);
|
||||
static void inputHandleMouseClickHook(int sdlButton, bool pressed);
|
||||
static void inputResetInternalEventQueue();
|
||||
static void inputHandleProgramActivationChange(bool isActive);
|
||||
|
||||
// 0x51E23C
|
||||
static int gKeyboardKeyRepeatRate = 80;
|
||||
@@ -135,6 +137,39 @@ static void inputHandleMouseClickHook(int sdlButton, bool pressed)
|
||||
ScriptHookCall(HOOK_MOUSECLICK, 0, { pressed ? 1 : 0, hookButton }).call();
|
||||
}
|
||||
|
||||
static void inputHandleProgramActivationChange(bool isActive)
|
||||
{
|
||||
if (gProgramIsActive == isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
gProgramIsActive = isActive;
|
||||
|
||||
// Cmd-tab on macOS can leave modifier/key repeat state and mouse mode out
|
||||
// of sync with SDL's actual app activation state. Drop queued input on
|
||||
// both transitions and reapply the desired mouse mode on return.
|
||||
keyboardReset();
|
||||
mouseReset();
|
||||
windowResetButtonState();
|
||||
inputResetInternalEventQueue();
|
||||
|
||||
if (isActive) {
|
||||
mouseDeviceInitMode();
|
||||
windowRefreshAll(&_scr_size);
|
||||
audioEngineResume();
|
||||
} else {
|
||||
audioEnginePause();
|
||||
}
|
||||
}
|
||||
|
||||
static void inputResetInternalEventQueue()
|
||||
{
|
||||
gInputEventQueueReadIndex = -1;
|
||||
gInputEventQueueWriteIndex = 0;
|
||||
_input_mx = -1;
|
||||
_input_my = -1;
|
||||
}
|
||||
|
||||
// 0x4C8A70
|
||||
int inputInit()
|
||||
{
|
||||
@@ -300,8 +335,7 @@ static int dequeueInputEvent()
|
||||
// 0x4C8D04
|
||||
void inputEventQueueReset()
|
||||
{
|
||||
gInputEventQueueReadIndex = -1;
|
||||
gInputEventQueueWriteIndex = 0;
|
||||
inputResetInternalEventQueue();
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) { } // Clear all input events
|
||||
}
|
||||
@@ -1016,8 +1050,9 @@ void _GNW95_process_message()
|
||||
if (!keyboardIsDisabled()) {
|
||||
keyboardData.key = e.key.keysym.scancode;
|
||||
keyboardData.down = (e.key.state & SDL_PRESSED) != 0;
|
||||
bool syntheticSfallKey = sfall_kb_consume_synthetic_key_event(keyboardData.key, keyboardData.down);
|
||||
|
||||
if (!e.key.repeat) {
|
||||
if (!e.key.repeat && !syntheticSfallKey) {
|
||||
int keyOverride = sfall_kb_handle_key_pressed(keyboardData.key, keyboardData.down);
|
||||
if (keyOverride != SDL_SCANCODE_UNKNOWN) {
|
||||
keyboardData.key = keyOverride;
|
||||
@@ -1034,14 +1069,17 @@ void _GNW95_process_message()
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
handleWindowSizeChanged();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
gProgramIsActive = true;
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
windowRefreshAll(&_scr_size);
|
||||
audioEngineResume();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
inputHandleProgramActivationChange(true);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_HIDDEN:
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
gProgramIsActive = false;
|
||||
audioEnginePause();
|
||||
inputHandleProgramActivationChange(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -656,6 +656,15 @@ int mouseGetEvent()
|
||||
return gMouseEvent;
|
||||
}
|
||||
|
||||
void mouseReset()
|
||||
{
|
||||
gMouseEvent = 0;
|
||||
_raw_buttons = 0;
|
||||
last_buttons = 0;
|
||||
gMouseWheelX = 0;
|
||||
gMouseWheelY = 0;
|
||||
}
|
||||
|
||||
// 0x4CAAA8
|
||||
bool cursorIsHidden()
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@ void mouseGetRect(Rect* rect);
|
||||
void mouseGetPosition(int* out_x, int* out_y);
|
||||
void _mouse_set_position(int x, int y);
|
||||
int mouseGetEvent();
|
||||
void mouseReset();
|
||||
bool cursorIsHidden();
|
||||
void _mouse_get_raw_state(int* out_x, int* out_y, int* out_buttons);
|
||||
void mouseSetSensitivity(double value);
|
||||
|
||||
+34
-3
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "game.h"
|
||||
#include "sfall_script_hooks.h"
|
||||
#include "svga.h"
|
||||
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace fallout {
|
||||
@@ -272,6 +274,7 @@ static constexpr SDL_Scancode kDiks[DIK_MAP_COUNT] = {
|
||||
};
|
||||
|
||||
std::unordered_map<SDL_Scancode, int> kScanCodeToDik;
|
||||
std::deque<std::pair<SDL_Scancode, bool>> syntheticKeyEvents;
|
||||
|
||||
/// Translates Sfall key code (DIK or VK constant) to SDL scancode.
|
||||
static SDL_Scancode get_scancode_from_key(int key)
|
||||
@@ -319,13 +322,41 @@ void sfall_kb_press_key(int key)
|
||||
}
|
||||
|
||||
SDL_Event event;
|
||||
event.key.keysym.scancode = scancode;
|
||||
SDL_zero(event);
|
||||
|
||||
event.type = SDL_KEYDOWN;
|
||||
SDL_PushEvent(&event);
|
||||
event.key.timestamp = SDL_GetTicks();
|
||||
event.key.windowID = gSdlWindow != nullptr ? SDL_GetWindowID(gSdlWindow) : 0;
|
||||
event.key.state = SDL_PRESSED;
|
||||
event.key.repeat = 0;
|
||||
event.key.keysym.scancode = scancode;
|
||||
event.key.keysym.sym = SDL_GetKeyFromScancode(scancode);
|
||||
event.key.keysym.mod = SDL_GetModState();
|
||||
if (SDL_PushEvent(&event) == 1) {
|
||||
syntheticKeyEvents.emplace_back(scancode, true);
|
||||
}
|
||||
|
||||
event.type = SDL_KEYUP;
|
||||
SDL_PushEvent(&event);
|
||||
event.key.timestamp = SDL_GetTicks();
|
||||
event.key.state = SDL_RELEASED;
|
||||
if (SDL_PushEvent(&event) == 1) {
|
||||
syntheticKeyEvents.emplace_back(scancode, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool sfall_kb_consume_synthetic_key_event(int sdlScanCode, bool pressed)
|
||||
{
|
||||
if (syntheticKeyEvents.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& [expectedScanCode, expectedPressed] = syntheticKeyEvents.front();
|
||||
if (expectedScanCode != static_cast<SDL_Scancode>(sdlScanCode) || expectedPressed != pressed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
syntheticKeyEvents.pop_front();
|
||||
return true;
|
||||
}
|
||||
|
||||
int sfall_kb_handle_key_pressed(int sdlScanCode, bool pressed)
|
||||
|
||||
@@ -9,6 +9,9 @@ bool sfall_kb_is_key_pressed(int key);
|
||||
/// Simulates pressing `key`.
|
||||
void sfall_kb_press_key(int key);
|
||||
|
||||
/// Returns `true` when the next matching SDL key event was injected by `tap_key`.
|
||||
bool sfall_kb_consume_synthetic_key_event(int sdlScanCode, bool pressed);
|
||||
|
||||
int sfall_kb_handle_key_pressed(int sdlScanCode, bool pressed);
|
||||
|
||||
} // namespace fallout
|
||||
|
||||
@@ -1238,6 +1238,19 @@ int _win_check_all_buttons()
|
||||
return keyCode;
|
||||
}
|
||||
|
||||
void windowResetButtonState()
|
||||
{
|
||||
if (!gWindowSystemInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < gWindowsLength; index++) {
|
||||
Window* window = gWindows[index];
|
||||
window->hoveredButton = nullptr;
|
||||
window->clickedButton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x4D79DC
|
||||
Button* buttonGetButton(int btn, Window** windowPtr)
|
||||
{
|
||||
|
||||
@@ -195,6 +195,7 @@ int windowGetHeight(int win);
|
||||
int windowGetRect(int win, Rect* rect);
|
||||
int _win_check_all_buttons();
|
||||
int _GNW_check_menu_bars(int input);
|
||||
void windowResetButtonState();
|
||||
void programWindowSetTitle(const char* title);
|
||||
bool showMesageBox(const char* str);
|
||||
int buttonCreate(int win, int x, int y, int width, int height, int mouseEnterEventCode, int mouseExitEventCode, int mouseDownEventCode, int mouseUpEventCode, unsigned char* up, unsigned char* dn, unsigned char* hover, int flags);
|
||||
|
||||
Reference in New Issue
Block a user