Add mouse wheel support

This commit is contained in:
Alexander Batalov 2022-08-07 14:52:44 +03:00
parent a47918a83c
commit 019dbbb56e
11 changed files with 242 additions and 0 deletions

View File

@ -830,6 +830,8 @@ int characterEditorShow(bool isCreationMode)
_frame_time = _get_time();
int keyCode = _get_input();
convertMouseWheelToArrowKey(&keyCode);
bool done = false;
if (keyCode == 500) {
done = true;
@ -5962,6 +5964,8 @@ static int perkDialogHandleInput(int count, void (*refreshProc)())
int keyCode = _get_input();
int v19 = 0;
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == 500) {
rc = 1;
} else if (keyCode == KEY_RETURN) {

View File

@ -373,6 +373,9 @@ SDL_Renderer* gSdlRenderer = NULL;
SDL_Texture* gSdlTexture = NULL;
SDL_Surface* gSdlTextureSurface = NULL;
static int gMouseWheelX = 0;
static int gMouseWheelY = 0;
// 0x4C8A70
int coreInit(int a1)
{
@ -1272,6 +1275,9 @@ void _GNW95_process_message()
// The data is accumulated in SDL itself and will be processed
// in `_mouse_info`.
break;
case SDL_MOUSEWHEEL:
handleMouseWheelEvent(&(e.wheel));
break;
case SDL_FINGERDOWN:
case SDL_FINGERMOTION:
case SDL_FINGERUP:
@ -1679,6 +1685,16 @@ void _mouse_info()
}
_mouse_simulate_input(x, y, buttons);
// TODO: Move to `_mouse_simulate_input`.
// TODO: Record wheel event in VCR.
gMouseWheelX = mouseData.wheelX;
gMouseWheelY = mouseData.wheelY;
if (gMouseWheelX != 0 || gMouseWheelY != 0) {
gMouseEvent |= MOUSE_EVENT_WHEEL;
_raw_buttons |= MOUSE_EVENT_WHEEL;
}
}
// 0x4CA698
@ -4804,3 +4820,26 @@ bool mouseHitTestInWindow(int win, int left, int top, int right, int bottom)
return _mouse_click_in(left, top, right, bottom);
}
void mouseGetWheel(int* x, int* y)
{
*x = gMouseWheelX;
*y = gMouseWheelY;
}
void convertMouseWheelToArrowKey(int* keyCodePtr)
{
if (*keyCodePtr == -1) {
if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
*keyCodePtr = KEY_ARROW_UP;
} else if (wheelY < 0) {
*keyCodePtr = KEY_ARROW_DOWN;
}
}
}
}

View File

@ -26,6 +26,7 @@
#define MOUSE_EVENT_ANY_BUTTON_UP (MOUSE_EVENT_LEFT_BUTTON_UP | MOUSE_EVENT_RIGHT_BUTTON_UP)
#define MOUSE_EVENT_LEFT_BUTTON_DOWN_REPEAT (MOUSE_EVENT_LEFT_BUTTON_DOWN | MOUSE_EVENT_LEFT_BUTTON_REPEAT)
#define MOUSE_EVENT_RIGHT_BUTTON_DOWN_REPEAT (MOUSE_EVENT_RIGHT_BUTTON_DOWN | MOUSE_EVENT_RIGHT_BUTTON_REPEAT)
#define MOUSE_EVENT_WHEEL 0x40
#define BUTTON_REPEAT_TIME 250
@ -682,5 +683,7 @@ int screenGetHeight();
int screenGetVisibleHeight();
void mouseGetPositionInWindow(int win, int* x, int* y);
bool mouseHitTestInWindow(int win, int left, int top, int right, int bottom);
void mouseGetWheel(int* x, int* y);
void convertMouseWheelToArrowKey(int* keyCodePtr);
#endif /* CORE_H */

View File

