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