Update internal mouse coordinates even if cursor movement is disabled

In TT2, keyboard/gamepad navigation is implemented by moving the mouse
cursor using IZ command. It did not work in browsers where mouse cursor
could not be moved or when mouse movement was disabled from the menu.

Now IZ command updates the internal mouse coordinates even when the
cursor cannot be moved.
This commit is contained in:
kichikuou
2023-09-04 13:32:00 +09:00
parent 10cdec98e6
commit f0ccfee40f
8 changed files with 55 additions and 44 deletions
+4 -2
View File
@@ -197,8 +197,10 @@ static void setup_selwindow() {
// デフォルトで選択される選択肢がある場合、そこへカーソルを移動
if (sact.sel.movecursor) {
ags_setCursorLocation(sp->cur.x + sact.sel.frame_dot + 2,
sp->cur.y + sact.sel.frame_dot + 2 + (sact.sel.font_size + sact.sel.linespace)*(sact.sel.movecursor -1), TRUE);
int x = sp->cur.x + sact.sel.frame_dot + 2;
int y = sp->cur.y + sact.sel.frame_dot + 2 +
(sact.sel.font_size + sact.sel.linespace) * (sact.sel.movecursor - 1);
ags_setCursorLocation(x, y, true, true);
selected_item = (sact.sel.movecursor -1);
oldstate = TRUE;
oldindex = selected_item -1;
+29 -23
View File
@@ -627,42 +627,48 @@ void ags_loadCursor(int p1,int p2) {
}
}
void ags_setCursorLocation(int x, int y, boolean is_dibgeo) {
int dx[8], dy[8];
int i, delx, dely;
MyPoint p;
void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection) {
if (!ags_check_param_xy(&x, &y)) return;
/* DIB 座表系か Window 座表系か */
if (is_dibgeo) {
// DIB coordinates -> Window coordinates
x -= nact->ags.view_area.x;
y -= nact->ags.view_area.y;
}
#ifdef __EMSCRIPTEN__
if (!for_selection) {
// We can't move the actual cursor in the browser, but can change the
// internal mouse coordinates. This can help with keyboard/gamepad
// navigation.
sdl_setCursorInternalLocation(x, y);
}
#else
switch(nact->ags.mouse_movesw) {
case MOUSE_WARP_DISABLED:
return;
if (!for_selection)
sdl_setCursorInternalLocation(x, y);
break;
case MOUSE_WARP_DIRECT:
sdl_setCursorLocation(x, y); break;
sdl_setCursorLocation(x, y);
break;
case MOUSE_WARP_SMOOTH:
sys_getMouseInfo(&p, is_dibgeo);
delx = x - p.x;
dely = y - p.y;
for (i = 1; i < 8; i++) {
dx[i-1] = ((delx*i*i*i) >> 9) - ((3*delx*i*i)>> 6) + ((3*delx*i) >> 3) + p.x;
dy[i-1] = ((dely*i*i*i) >> 9) - ((3*dely*i*i)>> 6) + ((3*dely*i) >> 3) + p.y;
}
dx[7] = x; dy[7] = y;
for (i = 0; i < 8; i++) {
sdl_setCursorLocation(dx[i], dy[i]);
usleep(cursor_move_time * 1000 / 8);
{
MyPoint p;
sys_getMouseInfo(&p, is_dibgeo);
int dx = x - p.x;
int dy = y - p.y;
for (int i = 1; i < 8; i++) {
int xi = ((dx*i*i*i) >> 9) - ((3*dx*i*i)>> 6) + ((3*dx*i) >> 3) + p.x;
int yi = ((dy*i*i*i) >> 9) - ((3*dy*i*i)>> 6) + ((3*dy*i) >> 3) + p.y;
sdl_setCursorLocation(xi, yi);
usleep(cursor_move_time * 1000 / 8);
}
sdl_setCursorLocation(x, y);
}
break;
default:
return;
}
#endif
}
EMSCRIPTEN_KEEPALIVE
+1 -1
View File
@@ -211,7 +211,7 @@ extern agsurface_t *ags_drawStringToSurface(const char *str);
/* カーソル関係 */
extern void ags_setCursorType(int type);
extern void ags_loadCursor(int ,int);
extern void ags_setCursorLocation(int x, int y, boolean dibgeo);
extern void ags_setCursorLocation(int x, int y, bool is_dibgeo, bool for_selection);
extern void ags_setCursorMoveTime(int msec);
extern int ags_getCursorMoveTime();
+1 -1
View File
@@ -127,7 +127,7 @@ void commandIZ() {
int x = getCaliValue();
int y = getCaliValue();
ags_setCursorLocation(x, y, TRUE);
ags_setCursorLocation(x, y, true, false);
DEBUG_COMMAND("IZ %d,%d:", x, y);
}
+1 -1
View File
@@ -326,7 +326,7 @@ void commandMJ() {
mj_param.h = h;
mj_param.oldstring = t1;
ags_setCursorLocation(x, y, FALSE); /* XXX */
ags_setCursorLocation(x, y, false, false);
menu_inputstring2(&mj_param);
if (mj_param.newstring == NULL) return;
+1
View File
@@ -95,6 +95,7 @@ void sdl_effect_finish(struct sdl_effect *eff);
/* key/pointer 関係 */
extern void sdl_setJoyDeviceIndex(int index);
extern void sdl_setCursorLocation(int x, int y);
extern void sdl_setCursorInternalLocation(int x, int y);
extern void sdl_setCursorType(int type);
extern boolean sdl_cursorNew(uint8_t* data, int no, CursorImage *cursorImage, TCursorDirEntry *cursordirentry);
extern int sdl_getKeyInfo();
+7 -3
View File
@@ -223,6 +223,12 @@ void send_agsevent(enum agsevent_type type, int code) {
nact->ags.eventcb(&agse); // Async in emscripten
}
void sdl_setCursorInternalLocation(int x, int y) {
mousex = x;
mousey = y;
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
}
// Improves map navigation of Rance4 v2. See also the function comment of
// rance4_Y3_IM_hack() in cmdy.c.
static void rance4v2_hack(void) {
@@ -274,9 +280,7 @@ void sdl_handle_event(SDL_Event *e) {
}
break;
case SDL_MOUSEMOTION:
mousex = e->motion.x;
mousey = e->motion.y;
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
sdl_setCursorInternalLocation(e->motion.x, e->motion.y);
break;
case SDL_MOUSEWHEEL:
+11 -13
View File
@@ -309,28 +309,26 @@ static void init_selwindow() {
ags_updateArea(saveArea.x, saveArea.y, saveArea.w, saveArea.h);
/* マウスカーソルの自動移動 */
int x = r.x + r.w * MOUSE_INIT_X_RATIO/100;
if (default_element == 0) {
MyPoint p;
sys_getMouseInfo(&p, TRUE);
if (p.y < r.y) {
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100,
TRUE);
int y = r.y + (sel.MsgFontSize +2) * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
} else if (p.y > (r.y + r.h)) {
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100,
TRUE);
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
} else {
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
p.y * MOUSE_INIT_Y_RATIO/100,
TRUE);
int y = p.y * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
}
} else if (default_element < regnum) {
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100, TRUE);
int y = r.y + (sel.MsgFontSize +2) * default_element * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
} else if (default_element < 1000) {
ags_setCursorLocation(r.x + r.w * MOUSE_INIT_X_RATIO/100,
r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100, TRUE);
int y = r.y + (sel.MsgFontSize +2) * regnum * MOUSE_INIT_Y_RATIO/100;
ags_setCursorLocation(x, y, true, true);
}
}