@ -707,6 +707,8 @@ int showLoadFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollCounter = 0;
bool isScrolling = false;
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == 500) {
if (fileListLength != 0) {
strncpy(dest, fileList[selectedFileIndex + pageOffset], 16);
@ -1115,6 +1117,8 @@ int showSaveFileDialog(char* title, char** fileList, char* dest, int fileListLen
int scrollCounter = 0;
bool isScrolling = false;
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == 500) {
rc = 0;
} else if (keyCode == KEY_RETURN) {

View File

@ -11,6 +11,9 @@ static unsigned int gTouchGestureLastTouchUpTimestamp = 0;
static int gTouchGestureTaps = 0;
static bool gTouchGestureHandled = false;
static int gMouseWheelDeltaX = 0;
static int gMouseWheelDeltaY = 0;
extern int screenGetWidth();
extern int screenGetHeight();
@ -64,6 +67,8 @@ bool mouseDeviceGetData(MouseData* mouseState)
mouseState->y = gTouchMouseDeltaY;
mouseState->buttons[0] = 0;
mouseState->buttons[1] = 0;
mouseState->wheelX = 0;
mouseState->wheelY = 0;
gTouchMouseDeltaX = 0;
gTouchMouseDeltaY = 0;
@ -94,8 +99,13 @@ bool mouseDeviceGetData(MouseData* mouseState)
Uint32 buttons = SDL_GetRelativeMouseState(&(mouseState->x), &(mouseState->y));
mouseState->buttons[0] = (buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
mouseState->buttons[1] = (buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
mouseState->wheelX = gMouseWheelDeltaX;
mouseState->wheelY = gMouseWheelDeltaY;
#endif
gMouseWheelDeltaX = 0;
gMouseWheelDeltaY = 0;
return true;
}
@ -186,3 +196,9 @@ void handleTouchFingerEvent(SDL_TouchFingerEvent* event)
gTouchGestureLastTouchUpTimestamp = event->timestamp;
}
}
void handleMouseWheelEvent(SDL_MouseWheelEvent* event)
{
gMouseWheelDeltaX += event->x;
gMouseWheelDeltaY += event->y;
}

View File

@ -7,6 +7,8 @@ typedef struct MouseData {
int x;
int y;
unsigned char buttons[2];
int wheelX;
int wheelY;
} MouseData;
typedef struct KeyboardData {
@ -29,5 +31,6 @@ bool keyboardDeviceInit();
void keyboardDeviceFree();
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
void handleMouseWheelEvent(SDL_MouseWheelEvent* event);
#endif /* DINPUT_H */

View File

@ -444,6 +444,27 @@ int gameHandleKey(int eventCode, bool isInCombatMode)
}
if (eventCode == -1) {
if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
int dx = 0;
if (wheelX > 0) {
dx = 1;
} else if (wheelX < 0) {
dx = -1;
}
int dy = 0;
if (wheelY > 0) {
dy = -1;
} else if (wheelY < 0) {
dy = 1;
}
mapScroll(dx, dy);
}
return 0;
}

View File

@ -1869,6 +1869,8 @@ int _gdProcess()
for (;;) {
int keyCode = _get_input();
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == KEY_CTRL_Q || keyCode == KEY_CTRL_X || keyCode == KEY_F10) {
showQuitConfirmationDialog();
}

View File

@ -615,6 +615,23 @@ void inventoryOpen()
_inven_pickup(keyCode, _stack_offset[_curr_stack]);
}
}
} else if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_stack_offset[_curr_stack] > 0) {
_stack_offset[_curr_stack] -= 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_NORMAL);
}
} else if (wheelY < 0) {
if (gInventorySlotsCount + _stack_offset[_curr_stack] < _pud->length) {
_stack_offset[_curr_stack] += 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_NORMAL);
}
}
}
}
}
}
@ -2188,6 +2205,23 @@ void inventoryOpenUseItemOn(Object* a1)
}
}
}
} else if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_SCROLLER_X, INVENTORY_SCROLLER_Y, INVENTORY_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_SCROLLER_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_stack_offset[_curr_stack] > 0) {
_stack_offset[_curr_stack] -= 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_USE_ITEM_ON);
}
} else if (wheelY < 0) {
if (_stack_offset[_curr_stack] + gInventorySlotsCount < _pud->length) {
_stack_offset[_curr_stack] += 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_USE_ITEM_ON);
}
}
}
}
}
@ -3713,6 +3747,40 @@ int inventoryOpenLooting(Object* a1, Object* a2)
}
}
}
} else if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_LEFT_SCROLLER_X, INVENTORY_LOOT_LEFT_SCROLLER_Y, INVENTORY_LOOT_LEFT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_LEFT_SCROLLER_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_stack_offset[_curr_stack] > 0) {
_stack_offset[_curr_stack] -= 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
}
} else if (wheelY < 0) {
if (_stack_offset[_curr_stack] + gInventorySlotsCount < _pud->length) {
_stack_offset[_curr_stack] += 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_LOOT);
}
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_LOOT_RIGHT_SCROLLER_X, INVENTORY_LOOT_RIGHT_SCROLLER_Y, INVENTORY_LOOT_RIGHT_SCROLLER_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_LOOT_RIGHT_SCROLLER_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_target_stack_offset[_target_curr_stack] > 0) {
_target_stack_offset[_target_curr_stack] -= 1;
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
windowRefresh(gInventoryWindow);
}
} else if (wheelY < 0) {
if (_target_stack_offset[_target_curr_stack] + gInventorySlotsCount < _target_pud->length) {
_target_stack_offset[_target_curr_stack] += 1;
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_LOOT);
windowRefresh(gInventoryWindow);
}
}
}
}
}
@ -4535,6 +4603,70 @@ void inventoryOpenTrade(int win, Object* a2, Object* a3, Object* a4, int a5)
keyCode = -1;
}
} else if ((mouseGetEvent() & MOUSE_EVENT_WHEEL) != 0) {
if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_LEFT_SCROLLER_TRACKING_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_stack_offset[_curr_stack] > 0) {
_stack_offset[_curr_stack] -= 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
}
} else if (wheelY < 0) {
if (_stack_offset[_curr_stack] + gInventorySlotsCount < _pud->length) {
_stack_offset[_curr_stack] += 1;
_display_inventory(_stack_offset[_curr_stack], -1, INVENTORY_WINDOW_TYPE_TRADE);
}
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_X, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_LEFT_SCROLLER_TRACKING_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_ptable_offset > 0) {
_ptable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
}
} else if (wheelY < 0) {
if (_ptable_offset + gInventorySlotsCount < _ptable_pud->length) {
_ptable_offset += 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
}
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_RIGHT_SCROLLER_TRACKING_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_target_stack_offset[_target_curr_stack] > 0) {
_target_stack_offset[_target_curr_stack] -= 1;
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
windowRefresh(gInventoryWindow);
}
} else if (wheelY < 0) {
if (_target_stack_offset[_target_curr_stack] + gInventorySlotsCount < _target_pud->length) {
_target_stack_offset[_target_curr_stack] += 1;
_display_target_inventory(_target_stack_offset[_target_curr_stack], -1, _target_pud, INVENTORY_WINDOW_TYPE_TRADE);
windowRefresh(gInventoryWindow);
}
}
} else if (mouseHitTestInWindow(gInventoryWindow, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_X, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y, INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_MAX_X, INVENTORY_SLOT_HEIGHT * gInventorySlotsCount + INVENTORY_TRADE_INNER_RIGHT_SCROLLER_TRACKING_Y)) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (wheelY > 0) {
if (_btable_offset > 0) {
_btable_offset -= 1;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
}
} else if (wheelY < 0) {
if (_btable_offset + gInventorySlotsCount < _btable_pud->length) {
_btable_offset++;
inventoryWindowRenderInnerInventories(win, a3, a4, -1);
}
}
}
}
}
}

