asm compatibility re-fixed, nsf for asm fixed, msg displ
[fceu.git] / drivers / gp2x / input.c
CommitLineData
35868d35 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#define JOY_A 1
22#define JOY_B 2
23#define JOY_SELECT 4
24#define JOY_START 8
25#define JOY_UP 0x10
26#define JOY_DOWN 0x20
27#define JOY_LEFT 0x40
28#define JOY_RIGHT 0x80
29
35868d35 30#include "minimal.h"
13624c8f 31
32
35868d35 33extern int swapbuttons;
937bf65b 34extern int scaled_display;
35868d35 35extern int FSkip_setting;
36
37extern void SetVideoScaling(int pixels,int width,int height);
35868d35 38
39
40
41/* UsrInputType[] is user-specified. InputType[] is current
42 (game loading can override user settings)
43*/
44static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
45static int InputType[2];
46
47static int UsrInputTypeFC={SI_NONE};
48static int InputTypeFC;
49
50static uint32 JSreturn;
51int NoWaiting=0;
52
53static int powerpadsc[2][12];
54static int powerpadside=0;
55
56
57static uint32 MouseData[3];
58static uint8 fkbkeys[0x48];
59unsigned long lastpad=0;
60
35868d35 61extern void ResetNES(void);
62extern void CleanSurface(void);
63
64char soundvolmeter[21];
65int soundvolIndex=0;
66int L_count=0;
67int R_count=0;
68extern int CurrentState;
69int TurboFireOff=1;
70int TurboFireTop=0; // 0 is none // 1 is A & X turbo // 2 is Y & B turbo
71int TurboFireBottom=0;
72int turbo_toggle_A=0;
73int turbo_toggle_B=0;
74
13624c8f 75
35868d35 76static void setsoundvol(int soundvolume)
77{
78 //FCEUI_SetSoundVolume(soundvol);
79 // draw on screen :D
80 gp2x_sound_volume(soundvolume, soundvolume);
81 int meterval=soundvolume/5;
82 for (soundvolIndex=0; soundvolIndex < 20; soundvolIndex++)
83 {
84 if (soundvolIndex < meterval)
85 {
86 soundvolmeter[soundvolIndex]='*';
87 }
88 else
89 {
90 soundvolmeter[soundvolIndex]='_';
91 }
92 }
93 soundvolmeter[20]=0;
94 FCEU_DispMessage("|%s|", soundvolmeter);
95}
13624c8f 96
97
98
99void FCEUD_UpdateInput(void)
35868d35 100{
13624c8f 101 long lastpad2=lastpad;
102 unsigned long pad=gp2x_joystick_read();
35868d35 103 uint32 JS=0;
104
35868d35 105#define down(b) (pad & GP2X_##b)
106#define last_down(b) (lastpad & GP2X_##b)
107#define L_down (pad & GP2X_L)
108#define R_down (pad & GP2X_R)
109#define last_L_down (lastpad & GP2X_L)
110#define last_R_down (lastpad & GP2X_R)
111#define shift ((pad & GP2X_PUSH) || ((pad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
112#define last_shift ((lastpad & GP2X_PUSH) || ((lastpad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN)))
113
114 if (L_down && R_down && !(pad & GP2X_PUSH) && !(last_R_down && last_L_down))
115 {
116 ResetNES();
117 puts("Reset");
118 goto no_pad;
119 }
120
121 if (down(VOL_UP) && !down(VOL_DOWN))
122 {
123 soundvol+=1;
124 if (soundvol >= 100) soundvol=100;
125 //FCEUI_SetSoundVolume(soundvol);
126 setsoundvol(soundvol);
127 }
128 else if (down(VOL_DOWN) && !down(VOL_UP))
129 {
130 soundvol-=1;
131 if (soundvol < 0) soundvol=0;
132 //FCEUI_SetSoundVolume(soundvol);
133 setsoundvol(soundvol);
134 }
135
136 if (shift)
137 {
138 // only if it's something else then last time, and not moving around the joystick
139 if (!(pad & (GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT)))
140 {
141 if (down(SELECT))
142 {
143 if (last_down(SELECT) && last_shift)
144 {
145 // still pressed down from stretching from last one
146 goto no_pad;
147 }
937bf65b 148 scaled_display = !scaled_display;
35868d35 149
937bf65b 150 if (scaled_display)
35868d35 151 {
937bf65b 152 SetVideoScaling(320, 256, 240);
35868d35 153 }
154 else
155 {
937bf65b 156 SetVideoScaling(320, 320, 240);
35868d35 157 }
158
159 goto no_pad;
160 }
161 else if (L_down && R_down)
162 {
163 FCEUI_CloseGame();
164 puts("Quit");
165 goto no_pad;
166 }
167 else if (R_down && !(last_R_down && last_shift))
168 {
169 FCEUI_LoadState();
170 goto no_pad;
171 }
172 else if (L_down && !(last_L_down && last_shift))
173 {
174 FCEUI_SaveState();
175 goto no_pad;
176 }
177 else if (down(A) && !(last_down(A) && last_shift))
178 {
179 FSkip_setting--;
180 if (FSkip_setting < 0) {
181 FSkip_setting = -1;
182 FCEUI_DispMessage("Auto frameskip");
183 }
184 else
185 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
186 goto no_pad;
187 }
188 else if (down(Y) && !(last_down(Y) && last_shift))
189 {
190 FSkip_setting++;
191 if (FSkip_setting > 8) FSkip_setting = 8;
192 FCEUI_DispMessage("Frameskip: %i", FSkip_setting);
193 goto no_pad;
194 }
195 }
196 }
197
198 // r is toggle savestate
199 if (R_down)
200 {
201 if (last_R_down)
202 {
203 R_count++;
204 if ((R_count & 31)== 31)
205 {
206 CurrentState=(CurrentState+1) % 10;
207 FCEUI_DispMessage("Now Using Save State %d", CurrentState);
208 }
209 }
210 }
211 else
212 {
213 R_count=0;
214 }
215
216 // l is toggle turbo
217 if (L_down)
218 {
219 if (last_L_down)
220 {
221 L_count++;
222 if ((L_count & 31)== 31)
223 {
224 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
225 if ((!TurboFireTop) && (!TurboFireBottom))
226 {
227 // was off
228 TurboFireTop=1;
229 TurboFireBottom=0;
230 if (swapbuttons)
231 {
232 FCEUI_DispMessage("Turbo A and Y");
233 }
234 else
235 {
236 FCEUI_DispMessage("Turbo Y and B");
237 }
238 }
239 else if (TurboFireTop)
240 {
241 TurboFireTop=0;
242 TurboFireBottom=1;
243 if (swapbuttons)
244 {
245 FCEUI_DispMessage("Turbo X and B");
246 }
247 else
248 {
249 FCEUI_DispMessage("Turbo A and X");
250 }
251 }
252 else
253 {
254 TurboFireTop=0;
255 TurboFireBottom=0;
256 FCEUI_DispMessage("Turbo Off");
257 }
258
259 }
260 }
261 }
262 else
263 {
264 L_count=0;
265 }
266
267 //unsigned long padTmp=0;
268 // shift the bits in
269 // up
270 //padTmp=(pad & GP2X_UP) ; // 1 is 2^0,
271 JS |= ((pad & GP2X_UP) << (4-0)); // 0x10 is 2^4
272
273 //padTmp=(pad & GP2X_DOWN); // 0x10 is 2^4,
274 JS |= ((pad & GP2X_DOWN) << (5-4)); // 0x20 is 2^5
275
276 //padTmp=(pad & GP2X_LEFT); // 0x4 is 2^2,
277 JS |= ((pad & GP2X_LEFT) << (6-2)); // 0x40 is 2^6
278
279 //padTmp=(pad & GP2X_RIGHT); // 0x40 is 2^6,
280 JS |= ((pad & GP2X_RIGHT) << (7-6)); // 0x80 is 2^7
281
282
283#define A_down (pad & GP2X_A)
284#define B_down (pad & GP2X_B)
285#define X_down (pad & GP2X_X)
286#define Y_down (pad & GP2X_Y)
287
288 // should be 2 cycles held, 1 cycle release
289 turbo_toggle_A=(turbo_toggle_A+1) % 3;
290 turbo_toggle_B=(turbo_toggle_B+1) % 3;
291
292 // 0 is none // 1 is Y & B turbo // 2 is X & A turbo
293 // B or X are both considered A
294 //padTmp=B_down >> 13; // 2^13,
295
296 if (!(TurboFireTop && (!turbo_toggle_A)))
297 {
298 JS |= ((B_down >> 13) << 0); // 0x1 is 2^0
299 }
300 // A or Y are both considered B
301 //padTmp=A_down >> 12; // 2^13,
302 if (!(TurboFireBottom && (!turbo_toggle_B)))
303 {
304 JS |= ((A_down >> 12) << 1); // 0x2 is 2^1
305 }
306
307 if (swapbuttons)
308 {
309 //padTmp=X_down >> 14; // 2^13,
310 if (!(TurboFireBottom && (!turbo_toggle_A)))
311 {
312// JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
313 JS |= ((Y_down >> 15) << 0); // 0x1 is 2^0
314 }
315
316 //padTmp=Y_down >> 15; // 2^13,
317 if (!(TurboFireTop && (!turbo_toggle_B)))
318 {
319 JS |= ((X_down >> 14) << 1); // 0x2 is 2^1
320 }
321 }
322 else
323 {
324 //padTmp=X_down >> 14; // 2^13,
325 if (!(TurboFireBottom && (!turbo_toggle_A)))
326 {
327 JS |= ((X_down >> 14) << 0); // 0x1 is 2^0
328 }
329
330 //padTmp=Y_down >> 15; // 2^13,
331 if (!(TurboFireTop && (!turbo_toggle_B)))
332 {
333 JS |= ((Y_down >> 15) << 1); // 0x2 is 2^1
334 }
335 }
336
337 // select
338 //padTmp=(pad & GP2X_SELECT) >> 9; // 0x40 is 2^9,
339 JS |= (((pad & GP2X_SELECT) >> 9) << 2); // 0x4 is 2^2
340
341 // start
342 //padTmp=(pad & GP2X_START) >> 8; // 2^8,
343 JS |= (((pad & GP2X_START) >> 8) << 3); // 0x8 is 2^3
344
35868d35 345 JSreturn = JS;
346 lastpad=pad;
347
35868d35 348 //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
13624c8f 349
350
351 // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8);
352 // TODO: make these bindable, use new interface
353 if(gametype==GIT_FDS)
354 {
355 NoWaiting&=~1;
356 if ((pad & GP2X_PUSH) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_R)) && (!(lastpad2 & GP2X_PUSH)))
357 {
358 DriverInterface(DES_FDSSELECT,0);
359 }
360 else if ((pad & GP2X_L) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_PUSH)) && (!(pad & GP2X_R))&& (!(lastpad2 & GP2X_L)))
361 {
362 DriverInterface(DES_FDSINSERT,0);
363 }
364 else if ((pad & GP2X_R) && (!(pad & GP2X_SELECT)) && (!(pad & GP2X_L)) && (!(pad & GP2X_PUSH)) && (!(lastpad2 & GP2X_R)))
365 {
366 DriverInterface(DES_FDSEJECT,0);
367 }
368 }
369 return;
370
35868d35 371no_pad:
372 JSreturn=0;
373 lastpad=pad;
35868d35 374}
35868d35 375
376
377static void InitOtherInput(void)
378{
379
380 void *InputDPtr;
381
382 int t;
383 int x;
384 int attrib;
385
386 for(t=0,x=0;x<2;x++)
387 {
388 attrib=0;
389 InputDPtr=0;
390 switch(InputType[x])
391 {
392 //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
393 case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
394 case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
395 case SI_ZAPPER:InputDPtr=MouseData;
396 t|=1;
397 attrib=1;
398 break;
399 }
400 FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
401 }
402
403 attrib=0;
404 InputDPtr=0;
405 switch(InputTypeFC)
406 {
407 case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
408 case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
409 case SIFC_FKB:InputDPtr=fkbkeys;break;
410 }
411
412 FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
413 FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
414
415 if(t && !(inited&16))
416 {
417 InitMouse();
418 inited|=16;
419 }
420}