6760af5f0ed694e76faec85b53973a6477ab121d
[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 static zeemote_t *zeemote;
31 static uint32 prev_buttons;
32 static int player;
33
34 void ZeeInit()
35 {
36         /* Check if Osso initialization was succesful. */
37         if (!OssoOk()) return;
38
39         /* Since Zeemote means GConf, we can read our own configuration from it */
40         GConfClient *gcc = gconf_client_get_default();
41
42         /* Check which player (if any) enabled Zeemote */
43         player = 0;
44         /* Player 1? */
45         gchar key[kGConfPlayerPathBufferLen];
46         gchar *relKey = key + sprintf(key, kGConfPlayerPath, 1);
47         strcpy(relKey, kGConfPlayerZeemoteEnable);
48         if (gconf_client_get_bool(gcc, key, NULL)) {
49                 player = 1;
50         } else {
51                 /* Player 2? */
52                 relKey = key + sprintf(key, kGConfPlayerPath, 2);
53                 strcpy(relKey, kGConfPlayerZeemoteEnable);
54                 if (gconf_client_get_bool(gcc, key, NULL)) {
55                         player = 2;
56                 }
57         }
58
59         if (player) {
60                 printf("Zeemote: Enabled for player %d\n", player);
61         } else {
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 devices are configured use the first one in the list as this */
74         /* is supposed to be a single player game */
75         if(scan_result && scan_result->number_of_devices > 0) {
76                 zeemote = zeemote_connect(&scan_result->device[0].bdaddr);
77         }
78 }
79
80 void ZeeRead(uint32* joypads)
81 {
82         if (!zeemote) return;
83
84         zeemote_state_t *state = zeemote_get_state(zeemote);
85         if (!state) return; // Some error
86         if (state->state != ZEEMOTE_STATE_CONNECTED) return; // Not connected
87
88         uint32 buttons = 0;
89         int i;
90
91         /* check zeemote buttons A-D */
92         for (i = 0; i < 4; i++) {
93                 if (state->buttons & (1<<i))
94                         buttons |= zeemote_mask[i];
95         }
96
97         /* handle direction */
98         if (state->axis[0] < -ZEEMOTE_LIMIT) buttons |= SNES_LEFT_MASK;
99         if (state->axis[0] >  ZEEMOTE_LIMIT) buttons |= SNES_RIGHT_MASK;
100         if (state->axis[1] < -ZEEMOTE_LIMIT) buttons |= SNES_UP_MASK;
101         if (state->axis[1] >  ZEEMOTE_LIMIT) buttons |= SNES_DOWN_MASK;
102  
103         /* prevent device screensaver when zeemote state changes */
104         if (buttons != prev_buttons) 
105         {
106                 osso_display_blanking_pause(ossoContext);
107                 prev_buttons = buttons;
108         }
109
110         joypads[player-1] |= buttons;
111 }
112
113 void ZeeQuit()
114 {
115         if (zeemote) {
116                 zeemote_disconnect(zeemote);
117                 zeemote = 0;
118         }
119 }
120