frontend: move layer size code
[pcsx_rearmed.git] / frontend / pl_gun_ts.c
CommitLineData
4c08b9e7 1/*
2 * (C) GraÅžvydas "notaz" Ignotas, 2011
3 *
4 * This work is licensed under the terms of any of these licenses
5 * (at your option):
6 * - GNU GPL, version 2 or later.
7 * - GNU LGPL, version 2.1 or later.
8 * See the COPYING file in the top-level directory.
9 */
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <dlfcn.h>
14#include <tslib.h>
15#include "plugin_lib.h"
16#include "pl_gun_ts.h"
17#include "menu.h"
18#include "../plugins/dfinput/main.h"
19
20static int gun_x, gun_y, gun_in;
21static int ts_multiplier_x, ts_multiplier_y, ts_offs_x, ts_offs_y;
50306d8d 22static int (*pts_read)(struct tsdev *dev, struct ts_sample *sample, int nr);
23static int (*pts_fd)(struct tsdev *dev);
4c08b9e7 24
25#define limit(v, min, max) \
26 if (v < min) v = min; \
27 else if (v > max) v = max
28
50306d8d 29int pl_gun_ts_update_raw(struct tsdev *ts, int *x, int *y, int *p)
4c08b9e7 30{
31 struct ts_sample sample;
32 int sx = 0, sy = 0, sp = 0, updated = 0;
33
34 if (ts != NULL) {
35 while (pts_read(ts, &sample, 1) > 0) {
36 sx = sample.x;
37 sy = sample.y;
38 sp = sample.pressure;
39 updated = 1;
40 }
41
42 if (updated) {
43 gun_x = (sx - ts_offs_x) * ts_multiplier_x >> 10;
44 gun_y = (sy - ts_offs_y) * ts_multiplier_y >> 10;
45 limit(gun_x, 0, 1023);
46 limit(gun_y, 0, 1023);
47 if (sp && !(g_opts & OPT_TSGUN_NOTRIGGER))
48 gun_in |= GUNIN_TRIGGER;
49 else
50 gun_in &= ~GUNIN_TRIGGER;
51 }
52 }
53
50306d8d 54 if (updated) {
55 if (x) *x = sx;
56 if (y) *y = sy;
57 if (p) *p = sp;
58 return 1;
59 }
60
61 return 0;
62}
63
64void pl_gun_ts_update(struct tsdev *ts, int *x, int *y, int *in)
65{
66 pl_gun_ts_update_raw(ts, NULL, NULL, NULL);
67
4c08b9e7 68 *x = gun_x;
69 *y = gun_y;
70 *in = gun_in | in_state_gun;
71}
72
73void pl_set_gun_rect(int x, int y, int w, int h)
74{
75 ts_offs_x = x;
76 ts_offs_y = y;
77 ts_multiplier_x = (1<<20) / w;
78 ts_multiplier_y = (1<<20) / h;
79}
80
50306d8d 81int pl_gun_ts_get_fd(struct tsdev *ts)
82{
83 if (ts != NULL && pts_fd != NULL)
84 return pts_fd(ts);
85
86 return -1;
87}
88
4c08b9e7 89struct tsdev *pl_gun_ts_init(void)
90{
91 struct tsdev *(*pts_open)(const char *dev_name, int nonblock) = NULL;
92 int (*pts_config)(struct tsdev *) = NULL;
93 int (*pts_close)(struct tsdev *) = NULL;
94 const char *tsdevname;
95 struct tsdev *ts;
96 void *ltsh;
97
98 tsdevname = getenv("TSLIB_TSDEVICE");
99 if (tsdevname == NULL)
100 tsdevname = "/dev/input/touchscreen0";
101
102 // avoid hard dep on tslib
faf2b2aa 103 ltsh = dlopen("/usr/lib/libts-1.0.so.0", RTLD_NOW|RTLD_GLOBAL);
4c08b9e7 104 if (ltsh == NULL)
faf2b2aa 105 ltsh = dlopen("/usr/lib/libts-0.0.so.0", RTLD_NOW|RTLD_GLOBAL);
50306d8d 106 if (ltsh == NULL)
107 ltsh = dlopen("/lib/libts-0.0.so.0", RTLD_NOW|RTLD_GLOBAL);
4c08b9e7 108 if (ltsh == NULL) {
109 fprintf(stderr, "%s\n", dlerror());
110 goto fail;
111 }
112
113 pts_open = dlsym(ltsh, "ts_open");
114 pts_config = dlsym(ltsh, "ts_config");
115 pts_read = dlsym(ltsh, "ts_read");
faf2b2aa 116 pts_fd = dlsym(ltsh, "ts_fd");
4c08b9e7 117 pts_close = dlsym(ltsh, "ts_close");
faf2b2aa 118 if (pts_open == NULL || pts_config == NULL || pts_read == NULL
119 || pts_fd == NULL || pts_close == NULL) {
4c08b9e7 120 fprintf(stderr, "%s\n", dlerror());
121 goto fail_dlsym;
122 }
123
124 ts = pts_open(tsdevname, 1);
125 if (ts == NULL)
126 goto fail_open;
127 if (pts_config(ts) != 0)
128 goto fail_config;
129
130 // FIXME: we should be able to get this somewhere
131 // the problem is this doesn't always match resolution due to different display modes
55b0eeea 132#ifdef __ARM_ARCH_7A__
4c08b9e7 133 pl_set_gun_rect(0, 0, 800, 480);
55b0eeea 134#else
135 pl_set_gun_rect(0, 0, 320, 240);
136#endif
4c08b9e7 137 return ts;
138
139fail_config:
366631aa 140 pts_close(ts);
4c08b9e7 141fail_open:
142fail_dlsym:
143 dlclose(ltsh);
144 ltsh = NULL;
145fail:
146 fprintf(stderr, "Could not open touchscreen\n");
147 return NULL;
148}
149