1 /*
2  * file w32_joystick.c - joystick support
3  *
4  * $Id: w32_joystick.c,v 1.6 2006/02/19 13:33:01 lodott Exp $
5  *
6  * Program XBLAST
7  * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2; or (at your option)
12  * any later version
13  *
14  * This program is distributed in the hope that it will be entertaining,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.
21  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 #include "xblast.h"
24 #include "w32_joystick.h"
25 #include "gui.h"
26 
27 //#include "w32_mm.h"
28 
29 /*
30  * local macros
31  */
32 #define MAX_JOYSTICK 2
33 
34 /* flags for joystick X and Y positions */
35 #define JOYDIR_NONE  0x00
36 #define JOYDIR_UP    0x01
37 #define JOYDIR_DOWN  0x02
38 #define JOYDIR_Y     0x03
39 #define JOYDIR_LEFT  0x04
40 #define JOYDIR_RIGHT 0x08
41 #define JOYDIR_X     0x0C
42 
43 /*
44  * local types
45  */
46 
47 /* joystick data */
48 typedef struct
49 {
50 	XBEventCode event;			/* event code to send */
51 	unsigned dir;				/* current direction */
52 	unsigned xLow;				/* calibration data */
53 	unsigned xHigh;				/* calibration data */
54 	unsigned yLow;				/* calibration data */
55 	unsigned yHigh;				/* calibration data */
56 } XBJoystick;
57 
58 /*
59  * local variables
60  */
61 
62 /* available joystick IDs */
63 static const UINT joyDevice[MAX_JOYSTICK] = {
64 	JOYSTICKID1,
65 	JOYSTICKID2,
66 };
67 
68 /* joystick parameters */
69 static XBJoystick joystick[MAX_JOYSTICK];
70 
71 /*
72  *  how many joystick do we support
73  */
74 int
GUI_NumJoysticks(void)75 GUI_NumJoysticks (void)
76 {
77 	int i, num;
78 
79 	for (i = 0, num = 0; i < MAX_JOYSTICK; i++) {
80 		if (XBE_NONE != joystick[i].event) {
81 			num++;
82 		}
83 	}
84 	return num;
85 }								/* GUI_NumJoysticks */
86 
87 /*
88  * init joystick support
89  */
90 XBBool
InitJoystick(void)91 InitJoystick (void)
92 {
93 	int i, j;
94 	UINT joyThres;
95 	static JOYCAPS joyCaps;
96 
97 	memset (joystick, 0, sizeof (joystick));
98 	for (i = 0, j = 0; i < joyGetNumDevs () && i < MAX_JOYSTICK && j < MAX_JOYSTICK; i++) {
99 		/* get device */
100 		if (JOYERR_NOERROR != joyGetDevCaps (joyDevice[i], &joyCaps, sizeof (joyCaps))) {
101 			continue;
102 		}
103 		/* set threshold */
104 		joyThres = ABS ((int)joyCaps.wYmin - (int)joyCaps.wYmax) / 8;
105 		if (JOYERR_NOERROR != joySetThreshold (joyDevice[i], joyThres)) {
106 			continue;
107 		}
108 		if (JOYERR_NOERROR != joySetCapture (window, joyDevice[i], 0, TRUE)) {
109 			continue;
110 		}
111 		joystick[i].event = XBE_JOYST_1 + j;
112 		joystick[i].dir = JOYDIR_NONE;
113 		joystick[i].xLow = 3 * (joyCaps.wXmin / 4) + 1 * (joyCaps.wXmax / 4);
114 		joystick[i].xHigh = 1 * (joyCaps.wXmin / 4) + 3 * (joyCaps.wXmax / 4);
115 		joystick[i].yLow = 3 * (joyCaps.wYmin / 4) + 1 * (joyCaps.wYmax / 4);
116 		joystick[i].yHigh = 1 * (joyCaps.wYmin / 4) + 3 * (joyCaps.wYmax / 4);
117 		j++;
118 		Dbg_Out ("Joystick (%d) %s connected as XBE_JOYST_%d. x=(%u,%u) y=(%u,%u)\n",
119 				 i + 1, joyCaps.szPname, j, joyCaps.wXmin, joyCaps.wXmax, joyCaps.wYmin,
120 				 joyCaps.wYmax);
121 	}
122 	return XBTrue;
123 }								/* InitJoystick */
124 
125 /*
126  * finish joystick support
127  */
128 void
FinishJoystick(void)129 FinishJoystick (void)
130 {
131 	size_t i;
132 
133 	for (i = 0; i < MAX_JOYSTICK; i++) {
134 		if (XBE_NONE != joystick[i].event) {
135 			joyReleaseCapture (joyDevice[i]);
136 		}
137 	}
138 }								/* FinishJoystick */
139 
140 /*
141  * calculate new joystick position for window message
142  */
143 static unsigned
EvalJoystickMove(LONG lParam,const XBJoystick * pJoy)144 EvalJoystickMove (LONG lParam, const XBJoystick * pJoy)
145 {
146 	UINT xPos, yPos;
147 	unsigned newDir = 0;
148 
149 	/* sanity check */
150 	assert (NULL != pJoy);
151 
152 	/* get x-position */
153 	xPos = LOWORD (lParam);
154 	if (pJoy->xHigh < pJoy->xLow) {
155 		if (xPos < pJoy->xHigh) {
156 			newDir |= JOYDIR_LEFT;
157 		}
158 		else if (xPos > pJoy->xLow) {
159 			newDir |= JOYDIR_RIGHT;
160 		}
161 	}
162 	else {
163 		if (xPos > pJoy->xHigh) {
164 			newDir |= JOYDIR_RIGHT;
165 		}
166 		else if (xPos < pJoy->xLow) {
167 			newDir |= JOYDIR_LEFT;
168 		}
169 	}
170 	/* get y-position */
171 	yPos = HIWORD (lParam);
172 	if (pJoy->yHigh < pJoy->yLow) {
173 		if (yPos < pJoy->yHigh) {
174 			newDir |= JOYDIR_UP;
175 		}
176 		else if (yPos > pJoy->yLow) {
177 			newDir |= JOYDIR_DOWN;
178 		}
179 	}
180 	else {
181 		if (yPos > pJoy->yHigh) {
182 			newDir |= JOYDIR_DOWN;
183 		}
184 		else if (yPos < pJoy->yLow) {
185 			newDir |= JOYDIR_UP;
186 		}
187 	}
188 	return newDir;
189 }								/* EvalJoyMove */
190 
191 /*
192  * handle joysticks messages in menu mode
193  */
194 void
HandleMenuJoy(UINT message,UINT wParam,LONG lParam)195 HandleMenuJoy (UINT message, UINT wParam, LONG lParam)
196 {
197 	XBJoystick *pJoy;
198 	unsigned newDir;
199 
200 	switch (message) {
201 		/* button presses */
202 	case MM_JOY1BUTTONDOWN:
203 	case MM_JOY2BUTTONDOWN:
204 		QueueEventValue (XBE_MENU, XBMK_SELECT);
205 		break;
206 		/* joystick movement */
207 	case MM_JOY1MOVE:
208 	case MM_JOY2MOVE:
209 		if (message == MM_JOY1MOVE) {
210 			pJoy = joystick + 0;
211 		}
212 		else {
213 			pJoy = joystick + 1;
214 		}
215 		newDir = EvalJoystickMove (lParam, pJoy);
216 		if (newDir != pJoy->dir) {
217 			/* test changes in y dir */
218 			if ((newDir & JOYDIR_Y) != (pJoy->dir & JOYDIR_Y)) {
219 				switch (newDir & JOYDIR_Y) {
220 				case JOYDIR_UP:
221 					QueueEventValue (XBE_MENU, XBMK_UP);
222 					break;
223 				case JOYDIR_DOWN:
224 					QueueEventValue (XBE_MENU, XBMK_DOWN);
225 					break;
226 				}
227 			}
228 			if ((newDir & JOYDIR_X) != (pJoy->dir & JOYDIR_X)) {
229 				switch (newDir & JOYDIR_X) {
230 				case JOYDIR_LEFT:
231 					QueueEventValue (XBE_MENU, XBMK_LEFT);
232 					break;
233 				case JOYDIR_RIGHT:
234 					QueueEventValue (XBE_MENU, XBMK_RIGHT);
235 					break;
236 				}
237 			}
238 			pJoy->dir = newDir;
239 		}
240 	}
241 }								/* HandleMenuJoy */
242 
243 /*
244  * handle joysticks messages in game mode
245  */
246 void
HandleXBlastJoy(UINT message,UINT wParam,LONG lParam)247 HandleXBlastJoy (UINT message, UINT wParam, LONG lParam)
248 {
249 	XBJoystick *pJoy;
250 	unsigned newDir;
251 	int value;
252 
253 	switch (message) {
254 		/* button presses */
255 	case MM_JOY1BUTTONDOWN:
256 	case MM_JOY2BUTTONDOWN:
257 		if (message == MM_JOY1BUTTONDOWN) {
258 			pJoy = joystick + 0;
259 		}
260 		else {
261 			pJoy = joystick + 1;
262 		}
263 		if (pJoy->event != XBE_NONE) {
264 			if (JOY_BUTTON1CHG & wParam) {
265 				QueueEventValue (pJoy->event, XBGK_BOMB);
266 			}
267 			if (JOY_BUTTON2CHG & wParam) {
268 				QueueEventValue (pJoy->event, XBGK_SPECIAL);
269 			}
270 		}
271 		break;
272 		/* moving */
273 	case MM_JOY1MOVE:
274 	case MM_JOY2MOVE:
275 		if (message == MM_JOY1MOVE) {
276 			pJoy = joystick + 0;
277 		}
278 		else {
279 			pJoy = joystick + 1;
280 		}
281 		if (pJoy->event != XBE_NONE) {
282 			newDir = EvalJoystickMove (lParam, pJoy);
283 			switch (newDir) {
284 			case JOYDIR_UP:
285 				value = XBGK_GO_UP;
286 				break;
287 			case JOYDIR_DOWN:
288 				value = XBGK_GO_DOWN;
289 				break;
290 			case JOYDIR_LEFT:
291 				value = XBGK_GO_LEFT;
292 				break;
293 			case JOYDIR_RIGHT:
294 				value = XBGK_GO_RIGHT;
295 				break;
296 			case JOYDIR_NONE:
297 				value = XBGK_STOP_ALL;
298 				break;
299 			default:
300 				value = XBGK_NONE;
301 				break;
302 			}
303 			if (value != XBGK_NONE && newDir != pJoy->dir) {
304 				QueueEventValue (pJoy->event, value);
305 				pJoy->dir = newDir;
306 			}
307 		}
308 		break;
309 	}
310 }								/* HandleXBlastJoy */
311 
312 /*
313  * end fo file w32_joystick.c
314  */
315