From 4c08b9e7dd350a48fc3e0515913d6ccc8b15e5ae Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 9 Aug 2011 01:16:59 +0300 Subject: add guncon support a bit basic but works --- frontend/main.c | 6 ++- frontend/main.h | 6 +++ frontend/menu.c | 44 ++++++++++++++----- frontend/menu.h | 1 + frontend/pl_gun_ts.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/pl_gun_ts.h | 14 ++++++ frontend/plat_omap.c | 4 ++ frontend/plugin.c | 6 +-- frontend/plugin_lib.c | 27 ++++++++++-- frontend/plugin_lib.h | 6 ++- 10 files changed, 212 insertions(+), 20 deletions(-) create mode 100644 frontend/pl_gun_ts.c create mode 100644 frontend/pl_gun_ts.h (limited to 'frontend') diff --git a/frontend/main.c b/frontend/main.c index b17df53..c5520cf 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -149,8 +149,6 @@ void do_emu_action(void) emu_action_old = emu_action; switch (emu_action) { - case SACTION_NONE: - return; case SACTION_ENTER_MENU: menu_loop(); return; @@ -196,6 +194,8 @@ void do_emu_action(void) snprintf(hud_msg, sizeof(hud_msg), "SCREENSHOT TAKEN"); break; } + default: + return; } hud_new_msg = 3; return; @@ -204,6 +204,7 @@ do_state_slot: snprintf(hud_msg, sizeof(hud_msg), "STATE SLOT %d [%s]", state_slot, emu_check_state(state_slot) == 0 ? "USED" : "FREE"); hud_new_msg = 3; + printf("* %s\n", hud_msg); } int main(int argc, char *argv[]) @@ -317,6 +318,7 @@ int main(int argc, char *argv[]) //in_probe(); plat_init(); menu_init(); // loads config + pl_init(); if (psxout) Config.PsxOut = 1; diff --git a/frontend/main.h b/frontend/main.h index eadb3c6..7267f2b 100644 --- a/frontend/main.h +++ b/frontend/main.h @@ -57,8 +57,14 @@ enum sched_action { SACTION_PREV_SSLOT, SACTION_TOGGLE_FSKIP, SACTION_SCREENSHOT, + SACTION_GUN_TRIGGER = 16, + SACTION_GUN_A, + SACTION_GUN_B, + SACTION_GUN_TRIGGER2, }; +#define SACTION_GUN_MASK (0x0f << SACTION_GUN_TRIGGER) + static inline void emu_set_action(enum sched_action action_) { extern enum sched_action emu_action, emu_action_old; diff --git a/frontend/menu.c b/frontend/menu.c index 6a07c8c..8b51c06 100644 --- a/frontend/menu.c +++ b/frontend/menu.c @@ -30,7 +30,7 @@ #include "../libpcsxcore/cdrom.h" #include "../libpcsxcore/psemu_plugin_defs.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" -#include "../plugins/dfinput/pad.h" +#include "../plugins/dfinput/main.h" #include "revision.h" #define MENU_X2 1 @@ -73,7 +73,7 @@ static int last_psx_w, last_psx_h, last_psx_bpp; static int scaling, filter, cpu_clock, cpu_clock_st, volume_boost; static char rom_fname_reload[MAXPATHLEN]; static char last_selected_fname[MAXPATHLEN]; -static int warned_about_bios, region, in_type_sel; +static int warned_about_bios, region, in_type_sel1, in_type_sel2; static int memcard1_sel, memcard2_sel; int g_opts; @@ -143,7 +143,16 @@ static void menu_sync_config(void) Config.PsxAuto = 0; Config.PsxType = region - 1; } - in_type = in_type_sel ? PSE_PAD_TYPE_ANALOGPAD : PSE_PAD_TYPE_STANDARD; + switch (in_type_sel1) { + case 1: in_type1 = PSE_PAD_TYPE_ANALOGPAD; break; + case 2: in_type1 = PSE_PAD_TYPE_GUNCON; break; + default: in_type1 = PSE_PAD_TYPE_STANDARD; + } + switch (in_type_sel2) { + case 1: in_type2 = PSE_PAD_TYPE_ANALOGPAD; break; + case 2: in_type2 = PSE_PAD_TYPE_GUNCON; break; + default: in_type2 = PSE_PAD_TYPE_STANDARD; + } if (in_evdev_allow_abs_only != allow_abs_only_old) { pandora_rescan_inputs(); allow_abs_only_old = in_evdev_allow_abs_only; @@ -165,7 +174,7 @@ static void menu_set_defconfig(void) volume_boost = 0; region = 0; - in_type_sel = 0; + in_type_sel1 = in_type_sel2 = 0; in_evdev_allow_abs_only = 0; Config.Xa = Config.Cdda = Config.Sio = Config.SpuIrq = Config.RCntFix = Config.VSyncWA = 0; @@ -233,7 +242,8 @@ static const struct { CE_INTVAL(state_slot), CE_INTVAL(cpu_clock), CE_INTVAL(g_opts), - CE_INTVAL(in_type_sel), + CE_INTVAL(in_type_sel1), + CE_INTVAL(in_type_sel2), CE_INTVAL_P(frameskip), CE_INTVAL_P(gpu_peops.iUseDither), CE_INTVAL_P(gpu_peops.dwActFixes), @@ -708,6 +718,10 @@ me_bind_action emuctrl_actions[] = { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP }, { "Take Screenshot ", 1 << SACTION_SCREENSHOT }, { "Enter Menu ", 1 << SACTION_ENTER_MENU }, + { "Gun Trigger ", 1 << SACTION_GUN_TRIGGER }, + { "Gun A button ", 1 << SACTION_GUN_A }, + { "Gun B button ", 1 << SACTION_GUN_B }, + { "Gun Offscreen Trigger", 1 << SACTION_GUN_TRIGGER2 }, { NULL, 0 } }; @@ -943,17 +957,25 @@ static int mh_input_rescan(int id, int keys) return 0; } -static const char *men_in_type_sel[] = { "Standard (SCPH-1080)", "Analog (SCPH-1150)", NULL }; +static const char *men_in_type_sel[] = { + "Standard (SCPH-1080)", + "Analog (SCPH-1150)", + "GunCon", + NULL +}; static const char h_nub_btns[] = "Experimental, keep this OFF if unsure. Select rescan after change."; +static const char h_notsgun[] = "Don't trigger (shoot) when touching screen in gun games."; static menu_entry e_menu_keyconfig[] = { - mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap), - mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap), - mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap), + mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap), + mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap), + mee_handler_id("Emulator/Gun controls", MA_CTRL_EMU, key_config_loop_wrap), mee_label (""), - mee_enum ("Controller", 0, in_type_sel, men_in_type_sel), + mee_enum ("Port 1 device", 0, in_type_sel1, men_in_type_sel), + mee_enum ("Port 2 device", 0, in_type_sel2, men_in_type_sel), mee_onoff_h ("Nubs as buttons", 0, in_evdev_allow_abs_only, 1, h_nub_btns), + mee_onoff_h ("No TS Gun trigger", 0, g_opts, OPT_TSGUN_NOTRIGGER, h_notsgun), mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), mee_handler ("Rescan devices", mh_input_rescan), @@ -2000,7 +2022,7 @@ void menu_prepare_emu(void) fprintf(stderr, "Warning: GPU_open returned %d\n", ret); } - dfinput_activate(in_type == PSE_PAD_TYPE_ANALOGPAD); + dfinput_activate(); } void me_update_msg(const char *msg) diff --git a/frontend/menu.h b/frontend/menu.h index 7e401a3..1635146 100644 --- a/frontend/menu.h +++ b/frontend/menu.h @@ -10,6 +10,7 @@ enum opts { OPT_SHOWCPU = 1 << 1, OPT_NO_FRAMELIM = 1 << 2, OPT_SHOWSPU = 1 << 3, + OPT_TSGUN_NOTRIGGER = 1 << 4, }; extern int g_opts; diff --git a/frontend/pl_gun_ts.c b/frontend/pl_gun_ts.c new file mode 100644 index 0000000..63cf33f --- /dev/null +++ b/frontend/pl_gun_ts.c @@ -0,0 +1,118 @@ +/* + * (C) GraÅžvydas "notaz" Ignotas, 2011 + * + * This work is licensed under the terms of any of these licenses + * (at your option): + * - GNU GPL, version 2 or later. + * - GNU LGPL, version 2.1 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include +#include "plugin_lib.h" +#include "pl_gun_ts.h" +#include "menu.h" +#include "../plugins/dfinput/main.h" + +static int gun_x, gun_y, gun_in; +static int ts_multiplier_x, ts_multiplier_y, ts_offs_x, ts_offs_y; +static int (*pts_read)(struct tsdev *dev, struct ts_sample *sample, int nr); + +#define limit(v, min, max) \ + if (v < min) v = min; \ + else if (v > max) v = max + +void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in) +{ + struct ts_sample sample; + int sx = 0, sy = 0, sp = 0, updated = 0; + + if (ts != NULL) { + while (pts_read(ts, &sample, 1) > 0) { + sx = sample.x; + sy = sample.y; + sp = sample.pressure; + updated = 1; + } + + if (updated) { + gun_x = (sx - ts_offs_x) * ts_multiplier_x >> 10; + gun_y = (sy - ts_offs_y) * ts_multiplier_y >> 10; + limit(gun_x, 0, 1023); + limit(gun_y, 0, 1023); + if (sp && !(g_opts & OPT_TSGUN_NOTRIGGER)) + gun_in |= GUNIN_TRIGGER; + else + gun_in &= ~GUNIN_TRIGGER; + } + } + + *x = gun_x; + *y = gun_y; + *in = gun_in | in_state_gun; +} + +void pl_set_gun_rect(int x, int y, int w, int h) +{ + ts_offs_x = x; + ts_offs_y = y; + ts_multiplier_x = (1<<20) / w; + ts_multiplier_y = (1<<20) / h; +} + +struct tsdev *pl_gun_ts_init(void) +{ + struct tsdev *(*pts_open)(const char *dev_name, int nonblock) = NULL; + int (*pts_config)(struct tsdev *) = NULL; + int (*pts_close)(struct tsdev *) = NULL; + const char *tsdevname; + struct tsdev *ts; + void *ltsh; + + tsdevname = getenv("TSLIB_TSDEVICE"); + if (tsdevname == NULL) + tsdevname = "/dev/input/touchscreen0"; + + // avoid hard dep on tslib + ltsh = dlopen("/usr/lib/libts-1.0.so.0", RTLD_LAZY); + if (ltsh == NULL) + ltsh = dlopen("/usr/lib/libts-0.0.so.0", RTLD_LAZY); + if (ltsh == NULL) { + fprintf(stderr, "%s\n", dlerror()); + goto fail; + } + + pts_open = dlsym(ltsh, "ts_open"); + pts_config = dlsym(ltsh, "ts_config"); + pts_read = dlsym(ltsh, "ts_read"); + pts_close = dlsym(ltsh, "ts_close"); + if (pts_open == NULL || pts_config == NULL || pts_read == NULL || pts_close == NULL) { + fprintf(stderr, "%s\n", dlerror()); + goto fail_dlsym; + } + + ts = pts_open(tsdevname, 1); + if (ts == NULL) + goto fail_open; + if (pts_config(ts) != 0) + goto fail_config; + + // FIXME: we should be able to get this somewhere + // the problem is this doesn't always match resolution due to different display modes + pl_set_gun_rect(0, 0, 800, 480); + return ts; + +fail_config: + pts_close(ltsh); +fail_open: +fail_dlsym: + dlclose(ltsh); + ltsh = NULL; +fail: + fprintf(stderr, "Could not open touchscreen\n"); + return NULL; +} + diff --git a/frontend/pl_gun_ts.h b/frontend/pl_gun_ts.h new file mode 100644 index 0000000..c68272a --- /dev/null +++ b/frontend/pl_gun_ts.h @@ -0,0 +1,14 @@ +#ifdef HAVE_TSLIB + +struct tsdev; + +struct tsdev *pl_gun_ts_init(void); +void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in); +void pl_set_gun_rect(int x, int y, int w, int h); + +#else + +#define pl_gun_ts_init() NULL +#define pl_gun_ts_update(...) do {} while (0) + +#endif diff --git a/frontend/plat_omap.c b/frontend/plat_omap.c index 516e06f..5939dcb 100644 --- a/frontend/plat_omap.c +++ b/frontend/plat_omap.c @@ -18,6 +18,7 @@ #include "linux/fbdev.h" #include "linux/oshide.h" #include "plugin_lib.h" +#include "pl_gun_ts.h" #include "omap.h" #include "pandora.h" @@ -80,6 +81,9 @@ static int omap_setup_layer_(int fd, int enabled, int x, int y, int w, int h, in int omap_enable_layer(int enabled) { + if (enabled) + pl_set_gun_rect(g_layer_x, g_layer_y, g_layer_w, g_layer_h); + return omap_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled, g_layer_x, g_layer_y, g_layer_w, g_layer_h, 0); } diff --git a/frontend/plugin.c b/frontend/plugin.c index 7b0d301..fa4cf21 100644 --- a/frontend/plugin.c +++ b/frontend/plugin.c @@ -43,9 +43,9 @@ extern void SPUplayCDDAchannel(short *, int); /* PAD */ static long PADreadPort1(PadDataS *pad) { - pad->controllerType = in_type; + pad->controllerType = in_type1; pad->buttonStatus = ~in_keystate; - if (in_type == PSE_PAD_TYPE_ANALOGPAD) { + if (in_type1 == PSE_PAD_TYPE_ANALOGPAD) { pad->leftJoyX = in_a1[0]; pad->leftJoyY = in_a1[1]; pad->rightJoyX = in_a2[0]; @@ -56,7 +56,7 @@ static long PADreadPort1(PadDataS *pad) static long PADreadPort2(PadDataS *pad) { - pad->controllerType = PSE_PAD_TYPE_STANDARD; + pad->controllerType = in_type2; pad->buttonStatus = ~in_keystate >> 16; return 0; } diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 8d5605f..bde4f9c 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -25,18 +25,23 @@ #include "menu.h" #include "main.h" #include "pcnt.h" +#include "pl_gun_ts.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../libpcsxcore/psemu_plugin_defs.h" void *pl_fbdev_buf; int pl_frame_interval; -int in_type, in_keystate, in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; +int in_type1, in_type2; +int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; +int in_keystate, in_state_gun; +static void *ts; static int pl_fbdev_w, pl_fbdev_h, pl_fbdev_bpp; static int flip_cnt, vsync_cnt, flips_per_sec, tick_per_sec; static float vsps_cur; static int vsync_usec_time; -static int get_cpu_ticks(void) + +static __attribute__((noinline)) int get_cpu_ticks(void) { static unsigned long last_utime; static int fd; @@ -185,9 +190,12 @@ static void update_input(void) unsigned int emu_act; in_update(actions); - if (in_type == PSE_PAD_TYPE_ANALOGPAD) + if (in_type1 == PSE_PAD_TYPE_ANALOGPAD) in_update_analogs(); emu_act = actions[IN_BINDTYPE_EMU]; + in_state_gun = (emu_act & SACTION_GUN_MASK) >> SACTION_GUN_TRIGGER; + + emu_act &= ~SACTION_GUN_MASK; if (emu_act) { int which = 0; for (; !(emu_act & 1); emu_act >>= 1, which++) @@ -205,6 +213,15 @@ static void update_input(void) #endif } +void pl_update_gun(int *xn, int *xres, int *y, int *in) +{ + if (ts) + pl_gun_ts_update(ts, xn, y, in); + + *xres = pl_fbdev_w; + *y = *y * pl_fbdev_h >> 10; +} + #define MAX_LAG_FRAMES 3 #define tvdiff(tv, tv_old) \ @@ -396,3 +413,7 @@ void pl_start_watchdog(void) fprintf(stderr, "could not start watchdog: %d\n", ret); } +void pl_init(void) +{ + ts = pl_gun_ts_init(); +} diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h index 49894af..759e125 100644 --- a/frontend/plugin_lib.h +++ b/frontend/plugin_lib.h @@ -17,7 +17,8 @@ enum { DKEY_CROSS, DKEY_SQUARE, }; -extern int in_type, in_keystate, in_a1[2], in_a2[2]; +extern int in_type1, in_type2; +extern int in_keystate, in_state_gun, in_a1[2], in_a2[2]; void in_update_analogs(void); extern void *pl_fbdev_buf; @@ -30,6 +31,9 @@ void pl_fbdev_close(void); void pl_text_out16(int x, int y, const char *texto, ...); void pl_start_watchdog(void); void *pl_prepare_screenshot(int *w, int *h, int *bpp); +void pl_init(void); + +void pl_update_gun(int *xn, int *xres, int *y, int *in); struct rearmed_cbs { void (*pl_get_layer_pos)(int *x, int *y, int *w, int *h); -- cgit v1.2.3