5 * Michael Laforest < para >
6 * Email: < thepara (--AT--) g m a i l [--DOT--] com >
10 * This file is part of wiiuse.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * $Header: /lvm/shared/ds/ds/cvs/devkitpro-cvsbackup/libogc/wiiuse/classic.c,v 1.7 2008-11-14 13:34:57 shagkur Exp $
31 * @brief Classic controller expansion device.
43 #include "definitions.h"
44 #include "wiiuse_internal.h"
50 static void classic_ctrl_pressed_buttons(struct classic_ctrl_t
* cc
, short now
);
53 * @brief Handle the handshake data from the classic controller.
55 * @param cc A pointer to a classic_ctrl_t structure.
56 * @param data The data read in from the device.
57 * @param len The length of the data block, in bytes.
59 * @return Returns 1 if handshake was successful, 0 if not.
61 int classic_ctrl_handshake(struct wiimote_t
* wm
, struct classic_ctrl_t
* cc
, ubyte
* data
, uword len
) {
67 cc
->btns_released
= 0;
71 for (i = 0; i < len; ++i)
72 data[i] = (data[i] ^ 0x17) + 0x17;
74 if (data
[offset
] == 0xFF) {
76 * Sometimes the data returned here is not correct.
77 * This might happen because the wiimote is lagging
78 * behind our initialization sequence.
79 * To fix this just request the handshake again.
81 * Other times it's just the first 16 bytes are 0xFF,
82 * but since the next 16 bytes are the same, just use
85 if (data
[offset
+ 16] == 0xFF) {
86 /* get the calibration data again */
87 WIIUSE_DEBUG("Classic controller handshake appears invalid, trying again.");
88 wiiuse_read_data(wm
, data
, WM_EXP_MEM_CALIBR
, EXP_HANDSHAKE_LEN
, wiiuse_handshake_expansion
);
95 cc
->ljs
.max
.x
= data
[0 + offset
] / 4 == 0 ? 64 : data
[0 + offset
] / 4;
96 cc
->ljs
.min
.x
= data
[1 + offset
] / 4;
97 cc
->ljs
.center
.x
= data
[2 + offset
] / 4 == 0 ? 32 : data
[2 + offset
] / 4;
98 cc
->ljs
.max
.y
= data
[3 + offset
] / 4 == 0 ? 64 : data
[3 + offset
] / 4;
99 cc
->ljs
.min
.y
= data
[4 + offset
] / 4;
100 cc
->ljs
.center
.y
= data
[5 + offset
] / 4 == 0 ? 32 : data
[5 + offset
] / 4;
102 cc
->rjs
.max
.x
= data
[6 + offset
] / 8 == 0 ? 32 : data
[6 + offset
] / 8;
103 cc
->rjs
.min
.x
= data
[7 + offset
] / 8;
104 cc
->rjs
.center
.x
= data
[8 + offset
] / 8 == 0 ? 16 : data
[8 + offset
] / 8;
105 cc
->rjs
.max
.y
= data
[9 + offset
] / 8 == 0 ? 32 : data
[9 + offset
] / 8;
106 cc
->rjs
.min
.y
= data
[10 + offset
] / 8;
107 cc
->rjs
.center
.y
= data
[11 + offset
] / 8 == 0 ? 16 : data
[11 + offset
] / 8;
110 wm
->event
= WIIUSE_CLASSIC_CTRL_INSERTED
;
111 wm
->exp
.type
= EXP_CLASSIC
;
114 wm
->timeout
= WIIMOTE_DEFAULT_TIMEOUT
;
122 * @brief The classic controller disconnected.
124 * @param cc A pointer to a classic_ctrl_t structure.
126 void classic_ctrl_disconnected(struct classic_ctrl_t
* cc
)
128 memset(cc
, 0, sizeof(struct classic_ctrl_t
));
134 * @brief Handle classic controller event.
136 * @param cc A pointer to a classic_ctrl_t structure.
137 * @param msg The message specified in the event packet.
139 void classic_ctrl_event(struct classic_ctrl_t
* cc
, ubyte
* msg
) {
144 for (i = 0; i < 6; ++i)
145 msg[i] = (msg[i] ^ 0x17) + 0x17;
147 classic_ctrl_pressed_buttons(cc
, BIG_ENDIAN_SHORT(*(short*)(msg
+ 4)));
149 /* left/right buttons */
150 cc
->ls_raw
= (((msg
[2] & 0x60) >> 2) | ((msg
[3] & 0xE0) >> 5));
151 cc
->rs_raw
= (msg
[3] & 0x1F);
154 * TODO - LR range hardcoded from 0x00 to 0x1F.
155 * This is probably in the calibration somewhere.
158 cc
->r_shoulder
= ((float)r
/ 0x1F);
159 cc
->l_shoulder
= ((float)l
/ 0x1F);
161 /* calculate joystick orientation */
162 cc
->ljs
.pos
.x
= (msg
[0] & 0x3F);
163 cc
->ljs
.pos
.y
= (msg
[1] & 0x3F);
164 cc
->rjs
.pos
.x
= ((msg
[0] & 0xC0) >> 3) | ((msg
[1] & 0xC0) >> 5) | ((msg
[2] & 0x80) >> 7);
165 cc
->rjs
.pos
.y
= (msg
[2] & 0x1F);
167 calc_joystick_state(&cc
->ljs
, cc
->ljs
.pos
.x
, cc
->ljs
.pos
.y
);
168 calc_joystick_state(&cc
->rjs
, cc
->rjs
.pos
.x
, cc
->rjs
.pos
.y
);
174 * @brief Find what buttons are pressed.
176 * @param cc A pointer to a classic_ctrl_t structure.
177 * @param msg The message byte specified in the event packet.
179 static void classic_ctrl_pressed_buttons(struct classic_ctrl_t
* cc
, short now
) {
180 /* message is inverted (0 is active, 1 is inactive) */
181 now
= ~now
& CLASSIC_CTRL_BUTTON_ALL
;
183 /* preserve old btns pressed */
184 cc
->btns_last
= cc
->btns
;
186 /* pressed now & were pressed, then held */
187 cc
->btns_held
= (now
& cc
->btns
);
189 /* were pressed or were held & not pressed now, then released */
190 cc
->btns_released
= ((cc
->btns
| cc
->btns_held
) & ~now
);
192 /* buttons pressed now */