initial fce ultra 0.81 import
[fceu.git] / drivers / cli / input.c
CommitLineData
c62d2810 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
30static void UpdateFKB(void);
31
32/* UsrInputType[] is user-specified. InputType[] is current
33 (game loading can override user settings)
34*/
35static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD};
36static int InputType[2];
37
38static int UsrInputTypeFC={SI_NONE};
39static int InputTypeFC;
40
41static uint32 JSreturn;
42int NoWaiting=0;
43
44static void DoCheatSeq(void)
45{
46 #if defined(DOS) || defined(SDL)
47 if(inited&1)
48 SilenceSound(1);
49 #endif
50 KillKeyboard();
51 KillVideo();
52
53 DoConsoleCheatConfig();
54 InitVideo();
55 InitKeyboard();
56 #if defined(DOS) || defined(SDL)
57 if(inited&1)
58 SilenceSound(0);
59 #endif
60}
61
62#include "keyscan.h"
63static char *keys;
64static int DIPS=0;
65static uint8 keyonce[MK_COUNT];
66#define KEY(__a) keys[MK(__a)]
67#define keyonly(__a,__z) {if(KEY(__a)){if(!keyonce[MK(__a)]) {keyonce[MK(__a)]=1;__z}}else{keyonce[MK(__a)]=0;}}
68static int JoySwap=0;
69static int cidisabled=0;
70static int KeyboardUpdate(void)
71{
72
73 if(!UpdateKeyboard())
74 if(keys)
75 return 0;
76
77 keys=GetKeyboard();
78
79 if(InputTypeFC==SIFC_FKB)
80 {
81 keyonly(SCROLLLOCK,cidisabled^=1;
82 FCEUI_DispMessage("Family Keyboard %sabled.",cidisabled?"en":"dis");)
83 #ifdef SDL
84 SDL_WM_GrabInput(cidisabled?SDL_GRAB_ON:SDL_GRAB_OFF);
85 #endif
86 if(cidisabled) return(1);
87 }
88 #ifdef SVGALIB
89 keyonly(F3,LockConsole();)
90 keyonly(F4,UnlockConsole();)
91 #elif SDL
92 keyonly(F4,ToggleFS();)
93 #endif
94 NoWaiting&=~1;
95 if(KEY(GRAVE))
96 NoWaiting|=1;
97
98 if(gametype==GIT_FDS)
99 {
100 keyonly(S,DriverInterface(DES_FDSSELECT,0);)
101 keyonly(I,DriverInterface(DES_FDSINSERT,0);)
102 keyonly(E,DriverInterface(DES_FDSEJECT,0);)
103 }
104
105 keyonly(F9,FCEUI_SaveSnapshot();)
106 if(gametype!=GIT_NSF)
107 {
108 keyonly(F2,DoCheatSeq();)
109 keyonly(F5,FCEUI_SaveState();)
110 keyonly(F7,FCEUI_LoadState();)
111 }
112 else
113 {
114 keyonly(CURSORLEFT,DriverInterface(DES_NSFDEC,0);)
115 keyonly(CURSORRIGHT,DriverInterface(DES_NSFINC,0);)
116 if( KEY(ENTER)) DriverInterface(DES_NSFRES,0);
117 if( KEY(CURSORUP)) DriverInterface(DES_NSFINC,0);
118 if( KEY(CURSORDOWN)) DriverInterface(DES_NSFDEC,0);
119 }
120
121 keyonly(F10,DriverInterface(DES_RESET,0);)
122 keyonly(F11,DriverInterface(DES_POWER,0);)
123 if(KEY(F12) || KEY(ESCAPE)) FCEUI_CloseGame();
124
125 if(gametype==GIT_VSUNI)
126 {
127 keyonly(C,DriverInterface(DES_VSUNICOIN,0);)
128 keyonly(V,DIPS^=1;DriverInterface(DES_VSUNITOGGLEDIPVIEW,0);)
129 if(!(DIPS&1)) goto DIPSless;
130 keyonly(1,DriverInterface(DES_VSUNIDIPSET,(void *)1);)
131 keyonly(2,DriverInterface(DES_VSUNIDIPSET,(void *)2);)
132 keyonly(3,DriverInterface(DES_VSUNIDIPSET,(void *)3);)
133 keyonly(4,DriverInterface(DES_VSUNIDIPSET,(void *)4);)
134 keyonly(5,DriverInterface(DES_VSUNIDIPSET,(void *)5);)
135 keyonly(6,DriverInterface(DES_VSUNIDIPSET,(void *)6);)
136 keyonly(7,DriverInterface(DES_VSUNIDIPSET,(void *)7);)
137 keyonly(8,DriverInterface(DES_VSUNIDIPSET,(void *)8);)
138 }
139 else
140 {
141 keyonly(H,DriverInterface(DES_NTSCSELHUE,0);)
142 keyonly(T,DriverInterface(DES_NTSCSELTINT,0);)
143 if(KEY(KP_MINUS) || KEY(MINUS)) DriverInterface(DES_NTSCDEC,0);
144 if(KEY(KP_PLUS) || KEY(EQUAL)) DriverInterface(DES_NTSCINC,0);
145
146 DIPSless:
147 keyonly(0,FCEUI_SelectState(0);)
148 keyonly(1,FCEUI_SelectState(1);)
149 keyonly(2,FCEUI_SelectState(2);)
150 keyonly(3,FCEUI_SelectState(3);)
151 keyonly(4,FCEUI_SelectState(4);)
152 keyonly(5,FCEUI_SelectState(5);)
153 keyonly(6,FCEUI_SelectState(6);)
154 keyonly(7,FCEUI_SelectState(7);)
155 keyonly(8,FCEUI_SelectState(8);)
156 keyonly(9,FCEUI_SelectState(9);)
157 }
158 return 1;
159}
160
161static uint32 KeyboardDodo(void)
162{
163 uint32 JS=0;
164
165 if(gametype!=GIT_NSF)
166 {
167 int x,y;
168 x=y=0;
169 keyonly(CAPSLOCK,
170 {
171 char tmp[64];
172 JoySwap=(JoySwap+8)%32;
173 sprintf(tmp,"Joystick %d selected.",(JoySwap>>3)+1);
174 FCEUI_DispMessage(tmp);
175 })
176
177 if(KEY(LEFTALT) || KEY(X)) JS|=JOY_A<<JoySwap;
178 if(KEY(LEFTCONTROL) || KEY(SPACE) || KEY(Z) ) JS |=JOY_B<<JoySwap;
179 if(KEY(ENTER)) JS |= JOY_START<<JoySwap;
180 if(KEY(TAB)) JS |= JOY_SELECT<<JoySwap;
181 if(KEY(CURSORDOWN)) y|= JOY_DOWN;
182 if(KEY(CURSORUP)) y|= JOY_UP;
183 if(KEY(CURSORLEFT)) x|= JOY_LEFT;
184 if(KEY(CURSORRIGHT)) x|= JOY_RIGHT;
185 if(y!=(JOY_DOWN|JOY_UP)) JS|=y<<JoySwap;
186 if(x!=(JOY_LEFT|JOY_RIGHT)) JS|=x<<JoySwap;
187 }
188 return JS;
189}
190
191static int powerpadsc[2][12]={
192 {
193 MK(O),MK(P),MK(BRACKET_LEFT),
194 MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
195 MK(APOSTROPHE),
196 MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
197 },
198 {
199 MK(O),MK(P),MK(BRACKET_LEFT),
200 MK(BRACKET_RIGHT),MK(K),MK(L),MK(SEMICOLON),
201 MK(APOSTROPHE),
202 MK(M),MK(COMMA),MK(PERIOD),MK(SLASH)
203 }
204 };
205
206static uint32 powerpadbuf[2];
207static int powerpadside=0;
208
209static uint32 UpdatePPadData(int w)
210{
211 static const char shifttableA[12]={8,9,0,1,11,7,4,2,10,6,5,3};
212 static const char shifttableB[12]={1,0,9,8,2,4,7,11,3,5,6,10};
213 uint32 r=0;
214 int *ppadtsc=powerpadsc[w];
215 int x;
216
217 if(powerpadside&(1<<w))
218 {
219 for(x=0;x<12;x++)
220 if(keys[ppadtsc[x]]) r|=1<<shifttableA[x];
221 }
222 else
223 {
224 for(x=0;x<12;x++)
225 if(keys[ppadtsc[x]]) r|=1<<shifttableB[x];
226 }
227 return r;
228}
229
230static uint32 MouseData[3];
231static uint8 fkbkeys[0x48];
232
233void FCEUD_UpdateInput(void)
234{
235 int x;
236 int t=0;
237 static uint32 KeyBJS=0;
238 uint32 JS;
239 int b;
240
241 b=KeyboardUpdate();
242
243 for(x=0;x<2;x++)
244 switch(InputType[x])
245 {
246 case SI_GAMEPAD:t|=1;break;
247 case SI_ARKANOID:t|=2;break;
248 case SI_ZAPPER:t|=2;break;
249 case SI_POWERPAD:powerpadbuf[x]=UpdatePPadData(x);break;
250 }
251
252 switch(InputTypeFC)
253 {
254 case SIFC_ARKANOID:t|=2;break;
255 case SIFC_SHADOW:t|=2;break;
256 case SIFC_FKB:if(cidisabled) UpdateFKB();break;
257 }
258
259 if(t&1)
260 {
261 if(b)
262 KeyBJS=KeyboardDodo();
263 JS=KeyBJS;
264 JS|=(uint32)GetJSOr();
265 JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8);
266 }
267 if(t&2)
268 GetMouseData(MouseData);
269}
270
271static void InitOtherInput(void)
272{
273 void *InputDPtr;
274
275 int t;
276 int x;
277 int attrib;
278
279 for(t=0,x=0;x<2;x++)
280 {
281 attrib=0;
282 InputDPtr=0;
283 switch(InputType[x])
284 {
285 case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break;
286 case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break;
287 case SI_ARKANOID:InputDPtr=MouseData;t|=1;break;
288 case SI_ZAPPER:InputDPtr=MouseData;
289 t|=1;
290 attrib=1;
291 break;
292 }
293 FCEUI_SetInput(x,InputType[x],InputDPtr,attrib);
294 }
295
296 attrib=0;
297 InputDPtr=0;
298 switch(InputTypeFC)
299 {
300 case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break;
301 case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break;
302 case SIFC_FKB:InputDPtr=fkbkeys;break;
303 }
304
305 FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib);
306 FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE);
307
308 if(t && !(inited&16))
309 {
310 InitMouse();
311 inited|=16;
312 }
313}
314
315int fkbmap[0x48]=
316{
317 MK(F1),MK(F2),MK(F3),MK(F4),MK(F5),MK(F6),MK(F7),MK(F8),
318 MK(1),MK(2),MK(3),MK(4),MK(5),MK(6),MK(7),MK(8),MK(9),MK(0),
319 MK(MINUS),MK(EQUAL),MK(BACKSLASH),MK(BACKSPACE),
320 MK(ESCAPE),MK(Q),MK(W),MK(E),MK(R),MK(T),MK(Y),MK(U),MK(I),MK(O),
321 MK(P),MK(GRAVE),MK(BRACKET_LEFT),MK(ENTER),
322 MK(LEFTCONTROL),MK(A),MK(S),MK(D),MK(F),MK(G),MK(H),MK(J),MK(K),
323 MK(L),MK(SEMICOLON),MK(APOSTROPHE),MK(BRACKET_RIGHT),MK(INSERT),
324 MK(LEFTSHIFT),MK(Z),MK(X),MK(C),MK(V),MK(B),MK(N),MK(M),MK(COMMA),
325 MK(PERIOD),MK(SLASH),MK(RIGHTALT),MK(RIGHTSHIFT),MK(LEFTALT),MK(SPACE),
326 MK(DELETE),MK(END),MK(PAGEDOWN),
327 MK(CURSORUP),MK(CURSORLEFT),MK(CURSORRIGHT),MK(CURSORDOWN)
328};
329
330static void UpdateFKB(void)
331{
332 int x;
333
334 for(x=0;x<0x48;x++)
335 {
336 fkbkeys[x]=0;
337 if(keys[fkbmap[x]])
338 fkbkeys[x]=1;
339 }
340}