View File

@ -478,6 +478,8 @@ int lsgSaveGame(int mode)
int v37 = 0;
int v102 = 0;
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == KEY_ESCAPE || keyCode == 501 || _game_user_wants_to_quit != 0) {
rc = 0;
} else {
@ -890,6 +892,8 @@ int lsgLoadGame(int mode)
int v107 = 0;
int v108 = -1;
convertMouseWheelToArrowKey(&keyCode);
if (keyCode == KEY_ESCAPE || keyCode == 501 || _game_user_wants_to_quit != 0) {
rc = 0;
} else {

View File

@ -3458,6 +3458,20 @@ int _wmWorldMapFunc(int a1)
}
}
if ((mouseEvent & MOUSE_EVENT_WHEEL) != 0) {
int wheelX;
int wheelY;
mouseGetWheel(&wheelX, &wheelY);
if (mouseHitTestInWindow(gWorldmapWindow, WM_VIEW_X, WM_VIEW_Y, 472, 465)) {
worldmapWindowScroll(20, 20, wheelX, -wheelY, NULL, true);
} else if (mouseHitTestInWindow(gWorldmapWindow, 501, 135, 501 + 119, 135 + 178)) {
if (wheelY != 0) {
_wmInterfaceScrollTabsStart(wheelY > 0 ? 27 : -27);
}
}
}
if (map != -1 || v25 == -1) {
break;
}