m_misc.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Main loop menu stuff.
  31. * Default Config File.
  32. * PCX Screenshots.
  33. *
  34. *-----------------------------------------------------------------------------*/
  35. #ifdef HAVE_CONFIG_H
  36. #include "config.h"
  37. #endif
  38. #include <stdio.h>
  39. #include <errno.h>
  40. #ifdef HAVE_UNISTD_H
  41. #include <unistd.h>
  42. #endif
  43. #ifdef _MSC_VER
  44. #include <io.h>
  45. #endif
  46. #include <fcntl.h>
  47. #include <sys/stat.h>
  48. #include "doomstat.h"
  49. #include "m_argv.h"
  50. #include "g_game.h"
  51. #include "m_menu.h"
  52. #include "am_map.h"
  53. #include "w_wad.h"
  54. #include "i_system.h"
  55. #include "i_sound.h"
  56. #include "i_video.h"
  57. #include "v_video.h"
  58. #include "hu_stuff.h"
  59. #include "st_stuff.h"
  60. #include "dstrings.h"
  61. #include "m_misc.h"
  62. #include "s_sound.h"
  63. #include "sounds.h"
  64. #include "i_joy.h"
  65. #include "lprintf.h"
  66. #include "d_main.h"
  67. #include "r_draw.h"
  68. #include "r_demo.h"
  69. #include "r_fps.h"
  70. /* cph - disk icon not implemented */
  71. static inline void I_BeginRead(void) {}
  72. static inline void I_EndRead(void) {}
  73. /*
  74. * M_WriteFile
  75. *
  76. * killough 9/98: rewritten to use stdio and to flash disk icon
  77. */
  78. boolean M_WriteFile(char const *name, void *source, int length)
  79. {
  80. FILE *fp;
  81. errno = 0;
  82. if (!(fp = fopen(name, "wb"))) // Try opening file
  83. return 0; // Could not open file for writing
  84. I_BeginRead(); // Disk icon on
  85. length = fwrite(source, 1, length, fp) == (size_t)length; // Write data
  86. fclose(fp);
  87. I_EndRead(); // Disk icon off
  88. if (!length) // Remove partially written file
  89. remove(name);
  90. return length;
  91. }
  92. /*
  93. * M_ReadFile
  94. *
  95. * killough 9/98: rewritten to use stdio and to flash disk icon
  96. */
  97. int M_ReadFile(char const *name, byte **buffer)
  98. {
  99. FILE *fp;
  100. if ((fp = fopen(name, "rb")))
  101. {
  102. size_t length;
  103. I_BeginRead();
  104. fseek(fp, 0, SEEK_END);
  105. length = ftell(fp);
  106. fseek(fp, 0, SEEK_SET);
  107. *buffer = Z_Malloc(length, PU_STATIC, 0);
  108. if (fread(*buffer, 1, length, fp) == length)
  109. {
  110. fclose(fp);
  111. I_EndRead();
  112. return length;
  113. }
  114. fclose(fp);
  115. }
  116. /* cph 2002/08/10 - this used to return 0 on error, but that's ambiguous,
  117. * because we could have a legit 0-length file. So make it -1. */
  118. return -1;
  119. }
  120. //
  121. // DEFAULTS
  122. //
  123. int usemouse;
  124. boolean precache = true; /* if true, load all graphics at start */
  125. extern int mousebfire;
  126. extern int mousebstrafe;
  127. extern int mousebforward;
  128. extern int displaywidth;
  129. extern int displayheight;
  130. extern int viewwidth;
  131. extern int viewheight;
  132. #ifdef GL_DOOM
  133. extern int gl_nearclip;
  134. extern int gl_colorbuffer_bits;
  135. extern int gl_depthbuffer_bits;
  136. extern const char *gl_tex_filter_string;
  137. extern const char *gl_tex_format_string;
  138. extern int gl_drawskys;
  139. extern int gl_sortsprites;
  140. extern int gl_use_paletted_texture;
  141. extern int gl_use_shared_texture_palette;
  142. extern int gl_sprite_offset;
  143. #endif
  144. extern int realtic_clock_rate; // killough 4/13/98: adjustable timer
  145. extern int tran_filter_pct; // killough 2/21/98
  146. extern int screenblocks;
  147. extern int showMessages;
  148. #ifndef DJGPP
  149. int mus_pause_opt; // 0 = kill music, 1 = pause, 2 = continue
  150. bool mus_on = true;
  151. #endif
  152. extern const char* chat_macros[];
  153. extern int endoom_mode;
  154. extern const char* S_music_files[]; // cournia
  155. /* cph - Some MBF stuff parked here for now
  156. * killough 10/98
  157. */
  158. int map_point_coordinates;
  159. default_t defaults[] =
  160. {
  161. {"Misc settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  162. {"default_compatibility_level",{(int*)&default_compatibility_level,NULL},
  163. {-1,NULL},-1,MAX_COMPATIBILITY_LEVEL-1,
  164. def_int,ss_none,NULL,NULL}, // compatibility level" - CPhipps
  165. {"realtic_clock_rate",{&realtic_clock_rate,NULL},{100,NULL},0,UL,
  166. def_int,ss_none,NULL,NULL}, // percentage of normal speed (35 fps) realtic clock runs at
  167. {"max_player_corpse", {&bodyquesize,NULL}, {32,NULL},-1,UL, // killough 2/8/98
  168. def_int,ss_none,NULL,NULL}, // number of dead bodies in view supported (-1 = no limit)
  169. {"flashing_hom",{&flashing_hom,NULL},{0,NULL},0,1,
  170. def_bool,ss_none,NULL,NULL}, // killough 10/98 - enable flashing HOM indicator
  171. {"demo_insurance",{&default_demo_insurance,NULL},{2,NULL},0,2, // killough 3/31/98
  172. def_int,ss_none,NULL,NULL}, // 1=take special steps ensuring demo sync, 2=only during recordings
  173. {"endoom_mode", {&endoom_mode,NULL},{5,NULL},0,7, // CPhipps - endoom flags
  174. def_hex, ss_none,NULL,NULL}, // 0, +1 for colours, +2 for non-ascii chars, +4 for skip-last-line
  175. {"level_precache",{(int*)&precache,NULL},{0,NULL},0,1,
  176. def_bool,ss_none,NULL,NULL}, // precache level data?
  177. {"demo_smoothturns", {&demo_smoothturns,NULL}, {0,NULL},0,1,
  178. def_bool,ss_stat,NULL,NULL},
  179. {"demo_smoothturnsfactor", {&demo_smoothturnsfactor,NULL}, {6,NULL},1,SMOOTH_PLAYING_MAXFACTOR,
  180. def_int,ss_stat,NULL,NULL},
  181. {"Files",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  182. /* cph - MBF-like wad/deh/bex autoload code */
  183. {"wadfile_1",{NULL,&wad_files[0]},{0,""},UL,UL,def_str,ss_none,NULL,NULL},
  184. {"wadfile_2",{NULL,&wad_files[1]},{0,""},UL,UL,def_str,ss_none,NULL,NULL},
  185. {"dehfile_1",{NULL,&deh_files[0]},{0,""},UL,UL,def_str,ss_none,NULL,NULL},
  186. {"dehfile_2",{NULL,&deh_files[1]},{0,""},UL,UL,def_str,ss_none,NULL,NULL},
  187. {"Game settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  188. {"default_skill",{&defaultskill,NULL},{3,NULL},1,5, // jff 3/24/98 allow default skill setting
  189. def_int,ss_none,NULL,NULL}, // selects default skill 1=TYTD 2=NTR 3=HMP 4=UV 5=NM
  190. {"weapon_recoil",{&default_weapon_recoil,NULL},{0,NULL},0,1,
  191. def_bool,ss_weap, &weapon_recoil,NULL},
  192. /* killough 10/98 - toggle between SG/SSG and Fist/Chainsaw */
  193. {"doom_weapon_toggles",{&doom_weapon_toggles,NULL}, {1,NULL}, 0, 1,
  194. def_bool, ss_weap,NULL,NULL},
  195. {"player_bobbing",{&default_player_bobbing,NULL},{1,NULL},0,1, // phares 2/25/98
  196. def_bool,ss_weap, &player_bobbing,NULL},
  197. {"monsters_remember",{&default_monsters_remember,NULL},{1,NULL},0,1, // killough 3/1/98
  198. def_bool,ss_enem, &monsters_remember,NULL},
  199. /* MBF AI enhancement options */
  200. {"monster_infighting",{&default_monster_infighting,NULL}, {1,NULL}, 0, 1,
  201. def_bool, ss_enem, &monster_infighting,NULL},
  202. {"monster_backing",{&default_monster_backing,NULL}, {0,NULL}, 0, 1,
  203. def_bool, ss_enem, &monster_backing,NULL},
  204. {"monster_avoid_hazards",{&default_monster_avoid_hazards,NULL}, {1,NULL}, 0, 1,
  205. def_bool, ss_enem, &monster_avoid_hazards,NULL},
  206. {"monkeys",{&default_monkeys,NULL}, {0,NULL}, 0, 1,
  207. def_bool, ss_enem, &monkeys,NULL},
  208. {"monster_friction",{&default_monster_friction,NULL}, {1,NULL}, 0, 1,
  209. def_bool, ss_enem, &monster_friction,NULL},
  210. {"help_friends",{&default_help_friends,NULL}, {1,NULL}, 0, 1,
  211. def_bool, ss_enem, &help_friends,NULL},
  212. {"allow_pushers",{&default_allow_pushers,NULL},{1,NULL},0,1,
  213. def_bool,ss_weap, &allow_pushers,NULL},
  214. {"variable_friction",{&default_variable_friction,NULL},{1,NULL},0,1,
  215. def_bool,ss_weap, &variable_friction,NULL},
  216. #ifdef DOGS
  217. {"player_helpers",{&default_dogs}, {0}, 0, 3,
  218. def_bool, ss_enem },
  219. {"friend_distance",{&default_distfriend}, {128}, 0, 999,
  220. def_int, ss_enem, &distfriend},
  221. {"dog_jumping",{&default_dog_jumping}, {1}, 0, 1,
  222. def_bool, ss_enem, &dog_jumping},
  223. #endif
  224. /* End of MBF AI extras */
  225. {"sts_always_red",{&sts_always_red,NULL},{1,NULL},0,1, // no color changes on status bar
  226. def_bool,ss_stat,NULL,NULL},
  227. {"sts_pct_always_gray",{&sts_pct_always_gray,NULL},{0,NULL},0,1, // 2/23/98 chg default
  228. def_bool,ss_stat,NULL,NULL}, // makes percent signs on status bar always gray
  229. {"sts_traditional_keys",{&sts_traditional_keys,NULL},{0,NULL},0,1, // killough 2/28/98
  230. def_bool,ss_stat,NULL,NULL}, // disables doubled card and skull key display on status bar
  231. {"show_messages",{&showMessages,NULL},{1,NULL},0,1,
  232. def_bool,ss_none,NULL,NULL}, // enables message display
  233. {"autorun",{&autorun,NULL},{0,NULL},0,1, // killough 3/6/98: preserve autorun across games
  234. def_bool,ss_none,NULL,NULL},
  235. {"Compatibility settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  236. {"comp_zombie",{&default_comp[comp_zombie],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_zombie],NULL},
  237. {"comp_infcheat",{&default_comp[comp_infcheat],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_infcheat],NULL},
  238. {"comp_stairs",{&default_comp[comp_stairs],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_stairs],NULL},
  239. {"comp_telefrag",{&default_comp[comp_telefrag],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_telefrag],NULL},
  240. {"comp_dropoff",{&default_comp[comp_dropoff],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_dropoff],NULL},
  241. {"comp_falloff",{&default_comp[comp_falloff],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_falloff],NULL},
  242. {"comp_staylift",{&default_comp[comp_staylift],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_staylift],NULL},
  243. {"comp_doorstuck",{&default_comp[comp_doorstuck],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_doorstuck],NULL},
  244. {"comp_pursuit",{&default_comp[comp_pursuit],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_pursuit],NULL},
  245. {"comp_vile",{&default_comp[comp_vile],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_vile],NULL},
  246. {"comp_pain",{&default_comp[comp_pain],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_pain],NULL},
  247. {"comp_skull",{&default_comp[comp_skull],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_skull],NULL},
  248. {"comp_blazing",{&default_comp[comp_blazing],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_blazing],NULL},
  249. {"comp_doorlight",{&default_comp[comp_doorlight],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_doorlight],NULL},
  250. {"comp_god",{&default_comp[comp_god],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_god],NULL},
  251. {"comp_skymap",{&default_comp[comp_skymap],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_skymap],NULL},
  252. {"comp_floors",{&default_comp[comp_floors],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_floors],NULL},
  253. {"comp_model",{&default_comp[comp_model],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_model],NULL},
  254. {"comp_zerotags",{&default_comp[comp_zerotags],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_zerotags],NULL},
  255. {"comp_moveblock",{&default_comp[comp_moveblock],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_moveblock],NULL},
  256. {"comp_sound",{&default_comp[comp_sound],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_sound],NULL},
  257. {"comp_666",{&default_comp[comp_666],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_666],NULL},
  258. {"comp_soul",{&default_comp[comp_soul],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_soul],NULL},
  259. {"comp_maskedanim",{&default_comp[comp_maskedanim],NULL},{0,NULL},0,1,def_bool,ss_comp,&comp[comp_maskedanim],NULL},
  260. {"Sound settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  261. {"sound_card",{&snd_card,NULL},{-1,NULL},-1,7, // jff 1/18/98 allow Allegro drivers
  262. def_int,ss_none,NULL,NULL}, // select sounds driver (DOS), -1 is autodetect, 0 is none; in Linux, non-zero enables sound
  263. {"music_card",{&mus_card,NULL},{-1,NULL},-1,9, // to be set, -1 = autodetect
  264. def_int,ss_none,NULL,NULL}, // select music driver (DOS), -1 is autodetect, 0 is none"; in Linux, non-zero enables music
  265. {"pitched_sounds",{&pitched_sounds,NULL},{0,NULL},0,1, // killough 2/21/98
  266. def_bool,ss_none,NULL,NULL}, // enables variable pitch in sound effects (from id's original code)
  267. {"samplerate",{&snd_samplerate,NULL},{22050,NULL},11025,48000, def_int,ss_none,NULL,NULL},
  268. {"sfx_volume",{&snd_SfxVolume,NULL},{8,NULL},0,15, def_int,ss_none,NULL,NULL},
  269. {"music_volume",{&snd_MusicVolume,NULL},{8,NULL},0,15, def_int,ss_none,NULL,NULL},
  270. {"mus_pause_opt",{&mus_pause_opt,NULL},{2,NULL},0,2, // CPhipps - music pausing
  271. def_int, ss_none,NULL,NULL}, // 0 = kill music when paused, 1 = pause music, 2 = let music continue
  272. {"snd_channels",{&default_numChannels,NULL},{8,NULL},1,32,
  273. def_int,ss_none,NULL,NULL}, // number of audio events simultaneously // killough
  274. {"Video settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  275. #ifdef GL_DOOM
  276. #ifdef _MSC_VER
  277. {"videomode",{NULL, &default_videomode},{0,"gl"},UL,UL,def_str,ss_none},
  278. #else
  279. {"videomode",{NULL, &default_videomode},{0,"8"},UL,UL,def_str,ss_none,NULL,NULL},
  280. #endif
  281. #else
  282. {"videomode",{NULL, &default_videomode},{0,"8"},UL,UL,def_str,ss_none},
  283. #endif
  284. /* 640x480 default resolution */
  285. {"screen_width",{&desired_screenwidth,NULL},{640,NULL}, 320, MAX_SCREENWIDTH,
  286. def_int,ss_none,NULL,NULL},
  287. {"screen_height",{&desired_screenheight,NULL},{480,NULL},200,MAX_SCREENHEIGHT,
  288. def_int,ss_none,NULL,NULL},
  289. {"use_fullscreen",{&use_fullscreen,NULL},{1,NULL},0,1, /* proff 21/05/2000 */
  290. def_bool,ss_none,NULL,NULL},
  291. #ifndef DISABLE_DOUBLEBUFFER
  292. {"use_doublebuffer",{&use_doublebuffer},{1},0,1, // proff 2001-7-4
  293. def_bool,ss_none}, // enable doublebuffer to avoid display tearing (fullscreen)
  294. #endif
  295. #ifdef IPHONE // JDC, don't waste time builing the tables at startup
  296. {"translucency",{&default_translucency,NULL},{0,NULL},0,1, // phares
  297. def_bool,ss_none,NULL,NULL}, // enables translucency
  298. #else
  299. {"translucency",{&default_translucency},{1},0,1, // phares
  300. def_bool,ss_none}, // enables translucency
  301. #endif
  302. {"tran_filter_pct",{&tran_filter_pct,NULL},{66,NULL},0,100, // killough 2/21/98
  303. def_int,ss_none,NULL,NULL}, // set percentage of foreground/background translucency mix
  304. {"screenblocks",{&screenblocks,NULL},{10,NULL},3,11, // killough 2/21/98: default to 10
  305. def_int,ss_none,NULL,NULL},
  306. {"usegamma",{&usegamma,NULL},{3,NULL},0,4, //jff 3/6/98 fix erroneous upper limit in range
  307. def_int,ss_none,NULL,NULL}, // gamma correction level // killough 1/18/98
  308. {"uncapped_framerate", {&movement_smooth,NULL}, {0,NULL},0,1,
  309. def_bool,ss_stat,NULL,NULL},
  310. {"filter_wall",{(int*)&drawvars.filterwall,NULL},{RDRAW_FILTER_POINT,NULL},
  311. RDRAW_FILTER_POINT, RDRAW_FILTER_ROUNDED, def_int,ss_none,NULL,NULL},
  312. {"filter_floor",{(int*)&drawvars.filterfloor,NULL},{RDRAW_FILTER_POINT,NULL},
  313. RDRAW_FILTER_POINT, RDRAW_FILTER_ROUNDED, def_int,ss_none,NULL,NULL},
  314. {"filter_sprite",{(int*)&drawvars.filtersprite,NULL},{RDRAW_FILTER_POINT,NULL},
  315. RDRAW_FILTER_POINT, RDRAW_FILTER_ROUNDED, def_int,ss_none,NULL,NULL},
  316. {"filter_z",{(int*)&drawvars.filterz,NULL},{RDRAW_FILTER_POINT,NULL},
  317. RDRAW_FILTER_POINT, RDRAW_FILTER_LINEAR, def_int,ss_none,NULL,NULL},
  318. {"filter_patch",{(int*)&drawvars.filterpatch,NULL},{RDRAW_FILTER_POINT,NULL},
  319. RDRAW_FILTER_POINT, RDRAW_FILTER_ROUNDED, def_int,ss_none,NULL,NULL},
  320. {"filter_threshold",{(int*)&drawvars.mag_threshold,NULL},{49152,NULL},
  321. 0, UL, def_int,ss_none,NULL,NULL},
  322. {"sprite_edges",{(int*)&drawvars.sprite_edges,NULL},{RDRAW_MASKEDCOLUMNEDGE_SQUARE,NULL},
  323. RDRAW_MASKEDCOLUMNEDGE_SQUARE, RDRAW_MASKEDCOLUMNEDGE_SLOPED, def_int,ss_none,NULL,NULL},
  324. {"patch_edges",{(int*)&drawvars.patch_edges,NULL},{RDRAW_MASKEDCOLUMNEDGE_SQUARE,NULL},
  325. RDRAW_MASKEDCOLUMNEDGE_SQUARE, RDRAW_MASKEDCOLUMNEDGE_SLOPED, def_int,ss_none,NULL,NULL},
  326. #ifdef GL_DOOM
  327. {"OpenGL settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  328. {"gl_nearclip",{&gl_nearclip,NULL},{5,NULL},0,UL,
  329. def_int,ss_none,NULL,NULL}, /* near clipping plane pos */
  330. {"gl_colorbuffer_bits",{&gl_colorbuffer_bits,NULL},{16,NULL},16,32,
  331. def_int,ss_none,NULL,NULL},
  332. {"gl_depthbuffer_bits",{&gl_depthbuffer_bits,NULL},{16,NULL},16,32,
  333. def_int,ss_none,NULL,NULL},
  334. {"gl_tex_filter_string", {NULL,&gl_tex_filter_string}, {0,"GL_LINEAR"},UL,UL,
  335. def_str,ss_none,NULL,NULL},
  336. {"gl_tex_format_string", {NULL,&gl_tex_format_string}, {0,"GL_RGB5_A1"},UL,UL,
  337. def_str,ss_none,NULL,NULL},
  338. {"gl_drawskys",{&gl_drawskys,NULL},{1,NULL},0,1,
  339. def_bool,ss_none,NULL,NULL},
  340. {"gl_sortsprites",{&gl_sortsprites,NULL},{1,NULL},0,1,
  341. def_bool,ss_none,NULL,NULL},
  342. {"gl_use_paletted_texture",{&gl_use_paletted_texture,NULL},{0,NULL},0,1,
  343. def_bool,ss_none,NULL,NULL},
  344. {"gl_use_shared_texture_palette",{&gl_use_shared_texture_palette,NULL},{0,NULL},0,1,
  345. def_bool,ss_none,NULL,NULL},
  346. #ifdef GL_DOOM
  347. {"gl_sprite_offset",{&gl_sprite_offset,NULL},{0,NULL}, 0, 5,
  348. def_int,ss_none,NULL,NULL}, // amount to bring items out of floor (GL) Mead 8/13/03
  349. #endif
  350. #endif
  351. {"Mouse settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  352. {"use_mouse",{&usemouse,NULL},{1,NULL},0,1,
  353. def_bool,ss_none,NULL,NULL}, // enables use of mouse with DOOM
  354. //jff 4/3/98 allow unlimited sensitivity
  355. {"mouse_sensitivity_horiz",{&mouseSensitivity_horiz,NULL},{10,NULL},0,UL,
  356. def_int,ss_none,NULL,NULL}, /* adjust horizontal (x) mouse sensitivity killough/mead */
  357. //jff 4/3/98 allow unlimited sensitivity
  358. {"mouse_sensitivity_vert",{&mouseSensitivity_vert,NULL},{10,NULL},0,UL,
  359. def_int,ss_none,NULL,NULL}, /* adjust vertical (y) mouse sensitivity killough/mead */
  360. //jff 3/8/98 allow -1 in mouse bindings to disable mouse function
  361. {"mouseb_fire",{&mousebfire,NULL},{0,NULL},-1,MAX_MOUSEB,
  362. def_int,ss_keys,NULL,NULL}, // mouse button number to use for fire
  363. {"mouseb_strafe",{&mousebstrafe,NULL},{1,NULL},-1,MAX_MOUSEB,
  364. def_int,ss_keys,NULL,NULL}, // mouse button number to use for strafing
  365. {"mouseb_forward",{&mousebforward,NULL},{2,NULL},-1,MAX_MOUSEB,
  366. def_int,ss_keys,NULL,NULL}, // mouse button number to use for forward motion
  367. //jff 3/8/98 end of lower range change for -1 allowed in mouse binding
  368. // For key bindings, the values stored in the key_* variables // phares
  369. // are the internal Doom Codes. The values stored in the default.cfg
  370. // file are the keyboard codes.
  371. // CPhipps - now they're the doom codes, so default.cfg can be portable
  372. {"Key bindings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  373. {"key_right", {&key_right,NULL}, {KEYD_RIGHTARROW,NULL},
  374. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to turn right
  375. {"key_left", {&key_left,NULL}, {KEYD_LEFTARROW,NULL} ,
  376. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to turn left
  377. {"key_up", {&key_up,NULL}, {KEYD_UPARROW,NULL} ,
  378. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move forward
  379. {"key_down", {&key_down,NULL}, {KEYD_DOWNARROW,NULL},
  380. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move backward
  381. {"key_menu_right", {&key_menu_right,NULL}, {KEYD_RIGHTARROW,NULL},// phares 3/7/98
  382. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move right in a menu // |
  383. {"key_menu_left", {&key_menu_left,NULL}, {KEYD_LEFTARROW,NULL} ,// V
  384. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move left in a menu
  385. {"key_menu_up", {&key_menu_up,NULL}, {KEYD_UPARROW,NULL} ,
  386. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move up in a menu
  387. {"key_menu_down", {&key_menu_down,NULL}, {KEYD_DOWNARROW,NULL} ,
  388. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to move down in a menu
  389. {"key_menu_backspace",{&key_menu_backspace,NULL}, {KEYD_BACKSPACE,NULL} ,
  390. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // delete key in a menu
  391. {"key_menu_escape", {&key_menu_escape,NULL}, {KEYD_ESCAPE,NULL} ,
  392. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to leave a menu , // phares 3/7/98
  393. {"key_menu_enter", {&key_menu_enter,NULL}, {KEYD_ENTER,NULL} ,
  394. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to select from menu
  395. {"key_strafeleft", {&key_strafeleft,NULL}, {',',NULL} ,
  396. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to strafe left
  397. {"key_straferight", {&key_straferight,NULL}, {'.',NULL} ,
  398. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to strafe right
  399. {"key_fire", {&key_fire,NULL}, {KEYD_RCTRL,NULL} ,
  400. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // duh
  401. {"key_use", {&key_use,NULL}, {' ',NULL} ,
  402. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to open a door, use a switch
  403. {"key_strafe", {&key_strafe,NULL}, {KEYD_RALT,NULL} ,
  404. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to use with arrows to strafe
  405. {"key_speed", {&key_speed,NULL}, {KEYD_RSHIFT,NULL} ,
  406. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to run
  407. {"key_savegame", {&key_savegame,NULL}, {KEYD_F2,NULL} ,
  408. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to save current game
  409. {"key_loadgame", {&key_loadgame,NULL}, {KEYD_F3,NULL} ,
  410. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to restore from saved games
  411. {"key_soundvolume", {&key_soundvolume,NULL}, {KEYD_F4,NULL} ,
  412. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to bring up sound controls
  413. {"key_hud", {&key_hud,NULL}, {KEYD_F5,NULL} ,
  414. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to adjust HUD
  415. {"key_quicksave", {&key_quicksave,NULL}, {KEYD_F6,NULL} ,
  416. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to to quicksave
  417. {"key_endgame", {&key_endgame,NULL}, {KEYD_F7,NULL} ,
  418. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to end the game
  419. {"key_messages", {&key_messages,NULL}, {KEYD_F8,NULL} ,
  420. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle message enable
  421. {"key_quickload", {&key_quickload,NULL}, {KEYD_F9,NULL} ,
  422. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to load from quicksave
  423. {"key_quit", {&key_quit,NULL}, {KEYD_F10,NULL} ,
  424. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to quit game
  425. {"key_gamma", {&key_gamma,NULL}, {KEYD_F11,NULL} ,
  426. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to adjust gamma correction
  427. {"key_spy", {&key_spy,NULL}, {KEYD_F12,NULL} ,
  428. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to view from another coop player's view
  429. {"key_pause", {&key_pause,NULL}, {KEYD_PAUSE,NULL} ,
  430. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to pause the game
  431. {"key_autorun", {&key_autorun,NULL}, {KEYD_CAPSLOCK,NULL} ,
  432. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle always run mode
  433. {"key_chat", {&key_chat,NULL}, {'t',NULL} ,
  434. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to enter a chat message
  435. {"key_backspace", {&key_backspace,NULL}, {KEYD_BACKSPACE,NULL} ,
  436. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // backspace key
  437. {"key_enter", {&key_enter,NULL}, {KEYD_ENTER,NULL} ,
  438. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to select from menu or see last message
  439. {"key_map", {&key_map,NULL}, {KEYD_TAB,NULL} ,
  440. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle automap display
  441. {"key_map_right", {&key_map_right,NULL}, {KEYD_RIGHTARROW,NULL},// phares 3/7/98
  442. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to shift automap right // |
  443. {"key_map_left", {&key_map_left,NULL}, {KEYD_LEFTARROW,NULL} ,// V
  444. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to shift automap left
  445. {"key_map_up", {&key_map_up,NULL}, {KEYD_UPARROW,NULL} ,
  446. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to shift automap up
  447. {"key_map_down", {&key_map_down,NULL}, {KEYD_DOWNARROW,NULL} ,
  448. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to shift automap down
  449. {"key_map_zoomin", {&key_map_zoomin,NULL}, {'=',NULL} ,
  450. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to enlarge automap
  451. {"key_map_zoomout", {&key_map_zoomout,NULL}, {'-',NULL} ,
  452. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to reduce automap
  453. {"key_map_gobig", {&key_map_gobig,NULL}, {'0',NULL} ,
  454. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to get max zoom for automap
  455. {"key_map_follow", {&key_map_follow,NULL}, {'f',NULL} ,
  456. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle follow mode
  457. {"key_map_mark", {&key_map_mark,NULL}, {'m',NULL} ,
  458. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to drop a marker on automap
  459. {"key_map_clear", {&key_map_clear,NULL}, {'c',NULL} ,
  460. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to clear all markers on automap
  461. {"key_map_grid", {&key_map_grid,NULL}, {'g',NULL} ,
  462. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle grid display over automap
  463. {"key_map_rotate", {&key_map_rotate,NULL}, {'r',NULL} ,
  464. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle rotating the automap to match the player's orientation
  465. {"key_map_overlay", {&key_map_overlay,NULL}, {'o',NULL} ,
  466. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle overlaying the automap on the rendered display
  467. {"key_reverse", {&key_reverse,NULL}, {'/',NULL} ,
  468. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to spin 180 instantly
  469. {"key_zoomin", {&key_zoomin,NULL}, {'=',NULL} ,
  470. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to enlarge display
  471. {"key_zoomout", {&key_zoomout,NULL}, {'-',NULL} ,
  472. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to reduce display
  473. {"key_chatplayer1", {&destination_keys[0],NULL}, {'g',NULL} ,
  474. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to chat with player 1
  475. // killough 11/98: fix 'i'/'b' reversal
  476. {"key_chatplayer2", {&destination_keys[1],NULL}, {'i',NULL} ,
  477. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to chat with player 2
  478. {"key_chatplayer3", {&destination_keys[2],NULL}, {'b',NULL} ,
  479. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to chat with player 3
  480. {"key_chatplayer4", {&destination_keys[3],NULL}, {'r',NULL} ,
  481. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to chat with player 4
  482. {"key_weapontoggle",{&key_weapontoggle,NULL}, {'0',NULL} ,
  483. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to toggle between two most preferred weapons with ammo
  484. {"key_weapon1", {&key_weapon1,NULL}, {'1',NULL} ,
  485. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 1 (fist/chainsaw)
  486. {"key_weapon2", {&key_weapon2,NULL}, {'2',NULL} ,
  487. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 2 (pistol)
  488. {"key_weapon3", {&key_weapon3,NULL}, {'3',NULL} ,
  489. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 3 (supershotgun/shotgun)
  490. {"key_weapon4", {&key_weapon4,NULL}, {'4',NULL} ,
  491. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 4 (chaingun)
  492. {"key_weapon5", {&key_weapon5,NULL}, {'5',NULL} ,
  493. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 5 (rocket launcher)
  494. {"key_weapon6", {&key_weapon6,NULL}, {'6',NULL} ,
  495. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 6 (plasma rifle)
  496. {"key_weapon7", {&key_weapon7,NULL}, {'7',NULL} ,
  497. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 7 (bfg9000) // ^
  498. {"key_weapon8", {&key_weapon8,NULL}, {'8',NULL} ,
  499. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 8 (chainsaw) // |
  500. {"key_weapon9", {&key_weapon9,NULL}, {'9',NULL} ,
  501. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to switch to weapon 9 (supershotgun) // phares
  502. // killough 2/22/98: screenshot key
  503. {"key_screenshot", {&key_screenshot,NULL}, {'*',NULL} ,
  504. 0,MAX_KEY,def_key,ss_keys,NULL,NULL}, // key to take a screenshot
  505. {"Joystick settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  506. {"use_joystick",{&usejoystick,NULL},{0,NULL},0,2,
  507. def_int,ss_none,NULL,NULL}, // number of joystick to use (0 for none)
  508. {"joy_left",{&joyleft,NULL},{0,NULL}, UL,UL,def_int,ss_none,NULL,NULL},
  509. {"joy_right",{&joyright,NULL},{0,NULL},UL,UL,def_int,ss_none,NULL,NULL},
  510. {"joy_up", {&joyup,NULL}, {0,NULL}, UL,UL,def_int,ss_none,NULL,NULL},
  511. {"joy_down",{&joydown,NULL},{0,NULL}, UL,UL,def_int,ss_none,NULL,NULL},
  512. {"joyb_fire",{&joybfire,NULL},{0,NULL},0,UL,
  513. def_int,ss_keys,NULL,NULL}, // joystick button number to use for fire
  514. {"joyb_strafe",{&joybstrafe,NULL},{1,NULL},0,UL,
  515. def_int,ss_keys,NULL,NULL}, // joystick button number to use for strafing
  516. {"joyb_speed",{&joybspeed,NULL},{2,NULL},0,UL,
  517. def_int,ss_keys,NULL,NULL}, // joystick button number to use for running
  518. {"joyb_use",{&joybuse,NULL},{3,NULL},0,UL,
  519. def_int,ss_keys,NULL,NULL}, // joystick button number to use for use/open
  520. {"Chat macros",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  521. {"chatmacro0", {0,&chat_macros[0]}, {0,HUSTR_CHATMACRO0},UL,UL,
  522. def_str,ss_chat,NULL,NULL}, // chat string associated with 0 key
  523. {"chatmacro1", {0,&chat_macros[1]}, {0,HUSTR_CHATMACRO1},UL,UL,
  524. def_str,ss_chat,NULL,NULL}, // chat string associated with 1 key
  525. {"chatmacro2", {0,&chat_macros[2]}, {0,HUSTR_CHATMACRO2},UL,UL,
  526. def_str,ss_chat,NULL,NULL}, // chat string associated with 2 key
  527. {"chatmacro3", {0,&chat_macros[3]}, {0,HUSTR_CHATMACRO3},UL,UL,
  528. def_str,ss_chat,NULL,NULL}, // chat string associated with 3 key
  529. {"chatmacro4", {0,&chat_macros[4]}, {0,HUSTR_CHATMACRO4},UL,UL,
  530. def_str,ss_chat,NULL,NULL}, // chat string associated with 4 key
  531. {"chatmacro5", {0,&chat_macros[5]}, {0,HUSTR_CHATMACRO5},UL,UL,
  532. def_str,ss_chat,NULL,NULL}, // chat string associated with 5 key
  533. {"chatmacro6", {0,&chat_macros[6]}, {0,HUSTR_CHATMACRO6},UL,UL,
  534. def_str,ss_chat,NULL,NULL}, // chat string associated with 6 key
  535. {"chatmacro7", {0,&chat_macros[7]}, {0,HUSTR_CHATMACRO7},UL,UL,
  536. def_str,ss_chat,NULL,NULL}, // chat string associated with 7 key
  537. {"chatmacro8", {0,&chat_macros[8]}, {0,HUSTR_CHATMACRO8},UL,UL,
  538. def_str,ss_chat,NULL,NULL}, // chat string associated with 8 key
  539. {"chatmacro9", {0,&chat_macros[9]}, {0,HUSTR_CHATMACRO9},UL,UL,
  540. def_str,ss_chat,NULL,NULL}, // chat string associated with 9 key
  541. {"Automap settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  542. //jff 1/7/98 defaults for automap colors
  543. //jff 4/3/98 remove -1 in lower range, 0 now disables new map features
  544. {"mapcolor_back", {&mapcolor_back,NULL}, {247,NULL},0,255, // black //jff 4/6/98 new black
  545. def_colour,ss_auto,NULL,NULL}, // color used as background for automap
  546. {"mapcolor_grid", {&mapcolor_grid,NULL}, {104,NULL},0,255, // dk gray
  547. def_colour,ss_auto,NULL,NULL}, // color used for automap grid lines
  548. {"mapcolor_wall", {&mapcolor_wall,NULL}, {23,NULL},0,255, // red-brown
  549. def_colour,ss_auto,NULL,NULL}, // color used for one side walls on automap
  550. {"mapcolor_fchg", {&mapcolor_fchg,NULL}, {55,NULL},0,255, // lt brown
  551. def_colour,ss_auto,NULL,NULL}, // color used for lines floor height changes across
  552. {"mapcolor_cchg", {&mapcolor_cchg,NULL}, {215,NULL},0,255, // orange
  553. def_colour,ss_auto,NULL,NULL}, // color used for lines ceiling height changes across
  554. {"mapcolor_clsd", {&mapcolor_clsd,NULL}, {208,NULL},0,255, // white
  555. def_colour,ss_auto,NULL,NULL}, // color used for lines denoting closed doors, objects
  556. {"mapcolor_rkey", {&mapcolor_rkey,NULL}, {175,NULL},0,255, // red
  557. def_colour,ss_auto,NULL,NULL}, // color used for red key sprites
  558. {"mapcolor_bkey", {&mapcolor_bkey,NULL}, {204,NULL},0,255, // blue
  559. def_colour,ss_auto,NULL,NULL}, // color used for blue key sprites
  560. {"mapcolor_ykey", {&mapcolor_ykey,NULL}, {231,NULL},0,255, // yellow
  561. def_colour,ss_auto,NULL,NULL}, // color used for yellow key sprites
  562. {"mapcolor_rdor", {&mapcolor_rdor,NULL}, {175,NULL},0,255, // red
  563. def_colour,ss_auto,NULL,NULL}, // color used for closed red doors
  564. {"mapcolor_bdor", {&mapcolor_bdor,NULL}, {204,NULL},0,255, // blue
  565. def_colour,ss_auto,NULL,NULL}, // color used for closed blue doors
  566. {"mapcolor_ydor", {&mapcolor_ydor,NULL}, {231,NULL},0,255, // yellow
  567. def_colour,ss_auto,NULL,NULL}, // color used for closed yellow doors
  568. {"mapcolor_tele", {&mapcolor_tele,NULL}, {119,NULL},0,255, // dk green
  569. def_colour,ss_auto,NULL,NULL}, // color used for teleporter lines
  570. {"mapcolor_secr", {&mapcolor_secr,NULL}, {252,NULL},0,255, // purple
  571. def_colour,ss_auto,NULL,NULL}, // color used for lines around secret sectors
  572. {"mapcolor_exit", {&mapcolor_exit,NULL}, {0,NULL},0,255, // none
  573. def_colour,ss_auto,NULL,NULL}, // color used for exit lines
  574. {"mapcolor_unsn", {&mapcolor_unsn,NULL}, {104,NULL},0,255, // dk gray
  575. def_colour,ss_auto,NULL,NULL}, // color used for lines not seen without computer map
  576. {"mapcolor_flat", {&mapcolor_flat,NULL}, {88,NULL},0,255, // lt gray
  577. def_colour,ss_auto,NULL,NULL}, // color used for lines with no height changes
  578. {"mapcolor_sprt", {&mapcolor_sprt,NULL}, {112,NULL},0,255, // green
  579. def_colour,ss_auto,NULL,NULL}, // color used as things
  580. {"mapcolor_item", {&mapcolor_item,NULL}, {231,NULL},0,255, // yellow
  581. def_colour,ss_auto,NULL,NULL}, // color used for counted items
  582. {"mapcolor_hair", {&mapcolor_hair,NULL}, {208,NULL},0,255, // white
  583. def_colour,ss_auto,NULL,NULL}, // color used for dot crosshair denoting center of map
  584. {"mapcolor_sngl", {&mapcolor_sngl,NULL}, {208,NULL},0,255, // white
  585. def_colour,ss_auto,NULL,NULL}, // color used for the single player arrow
  586. {"mapcolor_me", {&mapcolor_me,NULL}, {112,NULL},0,255, // green
  587. def_colour,ss_auto,NULL,NULL}, // your (player) colour
  588. {"mapcolor_enemy", {&mapcolor_enemy,NULL}, {177,NULL},0,255,
  589. def_colour,ss_auto,NULL,NULL},
  590. {"mapcolor_frnd", {&mapcolor_frnd,NULL}, {112,NULL},0,255,
  591. def_colour,ss_auto,NULL,NULL},
  592. //jff 3/9/98 add option to not show secrets til after found
  593. {"map_secret_after", {&map_secret_after,NULL}, {0,NULL},0,1, // show secret after gotten
  594. def_bool,ss_auto,NULL,NULL}, // prevents showing secret sectors till after entered
  595. {"map_point_coord", {&map_point_coordinates,NULL}, {0,NULL},0,1,
  596. def_bool,ss_auto,NULL,NULL},
  597. //jff 1/7/98 end additions for automap
  598. {"automapmode", {(int*)&automapmode,NULL}, {0,NULL}, 0, 31, // CPhipps - remember automap mode
  599. def_hex,ss_none,NULL,NULL}, // automap mode
  600. {"Heads-up display settings",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  601. //jff 2/16/98 defaults for color ranges in hud and status
  602. {"hudcolor_titl", {&hudcolor_titl,NULL}, {5,NULL},0,9, // gold range
  603. def_int,ss_auto,NULL,NULL}, // color range used for automap level title
  604. {"hudcolor_xyco", {&hudcolor_xyco,NULL}, {3,NULL},0,9, // green range
  605. def_int,ss_auto,NULL,NULL}, // color range used for automap coordinates
  606. {"hudcolor_mesg", {&hudcolor_mesg,NULL}, {6,NULL},0,9, // red range
  607. def_int,ss_mess,NULL,NULL}, // color range used for messages during play
  608. {"hudcolor_chat", {&hudcolor_chat,NULL}, {5,NULL},0,9, // gold range
  609. def_int,ss_mess,NULL,NULL}, // color range used for chat messages and entry
  610. {"hudcolor_list", {&hudcolor_list,NULL}, {5,NULL},0,9, // gold range //jff 2/26/98
  611. def_int,ss_mess,NULL,NULL}, // color range used for message review
  612. {"hud_msg_lines", {&hud_msg_lines,NULL}, {1,NULL},1,16, // 1 line scrolling window
  613. def_int,ss_mess,NULL,NULL}, // number of messages in review display (1=disable)
  614. {"hud_list_bgon", {&hud_list_bgon,NULL}, {0,NULL},0,1, // solid window bg ena //jff 2/26/98
  615. def_bool,ss_mess,NULL,NULL}, // enables background window behind message review
  616. {"hud_distributed",{&hud_distributed,NULL},{0,NULL},0,1, // hud broken up into 3 displays //jff 3/4/98
  617. def_bool,ss_none,NULL,NULL}, // splits HUD into three 2 line displays
  618. {"health_red", {&health_red,NULL} , {25,NULL},0,200, // below is red
  619. def_int,ss_stat,NULL,NULL}, // amount of health for red to yellow transition
  620. {"health_yellow", {&health_yellow,NULL}, {50,NULL},0,200, // below is yellow
  621. def_int,ss_stat,NULL,NULL}, // amount of health for yellow to green transition
  622. {"health_green", {&health_green,NULL} , {100,NULL},0,200,// below is green, above blue
  623. def_int,ss_stat,NULL,NULL}, // amount of health for green to blue transition
  624. {"armor_red", {&armor_red,NULL} , {25,NULL},0,200, // below is red
  625. def_int,ss_stat,NULL,NULL}, // amount of armor for red to yellow transition
  626. {"armor_yellow", {&armor_yellow,NULL} , {50,NULL},0,200, // below is yellow
  627. def_int,ss_stat,NULL,NULL}, // amount of armor for yellow to green transition
  628. {"armor_green", {&armor_green,NULL} , {100,NULL},0,200,// below is green, above blue
  629. def_int,ss_stat,NULL,NULL}, // amount of armor for green to blue transition
  630. {"ammo_red", {&ammo_red,NULL} , {25,NULL},0,100, // below 25% is red
  631. def_int,ss_stat,NULL,NULL}, // percent of ammo for red to yellow transition
  632. {"ammo_yellow", {&ammo_yellow,NULL} , {50,NULL},0,100, // below 50% is yellow, above green
  633. def_int,ss_stat,NULL,NULL}, // percent of ammo for yellow to green transition
  634. //jff 2/16/98 HUD and status feature controls
  635. {"hud_active", {&hud_active,NULL}, {2,NULL},0,2, // 0=off, 1=small, 2=full
  636. def_int,ss_none,NULL,NULL}, // 0 for HUD off, 1 for HUD small, 2 for full HUD
  637. //jff 2/23/98
  638. {"hud_displayed", {&hud_displayed,NULL}, {0,NULL},0,1, // whether hud is displayed
  639. def_bool,ss_none,NULL,NULL}, // enables display of HUD
  640. {"hud_nosecrets", {&hud_nosecrets,NULL}, {0,NULL},0,1, // no secrets/items/kills HUD line
  641. def_bool,ss_stat,NULL,NULL}, // disables display of kills/items/secrets on HUD
  642. {"Weapon preferences",{NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  643. // killough 2/8/98: weapon preferences set by user:
  644. {"weapon_choice_1", {&weapon_preferences[0][0],NULL}, {6,NULL}, 0,9,
  645. def_int,ss_weap,NULL,NULL}, // first choice for weapon (best)
  646. {"weapon_choice_2", {&weapon_preferences[0][1],NULL}, {9,NULL}, 0,9,
  647. def_int,ss_weap,NULL,NULL}, // second choice for weapon
  648. {"weapon_choice_3", {&weapon_preferences[0][2],NULL}, {4,NULL}, 0,9,
  649. def_int,ss_weap,NULL,NULL}, // third choice for weapon
  650. {"weapon_choice_4", {&weapon_preferences[0][3],NULL}, {3,NULL}, 0,9,
  651. def_int,ss_weap,NULL,NULL}, // fourth choice for weapon
  652. {"weapon_choice_5", {&weapon_preferences[0][4],NULL}, {2,NULL}, 0,9,
  653. def_int,ss_weap,NULL,NULL}, // fifth choice for weapon
  654. {"weapon_choice_6", {&weapon_preferences[0][5],NULL}, {8,NULL}, 0,9,
  655. def_int,ss_weap,NULL,NULL}, // sixth choice for weapon
  656. {"weapon_choice_7", {&weapon_preferences[0][6],NULL}, {5,NULL}, 0,9,
  657. def_int,ss_weap,NULL,NULL}, // seventh choice for weapon
  658. {"weapon_choice_8", {&weapon_preferences[0][7],NULL}, {7,NULL}, 0,9,
  659. def_int,ss_weap,NULL,NULL}, // eighth choice for weapon
  660. {"weapon_choice_9", {&weapon_preferences[0][8],NULL}, {1,NULL}, 0,9,
  661. def_int,ss_weap,NULL,NULL}, // ninth choice for weapon (worst)
  662. // cournia - support for arbitrary music file (defaults are mp3)
  663. {"Music", {NULL,NULL},{0,NULL},UL,UL,def_none,ss_none,NULL,NULL},
  664. {"mus_e1m1", {0,&S_music_files[mus_e1m1]}, {0,"e1m1.mp3"},UL,UL,
  665. def_str,ss_none,NULL,NULL},
  666. {"mus_e1m2", {0,&S_music_files[mus_e1m2]}, {0,"e1m2.mp3"},UL,UL,
  667. def_str,ss_none,NULL,NULL},
  668. {"mus_e1m3", {0,&S_music_files[mus_e1m3]}, {0,"e1m3.mp3"},UL,UL,
  669. def_str,ss_none,NULL,NULL},
  670. {"mus_e1m4", {0,&S_music_files[mus_e1m4]}, {0,"e1m4.mp3"},UL,UL,
  671. def_str,ss_none,NULL,NULL},
  672. {"mus_e1m5", {0,&S_music_files[mus_e1m5]}, {0,"e1m5.mp3"},UL,UL,
  673. def_str,ss_none,NULL,NULL},
  674. {"mus_e1m6", {0,&S_music_files[mus_e1m6]}, {0,"e1m6.mp3"},UL,UL,
  675. def_str,ss_none,NULL,NULL},
  676. {"mus_e1m7", {0,&S_music_files[mus_e1m7]}, {0,"e1m7.mp3"},UL,UL,
  677. def_str,ss_none,NULL,NULL},
  678. {"mus_e1m8", {0,&S_music_files[mus_e1m8]}, {0,"e1m8.mp3"},UL,UL,
  679. def_str,ss_none,NULL,NULL},
  680. {"mus_e1m9", {0,&S_music_files[mus_e1m9]}, {0,"e1m9.mp3"},UL,UL,
  681. def_str,ss_none,NULL,NULL},
  682. {"mus_e2m1", {0,&S_music_files[mus_e2m1]}, {0,"e2m1.mp3"},UL,UL,
  683. def_str,ss_none,NULL,NULL},
  684. {"mus_e2m2", {0,&S_music_files[mus_e2m2]}, {0,"e2m2.mp3"},UL,UL,
  685. def_str,ss_none,NULL,NULL},
  686. {"mus_e2m3", {0,&S_music_files[mus_e2m3]}, {0,"e2m3.mp3"},UL,UL,
  687. def_str,ss_none,NULL,NULL},
  688. {"mus_e2m4", {0,&S_music_files[mus_e2m4]}, {0,"e2m4.mp3"},UL,UL,
  689. def_str,ss_none,NULL,NULL},
  690. {"mus_e2m5", {0,&S_music_files[mus_e2m5]}, {0,"e1m7.mp3"},UL,UL,
  691. def_str,ss_none,NULL,NULL},
  692. {"mus_e2m6", {0,&S_music_files[mus_e2m6]}, {0,"e2m6.mp3"},UL,UL,
  693. def_str,ss_none,NULL,NULL},
  694. {"mus_e2m7", {0,&S_music_files[mus_e2m7]}, {0,"e2m7.mp3"},UL,UL,
  695. def_str,ss_none,NULL,NULL},
  696. {"mus_e2m8", {0,&S_music_files[mus_e2m8]}, {0,"e2m8.mp3"},UL,UL,
  697. def_str,ss_none,NULL,NULL},
  698. {"mus_e2m9", {0,&S_music_files[mus_e2m9]}, {0,"e3m1.mp3"},UL,UL,
  699. def_str,ss_none,NULL,NULL},
  700. {"mus_e3m1", {0,&S_music_files[mus_e3m1]}, {0,"e3m1.mp3"},UL,UL,
  701. def_str,ss_none,NULL,NULL},
  702. {"mus_e3m2", {0,&S_music_files[mus_e3m2]}, {0,"e3m2.mp3"},UL,UL,
  703. def_str,ss_none,NULL,NULL},
  704. {"mus_e3m3", {0,&S_music_files[mus_e3m3]}, {0,"e3m3.mp3"},UL,UL,
  705. def_str,ss_none,NULL,NULL},
  706. {"mus_e3m4", {0,&S_music_files[mus_e3m4]}, {0,"e1m8.mp3"},UL,UL,
  707. def_str,ss_none,NULL,NULL},
  708. {"mus_e3m5", {0,&S_music_files[mus_e3m5]}, {0,"e1m7.mp3"},UL,UL,
  709. def_str,ss_none,NULL,NULL},
  710. {"mus_e3m6", {0,&S_music_files[mus_e3m6]}, {0,"e1m6.mp3"},UL,UL,
  711. def_str,ss_none,NULL,NULL},
  712. {"mus_e3m7", {0,&S_music_files[mus_e3m7]}, {0,"e2m7.mp3"},UL,UL,
  713. def_str,ss_none,NULL,NULL},
  714. {"mus_e3m8", {0,&S_music_files[mus_e3m8]}, {0,"e3m8.mp3"},UL,UL,
  715. def_str,ss_none,NULL,NULL},
  716. {"mus_e3m9", {0,&S_music_files[mus_e3m9]}, {0,"e1m9.mp3"},UL,UL,
  717. def_str,ss_none,NULL,NULL},
  718. {"mus_inter", {0,&S_music_files[mus_inter]}, {0,"e2m3.mp3"},UL,UL,
  719. def_str,ss_none,NULL,NULL},
  720. {"mus_intro", {0,&S_music_files[mus_intro]}, {0,"intro.mp3"},UL,UL,
  721. def_str,ss_none,NULL,NULL},
  722. {"mus_bunny", {0,&S_music_files[mus_bunny]}, {0,"bunny.mp3"},UL,UL,
  723. def_str,ss_none,NULL,NULL},
  724. {"mus_victor", {0,&S_music_files[mus_victor]}, {0,"victor.mp3"},UL,UL,
  725. def_str,ss_none,NULL,NULL},
  726. {"mus_introa", {0,&S_music_files[mus_introa]}, {0,"intro.mp3"},UL,UL,
  727. def_str,ss_none,NULL,NULL},
  728. {"mus_runnin", {0,&S_music_files[mus_runnin]}, {0,"runnin.mp3"},UL,UL,
  729. def_str,ss_none,NULL,NULL},
  730. {"mus_stalks", {0,&S_music_files[mus_stalks]}, {0,"stalks.mp3"},UL,UL,
  731. def_str,ss_none,NULL,NULL},
  732. {"mus_countd", {0,&S_music_files[mus_countd]}, {0,"countd.mp3"},UL,UL,
  733. def_str,ss_none,NULL,NULL},
  734. {"mus_betwee", {0,&S_music_files[mus_betwee]}, {0,"betwee.mp3"},UL,UL,
  735. def_str,ss_none,NULL,NULL},
  736. {"mus_doom", {0,&S_music_files[mus_doom]}, {0,"doom.mp3"},UL,UL,
  737. def_str,ss_none,NULL,NULL},
  738. {"mus_the_da", {0,&S_music_files[mus_the_da]}, {0,"the_da.mp3"},UL,UL,
  739. def_str,ss_none,NULL,NULL},
  740. {"mus_shawn", {0,&S_music_files[mus_shawn]}, {0,"shawn.mp3"},UL,UL,
  741. def_str,ss_none,NULL,NULL},
  742. {"mus_ddtblu", {0,&S_music_files[mus_ddtblu]}, {0,"ddtblu.mp3"},UL,UL,
  743. def_str,ss_none,NULL,NULL},
  744. {"mus_in_cit", {0,&S_music_files[mus_in_cit]}, {0,"in_cit.mp3"},UL,UL,
  745. def_str,ss_none,NULL,NULL},
  746. {"mus_dead", {0,&S_music_files[mus_dead]}, {0,"dead.mp3"},UL,UL,
  747. def_str,ss_none,NULL,NULL},
  748. {"mus_stlks2", {0,&S_music_files[mus_stlks2]}, {0,"stalks.mp3"},UL,UL,
  749. def_str,ss_none,NULL,NULL},
  750. {"mus_theda2", {0,&S_music_files[mus_theda2]}, {0,"the_da.mp3"},UL,UL,
  751. def_str,ss_none,NULL,NULL},
  752. {"mus_doom2", {0,&S_music_files[mus_doom2]}, {0,"doom.mp3"},UL,UL,
  753. def_str,ss_none,NULL,NULL},
  754. {"mus_ddtbl2", {0,&S_music_files[mus_ddtbl2]}, {0,"ddtblu.mp3"},UL,UL,
  755. def_str,ss_none,NULL,NULL},
  756. {"mus_runni2", {0,&S_music_files[mus_runni2]}, {0,"runnin.mp3"},UL,UL,
  757. def_str,ss_none,NULL,NULL},
  758. {"mus_dead2", {0,&S_music_files[mus_dead2]}, {0,"dead.mp3"},UL,UL,
  759. def_str,ss_none,NULL,NULL},
  760. {"mus_stlks3", {0,&S_music_files[mus_stlks3]}, {0,"stalks.mp3"},UL,UL,
  761. def_str,ss_none,NULL,NULL},
  762. {"mus_romero", {0,&S_music_files[mus_romero]}, {0,"romero.mp3"},UL,UL,
  763. def_str,ss_none,NULL,NULL},
  764. {"mus_shawn2", {0,&S_music_files[mus_shawn2]}, {0,"shawn.mp3"},UL,UL,
  765. def_str,ss_none,NULL,NULL},
  766. {"mus_messag", {0,&S_music_files[mus_messag]}, {0,"messag.mp3"},UL,UL,
  767. def_str,ss_none,NULL,NULL},
  768. {"mus_count2", {0,&S_music_files[mus_count2]}, {0,"countd.mp3"},UL,UL,
  769. def_str,ss_none,NULL,NULL},
  770. {"mus_ddtbl3", {0,&S_music_files[mus_ddtbl3]}, {0,"ddtblu.mp3"},UL,UL,
  771. def_str,ss_none,NULL,NULL},
  772. {"mus_ampie", {0,&S_music_files[mus_ampie]}, {0,"ampie.mp3"},UL,UL,
  773. def_str,ss_none,NULL,NULL},
  774. {"mus_theda3", {0,&S_music_files[mus_theda3]}, {0,"the_da.mp3"},UL,UL,
  775. def_str,ss_none,NULL,NULL},
  776. {"mus_adrian", {0,&S_music_files[mus_adrian]}, {0,"adrian.mp3"},UL,UL,
  777. def_str,ss_none,NULL,NULL},
  778. {"mus_messg2", {0,&S_music_files[mus_messg2]}, {0,"messag.mp3"},UL,UL,
  779. def_str,ss_none,NULL,NULL},
  780. {"mus_romer2", {0,&S_music_files[mus_romer2]}, {0,"romero.mp3"},UL,UL,
  781. def_str,ss_none,NULL,NULL},
  782. {"mus_tense", {0,&S_music_files[mus_tense]}, {0,"tense.mp3"},UL,UL,
  783. def_str,ss_none,NULL,NULL},
  784. {"mus_shawn3", {0,&S_music_files[mus_shawn3]}, {0,"shawn.mp3"},UL,UL,
  785. def_str,ss_none,NULL,NULL},
  786. {"mus_openin", {0,&S_music_files[mus_openin]}, {0,"openin.mp3"},UL,UL,
  787. def_str,ss_none,NULL,NULL},
  788. {"mus_evil", {0,&S_music_files[mus_evil]}, {0,"evil.mp3"},UL,UL,
  789. def_str,ss_none,NULL,NULL},
  790. {"mus_ultima", {0,&S_music_files[mus_ultima]}, {0,"ultima.mp3"},UL,UL,
  791. def_str,ss_none,NULL,NULL},
  792. {"mus_read_m", {0,&S_music_files[mus_read_m]}, {0,"read_m.mp3"},UL,UL,
  793. def_str,ss_none,NULL,NULL},
  794. {"mus_dm2ttl", {0,&S_music_files[mus_dm2ttl]}, {0,"dm2ttl.mp3"},UL,UL,
  795. def_str,ss_none,NULL,NULL},
  796. {"mus_dm2int", {0,&S_music_files[mus_dm2int]}, {0,"dm2int.mp3"},UL,UL,
  797. def_str,ss_none,NULL,NULL},
  798. };
  799. int numdefaults;
  800. static const char* defaultfile; // CPhipps - static, const
  801. //
  802. // M_SaveDefaults
  803. //
  804. void M_SaveDefaults (void)
  805. {
  806. int i;
  807. FILE* f;
  808. f = fopen (defaultfile, "w");
  809. if (!f)
  810. return; // can't write the file, but don't complain
  811. // 3/3/98 explain format of file
  812. fprintf(f,"# Doom config file\n");
  813. fprintf(f,"# Format:\n");
  814. fprintf(f,"# variable value\n");
  815. for (i = 0 ; i < numdefaults ; i++) {
  816. if (defaults[i].type == def_none) {
  817. // CPhipps - pure headers
  818. fprintf(f, "\n# %s\n", defaults[i].name);
  819. } else
  820. // CPhipps - modified for new default_t form
  821. if (!IS_STRING(defaults[i])) //jff 4/10/98 kill super-hack on pointer value
  822. {
  823. // CPhipps - remove keycode hack
  824. // killough 3/6/98: use spaces instead of tabs for uniform justification
  825. if (defaults[i].type == def_hex)
  826. fprintf (f,"%-25s 0x%x\n",defaults[i].name,*(defaults[i].location.pi));
  827. else
  828. fprintf (f,"%-25s %5i\n",defaults[i].name,*(defaults[i].location.pi));
  829. }
  830. else
  831. {
  832. fprintf (f,"%-25s \"%s\"\n",defaults[i].name,*(defaults[i].location.ppsz));
  833. }
  834. }
  835. fclose (f);
  836. }
  837. /*
  838. * M_LookupDefault
  839. *
  840. * cph - mimic MBF function for now. Yes it's crap.
  841. */
  842. struct default_s *M_LookupDefault(const char *name)
  843. {
  844. int i;
  845. for (i = 0 ; i < numdefaults - 1 ; i++)
  846. if ((defaults[i].type != def_none) && !strcmp(name, defaults[i].name))
  847. return &defaults[i];
  848. I_Error("M_LookupDefault: %s not found",name);
  849. return NULL;
  850. }
  851. //
  852. // M_LoadDefaults
  853. //
  854. #define NUMCHATSTRINGS 10 // phares 4/13/98
  855. void M_LoadDefaults (void)
  856. {
  857. int i;
  858. int len;
  859. FILE* f;
  860. char def[80];
  861. char strparm[100];
  862. char* newstring = NULL; // killough
  863. int parm;
  864. boolean isstring;
  865. // set everything to base values
  866. numdefaults = sizeof(defaults)/sizeof(defaults[0]);
  867. for (i = 0 ; i < numdefaults ; i++) {
  868. if (defaults[i].location.ppsz)
  869. *defaults[i].location.ppsz = strdup(defaults[i].defaultvalue.psz);
  870. if (defaults[i].location.pi)
  871. *defaults[i].location.pi = defaults[i].defaultvalue.i;
  872. }
  873. // check for a custom default file
  874. i = M_CheckParm ("-config");
  875. if (i && i < myargc-1)
  876. defaultfile = myargv[i+1];
  877. else {
  878. const char* exedir = I_DoomExeDir();
  879. defaultfile = malloc(PATH_MAX+1);
  880. /* get config file from same directory as executable */
  881. #if ((defined GL_DOOM) && (defined _MSC_VER))
  882. #define PRBOOM_GL_OR_PR "gl"
  883. #else
  884. #define PRBOOM_GL_OR_PR "pr"
  885. #endif
  886. #ifdef HAVE_SNPRINTF
  887. snprintf((char *)defaultfile, PATH_MAX,
  888. "%s%s%sboom.cfg", exedir, HasTrailingSlash(exedir) ? "" : "/", PRBOOM_GL_OR_PR );
  889. #else
  890. sprintf ((char *)defaultfile,
  891. "%s%s%sboom.cfg", exedir, HasTrailingSlash(exedir) ? "" : "/", PRBOOM_GL_OR_PR );
  892. #endif
  893. }
  894. lprintf (LO_CONFIRM, " default file: %s\n",defaultfile);
  895. // read the file in, overriding any set defaults
  896. f = fopen (defaultfile, "r");
  897. if (f)
  898. {
  899. while (!feof(f))
  900. {
  901. isstring = false;
  902. if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
  903. {
  904. //jff 3/3/98 skip lines not starting with an alphanum
  905. if (!isalnum(def[0]))
  906. continue;
  907. if (strparm[0] == '"') {
  908. // get a string default
  909. isstring = true;
  910. len = strlen(strparm);
  911. newstring = (char *) malloc(len);
  912. strparm[len-1] = 0; // clears trailing double-quote mark
  913. strcpy(newstring, strparm+1); // clears leading double-quote mark
  914. } else if ((strparm[0] == '0') && (strparm[1] == 'x')) {
  915. // CPhipps - allow ints to be specified in hex
  916. sscanf(strparm+2, "%x", &parm);
  917. } else {
  918. sscanf(strparm, "%i", &parm);
  919. // Keycode hack removed
  920. }
  921. for (i = 0 ; i < numdefaults ; i++)
  922. if ((defaults[i].type != def_none) && !strcmp(def, defaults[i].name))
  923. {
  924. // CPhipps - safety check
  925. if (isstring != IS_STRING(defaults[i])) {
  926. lprintf(LO_WARN, "M_LoadDefaults: Type mismatch reading %s\n", defaults[i].name);
  927. continue;
  928. }
  929. if (!isstring)
  930. {
  931. //jff 3/4/98 range check numeric parameters
  932. if ((defaults[i].minvalue==UL || defaults[i].minvalue<=parm) &&
  933. (defaults[i].maxvalue==UL || defaults[i].maxvalue>=parm))
  934. *(defaults[i].location.pi) = parm;
  935. }
  936. else
  937. {
  938. free((char*)*(defaults[i].location.ppsz)); /* phares 4/13/98 */
  939. *(defaults[i].location.ppsz) = newstring;
  940. }
  941. break;
  942. }
  943. }
  944. }
  945. fclose (f);
  946. }
  947. //jff 3/4/98 redundant range checks for hud deleted here
  948. }
  949. //
  950. // SCREEN SHOTS
  951. //
  952. //
  953. // M_ScreenShot
  954. //
  955. // Modified by Lee Killough so that any number of shots can be taken,
  956. // the code is faster, and no annoying "screenshot" message appears.
  957. // CPhipps - modified to use its own buffer for the image
  958. // - checks for the case where no file can be created (doesn't occur on POSIX systems, would on DOS)
  959. // - track errors better
  960. // - split into 2 functions
  961. //
  962. // M_DoScreenShot
  963. // Takes a screenshot into the names file
  964. void M_DoScreenShot (const char* fname)
  965. {
  966. if (I_ScreenShot(fname) != 0)
  967. doom_printf("M_ScreenShot: Error writing screenshot\n");
  968. }
  969. #ifndef SCREENSHOT_DIR
  970. #define SCREENSHOT_DIR "."
  971. #endif
  972. #ifdef HAVE_LIBPNG
  973. #define SCREENSHOT_EXT ".png"
  974. #else
  975. #define SCREENSHOT_EXT ".bmp"
  976. #endif
  977. void M_ScreenShot(void)
  978. {
  979. static int shot;
  980. char lbmname[PATH_MAX + 1];
  981. int startshot;
  982. if (!access(SCREENSHOT_DIR,2))
  983. {
  984. startshot = shot; // CPhipps - prevent infinite loop
  985. do {
  986. sprintf(lbmname,"%s/doom%02d" SCREENSHOT_EXT, SCREENSHOT_DIR, shot++);
  987. } while (!access(lbmname,0) && (shot != startshot) && (shot < 10000));
  988. if (access(lbmname,0))
  989. {
  990. S_StartSound(NULL,gamemode==commercial ? sfx_radio : sfx_tink);
  991. M_DoScreenShot(lbmname); // cph
  992. return;
  993. }
  994. }
  995. doom_printf ("M_ScreenShot: Couldn't create screenshot");
  996. return;
  997. }