mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-22 22:48:08 +03:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dac0345e02 |
@@ -61,9 +61,13 @@ class GameActivity : SDLActivity() {
|
||||
}
|
||||
|
||||
override fun getArguments(): Array<String> {
|
||||
return arrayOf(
|
||||
val args = mutableListOf(
|
||||
"-gamedir", intent.getStringExtra(EXTRA_GAME_ROOT)!!,
|
||||
"-savedir", intent.getStringExtra(EXTRA_SAVE_DIRECTORY)!!)
|
||||
val prefs = getSharedPreferences(Launcher.PREFS_NAME, MODE_PRIVATE)
|
||||
if (prefs.getBoolean(Launcher.PREF_VIRTUAL_POINTER, false))
|
||||
args.add("-virtualpointer")
|
||||
return args.toTypedArray()
|
||||
}
|
||||
|
||||
override fun setTitle(title: CharSequence?) {
|
||||
|
||||
@@ -42,6 +42,8 @@ interface LauncherObserver {
|
||||
class Launcher private constructor(private val rootDir: File) {
|
||||
companion object {
|
||||
const val SAVE_DIR = "save"
|
||||
const val PREFS_NAME = "settings"
|
||||
const val PREF_VIRTUAL_POINTER = "virtual_pointer"
|
||||
const val TITLE_FILE = "title.txt"
|
||||
const val GAMEDIR_FILE = "game_directory.txt"
|
||||
const val PLAYLIST_FILE = "playlist.txt"
|
||||
|
||||
@@ -92,6 +92,9 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.launcher_menu, menu)
|
||||
val prefs = getSharedPreferences(Launcher.PREFS_NAME, MODE_PRIVATE)
|
||||
menu.findItem(R.id.virtual_pointer).isChecked =
|
||||
prefs.getBoolean(Launcher.PREF_VIRTUAL_POINTER, false)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -143,6 +146,13 @@ class LauncherActivity : Activity(), LauncherObserver {
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
R.id.virtual_pointer -> {
|
||||
val enabled = !item.isChecked
|
||||
item.isChecked = enabled
|
||||
getSharedPreferences(Launcher.PREFS_NAME, MODE_PRIVATE).edit()
|
||||
.putBoolean(Launcher.PREF_VIRTUAL_POINTER, enabled).apply()
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
<item
|
||||
android:id="@+id/clear_savedata"
|
||||
android:title="@string/action_clear_save_data" />
|
||||
<item
|
||||
android:id="@+id/virtual_pointer"
|
||||
android:checkable="true"
|
||||
android:title="@string/action_virtual_pointer" />
|
||||
<item
|
||||
android:id="@+id/help"
|
||||
android:title="@string/action_help" />
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<string name="action_install_from_zip">ZIPからインストール</string>
|
||||
<string name="action_licenses">オープンソースライセンス</string>
|
||||
<string name="action_clear_save_data">セーブデータをクリア</string>
|
||||
<string name="action_virtual_pointer">仮想マウスポインタ</string>
|
||||
<string name="cancel">キャンセル</string>
|
||||
<string name="cannot_find_ald">System 3.x のファイル (*.ald) が見つかりません。</string>
|
||||
<string name="choose_a_file">ファイルを選択</string>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<string name="action_import_save_data">Import Save Files</string>
|
||||
<string name="action_install_from_zip">Install from ZIP</string>
|
||||
<string name="action_licenses">Open source licenses</string>
|
||||
<string name="action_virtual_pointer">Virtual mouse pointer</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="cannot_find_ald">Cannot find System 3.x game files (*.ald).</string>
|
||||
<string name="choose_a_file">Choose a file</string>
|
||||
|
||||
@@ -91,6 +91,7 @@ target_sources(xsystem35 PRIVATE
|
||||
system.c
|
||||
texthook.c
|
||||
variable.c
|
||||
virtual_pointer.c
|
||||
vsp.c
|
||||
xsystem35.c
|
||||
)
|
||||
|
||||
@@ -131,6 +131,7 @@ struct _ags {
|
||||
bool enable_zb;
|
||||
bool noantialias; /* antialias を使用しない */
|
||||
bool noimagecursor; /* リソースファイルのカーソルを読みこまない */
|
||||
bool virtualpointer; /* enable the virtual mouse pointer (trackpad-style touch) */
|
||||
};
|
||||
typedef struct _ags ags_t;
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/* XPM */
|
||||
static const char *virtual_cursor[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
"16 19 3 1",
|
||||
/* colors */
|
||||
"X c #000000",
|
||||
". c #ffffff",
|
||||
" c None",
|
||||
/* pixels */
|
||||
"X ",
|
||||
"XX ",
|
||||
"X.X ",
|
||||
"X..X ",
|
||||
"X...X ",
|
||||
"X....X ",
|
||||
"X.....X ",
|
||||
"X......X ",
|
||||
"X.......X ",
|
||||
"X........X ",
|
||||
"X.....XXXXX ",
|
||||
"X..X..X ",
|
||||
"X.X X..X ",
|
||||
"XX X..X ",
|
||||
"X X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XX "
|
||||
};
|
||||
+154
@@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -40,6 +41,7 @@
|
||||
#include "input.h"
|
||||
#include "msgskip.h"
|
||||
#include "hacks.h"
|
||||
#include "virtual_pointer.h"
|
||||
|
||||
static void get_event(void);
|
||||
static void keyEventProsess(SDL_KeyboardEvent *e, bool pressed);
|
||||
@@ -277,6 +279,13 @@ void send_agsevent(enum agsevent_type type, int code) {
|
||||
}
|
||||
|
||||
void event_set_mouse_location(int x, int y) {
|
||||
if (vp_is_enabled()) {
|
||||
// In virtual pointer mode there is no visible OS cursor to warp; move
|
||||
// the internal location instead so the on-screen virtual cursor follows
|
||||
// (including each step of the eased path in ags_setCursorLocation()).
|
||||
event_set_mouse_internal_location(x, y);
|
||||
return;
|
||||
}
|
||||
// scale mouse x and y
|
||||
float scalex, scaley;
|
||||
SDL_RenderGetScale(gfx_renderer, &scalex, &scaley);
|
||||
@@ -306,9 +315,16 @@ void event_set_mouse_location(int x, int y) {
|
||||
void event_set_mouse_internal_location(int x, int y) {
|
||||
mousex = x;
|
||||
mousey = y;
|
||||
if (vp_is_enabled())
|
||||
gfx_dirty = true; // repaint so the virtual cursor follows
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
}
|
||||
|
||||
void event_get_pointer_pos(int *x, int *y) {
|
||||
*x = mousex;
|
||||
*y = mousey;
|
||||
}
|
||||
|
||||
// Stores a deferred touch event (valid if .timestamp != 0) to add a delay
|
||||
// between mouse pointer movement and mouse button state change caused by a
|
||||
// touch event. This prevents the game from processing a button down event
|
||||
@@ -352,6 +368,127 @@ static void rance4v2_hack(void) {
|
||||
cancel_yield();
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual mouse pointer (trackpad-style touch input).
|
||||
* Active only when nact->ags.virtualpointer is set. Reuses the pointer state
|
||||
* (mousex/mousey/mouseb, RawKeyInfo) so all game queries are unaffected.
|
||||
*/
|
||||
#define VP_SENSITIVITY 1.5f // finger-to-cursor movement multiplier
|
||||
#define VP_TAP_MAX_MOVE 0.02f // max normalized finger travel for a tap
|
||||
#define VP_TAP_MAX_TIME 300 // max touch duration (ms) for a tap
|
||||
#define VP_LONGPRESS_TIME 500 // hold time (ms) to start a drag
|
||||
#define VP_CLICK_HOLD_TIME 100 // how long (ms) a tap holds the left button
|
||||
|
||||
static bool vp_primary_down; // a finger is tracked as the pointer
|
||||
static SDL_FingerID vp_primary_id;
|
||||
static uint32_t vp_down_time;
|
||||
static float vp_moved_dist; // accumulated normalized finger travel
|
||||
static bool vp_moved; // travel exceeded the tap threshold
|
||||
static bool vp_longpress; // left button held due to a long press (drag)
|
||||
static bool vp_two_finger; // right button held due to a 2nd finger
|
||||
static bool vp_click_release_pending;
|
||||
static uint32_t vp_click_release_time;
|
||||
static bool vp_centered; // cursor has been placed at the center
|
||||
|
||||
static void vp_press(int button) {
|
||||
mouseb |= 1 << button;
|
||||
RawKeyInfo[mouse_to_rawkey(button)] = true;
|
||||
send_agsevent(AGSEVENT_BUTTON_PRESS, mouse_to_agsevent(button));
|
||||
}
|
||||
|
||||
static void vp_release(int button) {
|
||||
mouseb &= ~(1 << button);
|
||||
RawKeyInfo[mouse_to_rawkey(button)] = false;
|
||||
send_agsevent(AGSEVENT_BUTTON_RELEASE, mouse_to_agsevent(button));
|
||||
}
|
||||
|
||||
static void vp_move(float dnx, float dny) {
|
||||
mousex += (int)lroundf(dnx * view_w * VP_SENSITIVITY);
|
||||
mousey += (int)lroundf(dny * view_h * VP_SENSITIVITY);
|
||||
// Keep the cursor inside the view.
|
||||
if (mousex < 0) mousex = 0;
|
||||
else if (mousex >= view_w) mousex = view_w - 1;
|
||||
if (mousey < 0) mousey = 0;
|
||||
else if (mousey >= view_h) mousey = view_h - 1;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
gfx_dirty = true;
|
||||
}
|
||||
|
||||
static void vp_finger_down(SDL_TouchFingerEvent *t) {
|
||||
if (SDL_GetNumTouchFingers(t->touchId) >= 2) {
|
||||
// A second finger means a right click at the current position.
|
||||
if (!vp_two_finger) {
|
||||
vp_two_finger = true;
|
||||
vp_press(SDL_BUTTON_RIGHT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// First finger: start tracking. The cursor moves only on drag.
|
||||
vp_primary_down = true;
|
||||
vp_primary_id = t->fingerId;
|
||||
vp_down_time = SDL_GetTicks();
|
||||
vp_moved_dist = 0.0f;
|
||||
vp_moved = false;
|
||||
}
|
||||
|
||||
static void vp_finger_motion(SDL_TouchFingerEvent *t) {
|
||||
if (vp_two_finger || !vp_primary_down || t->fingerId != vp_primary_id)
|
||||
return;
|
||||
vp_moved_dist += hypotf(t->dx, t->dy);
|
||||
if (vp_moved_dist > VP_TAP_MAX_MOVE)
|
||||
vp_moved = true;
|
||||
vp_move(t->dx, t->dy);
|
||||
}
|
||||
|
||||
static void vp_finger_up(SDL_TouchFingerEvent *t) {
|
||||
if (vp_two_finger) {
|
||||
// Release the right button once every finger is lifted.
|
||||
if (SDL_GetNumTouchFingers(t->touchId) == 0) {
|
||||
vp_two_finger = false;
|
||||
vp_primary_down = false;
|
||||
vp_release(SDL_BUTTON_RIGHT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!vp_primary_down || t->fingerId != vp_primary_id)
|
||||
return;
|
||||
vp_primary_down = false;
|
||||
if (vp_longpress) {
|
||||
vp_longpress = false;
|
||||
vp_release(SDL_BUTTON_LEFT); // end drag
|
||||
} else if (!vp_moved && SDL_GetTicks() - vp_down_time < VP_TAP_MAX_TIME) {
|
||||
// Tap: left click. Hold the button briefly so polling games detect it.
|
||||
vp_press(SDL_BUTTON_LEFT);
|
||||
vp_click_release_pending = true;
|
||||
vp_click_release_time = SDL_GetTicks() + VP_CLICK_HOLD_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
// Time-driven virtual pointer transitions, polled each event pump.
|
||||
static void vp_tick(void) {
|
||||
if (!vp_is_enabled())
|
||||
return;
|
||||
uint32_t now = SDL_GetTicks();
|
||||
// Place the cursor at the center once the view size is known.
|
||||
if (!vp_centered && view_w > 0 && view_h > 0) {
|
||||
mousex = view_w / 2;
|
||||
mousey = view_h / 2;
|
||||
vp_centered = true;
|
||||
gfx_dirty = true;
|
||||
}
|
||||
// A stationary long press starts a left-button drag.
|
||||
if (vp_primary_down && !vp_moved && !vp_longpress && !vp_two_finger &&
|
||||
now - vp_down_time >= VP_LONGPRESS_TIME) {
|
||||
vp_longpress = true;
|
||||
vp_press(SDL_BUTTON_LEFT);
|
||||
}
|
||||
// Release the briefly-held tap click.
|
||||
if (vp_click_release_pending && now >= vp_click_release_time) {
|
||||
vp_click_release_pending = false;
|
||||
vp_release(SDL_BUTTON_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
void event_handle_event(SDL_Event *e) {
|
||||
if (event_custom_handler && event_custom_handler(e))
|
||||
return;
|
||||
@@ -396,6 +533,10 @@ void event_handle_event(SDL_Event *e) {
|
||||
#endif
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
// Ignore real mouse motion while the virtual pointer is active. This
|
||||
// also discards the spurious (0,0) motion seen right after startup.
|
||||
if (vp_is_enabled())
|
||||
break;
|
||||
event_set_mouse_internal_location(e->motion.x, e->motion.y);
|
||||
#ifdef _WIN32
|
||||
win_menu_onMouseMotion(e->motion.x, e->motion.y);
|
||||
@@ -429,6 +570,10 @@ void event_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
|
||||
case SDL_FINGERDOWN:
|
||||
if (vp_is_enabled()) {
|
||||
vp_finger_down(&e->tfinger);
|
||||
break;
|
||||
}
|
||||
if (SDL_GetNumTouchFingers(e->tfinger.touchId) >= 2) {
|
||||
mouseb &= ~(1 << SDL_BUTTON_LEFT);
|
||||
mouseb |= 1 << SDL_BUTTON_RIGHT;
|
||||
@@ -455,6 +600,10 @@ void event_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
|
||||
case SDL_FINGERUP:
|
||||
if (vp_is_enabled()) {
|
||||
vp_finger_up(&e->tfinger);
|
||||
break;
|
||||
}
|
||||
if (SDL_GetNumTouchFingers(e->tfinger.touchId) == 0) {
|
||||
int ags_button = (mouseb & 1 << SDL_BUTTON_LEFT) ? AGSEVENT_BUTTON_LEFT : AGSEVENT_BUTTON_RIGHT;
|
||||
mousex = e->tfinger.x * view_w;
|
||||
@@ -465,6 +614,10 @@ void event_handle_event(SDL_Event *e) {
|
||||
break;
|
||||
|
||||
case SDL_FINGERMOTION:
|
||||
if (vp_is_enabled()) {
|
||||
vp_finger_motion(&e->tfinger);
|
||||
break;
|
||||
}
|
||||
mousex = e->tfinger.x * view_w;
|
||||
mousey = e->tfinger.y * view_h;
|
||||
send_agsevent(AGSEVENT_MOUSE_MOTION, 0);
|
||||
@@ -554,6 +707,7 @@ static void get_event(void) {
|
||||
enum scheduler_event scheduler_event = SCHEDULER_EVENT_INPUT_CHECK_MISS;
|
||||
|
||||
fire_deferred_touch_event();
|
||||
vp_tick();
|
||||
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
|
||||
@@ -31,6 +31,7 @@ void event_remove(void);
|
||||
void event_set_joy_device_index(int index);
|
||||
void event_set_mouse_location(int x, int y);
|
||||
void event_set_mouse_internal_location(int x, int y);
|
||||
void event_get_pointer_pos(int *x, int *y);
|
||||
int event_get_key(void);
|
||||
int event_get_mouse(SDL_Point *p);
|
||||
void event_get_wheel(int *forward, int *back);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "image.h"
|
||||
#include "nact.h"
|
||||
#include "debugger.h"
|
||||
#include "virtual_pointer.h"
|
||||
|
||||
static void gfx_pal_check(void) {
|
||||
if (nact->ags.pal_changed) {
|
||||
@@ -60,6 +61,7 @@ void gfx_updateScreen(void) {
|
||||
return;
|
||||
SDL_RenderClear(gfx_renderer);
|
||||
SDL_RenderCopy(gfx_renderer, gfx_texture, NULL, NULL);
|
||||
vp_draw(gfx_renderer);
|
||||
SDL_RenderPresent(gfx_renderer);
|
||||
gfx_dirty = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* virtual_pointer.c Trackpad-style virtual mouse pointer for touch devices
|
||||
*
|
||||
* Copyright (C) 2026 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "portab.h"
|
||||
#include "system.h"
|
||||
#include "nact.h"
|
||||
#include "event.h"
|
||||
#include "virtual_pointer.h"
|
||||
|
||||
#include "bitmaps/virtual_cursor.xpm"
|
||||
|
||||
bool vp_is_enabled(void) {
|
||||
return nact->ags.virtualpointer;
|
||||
}
|
||||
|
||||
// Builds an ARGB surface from the (simple, 1 char/pixel) XPM array above.
|
||||
static SDL_Surface *create_cursor_surface(void) {
|
||||
int w, h, ncolors, cpp;
|
||||
if (sscanf(virtual_cursor[0], "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 || cpp != 1) {
|
||||
WARNING("virtual_pointer: unexpected cursor bitmap header");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Map each character to an ARGB8888 value.
|
||||
Uint32 colormap[256] = {0};
|
||||
for (int i = 0; i < ncolors; i++) {
|
||||
const char *line = virtual_cursor[1 + i];
|
||||
unsigned char ch = (unsigned char)line[0];
|
||||
// Format: "<ch> c <value>", value is "#rrggbb" or "None".
|
||||
const char *val = line + 4;
|
||||
if (val[0] == '#') {
|
||||
unsigned int rgb = (unsigned int)strtoul(val + 1, NULL, 16);
|
||||
colormap[ch] = 0xff000000u | rgb; // opaque
|
||||
} else {
|
||||
colormap[ch] = 0; // transparent
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface *s = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
if (!s)
|
||||
return NULL;
|
||||
const char **pixels = &virtual_cursor[1 + ncolors];
|
||||
for (int y = 0; y < h; y++) {
|
||||
Uint32 *row = (Uint32 *)((Uint8 *)s->pixels + y * s->pitch);
|
||||
const char *src = pixels[y];
|
||||
for (int x = 0; x < w; x++)
|
||||
row[x] = colormap[(unsigned char)src[x]];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// Lazily-created cursor texture. The hotspot (arrow tip) is at its top-left
|
||||
// corner, so it is drawn with its origin at the pointer position.
|
||||
static SDL_Texture *cursor_texture;
|
||||
static int cursor_w, cursor_h;
|
||||
|
||||
void vp_draw(SDL_Renderer *renderer) {
|
||||
if (!vp_is_enabled())
|
||||
return;
|
||||
|
||||
if (!cursor_texture) {
|
||||
SDL_Surface *s = create_cursor_surface();
|
||||
if (!s)
|
||||
return;
|
||||
cursor_w = s->w;
|
||||
cursor_h = s->h;
|
||||
cursor_texture = SDL_CreateTextureFromSurface(renderer, s);
|
||||
SDL_FreeSurface(s);
|
||||
if (!cursor_texture)
|
||||
return;
|
||||
SDL_SetTextureBlendMode(cursor_texture, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
|
||||
int x, y;
|
||||
event_get_pointer_pos(&x, &y);
|
||||
// The renderer's logical size is set to the game view, so drawing in view
|
||||
// coordinates positions the cursor exactly at the game's mouse coordinates.
|
||||
SDL_Rect dst = { x, y, cursor_w, cursor_h };
|
||||
SDL_RenderCopy(renderer, cursor_texture, NULL, &dst);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* virtual_pointer.h Trackpad-style virtual mouse pointer for touch devices
|
||||
*
|
||||
* Copyright (C) 2026 <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* This program 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 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __VIRTUAL_POINTER_H__
|
||||
#define __VIRTUAL_POINTER_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <SDL.h>
|
||||
|
||||
/* Returns true if the virtual mouse pointer feature is enabled. */
|
||||
bool vp_is_enabled(void);
|
||||
|
||||
/*
|
||||
* Draws the virtual cursor on top of the presented frame. No-op when the
|
||||
* feature is disabled. Called from gfx_updateScreen() between the game image
|
||||
* RenderCopy and RenderPresent.
|
||||
*/
|
||||
void vp_draw(SDL_Renderer *renderer);
|
||||
|
||||
#endif /* __VIRTUAL_POINTER_H__ */
|
||||
@@ -145,6 +145,7 @@ static void sys35_usage(bool verbose) {
|
||||
puts(" -fullscreen : start with fullscreen");
|
||||
puts(" -integerscale : use integer scaling when resizing");
|
||||
puts(" -noimagecursor : disable image cursor");
|
||||
puts(" -virtualpointer : enable the virtual mouse pointer (for touch)");
|
||||
puts(" -version : show version");
|
||||
puts(" -h : show this message");
|
||||
puts(" --help : show this message");
|
||||
@@ -286,6 +287,8 @@ static void sys35_ParseOption(int *argc, char **argv) {
|
||||
}
|
||||
} else if (0 == strcmp(argv[i], "-noimagecursor")) {
|
||||
nact->ags.noimagecursor = true;
|
||||
} else if (0 == strcmp(argv[i], "-virtualpointer")) {
|
||||
nact->ags.virtualpointer = true;
|
||||
} else if (0 == strcmp(argv[i], "-debuglv")) {
|
||||
if (argv[i + 1] != NULL) {
|
||||
sys_set_debug_level(argv[i + 1][0] - '0');
|
||||
@@ -380,6 +383,9 @@ static void check_profile() {
|
||||
/* disable image cursor */
|
||||
get_boolean_profile("no_imagecursor", &nact->ags.noimagecursor);
|
||||
|
||||
/* enable the virtual mouse pointer */
|
||||
get_boolean_profile("virtualpointer", &nact->ags.virtualpointer);
|
||||
|
||||
/* enable integer scaling */
|
||||
get_boolean_profile("integerscale", &integer_scaling);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user