more properly handling new haa semantics
[drnoksnes] / platform / zeemote.cpp
1 #include <stdio.h>
2
3 #include "snes9x.h"
4
5 #include <glib.h>
6 #include <libosso.h>
7 #include <gconf/gconf.h>
8 #include <gconf/gconf-client.h>
9
10 /* Zeemote driver contributed by Till Harbaum */
11
12 extern "C" {
13 #include <zeemote.h>
14 #include <zeemote-conf.h>
15 }
16
17 #include "platform.h"
18 #include "osso.h"
19 #include "../gui/gconf.h"
20 #include "zeemote.h"
21
22 /* Zeemote analog stick sensivity limit */
23 #define ZEEMOTE_LIMIT  8000
24
25 static const unsigned short zeemote_mask[] = 
26 {
27         SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK 
28 };
29
30 typedef struct zeemote_player {
31         /** Pointer to zeemote_t struct. If NULL, zeemote was not enabled for this player. */
32         zeemote_t *zeemote;
33         uint32 prev_buttons;
34 } zeemote_player_t;
35
36 static zeemote_player_t players[2] = { {0, 0}, {0, 0} };
37
38 void ZeeInit()
39 {
40         /* Check if Osso initialization was succesful. */
41         if (!OssoOk()) return;
42
43         /* Since Zeemote means GConf, we can read our own configuration from it */
44         GConfClient *gcc = gconf_client_get_default();
45
46         /* Check which players (if any) enabled Zeemote */
47         gchar key[kGConfPlayerPathBufferLen];
48         gchar *relKey;
49         bool enabled[2];
50
51         /* Player 1? */
52         relKey = key + sprintf(key, kGConfPlayerPath, 1);
53         strcpy(relKey, kGConfPlayerZeemoteEnable);
54         enabled[0] = gconf_client_get_bool(gcc, key, NULL);
55
56         /* Player 2? */
57         relKey = key + sprintf(key, kGConfPlayerPath, 2);
58         strcpy(relKey, kGConfPlayerZeemoteEnable);
59         enabled[1] = gconf_client_get_bool(gcc, key, NULL);
60
61         if (!enabled[0] && !enabled[1]) {
62                 /* No player wanted a zeemote! */
63                 return;
64         }
65
66         /* Get list of configured zeemotes from the conf tool. One could */
67         /* alternally call zeemote_scan() which would return the same type */
68         /* of list, but instead from the devices currently visible. Also */
69         /* zeemote_scan() blocks for about 10 seconds */
70         zeemote_scan_result_t *scan_result = 
71                 zeemote_get_scan_results_from_gconf();
72
73         if (!scan_result) {
74                 fprintf(stderr, "Zeemote: No scan results\n");
75         }
76
77         /* If we found a zeemote, assign it to the first player. If we found
78          * two zeemotes, assign the first found one to the first player, etc. */
79         /* Since the order comes from gconf, the user could potentially change
80            it */
81         if (enabled[0] && scan_result->number_of_devices > 0) {
82                 players[0].zeemote =
83                         zeemote_connect(&scan_result->device[0].bdaddr);
84                 if (players[0].zeemote) {
85                         Config.joypad1Enabled = true;
86                 } else {
87                         fprintf(stderr, "Zeemote: Failed to connect for player %d", 1);
88                 }
89         }
90         if (enabled[1] && scan_result->number_of_devices > 1) {
91                 players[1].zeemote =
92                         zeemote_connect(&scan_result->device[1].bdaddr);
93                 if (players[1].zeemote) {
94                         Config.joypad2Enabled = true;
95                 } else {
96                         fprintf(stderr, "Zeemote: Failed to connect for player %d", 2);
97                 }
98         }
99
100         if (players[0].zeemote && players[1].zeemote) {
101                 printf("Zeemote: enabled for two players\n");
102         } else if (players[0].zeemote) {
103                 printf("Zeemote: enabled for player %d\n", 1);
104         } else if (players[1].zeemote) {
105                 printf("Zeemote: enabled for player %d\n", 2);
106         } else {
107                 printf("Zeemote: disabled because of error\n");
108         }
109 }
110
111 static void read_for_player(zeemote_player_t *player, uint32 *joypad)
112 {
113         if (!player->zeemote) return;
114
115         zeemote_state_t *state = zeemote_get_state(player->zeemote);
116         if (!state) return; // Some error
117          // Zeemote was disconnected
118         if (state->state != ZEEMOTE_STATE_CONNECTED) return;
119
120         uint32 buttons = 0;
121         int i;
122
123         /* check zeemote buttons A-D */
124         for (i = 0; i < 4; i++) {
125                 if (state->buttons & (1<<i))
126                         buttons |= zeemote_mask[i];
127         }
128
129         /* handle direction */
130         if (state->axis[0] < -ZEEMOTE_LIMIT) buttons |= SNES_LEFT_MASK;
131         if (state->axis[0] >  ZEEMOTE_LIMIT) buttons |= SNES_RIGHT_MASK;
132         if (state->axis[1] < -ZEEMOTE_LIMIT) buttons |= SNES_UP_MASK;
133         if (state->axis[1] >  ZEEMOTE_LIMIT) buttons |= SNES_DOWN_MASK;
134
135         /* check which actual buttons were pressed or released */
136         uint32 buttons_changed = buttons ^ player->prev_buttons;
137         uint32 buttons_pressed = buttons_changed & buttons;
138         uint32 buttons_released = buttons_changed & player->prev_buttons;
139
140         /* prevent device screensaver when zeemote state changes */
141         if (buttons_changed)
142         {
143                 osso_display_blanking_pause(ossoContext);
144                 player->prev_buttons = buttons;
145         }
146
147         *joypad = (*joypad & ~buttons_released) | buttons_pressed;
148 }
149
150 void ZeeRead(uint32* joypads)
151 {
152         read_for_player(&players[0], &joypads[0]);
153         read_for_player(&players[1], &joypads[1]);
154 }
155
156 void ZeeQuit()
157 {
158         if (players[0].zeemote) {
159                 zeemote_disconnect(players[0].zeemote);
160                 players[0].zeemote = 0;
161         }
162         if (players[1].zeemote) {
163                 zeemote_disconnect(players[1].zeemote);
164                 players[1].zeemote = 0;
165         }
166 }
167