Files
kichikuou_system3-sdl2/src/sys/nact_input.cpp
T
kichikuou 51ab709da7 Advance messages by scrolling mouse wheel down
Now the 'A' command accepts mouse wheel down events in addition to
keyboard and mouse buttons.
2025-11-04 10:17:30 +09:00

202 lines
5.0 KiB
C++

/*
ALICE SOFT SYSTEM 3 for Win32
[ NACT - input ]
*/
#ifdef _WIN32
#include <windows.h>
#undef ERROR
#endif
#include <SDL_syswm.h>
#include "nact.h"
#include "ags.h"
#include "texthook.h"
#include "debugger/debugger.h"
enum TouchState {
TOUCH_NONE,
TOUCH_LBUTTON,
TOUCH_RBUTTON,
};
extern SDL_Window* g_window;
static int mousex, mousey, wheel;
static TouchState touch_state = TOUCH_NONE;
void NACT::handle_event(SDL_Event e)
{
if (handle_platform_event(e))
return;
switch (e.type) {
case SDL_QUIT:
show_quit_dialog();
break;
#ifdef __ANDROID__
case SDL_KEYUP:
if (e.key.keysym.scancode == SDL_SCANCODE_AC_BACK) {
show_quit_dialog();
}
break;
#endif
case SDL_MOUSEMOTION:
mousex = e.motion.x * ags->screen_width / ags->window_width;
mousey = e.motion.y * ags->screen_height / ags->window_height;
break;
case SDL_MOUSEWHEEL:
wheel += e.wheel.y * (e.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1);
break;
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION:
mousex = e.tfinger.x * ags->screen_width;
mousey = e.tfinger.y * ags->screen_height;
switch (SDL_GetNumTouchFingers(e.tfinger.touchId)) {
case 0:
touch_state = TOUCH_NONE;
break;
case 1:
// A touch outside of the viewport (SDL clamps it to 0.0-1.0) is
// a right-click.
if (e.tfinger.x == 0.0f || e.tfinger.x == 1.0f ||
e.tfinger.y == 0.0f || e.tfinger.y == 1.0f) {
touch_state = TOUCH_RBUTTON;
} else {
touch_state = TOUCH_LBUTTON;
}
break;
case 2:
// Two-finger touch is a right-click.
touch_state = TOUCH_RBUTTON;
break;
}
break;
default:
#ifdef ENABLE_DEBUGGER
if (e.type == sdl_custom_event_type) {
switch (e.user.code) {
case DEBUGGER_COMMAND:
g_debugger->post_command(e.user.data1);
break;
}
}
#endif
break;
}
}
void NACT::pump_events()
{
SDL_Event e;
while (SDL_PollEvent(&e)) {
handle_event(std::move(e));
}
}
void NACT::process_next_event()
{
SDL_Event e;
SDL_WaitEvent(&e);
handle_event(std::move(e));
}
uint8 NACT::get_key()
{
uint8 val = 0;
texthook_keywait();
pump_events();
// キーボード&マウス
const Uint8* key = SDL_GetKeyboardState(NULL);
Uint32 mouse = SDL_GetMouseState(NULL, NULL);
if(key[SDL_SCANCODE_UP ] || key[SDL_SCANCODE_KP_8 ] ) val |= 0x01;
if(key[SDL_SCANCODE_DOWN ] || key[SDL_SCANCODE_KP_2 ] ) val |= 0x02;
if(key[SDL_SCANCODE_LEFT ] || key[SDL_SCANCODE_KP_4 ] ) val |= 0x04;
if(key[SDL_SCANCODE_RIGHT ] || key[SDL_SCANCODE_KP_6 ] ) val |= 0x08;
if(key[SDL_SCANCODE_RETURN] || mouse & SDL_BUTTON_LMASK || touch_state == TOUCH_LBUTTON) val |= 0x10;
if(key[SDL_SCANCODE_SPACE ] || mouse & SDL_BUTTON_RMASK || touch_state == TOUCH_RBUTTON) val |= 0x20;
if(key[SDL_SCANCODE_ESCAPE] ) val |= 0x40;
if(key[SDL_SCANCODE_TAB ] ) val |= 0x80;
// マウス移動で方向入力はサポートしない
if(sdl_gamecontroller) {
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_DPAD_UP) || SDL_GameControllerGetAxis(sdl_gamecontroller, SDL_CONTROLLER_AXIS_LEFTY) <= -8000) val |= 0x01;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_DPAD_DOWN) || SDL_GameControllerGetAxis(sdl_gamecontroller, SDL_CONTROLLER_AXIS_LEFTY) >= 8000) val |= 0x02;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_DPAD_LEFT) || SDL_GameControllerGetAxis(sdl_gamecontroller, SDL_CONTROLLER_AXIS_LEFTX) <= -8000) val |= 0x04;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) || SDL_GameControllerGetAxis(sdl_gamecontroller, SDL_CONTROLLER_AXIS_LEFTX) >= 8000) val |= 0x08;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_A)) val |= 0x10;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_B)) val |= 0x20;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_X)) val |= 0x40;
if(SDL_GameControllerGetButton(sdl_gamecontroller, SDL_CONTROLLER_BUTTON_Y)) val |= 0x80;
}
return val;
}
void NACT::get_cursor(int* x, int* y)
{
pump_events();
*x = mousex;
*y = mousey;
}
void NACT::set_cursor(int x, int y)
{
if (!mouse_move_enabled)
return;
ags->translate_mouse_coords(&x, &y);
SDL_WarpMouseInWindow(g_window, x, y);
}
int NACT::get_wheel()
{
int val = wheel;
wheel = 0;
return val;
}
void NACT::show_quit_dialog()
{
const SDL_MessageBoxButtonData buttons[] = {
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Quit" },
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "Cancel" },
};
const SDL_MessageBoxData messagebox_data = {
SDL_MESSAGEBOX_INFORMATION,
nullptr,
"System3",
"Quit game?\nAny unsaved progress will be lost.",
SDL_arraysize(buttons),
buttons,
};
int buttonid = 0;
if (SDL_ShowMessageBox(&messagebox_data, &buttonid) < 0) {
WARNING("error displaying message box");
return;
}
if (buttonid == 1) {
quit(0);
}
}
#ifdef __EMSCRIPTEN__
extern "C" {
EMSCRIPTEN_KEEPALIVE
void simulate_right_button(int pressed) {
touch_state = pressed ? TOUCH_RBUTTON : TOUCH_NONE;
}
} // extern "C"
#endif