menu and controls wip..
[fceu.git] / drivers / gp2x / main.c
CommitLineData
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
35868d35 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"
b2b95d2e 32#include "menu.h"
33#include "gp2x.h"
35868d35 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
6587f346 42// just for printing some iNES info for user..
43#include "../../fce.h"
44#include "../../ines.h"
45
b2b95d2e 46// internals
47extern char lastLoadedGameName[2048];
48extern uint8 Exit; // exit emu loop flag
49void CloseGame(void);
50
51FCEUGI *fceugi = NULL;
35868d35 52static int ntsccol=0,ntschue=-1,ntsctint=-1;
53int soundvol=70;
54int inited=0;
35868d35 55
56int srendlinev[2]={0,0};
35868d35 57int erendlinev[2]={239,239};
35868d35 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),
b2b95d2e 122 ACA(lastLoadedGameName),
35868d35 123 ADDCFGSTRUCT(DriverConfig),
124 ENDCFGSTRUCT
125};
126
b547bda7 127void SaveConfig(const char *name)
35868d35 128{
129 char tdir[2048];
b547bda7 130 if (name)
131 sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
132 else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
35868d35 133 DriverInterface(DES_GETNTSCTINT,&ntsctint);
134 DriverInterface(DES_GETNTSCHUE,&ntschue);
135 SaveFCEUConfig(tdir,fceuconfig);
136}
137
b547bda7 138static void LoadConfig(const char *name)
35868d35 139{
140 char tdir[2048];
b547bda7 141 if (name)
142 sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name);
143 else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory);
35868d35 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{
b547bda7 151 char *subs[]={"fcs","snaps","gameinfo","sav","cheats","cfg"};
35868d35 152 char tdir[2048];
153 int x;
154
155 mkdir(BaseDirectory,S_IRWXU);
b547bda7 156 for(x=0;x<sizeof(subs)/sizeof(subs[0]);x++)
35868d35 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
b2b95d2e 197static int DoArgs(int argc, char *argv[])
35868d35 198{
199 static char *cortab[5]={"none","gamepad","zapper","powerpad","arkanoid"};
200 static int cortabi[5]={SI_NONE,SI_GAMEPAD,
d97315ac 201 SI_ZAPPER,SI_POWERPADA,SI_ARKANOID};
35868d35 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
b2b95d2e 206 int x, ret;
35868d35 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},
35868d35 229 {0,(void *)DriverArgs,0,0},
230 {0,0,0,0}
231 };
232
233 memset(docheckie,0,sizeof(docheckie));
b2b95d2e 234 ret=ParseArguments(argc, argv, FCEUArgs);
35868d35 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 }
b2b95d2e 301 return ret;
35868d35 302}
303
b547bda7 304
35868d35 305#include "usage.h"
306
307int CLImain(int argc, char *argv[])
308{
b2b95d2e 309 int last_arg_parsed;
310 /* TODO if(argc<=1)
937bf65b 311 {
312 ShowUsage(argv[0]);
313 return 1;
b2b95d2e 314 }*/
937bf65b 315
316 if(!DriverInitialize())
317 {
318 return 1;
319 }
320
b2b95d2e 321 if(!FCEUI_Initialize())
35868d35 322 return(1);
323 GetBaseDirectory(BaseDirectory);
324 FCEUI_SetBaseDirectory(BaseDirectory);
b2b95d2e 325 lastLoadedGameName[0] = 0;
35868d35 326
327 CreateDirs();
b547bda7 328 LoadConfig(NULL);
b2b95d2e 329 last_arg_parsed=DoArgs(argc-1,&argv[1]);
b547bda7 330 gp2x_opt_setup();
331 gp2x_cpuclock_update();
35868d35 332 if(cpalette)
333 LoadCPalette();
334 if(InitSound())
335 inited|=1;
336
b2b95d2e 337 if (argc > 1 && !last_arg_parsed)
6587f346 338 {
b2b95d2e 339 strncpy(lastLoadedGameName, argv[argc-1], sizeof(lastLoadedGameName));
340 lastLoadedGameName[sizeof(lastLoadedGameName)-1] = 0;
341 Exit = 0;
342 }
343 else
344 {
b2b95d2e 345 Exit = 1;
6587f346 346 }
347
b2b95d2e 348 while (1)
349 {
350 if(!Exit)
351 {
352 if (fceugi)
353 CloseGame();
354 fceugi=FCEUI_LoadGame(lastLoadedGameName);
355 if (fceugi)
356 {
b547bda7 357 LoadConfig(lastLoadedGameName);
b2b95d2e 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 }
35868d35 391
b547bda7 392 if (fceugi)
393 CloseGame();
394
35868d35 395 DriverKill();
b2b95d2e 396 return 0;
35868d35 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{
b547bda7 414 SaveConfig(NULL);
35868d35 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
937bf65b 430void FCEUD_Update(uint8 *xbuf, int16 *Buffer, int Count)
35868d35 431{
432 if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
433 SpeedThrottle();
937bf65b 434 BlitScreen(xbuf);
435 if(Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
436 WriteSound(Buffer,Count);
35868d35 437 FCEUD_UpdateInput();
438}
439