35868d35 |
1 | /* FCE Ultra - NES/Famicom Emulator |
35868d35 |
2 | * |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License |
14 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
16 | */ |
17 | |
971a1d07 |
18 | #include "../../state.h" |
19 | #include "../../general.h" |
e328100e |
20 | #include "../../input.h" |
6f6bc6fa |
21 | #include "../../svga.h" |
22 | #include "../../video.h" |
4a2a617a |
23 | #include "../libpicofe/input.h" |
24 | #include "input.h" |
35868d35 |
25 | |
26 | /* UsrInputType[] is user-specified. InputType[] is current |
971a1d07 |
27 | (game loading can override user settings) |
35868d35 |
28 | */ |
29 | static int UsrInputType[2]={SI_GAMEPAD,SI_GAMEPAD}; |
35868d35 |
30 | static int UsrInputTypeFC={SI_NONE}; |
971a1d07 |
31 | |
32 | static int InputType[2]; |
35868d35 |
33 | static int InputTypeFC; |
34 | |
35 | static uint32 JSreturn; |
35868d35 |
36 | |
37 | static int powerpadsc[2][12]; |
38 | static int powerpadside=0; |
39 | |
35868d35 |
40 | static uint32 MouseData[3]; |
41 | static uint8 fkbkeys[0x48]; |
35868d35 |
42 | |
971a1d07 |
43 | static uint32 combo_acts = 0, combo_keys = 0; |
44 | static uint32 prev_emu_acts = 0; |
35868d35 |
45 | |
13624c8f |
46 | |
35868d35 |
47 | static void setsoundvol(int soundvolume) |
48 | { |
971a1d07 |
49 | int soundvolIndex; |
50 | static char soundvolmeter[24]; |
7b356ee3 |
51 | static int prev_snd_on = 0; |
52 | |
53 | if ((!!soundvolume) ^ prev_snd_on) |
54 | { |
55 | FCEUI_Sound(Settings.sound_rate); |
56 | prev_snd_on = !!soundvolume; |
57 | } |
971a1d07 |
58 | |
4a2a617a |
59 | platform_set_volume(soundvolume); |
60 | |
971a1d07 |
61 | // draw on screen :D |
971a1d07 |
62 | int meterval=soundvolume/5; |
63 | for (soundvolIndex = 0; soundvolIndex < 20; soundvolIndex++) |
64 | { |
65 | if (soundvolIndex < meterval) |
66 | { |
67 | soundvolmeter[soundvolIndex]='*'; |
68 | } |
69 | else |
70 | { |
71 | soundvolmeter[soundvolIndex]='_'; |
72 | } |
73 | } |
74 | soundvolmeter[20]=0; |
75 | FCEU_DispMessage("|%s|", soundvolmeter); |
35868d35 |
76 | } |
13624c8f |
77 | |
78 | |
971a1d07 |
79 | static void do_emu_acts(uint32 acts) |
80 | { |
81 | uint32 actsc = acts; |
82 | acts &= acts ^ prev_emu_acts; |
83 | prev_emu_acts = actsc; |
84 | |
4a2a617a |
85 | if (acts & (EACT_SAVE_STATE | EACT_LOAD_STATE)) |
971a1d07 |
86 | { |
6f6bc6fa |
87 | int do_it = 1; |
4a2a617a |
88 | int need_confirm = 0; |
89 | const char *nm; |
90 | char tmp[64]; |
91 | int keys, len; |
92 | |
93 | if (acts & EACT_LOAD_STATE) |
971a1d07 |
94 | { |
6f6bc6fa |
95 | if (Settings.sstate_confirm & 2) |
96 | { |
4a2a617a |
97 | need_confirm = 1; |
6f6bc6fa |
98 | } |
971a1d07 |
99 | } |
100 | else |
101 | { |
6f6bc6fa |
102 | if (Settings.sstate_confirm & 1) |
103 | { |
104 | char *fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); |
4a2a617a |
105 | FILE *st = fopen(fname, "rb"); |
6f6bc6fa |
106 | free(fname); |
107 | if (st) |
108 | { |
109 | fclose(st); |
4a2a617a |
110 | need_confirm = 1; |
6f6bc6fa |
111 | } |
112 | } |
971a1d07 |
113 | } |
4a2a617a |
114 | |
115 | if (need_confirm) { |
116 | strcpy(tmp, (acts & EACT_LOAD_STATE) ? |
117 | "LOAD STATE?" : "OVERWRITE SAVE?"); |
118 | len = strlen(tmp); |
119 | nm = in_get_key_name(-1, -PBTN_MA3); |
120 | snprintf(tmp + len, sizeof(tmp) - len, "(%s=yes, ", nm); |
121 | len = strlen(tmp); |
122 | nm = in_get_key_name(-1, -PBTN_MBACK); |
123 | snprintf(tmp + len, sizeof(tmp) - len, "%s=no)", nm); |
124 | |
125 | FCEU_DispMessage(tmp); |
126 | FCEU_PutImage(); |
127 | FCEUD_Update(XBuf+8, NULL, 0); |
128 | |
129 | in_set_config_int(0, IN_CFG_BLOCKING, 1); |
130 | while (in_menu_wait_any(NULL, 50) & (PBTN_MA3|PBTN_MBACK)) |
131 | ; |
132 | while ( !((keys = in_menu_wait_any(NULL, 50)) & (PBTN_MA3|PBTN_MBACK)) ) |
133 | ; |
134 | if (keys & PBTN_MBACK) |
135 | do_it = 0; |
136 | while (in_menu_wait_any(NULL, 50) & (PBTN_MA3|PBTN_MBACK)) |
137 | ; |
138 | in_set_config_int(0, IN_CFG_BLOCKING, 0); |
139 | |
140 | FCEU_CancelDispMessage(); |
141 | } |
142 | if (do_it) { |
143 | if (acts & EACT_LOAD_STATE) |
144 | FCEUI_LoadState(); |
145 | else |
146 | FCEUI_SaveState(); |
147 | } |
148 | |
6f6bc6fa |
149 | RefreshThrottleFPS(); |
971a1d07 |
150 | } |
4a2a617a |
151 | else if (acts & (EACT_NEXT_SLOT|EACT_PREV_SLOT)) |
971a1d07 |
152 | { |
153 | FILE *st; |
154 | char *fname; |
155 | |
4a2a617a |
156 | CurrentState += (acts & EACT_NEXT_SLOT) ? 1 : -1; |
971a1d07 |
157 | if (CurrentState > 9) CurrentState = 0; |
e328100e |
158 | if (CurrentState < 0) CurrentState = 9; |
971a1d07 |
159 | |
160 | fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); |
161 | st=fopen(fname,"rb"); |
162 | free(fname); |
163 | FCEU_DispMessage("[%s] State Slot %i", st ? "USED" : "FREE", CurrentState); |
164 | if (st) fclose(st); |
165 | } |
4a2a617a |
166 | else if (acts & EACT_FDS_INSERT) |
e328100e |
167 | { |
c4980f9e |
168 | if(FCEUGameInfo.type == GIT_FDS) |
169 | FCEU_DoSimpleCommand(FCEUNPCMD_FDSINSERT); |
e328100e |
170 | } |
4a2a617a |
171 | else if (acts & EACT_FDS_SELECT) |
e328100e |
172 | { |
c4980f9e |
173 | if(FCEUGameInfo.type == GIT_FDS) |
174 | FCEU_DoSimpleCommand(FCEUNPCMD_FDSSELECT); |
e328100e |
175 | } |
4a2a617a |
176 | else if (acts & EACT_INSERT_COIN) |
e328100e |
177 | { |
c4980f9e |
178 | if(FCEUGameInfo.type == GIT_VSUNI) |
179 | FCEU_DoSimpleCommand(FCEUNPCMD_VSUNICOIN); |
e328100e |
180 | } |
181 | } |
182 | |
183 | |
4a2a617a |
184 | static void do_fake_mouse(uint32 acts) |
e328100e |
185 | { |
21afaa36 |
186 | static int x=256/2, y=240/2; |
e328100e |
187 | int speed = 3; |
188 | |
4a2a617a |
189 | if (acts & NKEY_B_TURBO) speed = 1; |
190 | if (acts & NKEY_A_TURBO) speed = 5; |
e328100e |
191 | |
4a2a617a |
192 | if (acts & NKEY_LEFT) |
e328100e |
193 | { |
194 | x -= speed; |
195 | if (x < 0) x = 0; |
196 | } |
4a2a617a |
197 | else if (acts & NKEY_RIGHT) |
e328100e |
198 | { |
199 | x += speed; |
200 | if (x > 255) x = 255; |
201 | } |
202 | |
4a2a617a |
203 | if (acts & NKEY_UP) |
e328100e |
204 | { |
205 | y -= speed; |
206 | if (y < 0) y = 0; |
207 | } |
4a2a617a |
208 | else if (acts & NKEY_DOWN) |
e328100e |
209 | { |
210 | y += speed; |
211 | if (y > 239) y = 239; |
212 | } |
213 | |
214 | MouseData[0] = x; |
215 | MouseData[1] = y; |
216 | MouseData[2] = 0; |
4a2a617a |
217 | if (acts & NKEY_A) MouseData[2] |= 1; |
218 | if (acts & NKEY_B) MouseData[2] |= 2; |
971a1d07 |
219 | } |
220 | |
13624c8f |
221 | |
9b451455 |
222 | static void FCEUD_UpdateInput(void) |
35868d35 |
223 | { |
b547bda7 |
224 | static int volpushed_frames = 0; |
6f6bc6fa |
225 | static int turbo_rate_cnt_a[2] = {0,0}, turbo_rate_cnt_b[2] = {0,0}; |
4a2a617a |
226 | uint32 all_acts[2], emu_acts; |
227 | int actions[IN_BINDTYPE_COUNT] = { 0, }; |
b547bda7 |
228 | |
4a2a617a |
229 | in_update(actions); |
230 | all_acts[0] = actions[IN_BINDTYPE_PLAYER12]; |
231 | all_acts[1] = actions[IN_BINDTYPE_PLAYER12] >> 16; |
232 | emu_acts = actions[IN_BINDTYPE_EMU]; |
233 | |
234 | if (emu_acts & EACT_ENTER_MENU) |
35868d35 |
235 | { |
b547bda7 |
236 | Exit = 1; |
b547bda7 |
237 | return; |
35868d35 |
238 | } |
4a2a617a |
239 | else if (emu_acts & EACT_VOLUME_UP) |
35868d35 |
240 | { |
b547bda7 |
241 | /* wait for at least 10 updates, because user may be just trying to enter menu */ |
0ab4d38f |
242 | if (volpushed_frames++ > 10 && (volpushed_frames&1)) { |
b547bda7 |
243 | soundvol++; |
244 | if (soundvol > 100) soundvol=100; |
245 | //FCEUI_SetSoundVolume(soundvol); |
246 | setsoundvol(soundvol); |
247 | } |
35868d35 |
248 | } |
4a2a617a |
249 | else if (emu_acts & EACT_VOLUME_DOWN) |
35868d35 |
250 | { |
0ab4d38f |
251 | if (volpushed_frames++ > 10 && (volpushed_frames&1)) { |
b547bda7 |
252 | soundvol-=1; |
253 | if (soundvol < 0) soundvol=0; |
254 | //FCEUI_SetSoundVolume(soundvol); |
255 | setsoundvol(soundvol); |
256 | } |
257 | } |
258 | else |
259 | { |
260 | volpushed_frames = 0; |
35868d35 |
261 | } |
262 | |
971a1d07 |
263 | JSreturn = 0; // RLDU SEBA |
264 | |
e328100e |
265 | if (InputType[1] != SI_GAMEPAD) |
266 | { |
267 | /* try to feed fake mouse there */ |
4a2a617a |
268 | do_fake_mouse(all_acts[0]); |
b547bda7 |
269 | } |
35868d35 |
270 | |
6f6bc6fa |
271 | // player 1 |
272 | JSreturn |= all_acts[0] & 0xff; |
4a2a617a |
273 | if (all_acts[0] & NKEY_A_TURBO) { |
6f6bc6fa |
274 | turbo_rate_cnt_a[0] += Settings.turbo_rate_add; |
275 | JSreturn |= (turbo_rate_cnt_a[0] >> 24) & 1; |
971a1d07 |
276 | } |
4a2a617a |
277 | if (all_acts[0] & NKEY_B_TURBO) { |
6f6bc6fa |
278 | turbo_rate_cnt_b[0] += Settings.turbo_rate_add; |
279 | JSreturn |= (turbo_rate_cnt_b[0] >> 23) & 2; |
971a1d07 |
280 | } |
35868d35 |
281 | |
6f6bc6fa |
282 | // player 2 |
283 | JSreturn |= (all_acts[1] & 0xff) << 16; |
4a2a617a |
284 | if (all_acts[1] & NKEY_A_TURBO) { |
6f6bc6fa |
285 | turbo_rate_cnt_a[1] += Settings.turbo_rate_add; |
286 | JSreturn |= (turbo_rate_cnt_a[1] >> 8) & 0x10000; |
287 | } |
4a2a617a |
288 | if (all_acts[1] & NKEY_B_TURBO) { |
6f6bc6fa |
289 | turbo_rate_cnt_b[1] += Settings.turbo_rate_add; |
290 | JSreturn |= (turbo_rate_cnt_b[1] >> 7) & 0x20000; |
291 | } |
292 | |
4a2a617a |
293 | do_emu_acts(emu_acts); |
35868d35 |
294 | } |
35868d35 |
295 | |
296 | |
297 | static void InitOtherInput(void) |
298 | { |
299 | |
300 | void *InputDPtr; |
301 | |
302 | int t; |
303 | int x; |
304 | int attrib; |
305 | |
e328100e |
306 | printf("InitOtherInput: InputType[0]: %i, InputType[1]: %i, InputTypeFC: %i\n", |
307 | InputType[0], InputType[1], InputTypeFC); |
308 | |
35868d35 |
309 | for(t=0,x=0;x<2;x++) |
310 | { |
311 | attrib=0; |
312 | InputDPtr=0; |
313 | switch(InputType[x]) |
314 | { |
315 | //case SI_POWERPAD:InputDPtr=&powerpadbuf[x];break; |
316 | case SI_GAMEPAD:InputDPtr=((uint8 *)&JSreturn)+(x<<1);break; |
317 | case SI_ARKANOID:InputDPtr=MouseData;t|=1;break; |
318 | case SI_ZAPPER:InputDPtr=MouseData; |
319 | t|=1; |
320 | attrib=1; |
321 | break; |
322 | } |
323 | FCEUI_SetInput(x,InputType[x],InputDPtr,attrib); |
324 | } |
325 | |
326 | attrib=0; |
327 | InputDPtr=0; |
328 | switch(InputTypeFC) |
329 | { |
330 | case SIFC_SHADOW:InputDPtr=MouseData;t|=1;attrib=1;break; |
331 | case SIFC_ARKANOID:InputDPtr=MouseData;t|=1;break; |
332 | case SIFC_FKB:InputDPtr=fkbkeys;break; |
333 | } |
334 | |
335 | FCEUI_SetInputFC(InputTypeFC,InputDPtr,attrib); |
336 | FCEUI_DisableFourScore(eoptions&EO_NOFOURSCORE); |
337 | |
971a1d07 |
338 | inited|=16; |
339 | } |
340 | |
341 | |
342 | static void PrepareOtherInput(void) |
343 | { |
282becab |
344 | uint32 act; |
971a1d07 |
345 | |
282becab |
346 | combo_acts = combo_keys = prev_emu_acts = 0; |
971a1d07 |
347 | |
282becab |
348 | for (act = 0; act < 32; act++) |
971a1d07 |
349 | { |
282becab |
350 | int u, keyc = 0, keyc2 = 0; |
351 | if (act == 16 || act == 17) continue; // player2 flag |
352 | if (act > 17) |
971a1d07 |
353 | { |
282becab |
354 | for (u = 0; u < 32; u++) |
355 | if (Settings.KeyBinds[u] & (1 << act)) keyc++; |
971a1d07 |
356 | } |
282becab |
357 | else |
971a1d07 |
358 | { |
282becab |
359 | for (u = 0; u < 32; u++) |
360 | if ((Settings.KeyBinds[u] & 0x30000) == 0 && // pl. 1 |
361 | (Settings.KeyBinds[u] & (1 << act))) keyc++; |
362 | for (u = 0; u < 32; u++) |
363 | if ((Settings.KeyBinds[u] & 0x30000) == 1 && // pl. 2 |
364 | (Settings.KeyBinds[u] & (1 << act))) keyc2++; |
365 | if (keyc2 > keyc) keyc = keyc2; |
366 | } |
367 | if (keyc > 1) |
368 | { |
369 | // loop again and mark those keys and actions as combo |
370 | for (u = 0; u < 32; u++) |
971a1d07 |
371 | { |
282becab |
372 | if (Settings.KeyBinds[u] & (1 << act)) { |
373 | combo_keys |= 1 << u; |
374 | combo_acts |= 1 << act; |
375 | } |
971a1d07 |
376 | } |
377 | } |
378 | } |
379 | |
03497cf8 |
380 | // printf("generated combo_acts: %08x, combo_keys: %08x\n", combo_acts, combo_keys); |
35868d35 |
381 | } |
971a1d07 |
382 | |