aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authornotaz2011-08-09 01:16:59 +0300
committernotaz2011-08-13 00:56:33 +0300
commit4c08b9e7dd350a48fc3e0515913d6ccc8b15e5ae (patch)
tree22f29a06fda180d8269878b3cdb413044a5e351e /frontend
parent19e57cbf170d1ce49f00097f3cc3a4ed96d77374 (diff)
downloadpcsx_rearmed-4c08b9e7dd350a48fc3e0515913d6ccc8b15e5ae.tar.gz
pcsx_rearmed-4c08b9e7dd350a48fc3e0515913d6ccc8b15e5ae.tar.bz2
pcsx_rearmed-4c08b9e7dd350a48fc3e0515913d6ccc8b15e5ae.zip
add guncon support
a bit basic but works
Diffstat (limited to 'frontend')
-rw-r--r--frontend/main.c6
-rw-r--r--frontend/main.h6
-rw-r--r--frontend/menu.c44
-rw-r--r--frontend/menu.h1
-rw-r--r--frontend/pl_gun_ts.c118
-rw-r--r--frontend/pl_gun_ts.h14
-rw-r--r--frontend/plat_omap.c4
-rw-r--r--frontend/plugin.c6
-rw-r--r--frontend/plugin_lib.c27
-rw-r--r--frontend/plugin_lib.h6
10 files changed, 212 insertions, 20 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <tslib.h>
+#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);