main.cpp 22 KB

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