gte_neon: use more accurate division
[pcsx_rearmed.git] / frontend / in_tsbutton.c
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 <tslib.h>
13
14 #include "common/input.h"
15 #include "pl_gun_ts.h"
16 #include "in_tsbutton.h"
17
18 #define IN_TSBUTTON_PREFIX "tsbutton:"
19 #define IN_TSBUTTON_COUNT 4
20 static int tsbutton_down_id;
21 static int last_tsbutton_id;
22
23 #define TS_WIDTH 320
24 #define TS_HEIGHT 240
25
26 // HACK: stealing this from plugin_lib
27 extern void *tsdev;
28
29 static const char * const in_tsbutton_keys[IN_TSBUTTON_COUNT] = {
30         "TS1", "TS2", "TS3", "TS4",
31 };
32
33 static void in_tsbutton_probe(void)
34 {
35         struct tsdev *dev = tsdev;
36         if (dev == NULL) {
37                 fprintf(stderr, "in_tsbutton_probe: missing tsdev\n");
38                 return;
39         }
40
41         in_register(IN_TSBUTTON_PREFIX "touchscreen as buttons",
42                 pl_gun_ts_get_fd(dev), NULL, IN_TSBUTTON_COUNT, in_tsbutton_keys, 0);
43 }
44
45 static const char * const *
46 in_tsbutton_get_key_names(int *count)
47 {
48         *count = IN_TSBUTTON_COUNT;
49         return in_tsbutton_keys;
50 }
51
52 static int update_button(void)
53 {
54         struct tsdev *dev = tsdev;
55         int sx = 0, sy = 0, sp = 0;
56
57         if (dev == NULL)
58                 return -1;
59
60         if (pl_gun_ts_update_raw(dev, &sx, &sy, &sp)) {
61                 if (sp == 0)
62                         tsbutton_down_id = -1;
63                 else {
64                         // 0 1
65                         // 2 3
66                         tsbutton_down_id = 0;
67                         if (sx > TS_WIDTH / 2)
68                                 tsbutton_down_id++;
69                         if (sy > TS_HEIGHT / 2)
70                                 tsbutton_down_id += 2;
71                 }
72         }
73
74         return 0;
75 }
76
77 static int in_tsbutton_update(void *drv_data, const int *binds, int *result)
78 {
79         int ret, t;
80         
81         ret = update_button();
82         if (ret != 0)
83                 return ret;
84
85         if (tsbutton_down_id >= 0)
86                 for (t = 0; t < IN_BINDTYPE_COUNT; t++)
87                         result[t] |= binds[IN_BIND_OFFS(tsbutton_down_id, t)];
88
89         return 0;
90 }
91
92 static int in_tsbutton_update_keycode(void *data, int *is_down)
93 {
94         int ret, ret_kc = -1, ret_down = 0;
95
96         ret = update_button();
97         if (ret != 0)
98                 return ret;
99
100         if (tsbutton_down_id == last_tsbutton_id)
101                 return -1;
102
103         if (tsbutton_down_id >= 0) {
104                 if (last_tsbutton_id >= 0) {
105                         ret_kc = last_tsbutton_id;
106                         last_tsbutton_id = -1;
107                 }
108                 else {
109                         ret_down = 1;
110                         ret_kc = tsbutton_down_id;
111                         last_tsbutton_id = tsbutton_down_id;
112                 }
113         }
114         else {
115                 ret_kc = last_tsbutton_id;
116                 last_tsbutton_id = -1;
117         }
118
119         if (is_down != NULL)
120                 *is_down = ret_down;
121
122         return ret_kc;
123 }
124
125 static const in_drv_t in_tsbutton_drv = {
126         .prefix         = IN_TSBUTTON_PREFIX,
127         .probe          = in_tsbutton_probe,
128         .get_key_names  = in_tsbutton_get_key_names,
129         .update         = in_tsbutton_update,
130         .update_keycode = in_tsbutton_update_keycode,
131 };
132
133 void in_tsbutton_init(void)
134 {
135         tsbutton_down_id = last_tsbutton_id = -1;
136         in_register_driver(&in_tsbutton_drv);
137 }
138