1 /*----------------
2 * Stuff to finish:
3 *
4 * It wouldn't be a stretch of the imagination to think the whole of the sdl 'port' needs a redo but here are the main things wrong with this version:
5 *
6 *
7 * The audio output code code could maybe do with some work, but it's getting there...
8 * There are lots of problems with the opengl renderer, but you should just use the SDL2 build anyway
9 *
10 * TODO for SDL2:
11 * Add autostart to menu as an ini config option
12 * Add menu for options e.g. dips, mapping, saves, IPS patches
13 * Maybe a better font output setup with some sort of scaling, maybe add sdl1 support?
14 * figure out what is going on with the sdl sound output, something breaks after a few frames
15 * ------------------*/
16
17 #include "burner.h"
18
19 INT32 Init_Joysticks(int p1_use_joystick);
20
21 int nAppVirtualFps = 0; // App fps * 100
22 bool bRunPause = 0;
23 bool bAppFullscreen = 0;
24 bool bAlwaysProcessKeyboardInput = 0;
25 int usemenu = 0, usejoy = 0, vsync = 1, dat = 0;
26 bool bSaveconfig = 1;
27 bool bIntegerScale = false;
28 bool bAlwaysMenu = false;
29 int nGameSelect = 0;
30 int nFilterSelect = HARDWARE_PUBLIC_MASK;
31 bool bShowAvailableOnly = true;
32 bool bShowClones = true;
33 int gameSelectedFromFilter = -1;
34 TCHAR szAppBurnVer[16];
35 char videofiltering[3];
36
37 #ifdef BUILD_SDL2
38 SDL_Window* sdlWindow = NULL;
39
40 static char* szSDLeepromPath = NULL;
41 static char* szSDLhiscorePath = NULL;
42 static char* szSDLHDDPath = NULL;
43 static char* szSDLSamplePath = NULL;
44 #endif
45
46 #define set_commandline_option_not_config(i,v) i = v;
47 #define set_commandline_option(i,v) i = v; bSaveconfig = 0;
48 #define set_commandline_option_string(i, v, length) snprintf(i, length, v); bSaveconfig = 0;
49
parseSwitches(int argc,char * argv[])50 int parseSwitches(int argc, char* argv[])
51 {
52 for (int i = 1; i < argc; i++)
53 {
54 if (*argv[i] != '-')
55 {
56 continue;
57 }
58
59 if (strcmp(argv[i] + 1, "joy") == 0)
60 {
61 set_commandline_option(usejoy, 1)
62 }
63
64 if (strcmp(argv[i] + 1, "menu") == 0)
65 {
66 set_commandline_option_not_config(usemenu, 1)
67
68 }
69
70 if (strcmp(argv[i] + 1, "novsync") == 0)
71 {
72 set_commandline_option(vsync, 0)
73 }
74
75 if (strcmp(argv[i] + 1, "integerscale") == 0)
76 {
77 set_commandline_option(bIntegerScale, 1)
78 }
79
80 if (strcmp(argv[i] + 1, "dat") == 0)
81 {
82 set_commandline_option_not_config(dat, 1)
83 }
84
85 if (strcmp(argv[i] + 1, "fullscreen") == 0)
86 {
87 set_commandline_option(bAppFullscreen, 1)
88 }
89
90 if (strcmp(argv[i] + 1, "nearest") == 0)
91 {
92 set_commandline_option_string(videofiltering, "0", 3)
93 }
94
95 if (strcmp(argv[i] + 1, "linear") == 0)
96 {
97 set_commandline_option_string(videofiltering, "1", 3)
98 }
99
100 if (strcmp(argv[i] + 1, "best") == 0)
101 {
102 set_commandline_option_string(videofiltering, "2", 3)
103 }
104 if (strcmp(argv[i] + 1, "autosave") == 0)
105 {
106 bDrvSaveAll = 1;
107 }
108 if (strcmp(argv[i] + 1, "cd") == 0)
109 {
110 _tcscpy(CDEmuImage, argv[i + 1]);
111 }
112 }
113 return 0;
114 }
115
generateDats()116 void generateDats()
117 {
118 char filename[1024] = { 0 };
119
120 #if defined(BUILD_SDL2)
121 printf("Creating fbneo dats in %s\n", SDL_GetPrefPath("fbneo", "dats"));
122 #if defined(ALT_DAT)
123 sprintf(filename, "%sFBNeo_-_ALL_SYSTEMS.dat", SDL_GetPrefPath("fbneo", "dats"));
124 create_datfile(filename, -1);
125 #endif
126 sprintf(filename, "%sFBNeo_-_Arcade.dat", SDL_GetPrefPath("fbneo", "dats"));
127 create_datfile(filename, DAT_ARCADE_ONLY);
128
129 sprintf(filename, "%sFBNeo_-_MegaDrive.dat", SDL_GetPrefPath("fbneo", "dats"));
130 create_datfile(filename, DAT_MEGADRIVE_ONLY);
131
132 sprintf(filename, "%sFBNeo_-_PC_ENGINE.dat", SDL_GetPrefPath("fbneo", "dats"));
133 create_datfile(filename, DAT_PCENGINE_ONLY);
134
135 sprintf(filename, "%sFBNeo_-_TurboGrafx-16.dat", SDL_GetPrefPath("fbneo", "dats"));
136 create_datfile(filename, DAT_TG16_ONLY);
137
138 sprintf(filename, "%sFBNeo_-_PC_Engine_SuperGrafx.dat", SDL_GetPrefPath("fbneo", "dats"));
139 create_datfile(filename, DAT_SGX_ONLY);
140
141 sprintf(filename, "%sFBNeo_-_Sega_SG-1000.dat", SDL_GetPrefPath("fbneo", "dats"));
142 create_datfile(filename, DAT_SG1000_ONLY);
143
144 sprintf(filename, "%sFBNeo_-_ColecoVision.dat", SDL_GetPrefPath("fbneo", "dats"));
145 create_datfile(filename, DAT_COLECO_ONLY);
146
147 sprintf(filename, "%sFBNeo_-_Sega_Master_System.dat", SDL_GetPrefPath("fbneo", "dats"));
148 create_datfile(filename, DAT_MASTERSYSTEM_ONLY);
149
150 sprintf(filename, "%sFBNeo_-_Sega_Game_Gear.dat", SDL_GetPrefPath("fbneo", "dats"));
151 create_datfile(filename, DAT_GAMEGEAR_ONLY);
152
153 sprintf(filename, "%sFBNeo_-_MSX.dat", SDL_GetPrefPath("fbneo", "dats"));
154 create_datfile(filename, DAT_MSX_ONLY);
155
156 sprintf(filename, "%sFBNeo_-_Sinclair_ZX_Spectrum.dat", SDL_GetPrefPath("fbneo", "dats"));
157 create_datfile(filename, DAT_SPECTRUM_ONLY);
158
159 sprintf(filename, "%sFBNeo_-_Neogeo.dat", SDL_GetPrefPath("fbneo", "dats"));
160 create_datfile(filename, DAT_NEOGEO_ONLY);
161
162 sprintf(filename, "%sFBNeo_-_Nintendo_Entertainment_System.dat", SDL_GetPrefPath("fbneo", "dats"));
163 create_datfile(filename, DAT_NES_ONLY);
164
165 sprintf(filename, "%sFBNeo_-_Nintendo_Famicom_Disk_System.dat", SDL_GetPrefPath("fbneo", "dats"));
166 create_datfile(filename, DAT_FDS_ONLY);
167
168 sprintf(filename, "%sFBNeo_-_Neo_Geo_Pocket.dat", SDL_GetPrefPath("fbneo", "dats"));
169 create_datfile(filename, DAT_NGP_ONLY);
170
171 sprintf(filename, "%sFBNeo_-_Fairchild_Channel_F.dat", SDL_GetPrefPath("fbneo", "dats"));
172 create_datfile(filename, DAT_CHANNELF_ONLY);
173
174 #else
175 printf("Creating fbneo dats\n");
176
177 #if defined(ALT_DAT)
178 sprintf(filename, "FBNeo_-_ALL_SYSTEMS.dat");
179 create_datfile(filename, -1);
180 #endif
181 sprintf(filename, "FBNeo_-_Arcade.dat");
182 create_datfile(filename, DAT_ARCADE_ONLY);
183
184 sprintf(filename, "FBNeo_-_MegaDrive.dat");
185 create_datfile(filename, DAT_MEGADRIVE_ONLY);
186
187 sprintf(filename, "FBNeo_-_PC_ENGINE.dat");
188 create_datfile(filename, DAT_PCENGINE_ONLY);
189
190 sprintf(filename, "FBNeo_-_TurboGrafx-16.dat");
191 create_datfile(filename, DAT_TG16_ONLY);
192
193 sprintf(filename, "FBNeo_-_PC_Engine_SuperGrafx.dat");
194 create_datfile(filename, DAT_SGX_ONLY);
195
196 sprintf(filename, "FBNeo_-_Sega_SG-1000.dat");
197 create_datfile(filename, DAT_SG1000_ONLY);
198
199 sprintf(filename, "FBNeo_-_ColecoVision.dat");
200 create_datfile(filename, DAT_COLECO_ONLY);
201
202 sprintf(filename, "FBNeo_-_Sega_Master_System.dat");
203 create_datfile(filename, DAT_MASTERSYSTEM_ONLY);
204
205 sprintf(filename, "FBNeo_-_Sega_Game_Gear.dat");
206 create_datfile(filename, DAT_GAMEGEAR_ONLY);
207
208 sprintf(filename, "FBNeo_-_MSX.dat");
209 create_datfile(filename, DAT_MSX_ONLY);
210
211 sprintf(filename, "FBNeo_-_Sinclair_ZX_Spectrum.dat");
212 create_datfile(filename, DAT_SPECTRUM_ONLY);
213
214 sprintf(filename, "FBNeo_-_Neogeo.dat");
215 create_datfile(filename, DAT_NEOGEO_ONLY);
216
217 sprintf(filename, "FBNeo_-_Nintendo_Entertainment_System.dat");
218 create_datfile(filename, DAT_NES_ONLY);
219
220 sprintf(filename, "FBNeo_-_Nintendo_Famicom_Disk_System.dat");
221 create_datfile(filename, DAT_FDS_ONLY);
222
223 sprintf(filename, "FBNeo_-_Neo_Geo_Pocket.dat");
224 create_datfile(filename, DAT_NGP_ONLY);
225
226 sprintf(filename, "FBNeo_-_Fairchild_Channel_F.dat");
227 create_datfile(filename, DAT_CHANNELF_ONLY);
228 #endif
229 }
230
231
DoGame(int gameToRun)232 void DoGame(int gameToRun)
233 {
234
235 if (!DrvInit(gameToRun, 0))
236 {
237 MediaInit();
238 Init_Joysticks(usejoy);
239 RunMessageLoop();
240 }
241 else
242 {
243 printf("There was an error loading your selected game.\n");
244 }
245
246 if (bSaveconfig)
247 {
248 ConfigAppSave();
249 }
250 DrvExit();
251 MediaExit();
252 }
253
bye(void)254 void bye(void)
255 {
256 printf("Doing exit cleanup\n");
257
258 DrvExit();
259 MediaExit();
260 BurnLibExit();
261 SDL_Quit();
262 }
263
AppDebugPrintf(int nStatus,TCHAR * pszFormat,...)264 static int __cdecl AppDebugPrintf(int nStatus, TCHAR* pszFormat, ...)
265 {
266
267 va_list args;
268 va_start(args, pszFormat);
269 printf(pszFormat, args);
270 va_end(args);
271
272 return 0;
273 }
274
main(int argc,char * argv[])275 int main(int argc, char* argv[])
276 {
277 const char* romname = NULL;
278 UINT32 i = 0;
279 bool gamefound = 0;
280 int fail = 0;
281 atexit(bye);
282 // TODO: figure out if we can use hardware Gamma until then, force software gamma
283 bVidUseHardwareGamma = 0;
284 bHardwareGammaOnly = 0;
285 //
286
287 // Make version string
288 if (nBurnVer & 0xFF)
289 {
290 // private version (alpha)
291 _stprintf(szAppBurnVer, _T("%x.%x.%x.%02x"), nBurnVer >> 20, (nBurnVer >> 16) & 0x0F, (nBurnVer >> 8) & 0xFF, nBurnVer & 0xFF);
292 }
293 else
294 {
295 // public version
296 _stprintf(szAppBurnVer, _T("%x.%x.%x"), nBurnVer >> 20, (nBurnVer >> 16) & 0x0F, (nBurnVer >> 8) & 0xFF);
297 }
298
299 // set default videofiltering
300 snprintf(videofiltering, 3, "0");
301
302 printf("FBNeo v%s\n", szAppBurnVer);
303
304 // create a default ini if one is not valid
305 fail = ConfigAppLoad();
306 if (fail)
307 {
308 if (bSaveconfig)
309 {
310 ConfigAppSave();
311 }
312 }
313
314 for (int i = 1; i < argc; i++)
315 {
316 if (*argv[i] != '-' && !gamefound)
317 {
318 romname = argv[i];
319 gamefound = 1;
320 }
321 }
322
323 parseSwitches(argc, argv);
324
325 if (romname == NULL)
326 {
327 printf("Usage: %s [-cd] [-joy] [-menu] [-novsync] [-integerscale] [-fullscreen] [-dat] [-autosave] [-nearest] [-linear] [-best] <romname>\n", argv[0]);
328 printf("Note the -menu switch does not require a romname\n");
329 printf("e.g.: %s mslug\n", argv[0]);
330 printf("e.g.: %s -menu -joy\n", argv[0]);
331 printf("For NeoCD games:\n");
332 printf("%s neocdz -cd path/to/ccd/filename.cue (or .ccd)\n", argv[0]);
333 printf("Usage is restricted by the license at https://raw.githubusercontent.com/finalburnneo/FBNeo/master/src/license.txt\n");
334
335 if (!usemenu && !bAlwaysMenu && !dat)
336 {
337 return 0;
338 }
339 }
340
341 // Do these bits before override via ConfigAppLoad
342 bCheatsAllowed = 1;
343 nAudDSPModule[0] = 0;
344 EnableHiscores = 1;
345
346 #ifdef BUILD_SDL
347 SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
348
349 SDL_WM_SetCaption("FinalBurn Neo", "FinalBurn Neo");
350 #endif
351
352 #ifdef BUILD_SDL2
353 #ifdef SDL_WINDOWS
354 char *base_path = SDL_GetBasePath();
355 #define DIRCNT 9
356 // Make sure there are roms and cfg subdirectories
357 TCHAR szDirs[DIRCNT][MAX_PATH] = {
358 {_T("config")},
359 {_T("config/games")},
360 {_T("config/ips")},
361 {_T("config/localisation")},
362 {_T("config/presets")},
363 {_T("recordings")},
364 {_T("roms")},
365 {_T("savestates")},
366 {_T("screenshots")},
367 };
368 TCHAR currentPath[MAX_PATH];
369 for(int x = 0; x < DIRCNT; x++) {
370 snprintf(currentPath, MAX_PATH, "%s%s", base_path, szDirs[x]);
371 CreateDirectory(currentPath, NULL);
372 }
373 #undef DIRCNT
374
375 SDL_setenv("SDL_AUDIODRIVER", "directsound", true); // fix audio for windows
376 #endif
377 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0)
378 {
379 printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
380 return 0;
381 }
382 #endif
383
384 //SDL_ShowCursor(SDL_DISABLE);
385
386 #if defined(BUILD_SDL2) && !defined(SDL_WINDOWS)
387 szSDLhiscorePath = SDL_GetPrefPath("fbneo", "hiscore");
388 szSDLeepromPath = SDL_GetPrefPath("fbneo", "eeprom");
389 szSDLHDDPath = SDL_GetPrefPath("fbneo", "hdd");
390 szSDLSamplePath = SDL_GetPrefPath("fbneo", "samples");
391 _stprintf(szAppHiscorePath, _T("%s"), szSDLhiscorePath);
392 _stprintf(szAppEEPROMPath, _T("%s"), szSDLeepromPath);
393 _stprintf(szAppHDDPath, _T("%s"), szSDLHDDPath);
394 _stprintf(szAppSamplesPath, _T("%s"), szSDLSamplePath);
395 #endif
396
397 fail = ConfigAppLoad();
398 if (fail)
399 {
400 if (bSaveconfig)
401 {
402 ConfigAppSave();
403 }
404 }
405 ComputeGammaLUT();
406 #if defined(BUILD_SDL2) && !defined(SDL_WINDOWS)
407 bprintf = AppDebugPrintf;
408 #endif
409 BurnLibInit();
410
411 // Search for a game now, for use in the menu and loading a games
412 if (romname != NULL)
413 {
414 for (i = 0; i < nBurnDrvCount; i++)
415 {
416 nBurnDrvActive = i;
417 if (strcmp(BurnDrvGetTextA(DRV_NAME), romname) == 0)
418 {
419 break;
420 }
421 }
422 }
423
424 if (usemenu || bAlwaysMenu)
425 {
426 #ifdef BUILD_SDL2
427 bool quit = 0;
428
429 while (!quit)
430 {
431 gui_init();
432 int selectedOk = gui_process();
433 gui_exit();
434
435 switch (selectedOk)
436 {
437 case -1:
438 BurnLibExit();
439 SDL_Quit();
440 quit = 1;
441 return 0;
442
443 default:
444 DoGame(selectedOk);
445 break;
446 }
447 }
448 #endif
449 }
450 else if (dat)
451 {
452 generateDats();
453 }
454 else
455 {
456 if (i == nBurnDrvCount)
457 {
458 printf("%s is not supported by FinalBurn Neo.\n", romname);
459 return 1;
460 }
461
462 DoGame(i);
463 }
464
465 return 0;
466 }
467
ANSIToTCHAR(const char * pszInString,TCHAR * pszOutString,int nOutSize)468 /* const */ TCHAR* ANSIToTCHAR(const char* pszInString, TCHAR* pszOutString, int nOutSize)
469 {
470 #if defined (UNICODE)
471 static TCHAR szStringBuffer[1024];
472
473 TCHAR* pszBuffer = pszOutString ? pszOutString : szStringBuffer;
474 int nBufferSize = pszOutString ? nOutSize * 2 : sizeof(szStringBuffer);
475
476 if (MultiByteToWideChar(CP_ACP, 0, pszInString, -1, pszBuffer, nBufferSize))
477 {
478 return pszBuffer;
479 }
480
481 return NULL;
482 #else
483 if (pszOutString)
484 {
485 _tcscpy(pszOutString, pszInString);
486 return pszOutString;
487 }
488
489 return (TCHAR*)pszInString;
490 #endif
491 }
492
TCHARToANSI(const TCHAR * pszInString,char * pszOutString,int nOutSize)493 /* const */ char* TCHARToANSI(const TCHAR* pszInString, char* pszOutString, int nOutSize)
494 {
495 #if defined (UNICODE)
496 static char szStringBuffer[1024];
497 memset(szStringBuffer, 0, sizeof(szStringBuffer));
498
499 char* pszBuffer = pszOutString ? pszOutString : szStringBuffer;
500 int nBufferSize = pszOutString ? nOutSize * 2 : sizeof(szStringBuffer);
501
502 if (WideCharToMultiByte(CP_ACP, 0, pszInString, -1, pszBuffer, nBufferSize, NULL, NULL))
503 {
504 return pszBuffer;
505 }
506
507 return NULL;
508 #else
509 if (pszOutString)
510 {
511 strcpy(pszOutString, pszInString);
512 return pszOutString;
513 }
514
515 return (char*)pszInString;
516 #endif
517 }
518
AppProcessKeyboardInput()519 bool AppProcessKeyboardInput()
520 {
521 return true;
522 }
523