PageRenderTime 63ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/zloader.c

https://bitbucket.org/nullplan/zsnes64
C | 971 lines | 792 code | 89 blank | 90 comment | 158 complexity | 41ee7785cbe1f9db9456d2481ff4c0cb MD5 | raw file
  1. /*
  2. Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
  3. http://www.zsnes.com
  4. http://sourceforge.net/projects/zsnes
  5. https://zsnes.bountysource.com
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. version 2 as published by the Free Software Foundation.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef __UNIXSDL__
  18. #include "gblhdr.h"
  19. #ifdef __LIBAO__
  20. #include <ao/ao.h>
  21. #endif
  22. #else
  23. #define _POSIX_
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <limits.h>
  29. #include <time.h>
  30. #ifdef __WIN32__
  31. #include <windows.h>
  32. #include <direct.h>
  33. #undef _POSIX_
  34. #include <io.h>
  35. #else
  36. #include <unistd.h>
  37. #endif
  38. #endif
  39. #include "asm_call.h"
  40. #include "cfg.h"
  41. #include "input.h"
  42. #include "zpath.h"
  43. #include "zloader.h"
  44. #ifdef __WIN32__
  45. void ImportDirectX();
  46. #endif
  47. extern unsigned char romtype, MouseDis, ZMVZClose, ZMVRawDump, debugger, debugdisble;
  48. extern unsigned char gammalevel, spcon, ForcePal, DSPDisable, V8Mode;
  49. extern unsigned char autoloadstate, autoloadmovie, MovieForcedLengthEnabled;
  50. extern char *STCart2;
  51. extern unsigned int NumInputDevices, MovieForcedLength;
  52. void zstart();
  53. #ifdef __WIN32__
  54. void InitDebugger();
  55. #endif
  56. #define put_line(x) \
  57. if (tty && (lines_out == 22)) \
  58. { \
  59. puts(" -- Press Enter to Continue --"); \
  60. getchar(); \
  61. lines_out = 0; \
  62. } \
  63. puts(x); \
  64. lines_out++;
  65. static void display_help()
  66. {
  67. size_t lines_out = 0;
  68. bool tty = isatty(fileno(stdout));
  69. #ifdef __UNIXSDL__
  70. #ifdef __LIBAO__
  71. int driver_count;
  72. ao_info **driver_info;
  73. #endif
  74. char line[75];
  75. #endif
  76. put_line("Usage : zsnes [-d,-f #, ... ] <filename.sfc>");
  77. put_line(" Eg : zsnes -s -r 2 game.sfc");
  78. put_line("");
  79. #ifdef __MSDOS__
  80. put_line(" -0 Force black blackground in 8-bit modes");
  81. #endif
  82. put_line(" -1 #/-2 # Select Player 1/2 Input :");
  83. #ifdef __MSDOS__
  84. put_line(" 0 = None 1 = Keyboard 2 = 2 button pad");
  85. put_line(" 3 = 4 button pad 4 = 6 button pad 5 = 8 button pad");
  86. put_line(" 6 = Sidewinder #1 7 = Sidewinder #2 8 = Sidewinder #3");
  87. put_line(" 9 = Sidewinder #4 10 = Gamepad Pro #0 11 = Gamepad Pro #1");
  88. put_line(" 12 = LPT1 #1 13 = LPT1 #2 14 = LPT1 #3");
  89. put_line(" 15 = LPT1 #4 16 = LPT1 #5");
  90. #else
  91. put_line(" 0 = None 1 = Keyboard/Gamepad");
  92. #endif
  93. #ifndef __UNIXSDL__
  94. put_line(" -3 Enable triple buffering (replaces vsync)");
  95. #endif
  96. #ifdef __WIN32__
  97. put_line(" -6 # Force a user-specified refresh rate for fullscreen modes [50..180]");
  98. #endif
  99. #ifdef __UNIXSDL__
  100. put_line(" -ad <> Select Audio Driver :");
  101. snprintf(line, sizeof(line), "%22s = Automatically select output", "auto");
  102. put_line(line);
  103. #ifdef __LIBAO__
  104. driver_info = ao_driver_info_list(&driver_count);
  105. while (driver_count--)
  106. {
  107. if (driver_info[driver_count]->type == AO_TYPE_LIVE)
  108. {
  109. snprintf(line, sizeof(line), "%22s = %s", driver_info[driver_count]->short_name, driver_info[driver_count]->name);
  110. put_line(line);
  111. }
  112. }
  113. #endif
  114. snprintf(line, sizeof(line), "%22s = Simple DirectMedia Layer output", "sdl");
  115. put_line(line);
  116. #endif
  117. #ifdef __MSDOS__
  118. put_line(" -8 Force 8-bit sound");
  119. put_line(" -c Enable full/wide screen (when available)");
  120. put_line(" -cc Enable small screen (when available)");
  121. #endif
  122. #ifndef NO_DEBUGGER
  123. put_line(" -d Start with debugger enabled");
  124. #endif
  125. put_line(" -dd Disable sound SPC700/DSP emulation which also disables sound output");
  126. put_line(" -ds Disable sound output");
  127. put_line(" -dh Disable ROM-specific hacks");
  128. put_line(" -f # Enable fixed frame rate [0..9]");
  129. put_line(" -g # Specify gamma correction value [0..15]");
  130. put_line(" -h Force HiROM");
  131. put_line(" -j Disable mouse (Automatically turns off right mouse click)");
  132. #ifndef __MSDOS__
  133. put_line(" -js # Set joystick sensitivity [0..32767]");
  134. #endif
  135. put_line(" -k # Set volume level [0..100]");
  136. #ifdef __WIN32__
  137. put_line(" -kp Enable the KitchenSync for PAL only");
  138. put_line(" -ks Enable the KitchenSync");
  139. #endif
  140. put_line(" -l Force LoROM");
  141. put_line(" -m Disable GUI (Must specify ROM filename)");
  142. put_line(" -mc Exit ZSNES when closing a movie (use with -zm)");
  143. put_line(" -md # Dump Video (use with -zm)");
  144. put_line(" 1 = Raw 2 = FFV1 3 = x264");
  145. put_line(" 4 = XviD 5 = Custom");
  146. put_line(" -ml # Define movie dump length in amount of frames (use with -md)");
  147. put_line(" -n # Enable scanlines (when available)");
  148. put_line(" 0 = None, 1 = Full, 2 = 25%, 3 = 50%");
  149. put_line(" -o Disable MMX support");
  150. put_line(" -p # Percentage of instructions to execute [50..150]");
  151. put_line(" -r # Set sound sampling rate:");
  152. put_line(" 0 = 8000Hz 1 = 11025Hz 2 = 22050Hz 3 = 44100Hz");
  153. put_line(" 4 = 16000Hz 5 = 32000Hz 6 = 48000Hz");
  154. put_line(" -s Enable sound output and enable SPC700/DSP emulation");
  155. put_line(" -sa Show all files in GUI (*.*)");
  156. #ifdef __MSDOS__
  157. put_line(" -sp Display sound information");
  158. #endif
  159. put_line(" -t Force NTSC timing");
  160. put_line(" -u Force PAL timing");
  161. put_line(" -v # Select video mode :");
  162. #ifdef __WIN32__
  163. #define VIDEO_MODE_COUNT 42
  164. put_line(" 0 = 256x224 R WIN 1 = 256x224 R FULL");
  165. put_line(" 2 = 512x448 R WIN 3 = 512x448 DR WIN");
  166. put_line(" 4 = 640x480 S WIN 5 = 640x480 DS WIN");
  167. put_line(" 6 = 640x480 DR FULL 7 = 640x480 DS FULL");
  168. put_line(" 8 = 640x480 S FULL 9 = 768x672 R WIN");
  169. put_line(" 10 = 768x672 DR WIN 11 = 800x600 S WIN");
  170. put_line(" 12 = 800x600 DS WIN 13 = 800x600 S FULL");
  171. put_line(" 14 = 800x600 DR FULL 15 = 800x600 DS FULL");
  172. put_line(" 16 = 1024x768 S WIN 17 = 1024x768 DS WIN");
  173. put_line(" 18 = 1024x768 S FULL 19 = 1024x768 DR FULL");
  174. put_line(" 20 = 1024x768 DS FULL 21 = 1024x896 R WIN");
  175. put_line(" 22 = 1024x896 DR WIN 23 = 1280x960 S WIN");
  176. put_line(" 24 = 1280x960 DS WIN 25 = 1280x960 S FULL");
  177. put_line(" 26 = 1280x960 DR FULL 27 = 1280x960 DS FULL");
  178. put_line(" 28 = 1280x1024 S WIN 29 = 1280x1024 DS WIN");
  179. put_line(" 30 = 1280x1024 S FULL 31 = 1280x1024 DR FULL");
  180. put_line(" 32 = 1280x1024 DS FULL 33 = 1600x1200 S WIN");
  181. put_line(" 34 = 1600x1200 DS WIN 35 = 1600x1200 DR FULL");
  182. put_line(" 36 = 1600x1200 DS FULL 37 = 1600x1200 S FULL");
  183. put_line(" 38 = CUSTOM D WIN 39 = CUSTOM DS FULL");
  184. put_line(" 40 = CUSTOM WIN 41 = CUSTOM S FULL");
  185. put_line(" 42 = CUSTOM DR FULL");
  186. #endif
  187. #ifdef __UNIXSDL__
  188. put_line(" 0 = 256x224 R WIN 1 = 256x224 R FULL");
  189. put_line(" 2 = 512x448 DR WIN 3 = 512x448 DR FULL");
  190. put_line(" 4 = 640x480 DR FULL");
  191. #ifndef __OPENGL__
  192. #define VIDEO_MODE_COUNT 4
  193. #else
  194. #define VIDEO_MODE_COUNT 22
  195. put_line(" 5 = 256x224 O R WIN 6 = 512x448 ODR WIN");
  196. put_line(" 7 = 640x480 ODS FULL 8 = 640x480 ODS WIN");
  197. put_line(" 9 = 640x560 ODR WIN 10 = 768x672 ODR WIN");
  198. put_line(" 11 = 800x600 ODS FULL 12 = 800x600 ODS WIN");
  199. put_line(" 13 = 896x784 ODR WIN 14 = 1024x768 ODS FULL");
  200. put_line(" 15 = 1024x768 ODS WIN 16 = 1024x896 ODR WIN");
  201. put_line(" 17 = 1280x960 ODS FULL 18 = 1280x1024 ODS FULL");
  202. put_line(" 19 = 1600x1200 ODS FULL 20 = VARIABLE ODR WIN");
  203. put_line(" 21 = VARIABLE ODS WIN 22 = CUSTOM OD FULL");
  204. #endif
  205. #endif
  206. #ifdef __MSDOS__
  207. #define VIDEO_MODE_COUNT 18
  208. put_line(" 0 = 256x224x8B MODEQ 1 = 256x240x8B MODEQ");
  209. put_line(" 2 = 256x256x8B MODEQ 3 = 320x224x8B MODEX");
  210. put_line(" 4 = 320x240x8B MODEX 5 = 320x256x8B MODEX");
  211. put_line(" 6 = 640x480x16B VESA1 7 = 320x240x8B VESA2");
  212. put_line(" 8 = 320x240x16B VESA2 9 = 320x480x8B VESA2");
  213. put_line(" 10 = 320x480x16B VESA2 11 = 512x384x8B VESA2");
  214. put_line(" 12 = 512x384x16B VESA2 13 = 640x400x8B VESA2");
  215. put_line(" 14 = 640x400x16B VESA2 15 = 640x480x8B VESA2");
  216. put_line(" 16 = 640x480x16B VESA2 17 = 800x600x8B VESA2");
  217. put_line(" 18 = 800x600x16B VESA2");
  218. #endif
  219. put_line(" -v8 Grayscale mode");
  220. #ifndef __UNIXSDL__
  221. put_line(" -w Enable vsync (disables triple buffering)");
  222. #endif
  223. put_line(" -y Enable anti-aliasing (video interpolation)");
  224. put_line(" -z Disable stereo sound");
  225. put_line(" -zm # Auto load specified movie slot on startup [0..9]");
  226. put_line(" -zs # Auto load specified save state slot on startup [0..99]");
  227. put_line("");
  228. put_line(" File Formats Supported by GUI : SMC,SFC,SWC,FIG,MGD,MGH,UFO,BIN,");
  229. put_line(" GD3,GD7,USA,EUR,JAP,AUS,ST,BS,");
  230. put_line(" DX2,048,058,078,1,A,GZ,ZIP,JMA");
  231. put_line("");
  232. #ifndef __UNIXSDL__
  233. put_line(" Microsoft-style options (/option) are also accepted");
  234. #endif
  235. /*
  236. #ifndef __MSDOS__
  237. put_line(" --Netplay Parameters--");
  238. put_line(" Commandline: /ABCDE <nickname> <fname> <IP Addy>");
  239. put_line(" nickname = user nickname");
  240. put_line(" fname = filename w/ full path (if L) or path name (if C)");
  241. put_line(" IP Addy = IP Address (Client Only)");
  242. put_line(" A = U (UDP - Recommended if works), T (TCP/IP)");
  243. put_line(" B = S (Server), C (Client)");
  244. put_line(" C = C (Chat first), L (load game first)");
  245. put_line(" D = N (Stay in ZSNES after disconnect), Q (Quit after disconnect)");
  246. put_line(" E = # of connections (Keep it 2 for now)");
  247. #ifdef __WIN32__
  248. put_line(" eg: ZSNESW /UCCN2 nickname d:\\snesroms 202.36.124.28");
  249. #else
  250. put_line(" eg: zsnes /UCCN2 nickname /home/zuser/snesroms 202.36.124.28");
  251. #endif
  252. #endif
  253. */
  254. exit(1);
  255. }
  256. #define ConvertJoyMapHelp(a,b) if (b && (a == b)) { b += 0x81; }
  257. void ConvertJoyMap1()
  258. {
  259. unsigned int bl;
  260. // Convert if 2,4,6, or sidewinder
  261. if (pl1contrl == 2)
  262. {
  263. pl1Bk = 0x83;
  264. pl1Yk = 0x82;
  265. pl1upk = 0xCC;
  266. pl1downk = 0xCD;
  267. pl1leftk = 0xCE;
  268. pl1rightk = 0xCF;
  269. }
  270. bl = (pl1contrl == 3 || pl1contrl == 4) ? 4 : 0;
  271. if (pl1contrl == 5) { bl = 6; }
  272. if (bl)
  273. {
  274. // Convert button data
  275. pl1upk = 0xCC;
  276. pl1downk = 0xCD;
  277. pl1leftk = 0xCE;
  278. pl1rightk = 0xCF;
  279. ConvertJoyMapHelp(bl, pl1startk);
  280. ConvertJoyMapHelp(bl, pl1selk);
  281. ConvertJoyMapHelp(bl, pl1Yk);
  282. ConvertJoyMapHelp(bl, pl1Xk);
  283. ConvertJoyMapHelp(bl, pl1Bk);
  284. ConvertJoyMapHelp(bl, pl1Ak);
  285. ConvertJoyMapHelp(bl, pl1Lk);
  286. ConvertJoyMapHelp(bl, pl1Rk);
  287. }
  288. if (pl1contrl == 6)
  289. {
  290. pl1upk = 0xD4;
  291. pl1downk = 0xD5;
  292. pl1leftk = 0xD6;
  293. pl1rightk = 0xD7;
  294. pl1startk = 0xC8;
  295. pl1selk = 0xC9;
  296. pl1Ak = 0x89;
  297. pl1Bk = 0x88;
  298. pl1Xk = 0x8C;
  299. pl1Yk = 0x8B;
  300. pl1Lk = 0x8E;
  301. pl1Rk = 0x8F;
  302. }
  303. return;
  304. }
  305. void ConvertJoyMap2()
  306. {
  307. unsigned int bl;
  308. //If pl1contrl=2 and pl2contrl=2, then set pl2 buttons to 3 & 4
  309. if (pl2contrl == 2)
  310. {
  311. if (pl1contrl != 2)
  312. {
  313. pl2Bk = 0x83;
  314. pl2Yk = 0x82;
  315. pl2upk = 0xCC;
  316. pl2downk = 0xCD;
  317. pl2leftk = 0xCE;
  318. pl2rightk = 0xCF;
  319. }
  320. else
  321. {
  322. pl2Bk = 0x85;
  323. pl2Yk = 0x84;
  324. pl2upk = 0xE8;
  325. pl2downk = 0xE9;
  326. pl2leftk = 0xEA;
  327. pl2rightk = 0xEB;
  328. }
  329. }
  330. bl = (pl2contrl == 3 || pl2contrl == 4) ? 4 : 0;
  331. if (pl2contrl == 5) { bl = 6; }
  332. if (bl)
  333. {
  334. //Convert button data
  335. pl2upk = 0xCC;
  336. pl2downk = 0xCD;
  337. pl2leftk = 0xCE;
  338. pl2rightk = 0xCF;
  339. ConvertJoyMapHelp(bl, pl2startk);
  340. ConvertJoyMapHelp(bl, pl2selk);
  341. ConvertJoyMapHelp(bl, pl2Yk);
  342. ConvertJoyMapHelp(bl, pl2Xk);
  343. ConvertJoyMapHelp(bl, pl2Bk);
  344. ConvertJoyMapHelp(bl, pl2Ak);
  345. ConvertJoyMapHelp(bl, pl2Lk);
  346. ConvertJoyMapHelp(bl, pl2Rk);
  347. }
  348. //If both sidewinder, set pl2 buttons to sw2
  349. if (pl2contrl == 6)
  350. {
  351. if (pl1contrl != 6)
  352. {
  353. pl2upk = 0xD4;
  354. pl2downk = 0xD5;
  355. pl2leftk = 0xD6;
  356. pl2rightk = 0xD7;
  357. pl2startk = 0xC8;
  358. pl2selk = 0xC9;
  359. pl2Ak = 0x89;
  360. pl2Bk = 0x88;
  361. pl2Xk = 0x8C;
  362. pl2Yk = 0x8B;
  363. pl2Lk = 0x8E;
  364. pl2Rk = 0x8F;
  365. }
  366. else
  367. {
  368. pl2contrl = 7;
  369. pl2upk = 0xDC;
  370. pl2downk = 0xDD;
  371. pl2leftk = 0xDE;
  372. pl2rightk = 0xDF;
  373. pl2startk = 0xD0;
  374. pl2selk = 0xD1;
  375. pl2Ak = 0x91;
  376. pl2Bk = 0x90;
  377. pl2Xk = 0x94;
  378. pl2Yk = 0x93;
  379. pl2Lk = 0x96;
  380. pl2Rk = 0x97;
  381. }
  382. }
  383. return;
  384. }
  385. struct backup_cmdline_vars saved_cmdline_vars;
  386. #ifdef __MSDOS__
  387. #define BACKUP_HELP_DOS(func) \
  388. func(Palette0); \
  389. #else
  390. #define BACKUP_HELP_DOS(func)
  391. #endif
  392. #ifdef __WIN32__
  393. #define BACKUP_HELP_WIN(func) \
  394. func(KitchenSync); \
  395. func(KitchenSyncPAL); \
  396. func(ForceRefreshRate); \
  397. func(SetRefreshRate); \
  398. func(joy_sensitivity); \
  399. #else
  400. #define BACKUP_HELP_WIN(func)
  401. #endif
  402. #ifdef __UNIXSDL__
  403. #define BACKUP_HELP_SDL(func) \
  404. func(joy_sensitivity); \
  405. #else
  406. #define BACKUP_HELP_SDL(func)
  407. #endif
  408. #define BACKUP_HELP(func) \
  409. func(guioff) \
  410. func(per2exec) \
  411. func(HacksDisable) \
  412. func(AllowMMX) \
  413. BACKUP_HELP_DOS(func) \
  414. BACKUP_HELP_WIN(func) \
  415. BACKUP_HELP_SDL(func)
  416. #define BACKUP_VAR(var) saved_cmdline_vars._ ## var = var;
  417. static void backup_all_vars()
  418. {
  419. BACKUP_HELP(BACKUP_VAR)
  420. }
  421. #define SWAP_BACKUP_VAR(var) \
  422. saved_cmdline_vars._ ## var ^= var; \
  423. var ^= saved_cmdline_vars._ ## var; \
  424. saved_cmdline_vars._ ## var ^= var;
  425. void swap_backup_vars()
  426. {
  427. BACKUP_HELP(SWAP_BACKUP_VAR)
  428. }
  429. static size_t zatoi(const char *str)
  430. {
  431. const char *orig_str = str;
  432. if (str)
  433. {
  434. while (*str)
  435. {
  436. if (!isdigit(*str++)) { return(~0); }
  437. }
  438. return((size_t)atoi(orig_str));
  439. }
  440. return(~0);
  441. }
  442. static void handle_params(int argc, char *argv[])
  443. {
  444. int i;
  445. backup_all_vars();
  446. #ifndef __MSDOS__
  447. /*
  448. if (argc >= 5 && argv[1][0] == '/' && strlen(argv[1]) == 6)
  449. {
  450. size_t i = 0, j = 0;
  451. char *strp;
  452. if (toupper(argv[1][1]) == 'T') UDPConfig=0;
  453. //Next should be # of connections
  454. while (argv[2][i]!=0)
  455. {
  456. switch (argv[2][i])
  457. {
  458. case '_':
  459. case '-':
  460. case '^':
  461. case '=':
  462. case '+':
  463. case '[':
  464. case ']':
  465. if ( j < 10)
  466. {
  467. strp[j] = argv[2][i];
  468. j++;
  469. }
  470. break;
  471. default:
  472. if (((toupper(argv[2][i]) >= 'A') && (toupper(argv[2][i]) <= 'Z')) ||
  473. ((argv[2][i] >= '0') && (argv[2][i] <= '9')))
  474. {
  475. if (j < 10)
  476. {
  477. strp[j] = argv[2][i];
  478. j++;
  479. }
  480. }
  481. break;
  482. }
  483. i++;
  484. }
  485. strp[j] = 0;
  486. }
  487. */
  488. #endif
  489. for (i = 1; i < argc; i++)
  490. {
  491. #ifndef __UNIXSDL__
  492. if (argv[i][0] == '-' || argv[i][0] == '/')
  493. #else
  494. if (argv[i][0] == '-')
  495. #endif
  496. {
  497. if (!argv[i][1]) //Nothing but a - or /
  498. {
  499. display_help();
  500. }
  501. else if (!argv[i][2]) //- followed by a single letter
  502. {
  503. switch (tolower(argv[i][1]))
  504. {
  505. #ifdef __MSDOS__
  506. case '0': //Palette color 0 disable
  507. Palette0 = 1;
  508. break;
  509. #endif
  510. case '1': //Player 1 Input
  511. i++;
  512. if ((pl1contrl = zatoi(argv[i])) >= NumInputDevices)
  513. {
  514. printf("Player 1 Input must be a value from 0 to %u!\n", NumInputDevices);
  515. exit(1);
  516. }
  517. ConvertJoyMap1();
  518. break;
  519. case '2': //Player 2 Input
  520. i++;
  521. if ((pl2contrl = zatoi(argv[i])) > NumInputDevices)
  522. {
  523. printf("Player 2 Input must be a value from 0 to %u!\n", NumInputDevices);
  524. exit(1);
  525. }
  526. ConvertJoyMap2();
  527. break;
  528. #ifndef __UNIXSDL__
  529. case '3': //Enable triple buffering for DOS/Windows
  530. vsyncon = 0;
  531. #ifdef __MSDOS__
  532. Triplebufen = 1;
  533. #elif __WIN32__
  534. TripleBufferWin = 1;
  535. #endif
  536. break;
  537. #endif
  538. #ifdef __WIN32__
  539. case '6': //Force Refresh Rate
  540. i++;
  541. SetRefreshRate = zatoi(argv[i]);
  542. if((SetRefreshRate < 50) || (SetRefreshRate > 180))
  543. {
  544. ForceRefreshRate = 0;
  545. puts("Refresh Rate must be a value 50 to 180!");
  546. exit(1);
  547. }
  548. else
  549. {
  550. ForceRefreshRate = 1;
  551. }
  552. break;
  553. #endif
  554. #ifdef __MSDOS__
  555. case '8': //Force 8-bit sound
  556. Force8b = 1;
  557. break;
  558. case 'c': //Enable full screen (when available)
  559. ScreenScale = 1;
  560. break;
  561. #endif
  562. #ifndef NO_DEBUGGER
  563. case 'd': //Start with debugger enabled
  564. debugger = 1;
  565. debugdisble = 0;
  566. #ifdef __WIN32__
  567. InitDebugger();
  568. #endif
  569. break;
  570. #endif
  571. case 'f': //Enable fixed frame rate
  572. i++;
  573. if ((frameskip = zatoi(argv[i])+1) > 10)
  574. {
  575. puts("Frame Skip must be a value of 0 to 9!");
  576. exit(1);
  577. }
  578. break;
  579. case 'g': //Specify gamma correction value
  580. i++;
  581. if ((gammalevel = zatoi(argv[i])) > 15)
  582. {
  583. puts("Gamma Correction Level must be a value of 0 to 15!");
  584. exit(1);
  585. }
  586. break;
  587. case 'h': //Force HiROM
  588. romtype = 2;
  589. break;
  590. case 'j': //Disable mouse
  591. MouseDis = 1;
  592. break;
  593. case 'k': //Set volume level
  594. i++;
  595. if ((MusicRelVol = zatoi(argv[i])) > 100)
  596. {
  597. puts("Volume must be a value from 0 to 100!");
  598. exit(1);
  599. }
  600. break;
  601. case 'l': //Force LoROM
  602. romtype = 1;
  603. break;
  604. case 'm': //Disable GUI
  605. guioff = 1;
  606. break;
  607. case 'n': //Enable scanlines (when available)
  608. i++;
  609. if ((scanlines = zatoi(argv[i])) > 3)
  610. {
  611. puts("Scanlines must be a value 0 to 3!");
  612. exit(1);
  613. }
  614. break;
  615. case 'o': //Disable MMX support
  616. AllowMMX = 0;
  617. break;
  618. case 'p': //Percentage of instructions to execute
  619. i++;
  620. per2exec = zatoi(argv[i]);
  621. if (per2exec > 150 || per2exec < 50)
  622. {
  623. puts("Percentage of instructions to execute must be a value from 50 to 150!");
  624. exit(1);
  625. }
  626. break;
  627. case 'r': //Set sampling rate
  628. i++;
  629. if ((SoundQuality = zatoi(argv[i])) > 6)
  630. {
  631. puts("Sound Sampling Rate must be a value of 0 to 6!");
  632. exit(1);
  633. }
  634. break;
  635. case 's': //Enable sound output, and SPC700/DSP emulation
  636. spcon = 1;
  637. soundon = 1;
  638. break;
  639. case 't': //Force NTSC
  640. ForcePal = 1;
  641. break;
  642. case 'u': //Force PAL
  643. ForcePal = 2;
  644. break;
  645. case 'v': //Select video mode
  646. i++;
  647. if ((cvidmode = zatoi(argv[i])) > VIDEO_MODE_COUNT)
  648. {
  649. puts("Invalid Video Mode!");
  650. exit(1);
  651. }
  652. break;
  653. #ifndef __UNIXSDL__
  654. case 'w': //Enable vsync for DOS/Windows
  655. vsyncon = 1;
  656. #ifdef __MSDOS__
  657. Triplebufen = 0;
  658. #elif __WIN32__
  659. TripleBufferWin = 0;
  660. #endif
  661. break;
  662. #endif
  663. case 'y': //Enable anti-aliasing
  664. antienab = 1;
  665. break;
  666. case 'z': //Disable stereo sound
  667. StereoSound = 0;
  668. break;
  669. default:
  670. display_help();
  671. break;
  672. }
  673. }
  674. else if (!argv[i][3]) //- followed by two letters
  675. {
  676. if (tolower(argv[i][1]) == 'd' && tolower(argv[i][2]) == 'd') //Disable sound DSP emulation
  677. {
  678. DSPDisable = 1;
  679. }
  680. #ifdef __UNIXSDL__
  681. else if (tolower(argv[i][1]) == 'a' && tolower(argv[i][2]) == 'd') //Disable sound DSP emulation
  682. {
  683. i++;
  684. if (!argv[i])
  685. {
  686. display_help();
  687. }
  688. #ifdef __LIBAO__
  689. if (!strcmp(argv[i], "auto") || !strcmp(argv[i], "sdl") || (ao_driver_id(argv[i]) >= 0))
  690. #else
  691. if (!strcmp(argv[i], "auto") || !strcmp(argv[i], "sdl"))
  692. #endif
  693. {
  694. strcpy(libAoDriver, argv[i]);
  695. }
  696. else
  697. {
  698. puts("Audio driver selection invalid.");
  699. exit(1);
  700. }
  701. }
  702. #endif
  703. else if (tolower(argv[i][1]) == 'd' && tolower(argv[i][2]) == 's') //Disable sound output
  704. {
  705. soundon = 0;
  706. }
  707. #ifdef __MSDOS__
  708. else if (tolower(argv[i][1]) == 'c' && tolower(argv[i][2]) == 'c') //Enable small screen (when available)
  709. {
  710. smallscreenon = 1;
  711. }
  712. #endif
  713. else if (tolower(argv[i][1]) == 'd' && tolower(argv[i][2]) == 'h') //Disable hacks
  714. {
  715. HacksDisable = 1;
  716. }
  717. #ifndef __MSDOS__
  718. else if (tolower(argv[i][1]) == 'j' && tolower(argv[i][2]) == 's') //Set joystick sensitivity
  719. {
  720. i++;
  721. if ((joy_sensitivity = zatoi(argv[i])+1) > 32767)
  722. {
  723. puts("Joystick sensitivity must be a value of 0 to 32767!");
  724. exit(1);
  725. }
  726. }
  727. #endif
  728. #ifdef __WIN32__
  729. else if (tolower(argv[i][1]) == 'k' && tolower(argv[i][2]) == 's') //Enable KitchenSync
  730. {
  731. KitchenSync = 1;
  732. }
  733. #endif
  734. #ifdef __WIN32__
  735. else if (tolower(argv[i][1]) == 'k' && tolower(argv[i][2]) == 'p') //Enable KitchenSync for PAL only
  736. {
  737. KitchenSyncPAL = 1;
  738. KitchenSync = 0;
  739. }
  740. #endif
  741. else if (tolower(argv[i][1]) == 'm' && tolower(argv[i][2]) == 'c') //Close ZSNES when ZMV closes
  742. {
  743. ZMVZClose = 1;
  744. }
  745. else if (tolower(argv[i][1]) == 'm' && tolower(argv[i][2]) == 'd') //Dump raw vid with ZMV
  746. {
  747. i++;
  748. if ((ZMVRawDump = zatoi(argv[i])) > 5)
  749. {
  750. puts("Movie mode must be a number 1 to 5");
  751. exit(1);
  752. }
  753. }
  754. else if (tolower(argv[i][1]) == 'm' && tolower(argv[i][2]) == 'l') //Force ZMV length
  755. {
  756. i++;
  757. MovieForcedLengthEnabled = true;
  758. MovieForcedLength = zatoi(argv[i]);
  759. }
  760. #ifdef __MSDOS__
  761. else if (tolower(argv[i][1]) == 's' && tolower(argv[i][2]) == 'p') //Display sound information
  762. {
  763. DisplayS = 1;
  764. }
  765. #endif
  766. else if (tolower(argv[i][1]) == 's' && tolower(argv[i][2]) == 'a') //Show all extensions in GUI
  767. {
  768. showallext = 1;
  769. }
  770. else if (tolower(argv[i][1]) == 'v' && argv[i][2] == '8') //V8 Mode
  771. {
  772. V8Mode = 1;
  773. }
  774. else if (tolower(argv[i][1]) == 'z' && tolower(argv[i][2]) == 's') //Autoload save state
  775. {
  776. i++;
  777. if ((autoloadstate = zatoi(argv[i])+1) > 100)
  778. {
  779. puts("State load position must be a value of 0 to 99!");
  780. exit(1);
  781. }
  782. }
  783. else if (tolower(argv[i][1]) == 'z' && tolower(argv[i][2]) == 'm') //Autoload movie
  784. {
  785. i++;
  786. if ((autoloadmovie = zatoi(argv[i])+1) > 10)
  787. {
  788. puts("Movie load position must be a value of 0 to 9!");
  789. exit(1);
  790. }
  791. }
  792. else
  793. {
  794. display_help();
  795. break;
  796. }
  797. }
  798. else //- followed by more than 2 letters
  799. {
  800. display_help();
  801. }
  802. }
  803. else //Param with no - or / prefix
  804. {
  805. if (argv[i] && !init_rom_path(argv[i]))
  806. {
  807. printf("Could not load: %s\n", argv[i]);
  808. }
  809. if ((STCart2 = argv[i+1])) //Sufami Turbo second cart
  810. {
  811. char *p;
  812. natify_slashes(STCart2);
  813. p = strrchr(STCart2, DIR_SLASH_C);
  814. if (!p) { p = STCart2; }
  815. else { p++; }
  816. strcpy(ZSaveST2Name, p);
  817. setextension(ZSaveST2Name, "srm");
  818. }
  819. break;
  820. }
  821. }
  822. }
  823. static void ZCleanup(void)
  824. {
  825. void deinit_paths();
  826. void deallocmem();
  827. void DeallocRewindBuffer();
  828. void DeallocPauseFrame();
  829. void DeallocSystemVars();
  830. void free_all_file_lists();
  831. #ifdef __UNIXSDL__
  832. void UnloadSDL();
  833. #endif
  834. deinit_paths();
  835. deallocmem();
  836. DeallocRewindBuffer();
  837. DeallocPauseFrame();
  838. DeallocSystemVars();
  839. free_all_file_lists();
  840. #ifdef __UNIXSDL__
  841. UnloadSDL();
  842. #endif
  843. }
  844. void zmain(int zargc, char *zargv[])
  845. {
  846. if (init_paths(*zargv))
  847. {
  848. #ifdef __LIBAO__
  849. ao_initialize();
  850. atexit(ao_shutdown);
  851. #endif
  852. handle_params(zargc, zargv);
  853. atexit(ZCleanup);
  854. srand(time(0));
  855. zstart();
  856. }
  857. }
  858. #ifdef __WIN32__
  859. extern HINSTANCE hInst;
  860. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  861. {
  862. hInst=hInstance;
  863. ImportDirectX();
  864. zmain(__argc, __argv);
  865. return(0);
  866. }
  867. #else
  868. int main(int zargc, char *zargv[])
  869. {
  870. zmain(zargc, zargv);
  871. return(0);
  872. }
  873. #endif