menu and controls wip..
[fceu.git] / drivers / gp2x / main.c
... / ...
CommitLineData
1/* FCE Ultra - NES/Famicom Emulator
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
18
19#include <unistd.h>
20#include <sys/types.h>
21#include <signal.h>
22#include <sys/time.h>
23#include <sys/stat.h>
24#include <string.h>
25#include <strings.h>
26#include <errno.h>
27#include <stdio.h>
28#include <stdlib.h>
29
30#include "main.h"
31#include "throttle.h"
32#include "menu.h"
33#include "gp2x.h"
34
35#include "../common/config.h"
36#include "../common/args.h"
37#include "../common/unixdsp.h"
38#include "../common/cheat.h"
39
40#include "dface.h"
41
42// just for printing some iNES info for user..
43#include "../../fce.h"
44#include "../../ines.h"
45
46// internals
47extern char lastLoadedGameName[2048];
48extern uint8 Exit; // exit emu loop flag
49void CloseGame(void);
50
51FCEUGI *fceugi = NULL;
52static int ntsccol=0,ntschue=-1,ntsctint=-1;
53int soundvol=70;
54int inited=0;
55
56int srendlinev[2]={0,0};
57int erendlinev[2]={239,239};
58int srendline,erendline;
59
60
61static char BaseDirectory[2048];
62
63int eoptions=0;
64
65static void DriverKill(void);
66static int DriverInitialize(void);
67
68static int gametype;
69#include "input.c"
70
71static void ParseGI(FCEUGI *gi)
72{
73 gametype=gi->type;
74
75 InputType[0]=UsrInputType[0];
76 InputType[1]=UsrInputType[1];
77 InputTypeFC=UsrInputTypeFC;
78
79 if(gi->input[0]>=0)
80 InputType[0]=gi->input[0];
81 if(gi->input[1]>=0)
82 InputType[1]=gi->input[1];
83 if(gi->inputfc>=0)
84 InputTypeFC=gi->inputfc;
85 FCEUI_GetCurrentVidSystem(&srendline,&erendline);
86}
87
88void FCEUD_PrintError(char *s)
89{
90 puts(s);
91}
92
93static char *cpalette=0;
94static void LoadCPalette(void)
95{
96 char tmpp[192];
97 FILE *fp;
98
99 if(!(fp=fopen(cpalette,"rb")))
100 {
101 printf(" Error loading custom palette from file: %s\n",cpalette);
102 return;
103 }
104 fread(tmpp,1,192,fp);
105 FCEUI_SetPaletteArray((uint8 *)tmpp);
106 fclose(fp);
107}
108
109static CFGSTRUCT fceuconfig[]={
110 AC(soundvol),
111 ACS(cpalette),
112 AC(ntsctint),
113 AC(ntschue),
114 AC(ntsccol),
115 AC(UsrInputTypeFC),
116 ACA(UsrInputType),
117 AC(powerpadside),
118 AC(powerpadsc),
119 AC(eoptions),
120 ACA(srendlinev),
121 ACA(erendlinev),
122 ACA(lastLoadedGameName),
123 ADDCFGSTRUCT(DriverConfig),
124 ENDCFGSTRUCT
125};
126
127void SaveConfig(const char *name)
128{
129 char tdir[2048];
130 if (name)
131 sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
132 else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
133 DriverInterface(DES_GETNTSCTINT,&ntsctint);
134 DriverInterface(DES_GETNTSCHUE,&ntschue);
135 SaveFCEUConfig(tdir,fceuconfig);
136}
137
138static void LoadConfig(const char *name)
139{
140 char tdir[2048];
141 if (name)
142 sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
143 else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
144 LoadFCEUConfig(tdir,fceuconfig);
145 if(ntsctint>=0) DriverInterface(DES_SETNTSCTINT,&ntsctint);
146 if(ntschue>=0) DriverInterface(DES_SETNTSCHUE,&ntschue);
147}
148
149static void CreateDirs(void)
150{
151 char *subs[]={"fcs","snaps","gameinfo","sav","cheats","cfg"};
152 char tdir[2048];
153 int x;
154
155 mkdir(BaseDirectory,S_IRWXU);
156 for(x=0;x<sizeof(subs)/sizeof(subs[0]);x++)
157 {
158 sprintf(tdir,"%s"PSS"%s",BaseDirectory,subs[x]);
159 mkdir(tdir,S_IRWXU);
160 }
161}
162
163static void SetSignals(void (*t)(int))
164{
165 int sigs[11]={SIGINT,SIGTERM,SIGHUP,SIGPIPE,SIGSEGV,SIGFPE,SIGKILL,SIGALRM,SIGABRT,SIGUSR1,SIGUSR2};
166 int x;
167 for(x=0;x<11;x++)
168 signal(sigs[x],t);
169}
170
171static void CloseStuff(int signum)
172{
173 DriverKill();
174 printf("\nSignal %d has been caught and dealt with...\n",signum);
175 switch(signum)
176 {
177 case SIGINT:printf("How DARE you interrupt me!\n");break;
178 case SIGTERM:printf("MUST TERMINATE ALL HUMANS\n");break;
179 case SIGHUP:printf("Reach out and hang-up on someone.\n");break;
180 case SIGPIPE:printf("The pipe has broken! Better watch out for floods...\n");break;
181 case SIGSEGV:printf("Iyeeeeeeeee!!! A segmentation fault has occurred. Have a fluffy day.\n");break;
182 /* So much SIGBUS evil. */
183 #ifdef SIGBUS
184 #if(SIGBUS!=SIGSEGV)
185 case SIGBUS:printf("I told you to be nice to the driver.\n");break;
186 #endif
187 #endif
188 case SIGFPE:printf("Those darn floating points. Ne'er know when they'll bite!\n");break;
189 case SIGALRM:printf("Don't throw your clock at the meowing cats!\n");break;
190 case SIGABRT:printf("Abort, Retry, Ignore, Fail?\n");break;
191 case SIGUSR1:
192 case SIGUSR2:printf("Killing your processes is not nice.\n");break;
193 }
194 exit(1);
195}
196
197static int DoArgs(int argc, char *argv[])
198{
199 static char *cortab[5]={"none","gamepad","zapper","powerpad","arkanoid"};
200 static int cortabi[5]={SI_NONE,SI_GAMEPAD,
201 SI_ZAPPER,SI_POWERPADA,SI_ARKANOID};
202 static char *fccortab[5]={"none","arkanoid","shadow","4player","fkb"};
203 static int fccortabi[5]={SIFC_NONE,SIFC_ARKANOID,SIFC_SHADOW,
204 SIFC_4PLAYER,SIFC_FKB};
205
206 int x, ret;
207 static char *inputa[2]={0,0};
208 static char *fcexp=0;
209 static int docheckie[4];
210
211 static ARGPSTRUCT FCEUArgs[]={
212 {"-soundvol",0,&soundvol,0},
213 {"-cpalette",0,&cpalette,0x4001},
214
215 {"-ntsccol",0,&ntsccol,0},
216 {"-pal",&docheckie[0],0,0},
217 {"-input1",0,&inputa[0],0x4001},{"-input2",0,&inputa[1],0x4001},
218 {"-fcexp",0,&fcexp,0x4001},
219
220 {"-gg",&docheckie[1],0,0},
221 {"-no8lim",0,&eoptions,0x8001},
222 {"-subase",0,&eoptions,0x8002},
223 {"-snapname",0,&eoptions,0x8000|EO_SNAPNAME},
224 {"-nofs",0,&eoptions,0x8000|EO_NOFOURSCORE},
225 {"-clipsides",0,&eoptions,0x8000|EO_CLIPSIDES},
226 {"-nothrottle",0,&eoptions,0x8000|EO_NOTHROTTLE},
227 {"-slstart",0,&srendlinev[0],0},{"-slend",0,&erendlinev[0],0},
228 {"-slstartp",0,&srendlinev[1],0},{"-slendp",0,&erendlinev[1],0},
229 {0,(void *)DriverArgs,0,0},
230 {0,0,0,0}
231 };
232
233 memset(docheckie,0,sizeof(docheckie));
234 ret=ParseArguments(argc, argv, FCEUArgs);
235 if(cpalette)
236 {
237 if(cpalette[0]=='0')
238 if(cpalette[1]==0)
239 {
240 free(cpalette);
241 cpalette=0;
242 }
243 }
244 if(docheckie[0])
245 FCEUI_SetVidSystem(1);
246 if(docheckie[1])
247 FCEUI_SetGameGenie(1);
248 FCEUI_DisableSpriteLimitation(1);
249 FCEUI_SaveExtraDataUnderBase(eoptions&2);
250 FCEUI_SetSnapName(eoptions&EO_SNAPNAME);
251
252 for(x=0;x<2;x++)
253 {
254 if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
255 if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
256 }
257
258 printf("main() setrendered lines: %d, %d, %d, %d\n",srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
259 printf("main() clip sides %d\n", eoptions&EO_CLIPSIDES);
260 srendlinev[0]=0;
261 FCEUI_SetRenderedLines(srendlinev[0],erendlinev[0],srendlinev[1],erendlinev[1]);
262 FCEUI_SetRenderedLines(0,erendlinev[0],srendlinev[1],erendlinev[1]);
263 FCEUI_SetSoundVolume(soundvol);
264 DriverInterface(DES_NTSCCOL,&ntsccol);
265 DoDriverArgs();
266
267 if(fcexp)
268 {
269 int y;
270 for(y=0;y<5;y++)
271 {
272 if(!strncmp(fccortab[y],fcexp,8))
273 {
274 UsrInputTypeFC=fccortabi[y];
275 break;
276 }
277 }
278 free(fcexp);
279 }
280 for(x=0;x<2;x++)
281 {
282 int y;
283
284 if(!inputa[x])
285 continue;
286
287 for(y=0;y<5;y++)
288 {
289 if(!strncmp(cortab[y],inputa[x],8))
290 {
291 UsrInputType[x]=cortabi[y];
292 if(y==3)
293 {
294 powerpadside&=~(1<<x);
295 powerpadside|=((((inputa[x][8])-'a')&1)^1)<<x;
296 }
297 free(inputa[x]);
298 }
299 }
300 }
301 return ret;
302}
303
304
305#include "usage.h"
306
307int CLImain(int argc, char *argv[])
308{
309 int last_arg_parsed;
310 /* TODO if(argc<=1)
311 {
312 ShowUsage(argv[0]);
313 return 1;
314 }*/
315
316 if(!DriverInitialize())
317 {
318 return 1;
319 }
320
321 if(!FCEUI_Initialize())
322 return(1);
323 GetBaseDirectory(BaseDirectory);
324 FCEUI_SetBaseDirectory(BaseDirectory);
325 lastLoadedGameName[0] = 0;
326
327 CreateDirs();
328 LoadConfig(NULL);
329 last_arg_parsed=DoArgs(argc-1,&argv[1]);
330 gp2x_opt_setup();
331 gp2x_cpuclock_update();
332 if(cpalette)
333 LoadCPalette();
334 if(InitSound())
335 inited|=1;
336
337 if (argc > 1 && !last_arg_parsed)
338 {
339 strncpy(lastLoadedGameName, argv[argc-1], sizeof(lastLoadedGameName));
340 lastLoadedGameName[sizeof(lastLoadedGameName)-1] = 0;
341 Exit = 0;
342 }
343 else
344 {
345 Exit = 1;
346 }
347
348 while (1)
349 {
350 if(!Exit)
351 {
352 if (fceugi)
353 CloseGame();
354 fceugi=FCEUI_LoadGame(lastLoadedGameName);
355 if (fceugi)
356 {
357 LoadConfig(lastLoadedGameName);
358 ParseGI(fceugi);
359 //RefreshThrottleFPS();
360 InitOtherInput();
361
362 // additional print for gpfce
363 // TODO: handlers for other formats then iNES
364 {
365 int MapperNo;
366 iNES_HEADER *head = iNESGetHead();
367 MapperNo = (head->ROM_type>>4);
368 MapperNo|=(head->ROM_type2&0xF0);
369 FCEU_DispMessage("%s, Mapper: %d%s%s", PAL?"PAL":"NTSC", MapperNo, (head->ROM_type&2)?", BB":"", (head->ROM_type&4)?", T":"");
370 }
371 }
372 else
373 strcpy(menuErrorMsg, "failed to load ROM");
374 }
375 if(Exit || !fceugi)
376 {
377 int ret;
378 ret = gp2x_menu_do();
379 if (ret == 1) break; // exit emu
380 if (ret == 2) { // reload ROM
381 Exit = 0;
382 continue;
383 }
384 }
385
386 gp2x_video_changemode(Settings.scaling == 3 ? 15 : 8);
387 gp2x_video_RGB_setscaling(0, 320, 240);
388 gp2x_start_sound(22050, 16, 0);
389 FCEUI_Emulate();
390 }
391
392 if (fceugi)
393 CloseGame();
394
395 DriverKill();
396 return 0;
397}
398
399static int DriverInitialize(void)
400{
401 SetSignals((void *)CloseStuff);
402
403 if(InitJoysticks())
404 inited|=2;
405 if(!InitVideo()) return 0;
406 inited|=4;
407 if(!InitKeyboard()) return 0;
408 inited|=8;
409 return 1;
410}
411
412static void DriverKill(void)
413{
414 SaveConfig(NULL);
415 SetSignals(SIG_IGN);
416
417 if(inited&2)
418 KillJoysticks();
419 if(inited&8)
420 KillKeyboard();
421 if(inited&4)
422 KillVideo();
423 if(inited&1)
424 KillSound();
425 if(inited&16)
426 KillMouse();
427 inited=0;
428}
429
430void FCEUD_Update(uint8 *xbuf, int16 *Buffer, int Count)
431{
432 if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
433 SpeedThrottle();
434 BlitScreen(xbuf);
435 if(Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
436 WriteSound(Buffer,Count);
437 FCEUD_UpdateInput();
438}
439