main.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. * Copyright (C) 1999 Charles Goetzman
  7. * Copyright (C) 2002 B.D.A. (Koji) - Koji_Takeo@worldmailer.com
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. //This source code should be 8086 compatible
  24. #pragma option -2-
  25. #pragma option -1-
  26. #include "beep.h"
  27. #include "profile.h"
  28. #include "ceh.h"
  29. #include "helpsys.h"
  30. #include "sfx.h"
  31. #include "random.h"
  32. #include "edit.h"
  33. #include "ezboard.h"
  34. #include "roballoc.h"
  35. #include <setjmp.h>
  36. #include <dir.h>
  37. #include "blink.h"
  38. #include "timer.h"
  39. #include "egacode.h"
  40. #include "meminter.h"
  41. #include "string.h"
  42. #include "arrowkey.h"
  43. #include "comp_chk.h"
  44. #include "dt_data.h"
  45. #include "graphics.h"
  46. #include "cursor.h"
  47. #include "window.h"
  48. #include "palette.h"
  49. #include "getkey.h"
  50. #include "ems.h"
  51. #include <stdlib.h>
  52. #include "main.h"
  53. #include <dos.h>
  54. #include <stdio.h>
  55. #include "detect.h"
  56. #include "data.h"
  57. #include "mod.h"
  58. #include "game.h"
  59. #include "error.h"
  60. #include <time.h>
  61. #define SAVE_INDIVIDUAL
  62. //new_settings=1 if Addr IRQ or DMA was updated via CMD line so we
  63. //should keep them even if config is entered
  64. char force_ega=0,no_mouse=0,no_ems=0,new_settings=0;
  65. jmp_buf exit_jump;//Used in error function and nowhere else
  66. extern unsigned int Addr,IRQ,DMA;//Sound card parameters (-1=detect)
  67. #ifdef UNREG
  68. char *unreg_exit_mesg=
  69. "This message should not be displayed, it is a bug, if it is.";
  70. #else
  71. char *reg_exit_mesg=
  72. "Thank you for playing MegaZeux.\n\r"
  73. "Read the files help.txt, megazeux.doc and readme.1st if you need help.\n\n\r"
  74. "Contributors to MZX:\n\r"
  75. "MZX 1.0-2.51 base code:\n\r"
  76. " Greg Janson - everything\n\r"
  77. "MZX spider s1-s3.1 series contributers:\n\r"
  78. " Charles Goetzman - mzx s1 base and misc. code\n\r"
  79. " MenTaLguY - anti-flicker code, mouse buffering, mod \"*\"\n\r"
  80. " Ben Zeigler - under bug fix and getting the thing to run\n\r"
  81. "MadBrain - MZX s3.2 (BIMSG, etc.)\n\r"
  82. "Akwende - MZXAK 1.0 basecode and misc. code\n\r"
  83. "MZX 2.6:\n\r"
  84. " Koji - New functions, real distance, etc.\n\r"
  85. " Exophase - New functions, debugging, etc.\n\r"
  86. " Inmate2993 - Use all 16 bits of a counter.\n\r"
  87. "MZX 2.61:\n\r"
  88. " Koji - Bug fixes and etc.\n\r"
  89. "MZX 2.62:\n\r"
  90. " Exophase - Strings, Mod_order, etc.\n\r"
  91. "\nhttp://www.digitalmzx.net/ for MZX source and binary distributions.\n\r$";
  92. #endif
  93. #pragma warn -par
  94. int main(int argc,char **argv) {
  95. //Temp var for number->string conversion
  96. char temp[7];
  97. //Set to 1 if any errors occur during startup
  98. char errors=0;
  99. //Used to save result of early ec_init() call
  100. char ec_i=0;
  101. //Temporary variables
  102. int t1;
  103. //Return code
  104. int ret=0;
  105. //Set if we need first time help
  106. char first_time=0;
  107. //Jump destination for exiting to DOS
  108. if(setjmp(exit_jump)) {//Exiting to DOS
  109. mod_exit();
  110. ret=3;
  111. goto escape;
  112. }
  113. //First thing- check for card and processor
  114. if(computer_check()) return 1;
  115. //Scan command line options, exit if need be
  116. if(scan_options()) return 2;
  117. if(force_ega) vga_avail=0;
  118. //Now- Page 0
  119. page_flip(0);
  120. //Init palette system and fade out
  121. init_palette();
  122. vquick_fadeout();
  123. //Setup directory strings
  124. //Get megazeux directory
  125. str_cpy(help_file,argv[0]);
  126. //Chop at last backslash
  127. for(t1=str_len(help_file);t1>=0;t1--)
  128. if(help_file[t1]=='\\') break;
  129. help_file[t1+1]=0;
  130. //Copy to config_file and MSE_file and blank_mod_file and convert_mod_file
  131. str_cpy(config_file,help_file);
  132. str_cpy(MSE_file,help_file);
  133. str_cpy(mzx_blank_mod_file,help_file);
  134. str_cpy(mzx_convert_mod_file,help_file);
  135. //Caton filenames
  136. str_cat(config_file,"megazeux.cfg");
  137. str_cat(help_file,"mzx_help.fil");
  138. //Get current directory and drive (form- C:\DIR\SUBDIR)
  139. getcwd(current_dir,PATHNAME_SIZE);
  140. str_cpy(megazeux_dir,current_dir);
  141. megazeux_drive=current_drive=getdisk();
  142. //Disable smzx mode
  143. //Switch to EGA 14 point mode and turn off cursor
  144. ega_14p_mode();
  145. cursor_off();
  146. //Init ec code and load up default set NOW to avoid seeing the
  147. //line characters shift. Save status of call for later.
  148. ec_i=ec_init();
  149. //These lines prevent a white flash onscreen
  150. init_palette();
  151. insta_fadeout();
  152. //Display Megazeux startup screen
  153. draw_window_box(0,0,79,24,0xB800,127,120,113,0);
  154. draw_window_box(2,1,77,3,0xB800,120,127,113,0);
  155. draw_window_box(2,4,77,16,0xB800,120,127,113,0);
  156. draw_window_box(2,17,77,23,0xB800,120,127,113,0);
  157. write_string("MegaZeux version 2.62",27,2,127,0xB800);
  158. // #ifdef BETA
  159. write_string("Beta - Distribute me please!",27,17,127,0xB800);
  160. // #endif
  161. #ifdef GAMMA
  162. write_string("GAMMA- MAY CONTAIN BUGz!",27,17,127,0xB800);
  163. #endif
  164. #ifdef UNREG
  165. write_string("Unregistered Evaluation Copy",25,0,122,0xB800);
  166. #endif
  167. write_string("Graphics card:",4,18,122,0xB800);
  168. write_string("EMS available:",4,20,122,0xB800);
  169. write_string("Core mem free:",4,21,122,0xB800);
  170. write_string("Memory allocs:",4,22,122,0xB800);
  171. write_string("Keyboard handler:",41,18,122,0xB800);
  172. write_string("Mouse handler:",44,19,122,0xB800);
  173. write_string("Sound card port:",42,20,122,0xB800);
  174. write_string("Sound card IRQ:",43,21,122,0xB800);
  175. write_string("Sound card DMA:",43,22,122,0xB800);
  176. // I restored the original startup palette... - Exo
  177. set_rgb(1,31,31,31);
  178. set_rgb(6,63,0,0);
  179. set_rgb(7,21,21,21);
  180. set_rgb(8,8,8,8);
  181. set_rgb(9,42,42,63);
  182. set_rgb(10,42,63,42);
  183. set_rgb(11,42,63,63);
  184. set_rgb(12,63,42,42);
  185. set_rgb(13,63,42,63);
  186. //Fix palette to be nicer.
  187. //Not if I can help it!
  188. //the random palettes are uglier
  189. //than sin! Couldn't find the original
  190. //so I'll just use the default -Koji
  191. /* randomize();
  192. switch(random(100)%4)
  193. {
  194. case(0):
  195. set_rgb(1,31,0,0);
  196. set_rgb(6,53,0,0);
  197. set_rgb(7,21,0,0);
  198. set_rgb(8,11,0,0);
  199. set_rgb(9,63,63,0);
  200. set_rgb(10,63,31,0);
  201. set_rgb(11,63,21,21);
  202. set_rgb(12,63,42,42);
  203. set_rgb(13,63,42,21);
  204. set_rgb(15,63,0,0);
  205. break;
  206. case(1):
  207. set_rgb(1,46,29,31); //CORNER
  208. set_rgb(6,50,33,35); //BACKGROUN
  209. set_rgb(7,55,38,40); //MID Edge
  210. set_rgb(8,41,24,26); //DARK Edge
  211. set_rgb(9,63,46,48); //ACTIVE Text
  212. set_rgb(10,41,24,26); //STATIC Text
  213. set_rgb(11,55,36,39); //SELECTION Text
  214. set_rgb(12,51,34,38); //
  215. set_rgb(13,63,46,48); //
  216. set_rgb(15,63,46,48); //LIGHT EDGE
  217. break;
  218. case(2):
  219. set_rgb(1,0,31,0);
  220. set_rgb(6,0,53,0);
  221. set_rgb(7,0,21,0);
  222. set_rgb(8,0,11,0);
  223. set_rgb(9,0,63,63);
  224. set_rgb(10,0,63,31);
  225. set_rgb(11,21,63,21);
  226. set_rgb(12,42,63,42);
  227. set_rgb(13,21,63,42);
  228. set_rgb(15,0,63,0);
  229. break;
  230. case(3):
  231. set_rgb(1,0,0,31);
  232. set_rgb(6,0,0,53);
  233. set_rgb(7,0,0,21);
  234. set_rgb(8,0,0,11);
  235. set_rgb(9,0,63,63);
  236. set_rgb(10,0,31,63);
  237. set_rgb(11,21,21,63);
  238. set_rgb(12,42,42,63);
  239. set_rgb(13,21,42,63);
  240. set_rgb(15,0,0,63);
  241. break;
  242. }*/
  243. //Fade in
  244. vquick_fadein();
  245. //Initialize systems and display progess at bottom
  246. //First, show graphics card and processor
  247. if(force_ega) write_string("EGA (command line)",19,18,125,0xB800);
  248. else write_string(gcard_strs[card-3],19,18,121,0xB800);
  249. //Initialize EMS systems
  250. if(no_ems) write_string("Forced off",19,20,125,0xB800);
  251. else if(setup_EMS()) write_string("None",19,20,124,0xB800);
  252. else {
  253. itoa(free_mem_EMS()*16,temp,10);
  254. temp[str_len(temp)+1]=0;
  255. temp[str_len(temp)]='k';
  256. if(free_mem_EMS()>=64) write_string(temp,19,20,121,0xB800);
  257. else write_string(temp,19,20,124,0xB800);
  258. }
  259. //Write up keyboard mode
  260. if(keyb_mode) write_string("Alternate mode",59,18,125,0xB800);
  261. else write_string("Default mode",59,18,121,0xB800);
  262. //Initialize windowing code
  263. if(window_cpp_entry()) {
  264. write_string("OUT OF MEMORY",19,22,124,0xB800);
  265. errors=1;
  266. }
  267. //Initialize mouse handler (from now on must hide/show it)
  268. if(!no_mouse) {
  269. m_init();
  270. m_hide();
  271. }
  272. if(no_mouse) write_string("Forced off",59,19,125,0xB800);
  273. else if(driver_activated) write_string("Ok",59,19,121,0xB800);
  274. else write_string("No mouse found",59,19,124,0xB800);
  275. //Initialize character edit code and character set
  276. if(ec_i) {
  277. write_string("OUT OF MEMORY",19,22,124,0xB800);
  278. errors=1;
  279. }
  280. //Install new timer ISR
  281. install_timer();
  282. //Allocate misc. memory
  283. t1=0;//Set to 1 for error
  284. board_list=(char far *)farmalloc(NUM_BOARDS*BOARD_NAME_SIZE);
  285. if(board_list==NULL) t1=1;
  286. board_offsets=(bOffset far *)farmalloc(NUM_BOARDS*sizeof(bOffset));
  287. if(board_offsets==NULL) t1=1;
  288. board_sizes=(unsigned long far *)farmalloc(NUM_BOARDS*4);
  289. if(board_sizes==NULL) t1=1;
  290. board_filenames=(char far *)farmalloc(NUM_BOARDS*FILENAME_SIZE);
  291. if(board_filenames==NULL) t1=1;
  292. level_id=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  293. if(level_id==NULL) t1=1;
  294. level_color=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  295. if(level_color==NULL) t1=1;
  296. level_param=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  297. if(level_param==NULL) t1=1;
  298. level_under_id=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  299. if(level_under_id==NULL) t1=1;
  300. level_under_color=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  301. if(level_under_color==NULL) t1=1;
  302. level_under_param=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  303. if(level_under_param==NULL) t1=1;
  304. overlay=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  305. if(overlay==NULL) t1=1;
  306. overlay_color=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  307. if(overlay_color==NULL) t1=1;
  308. update_done=(unsigned char far *)farmalloc(MAX_ARRAY_X*MAX_ARRAY_Y);
  309. if(update_done==NULL) t1=1;
  310. //Allocate one more for global robot
  311. robots=(Robot far *)farmalloc((NUM_ROBOTS+1)*sizeof(Robot));
  312. if(robots==NULL) t1=1;
  313. scrolls=(Scroll far *)farmalloc(NUM_SCROLLS*sizeof(Scroll));
  314. if(scrolls==NULL) t1=1;
  315. counters=(Counter far *)farmalloc(NUM_COUNTERS*sizeof(Counter));
  316. if(counters==NULL) t1=1;
  317. sensors=(Sensor far *)farmalloc(NUM_SENSORS*sizeof(Sensor));
  318. if(sensors==NULL) t1=1;
  319. if(init_robot_mem()) t1=1;
  320. board_setup();
  321. if(sfx_init()) t1=1;
  322. if(t1) {
  323. write_string("OUT OF MEMORY",19,22,124,0xB800);
  324. errors=1;
  325. }
  326. //Initialize blink code, mod code, random number generator, and keyboard
  327. blink_off();
  328. random_seed();
  329. install_i09();
  330. installceh();
  331. //Write up free memory (below 100 shown as bad)
  332. itoa(t1=(int)(farcoreleft()>>10),temp,10);
  333. temp[str_len(temp)+1]=0;
  334. temp[str_len(temp)]='k';
  335. if(t1>=100) write_string(temp,19,21,121,0xB800);
  336. else write_string(temp,19,21,124,0xB800);
  337. //Give error message if appropriate (including if free Kb below 20)
  338. if((errors)||(t1<20)) {
  339. draw_window_box(3,9,76,11,0xB800,76,64,70,0);
  340. write_string("Out of memory error- Please increase available core/EMS memory",
  341. 9,10,79,0xB800);
  342. getkey();
  343. goto escape;
  344. }
  345. else {
  346. write_string("Ok",19,22,121,0xB800);
  347. //Configuration time
  348. //Note- music_device is from 0 to 6 at all times.
  349. //Mixing rate is 0 1 or 2, and converted to kHz before game is
  350. //started.
  351. //Search for .CFG file
  352. if(!load_config_file()) {
  353. //Loaded- display and verify
  354. save_config_file();//Update Port/IRQ/DMA
  355. write_string("Current configuration-",3,5,127,0xB800);
  356. write_string("Device for digitized music and sound:",5,6,122,0xB800);
  357. if((music_device>0)&&(music_device<6)) {
  358. write_string("Sound quality for digitized output:",7,7,122,0xB800);
  359. write_string(music_quality[mixing_rate],43,7,123,0xB800);
  360. }
  361. if((music_device>0)&&(music_device<6)) {
  362. write_string("Number of digitized sfx channels:",9,8,122,0xB800);
  363. draw_char('0'+sfx_channels,123,43,8,0xB800);
  364. }
  365. write_string("PC speaker sound effects:",17,9,122,0xB800);
  366. if(music_device==6) write_string("Gravis Ultra-Sound (no sfx)",43,6,123,0xB800);
  367. else write_string(music_devices[music_device],43,6,123,0xB800);
  368. if(sfx_on) write_string("On",43,9,123,0xB800);
  369. else write_string("Off",43,9,123,0xB800);
  370. //Port/IRQ/DMA-
  371. if(Addr==0xFFFF) write_string("Autodetect",59,20,121,0xB800);
  372. else {
  373. itoa(Addr,temp,16);
  374. temp[str_len(temp)+1]=0;
  375. temp[str_len(temp)]='h';
  376. write_string(temp,59,20,125,0xB800);
  377. }
  378. if(IRQ==0xFF) write_string("Autodetect",59,21,121,0xB800);
  379. else {
  380. itoa(IRQ,temp,10);
  381. write_string(temp,59,21,125,0xB800);
  382. }
  383. if(DMA==0xFF) write_string("Autodetect",59,22,121,0xB800);
  384. else {
  385. itoa(DMA,temp,10);
  386. write_string(temp,59,22,125,0xB800);
  387. }
  388. write_string("Press C to configure, ESC to exit, or any other key to continue.",
  389. 3,10,127,0xB800);
  390. rekey:
  391. t1=getkey();
  392. if(t1==27) goto escape;
  393. if(t1==0) goto rekey;
  394. if((t1!='c')&&(t1!='C')) goto maingame;
  395. if(!new_settings) {
  396. Addr=0xFFFF;
  397. IRQ=DMA=0xFF;
  398. write_string("Autodetect",59,20,121,0xB800);
  399. write_string("Autodetect",59,21,121,0xB800);
  400. write_string("Autodetect",59,22,121,0xB800);
  401. }
  402. }
  403. else {
  404. first_time=1;
  405. write_string("Autodetect",59,20,121,0xB800);
  406. write_string("Autodetect",59,21,121,0xB800);
  407. write_string("Autodetect",59,22,121,0xB800);
  408. }
  409. //Configure
  410. //Digitized output device
  411. draw_window_box(2,4,77,16,0xB800,120,127,113,0);
  412. write_string("Devices for digitized music and sound-",3,5,127,0xB800);
  413. for(t1=0;t1<(NUM_DEVICES/2+1);t1++) {
  414. draw_char('A'+t1,127,5,6+t1,0xB800);
  415. draw_char(')',127,6,6+t1,0xB800);
  416. write_string(music_devices[t1],8,6+t1,125,0xB800);
  417. }
  418. for(;t1<NUM_DEVICES;t1++) {
  419. draw_char('A'+t1,127,40,6+t1-NUM_DEVICES/2-1,0xB800);
  420. draw_char(')',127,41,6+t1-NUM_DEVICES/2-1,0xB800);
  421. write_string(music_devices[t1],43,6+t1-NUM_DEVICES/2-1,125,0xB800);
  422. }
  423. write_string(music_devices[NUM_DEVICES],43,9,125,0xB800);
  424. write_string("Choose an output device or press ESC to exit.",3,13,127,
  425. 0xB800);
  426. do {
  427. t1=getkey();
  428. if((t1>='a')&&(t1<='z')) t1-=32;
  429. } while((t1!=27)&&((t1<'A')||(t1>'G')));
  430. if(t1==27) goto escape;
  431. music_device=t1-'A';
  432. //Mixing rate
  433. if(music_device==0) mixing_rate=0;
  434. else if(music_device==6) mixing_rate=2;
  435. else {
  436. draw_window_box(2,4,77,16,0xB800,120,127,113,0);
  437. write_string("Choose music quality (higher quality requires more processor power)",3,5,127,0xB800);
  438. for(t1=0;t1<3;t1++) {
  439. draw_char('A'+t1,127,5,6+t1,0xB800);
  440. draw_char(')',127,6,6+t1,0xB800);
  441. write_string(music_quality[t1],8,6+t1,125,0xB800);
  442. }
  443. write_string("Choose a music quality or press ESC to exit.",3,15,127,
  444. 0xB800);
  445. do {
  446. t1=getkey();
  447. if((t1>='a')&&(t1<='z')) t1-=32;
  448. } while((t1!=27)&&((t1<'A')||(t1>'C')));
  449. if(t1==27) goto escape;
  450. mixing_rate=t1-'A';
  451. }
  452. //Sfx channels
  453. if((music_device==0)||(music_device==6)) sfx_channels=0;
  454. else {
  455. draw_window_box(2,4,77,16,0xB800,120,127,113,0);
  456. write_string("Choose number of digitized sound effect channels-",3,5,
  457. 127,0xB800);
  458. write_string("1, 2, 3, or 4, or ESC to exit.",3,7,127,0xB800);
  459. write_string("(higher requires more memory and is slower)",3,8,125,0xB800);
  460. do {
  461. t1=getkey();
  462. } while((t1!=27)&&((t1<'1')||(t1>'4')));
  463. if(t1==27) goto escape;
  464. sfx_channels=t1-'0';
  465. }
  466. //Sound effects
  467. draw_window_box(2,4,77,16,0xB800,120,127,113,0);
  468. write_string("PC speaker sound effects-",3,5,127,0xB800);
  469. write_string("Press 1 for On, 2 for Off, or ESC to exit.",3,7,127,
  470. 0xB800);
  471. do {
  472. t1=getkey();
  473. } while((t1!=27)&&(t1!='1')&&(t1!='2'));
  474. if(t1==27) goto escape;
  475. sfx_on='2'-t1;
  476. //Done
  477. save_config_file();
  478. }
  479. maingame:
  480. mixing_rate=mixing_rates[music_device][mixing_rate];
  481. if(music_device==0) music_on=0;
  482. else music_on=1;
  483. vquick_fadeout();
  484. clear_screen(1824,0xB800);
  485. //Init mod code
  486. mod_init();
  487. //First time help
  488. if(first_time) {
  489. default_palette();
  490. insta_fadein();
  491. context=71;
  492. help_system();
  493. insta_fadeout();
  494. }
  495. context=72;
  496. //Run main game (mouse is hidden and palette is faded)
  497. title_screen();
  498. update_config_file();//Save speed setting
  499. mod_exit();
  500. escape:
  501. music_device=0;//To prevent errors in accessing end_mod()
  502. vquick_fadeout();
  503. //Deallocate miscellaneous memory items
  504. sfx_exit();
  505. clear_world();
  506. exit_robot_mem();
  507. if(board_list!=NULL) farfree(board_list);
  508. if(board_offsets!=NULL) farfree(board_offsets);
  509. if(board_sizes!=NULL) farfree(board_sizes);
  510. if(board_filenames!=NULL) farfree(board_filenames);
  511. if(level_id!=NULL) farfree(level_id);
  512. if(level_color!=NULL) farfree(level_color);
  513. if(level_param!=NULL) farfree(level_param);
  514. if(level_under_id!=NULL) farfree(level_under_id);
  515. if(level_under_color!=NULL) farfree(level_under_color);
  516. if(level_under_param!=NULL) farfree(level_under_param);
  517. if(overlay!=NULL) farfree(overlay);
  518. if(overlay_color!=NULL) farfree(overlay_color);
  519. if(update_done!=NULL) farfree(update_done);
  520. if(robots!=NULL) farfree(robots);
  521. if(scrolls!=NULL) farfree(scrolls);
  522. if(counters!=NULL) farfree(counters);
  523. if(sensors!=NULL) farfree(sensors);
  524. //Uninstall systems in reverse order
  525. uninstall_i09();
  526. blink_on();
  527. clear_sfx_queue();
  528. uninstall_timer();
  529. m_deinit();
  530. window_cpp_exit();
  531. ec_exit();
  532. clear_screen(1824,0xB800);
  533. page_flip(0);
  534. init_palette();
  535. if((vga_avail)||((force_ega)&&(card>=VGAm))) vga_16p_mode();
  536. cursor_underline();
  537. asm push ds
  538. #ifdef UNREG
  539. asm mov dx,SEG unreg_exit_mesg
  540. asm mov ds,dx
  541. asm lds dx,ds:unreg_exit_mesg
  542. #else
  543. asm mov dx,SEG reg_exit_mesg
  544. asm mov ds,dx
  545. asm lds dx,ds:reg_exit_mesg
  546. #endif
  547. asm mov ah,9
  548. asm int 21h
  549. asm pop ds
  550. profiling_summary();
  551. //ERRORLEVEL
  552. return ret;
  553. }
  554. #pragma warn +par
  555. char scan_options(void) {
  556. int t1,t2;
  557. char help=0;//Set to 1 for beep+help, 2 for help
  558. //Scan the command line options and adjust global variables accordingly.
  559. //Returns non-0 if need to exit.
  560. if(_argc>1) {
  561. for(t1=1;t1<_argc;t1++) {
  562. if((_argv[t1][0]!='-')&&(_argv[t1][0]!='+')&&
  563. (_argv[t1][0]!='/')) {
  564. help=1;
  565. break;
  566. }
  567. str_lwr(_argv[t1]);
  568. //Figure it out...
  569. if(!str_cmp(&_argv[t1][1],"?")) help=2;
  570. else if(!str_cmp(&_argv[t1][1],"nomouse")) no_mouse=1;
  571. else if(!str_cmp(&_argv[t1][1],"noems")) no_ems=1;
  572. else if(!str_cmp(&_argv[t1][1],"ega")) force_ega=1;
  573. else if(!str_cmp(&_argv[t1][1],"keyb2")) keyb_mode=1;
  574. //Cheat mode- use a - followed by an ALT-254.
  575. else if(((unsigned char)_argv[t1][1])==254) cheats_active++;
  576. else if(_argv[t1][1]=='l') {
  577. //Set "current" file to string after 'l'
  578. if(str_len(&_argv[t1][2])<FILENAME_SIZE) {//Only if short enough
  579. str_cpy(curr_file,&_argv[t1][2]);
  580. add_ext(curr_file,".MZX");
  581. }
  582. }
  583. else {
  584. //Check for variable arguments for sound card port/irq/dma
  585. t2=_argv[t1][5];
  586. _argv[t1][5]=0;
  587. if(!str_cmp(&_argv[t1][1],"port")) {
  588. _argv[t1][5]=t2;
  589. //Set port
  590. Addr=strtol(&_argv[t1][5],NULL,16);
  591. new_settings=1;
  592. }
  593. else {
  594. _argv[t1][5]=t2;
  595. t2=_argv[t1][4];
  596. _argv[t1][4]=0;
  597. if(!str_cmp(&_argv[t1][1],"irq")) {
  598. _argv[t1][4]=t2;
  599. //Set IRQ
  600. IRQ=strtol(&_argv[t1][4],NULL,10);
  601. new_settings=1;
  602. }
  603. else if(!str_cmp(&_argv[t1][1],"dma")) {
  604. _argv[t1][4]=t2;
  605. //Set DMA
  606. DMA=strtol(&_argv[t1][4],NULL,10);
  607. new_settings=1;
  608. }
  609. else {
  610. help=1;
  611. break;
  612. }
  613. }
  614. }
  615. }
  616. }
  617. if(help) {
  618. if(help==1) puts("\a");
  619. else puts("");
  620. puts("MegaZeux version 2.61\tCommand line parameters-\n");
  621. puts(" -? Help with parameters.");
  622. puts("-nomouse Don't use mouse, even if found.");
  623. puts(" -noems Don't use EMS memory, even if available. (NOT RECOMMENDED)");
  624. puts(" -ega Use EGA mode even if VGA or better found.");
  625. puts(" -keyb2 Use the alternate keyboard handler; Try this if the keyboard acts");
  626. puts("\t strange within the game or keys come out as if you are holding the");
  627. puts("\t Ctrl, Shift, or Alt key down, when you aren't.");
  628. puts("-l[file] Loads the world [file] up when starting MegaZeux. Do not include the");
  629. puts("\t [ or ]. You do not have to include the extension.\n");
  630. puts("Sound card settings- (see your sound card manual for details)");
  631. puts("These are only needed if autodetection fails. They are saved in the");
  632. puts("configuration file (MEGAZEUX.CFG) until you 'C'hange your configuration.\n");
  633. puts("-port230 Use base port 230h (substitute 240h, 250h, etc.)");
  634. puts(" -irq5 Use IRQ 5 (substitute 3, 4, etc.)");
  635. puts(" -dma3 Use DMA 3 (substitute 4, 5, etc.)");
  636. return 1;
  637. }
  638. return 0;
  639. }
  640. //Configuration file- MEGAZEUX.CFG.
  641. //Simple file containing music device (byte), mixing rate (word), and
  642. //whether sound is on. (byte)
  643. char load_config_file(void) {//Returns non-0 if not found
  644. int t1;
  645. FILE *fp;
  646. fp=fopen(config_file,"rb");
  647. if(fp==NULL) return 1;
  648. t1=fgetc(fp);
  649. if((t1!=126)&&(t1!=127)) {
  650. //old file- load overall_speed and return "no config file"
  651. fgetc(fp);
  652. fgetc(fp);
  653. fgetc(fp);
  654. overall_speed=fgetc(fp);
  655. if((overall_speed>9)||(overall_speed<1)) overall_speed=4;
  656. fclose(fp);
  657. return 1;
  658. }
  659. music_device=fgetc(fp);
  660. fread(&mixing_rate,2,1,fp);
  661. sfx_on=fgetc(fp);
  662. overall_speed=fgetc(fp);
  663. sfx_channels=fgetc(fp);
  664. if((overall_speed>9)||(overall_speed<1)) overall_speed=4;
  665. if(Addr==0xFFFF) fread(&Addr,2,1,fp);
  666. else fseek(fp,2,SEEK_CUR);
  667. if(DMA==0xFF) fread(&DMA,2,1,fp);
  668. else fseek(fp,2,SEEK_CUR);
  669. if(IRQ==0xFF) fread(&IRQ,2,1,fp);
  670. if(t1==126) {
  671. music_gvol=fgetc(fp);
  672. sound_gvol=fgetc(fp);
  673. }
  674. fclose(fp);
  675. return 0;
  676. }
  677. void save_config_file(void) {//Saves the .CFG file
  678. FILE *fp;
  679. fp=fopen(config_file,"wb");
  680. if(fp==NULL) return;
  681. fputc(126,fp);//Code to signify version 2.50 config file
  682. fputc(music_device,fp);
  683. fwrite(&mixing_rate,2,1,fp);
  684. fputc(sfx_on,fp);
  685. fputc(overall_speed,fp);
  686. fputc(sfx_channels,fp);
  687. fwrite(&Addr,2,1,fp);
  688. fwrite(&DMA,2,1,fp);
  689. fwrite(&IRQ,2,1,fp);
  690. fputc(music_gvol,fp);
  691. fputc(sound_gvol,fp);
  692. fclose(fp);
  693. }
  694. void update_config_file(void) {//Updates the speed setting in the .CFG file
  695. FILE *fp;
  696. fp=fopen(config_file,"rb+");
  697. if(fp==NULL) return;
  698. fseek(fp,5,SEEK_SET);
  699. fputc(overall_speed,fp);
  700. fseek(fp,7,SEEK_CUR);
  701. fputc(music_gvol,fp);
  702. fputc(sound_gvol,fp);
  703. fclose(fp);
  704. }