m_misc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. // Emacs style mode select -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. //
  18. // $Log:$
  19. //
  20. // DESCRIPTION:
  21. // Main loop menu stuff.
  22. // Default Config File.
  23. // PCX Screenshots.
  24. //
  25. //-----------------------------------------------------------------------------
  26. static const char
  27. rcsid[] = "$Id: m_misc.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
  28. #include <sys/stat.h>
  29. #include <sys/types.h>
  30. #include <fcntl.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #include <ctype.h>
  34. #include "doomdef.h"
  35. #include "z_zone.h"
  36. #include "m_swap.h"
  37. #include "m_argv.h"
  38. #include "w_wad.h"
  39. #include "i_system.h"
  40. #include "i_video.h"
  41. #include "v_video.h"
  42. #include "hu_stuff.h"
  43. // State.
  44. #include "doomstat.h"
  45. // Data.
  46. #include "dstrings.h"
  47. #include "m_misc.h"
  48. //
  49. // M_DrawText
  50. // Returns the final X coordinate
  51. // HU_Init must have been called to init the font
  52. //
  53. extern patch_t* hu_font[HU_FONTSIZE];
  54. int
  55. M_DrawText
  56. ( int x,
  57. int y,
  58. boolean direct,
  59. char* string )
  60. {
  61. int c;
  62. int w;
  63. while (*string)
  64. {
  65. c = toupper(*string) - HU_FONTSTART;
  66. string++;
  67. if (c < 0 || c> HU_FONTSIZE)
  68. {
  69. x += 4;
  70. continue;
  71. }
  72. w = SHORT (hu_font[c]->width);
  73. if (x+w > SCREENWIDTH)
  74. break;
  75. if (direct)
  76. V_DrawPatchDirect(x, y, 0, hu_font[c]);
  77. else
  78. V_DrawPatch(x, y, 0, hu_font[c]);
  79. x+=w;
  80. }
  81. return x;
  82. }
  83. //
  84. // M_WriteFile
  85. //
  86. #ifndef O_BINARY
  87. #define O_BINARY 0
  88. #endif
  89. boolean
  90. M_WriteFile
  91. ( char const* name,
  92. void* source,
  93. int length )
  94. {
  95. int handle;
  96. int count;
  97. handle = open ( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
  98. if (handle == -1)
  99. return false;
  100. count = write (handle, source, length);
  101. close (handle);
  102. if (count < length)
  103. return false;
  104. return true;
  105. }
  106. //
  107. // M_ReadFile
  108. //
  109. int
  110. M_ReadFile
  111. ( char const* name,
  112. byte** buffer )
  113. {
  114. int handle, count, length;
  115. struct stat fileinfo;
  116. byte *buf;
  117. handle = open (name, O_RDONLY | O_BINARY, 0666);
  118. if (handle == -1)
  119. I_Error ("Couldn't read file %s", name);
  120. if (fstat (handle,&fileinfo) == -1)
  121. I_Error ("Couldn't read file %s", name);
  122. length = fileinfo.st_size;
  123. buf = Z_Malloc (length, PU_STATIC, NULL);
  124. count = read (handle, buf, length);
  125. close (handle);
  126. if (count < length)
  127. I_Error ("Couldn't read file %s", name);
  128. *buffer = buf;
  129. return length;
  130. }
  131. //
  132. // DEFAULTS
  133. //
  134. int usemouse;
  135. int usejoystick;
  136. extern int key_right;
  137. extern int key_left;
  138. extern int key_up;
  139. extern int key_down;
  140. extern int key_strafeleft;
  141. extern int key_straferight;
  142. extern int key_fire;
  143. extern int key_use;
  144. extern int key_strafe;
  145. extern int key_speed;
  146. extern int mousebfire;
  147. extern int mousebstrafe;
  148. extern int mousebforward;
  149. extern int joybfire;
  150. extern int joybstrafe;
  151. extern int joybuse;
  152. extern int joybspeed;
  153. extern int viewwidth;
  154. extern int viewheight;
  155. extern int mouseSensitivity;
  156. extern int showMessages;
  157. extern int detailLevel;
  158. extern int screenblocks;
  159. extern int showMessages;
  160. // machine-independent sound params
  161. extern int numChannels;
  162. // UNIX hack, to be removed.
  163. #ifdef SNDSERV
  164. extern char* sndserver_filename;
  165. extern int mb_used;
  166. #endif
  167. #ifdef LINUX
  168. char* mousetype;
  169. char* mousedev;
  170. #endif
  171. extern char* chat_macros[];
  172. typedef struct
  173. {
  174. char* name;
  175. int* location;
  176. int defaultvalue;
  177. int scantranslate; // PC scan code hack
  178. int untranslated; // lousy hack
  179. } default_t;
  180. default_t defaults[] =
  181. {
  182. {"mouse_sensitivity",&mouseSensitivity, 5},
  183. {"sfx_volume",&snd_SfxVolume, 8},
  184. {"music_volume",&snd_MusicVolume, 8},
  185. {"show_messages",&showMessages, 1},
  186. #ifdef NORMALUNIX
  187. {"key_right",&key_right, KEY_RIGHTARROW},
  188. {"key_left",&key_left, KEY_LEFTARROW},
  189. {"key_up",&key_up, KEY_UPARROW},
  190. {"key_down",&key_down, KEY_DOWNARROW},
  191. {"key_strafeleft",&key_strafeleft, ','},
  192. {"key_straferight",&key_straferight, '.'},
  193. {"key_fire",&key_fire, KEY_RCTRL},
  194. {"key_use",&key_use, ' '},
  195. {"key_strafe",&key_strafe, KEY_RALT},
  196. {"key_speed",&key_speed, KEY_RSHIFT},
  197. // UNIX hack, to be removed.
  198. #ifdef SNDSERV
  199. {"sndserver", (int *) &sndserver_filename, (int) "sndserver"},
  200. {"mb_used", &mb_used, 2},
  201. #endif
  202. #endif
  203. #ifdef LINUX
  204. {"mousedev", (int*)&mousedev, (int)"/dev/ttyS0"},
  205. {"mousetype", (int*)&mousetype, (int)"microsoft"},
  206. #endif
  207. {"use_mouse",&usemouse, 1},
  208. {"mouseb_fire",&mousebfire,0},
  209. {"mouseb_strafe",&mousebstrafe,1},
  210. {"mouseb_forward",&mousebforward,2},
  211. {"use_joystick",&usejoystick, 0},
  212. {"joyb_fire",&joybfire,0},
  213. {"joyb_strafe",&joybstrafe,1},
  214. {"joyb_use",&joybuse,3},
  215. {"joyb_speed",&joybspeed,2},
  216. {"screenblocks",&screenblocks, 9},
  217. {"detaillevel",&detailLevel, 0},
  218. {"snd_channels",&numChannels, 3},
  219. {"usegamma",&usegamma, 0},
  220. {"chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 },
  221. {"chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 },
  222. {"chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 },
  223. {"chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 },
  224. {"chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 },
  225. {"chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 },
  226. {"chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 },
  227. {"chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 },
  228. {"chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 },
  229. {"chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 }
  230. };
  231. int numdefaults;
  232. char* defaultfile;
  233. //
  234. // M_SaveDefaults
  235. //
  236. void M_SaveDefaults (void)
  237. {
  238. int i;
  239. int v;
  240. FILE* f;
  241. f = fopen (defaultfile, "w");
  242. if (!f)
  243. return; // can't write the file, but don't complain
  244. for (i=0 ; i<numdefaults ; i++)
  245. {
  246. if (defaults[i].defaultvalue > -0xfff
  247. && defaults[i].defaultvalue < 0xfff)
  248. {
  249. v = *defaults[i].location;
  250. fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
  251. } else {
  252. fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
  253. * (char **) (defaults[i].location));
  254. }
  255. }
  256. fclose (f);
  257. }
  258. //
  259. // M_LoadDefaults
  260. //
  261. extern byte scantokey[128];
  262. void M_LoadDefaults (void)
  263. {
  264. int i;
  265. int len;
  266. FILE* f;
  267. char def[80];
  268. char strparm[100];
  269. char* newstring;
  270. int parm;
  271. boolean isstring;
  272. // set everything to base values
  273. numdefaults = sizeof(defaults)/sizeof(defaults[0]);
  274. for (i=0 ; i<numdefaults ; i++)
  275. *defaults[i].location = defaults[i].defaultvalue;
  276. // check for a custom default file
  277. i = M_CheckParm ("-config");
  278. if (i && i<myargc-1)
  279. {
  280. defaultfile = myargv[i+1];
  281. printf (" default file: %s\n",defaultfile);
  282. }
  283. else
  284. defaultfile = basedefault;
  285. // read the file in, overriding any set defaults
  286. f = fopen (defaultfile, "r");
  287. if (f)
  288. {
  289. while (!feof(f))
  290. {
  291. isstring = false;
  292. if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
  293. {
  294. if (strparm[0] == '"')
  295. {
  296. // get a string default
  297. isstring = true;
  298. len = strlen(strparm);
  299. newstring = (char *) malloc(len);
  300. strparm[len-1] = 0;
  301. strcpy(newstring, strparm+1);
  302. }
  303. else if (strparm[0] == '0' && strparm[1] == 'x')
  304. sscanf(strparm+2, "%x", &parm);
  305. else
  306. sscanf(strparm, "%i", &parm);
  307. for (i=0 ; i<numdefaults ; i++)
  308. if (!strcmp(def, defaults[i].name))
  309. {
  310. if (!isstring)
  311. *defaults[i].location = parm;
  312. else
  313. *defaults[i].location =
  314. (int) newstring;
  315. break;
  316. }
  317. }
  318. }
  319. fclose (f);
  320. }
  321. }
  322. //
  323. // SCREEN SHOTS
  324. //
  325. typedef struct
  326. {
  327. char manufacturer;
  328. char version;
  329. char encoding;
  330. char bits_per_pixel;
  331. unsigned short xmin;
  332. unsigned short ymin;
  333. unsigned short xmax;
  334. unsigned short ymax;
  335. unsigned short hres;
  336. unsigned short vres;
  337. unsigned char palette[48];
  338. char reserved;
  339. char color_planes;
  340. unsigned short bytes_per_line;
  341. unsigned short palette_type;
  342. char filler[58];
  343. unsigned char data; // unbounded
  344. } pcx_t;
  345. //
  346. // WritePCXfile
  347. //
  348. void
  349. WritePCXfile
  350. ( char* filename,
  351. byte* data,
  352. int width,
  353. int height,
  354. byte* palette )
  355. {
  356. int i;
  357. int length;
  358. pcx_t* pcx;
  359. byte* pack;
  360. pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
  361. pcx->manufacturer = 0x0a; // PCX id
  362. pcx->version = 5; // 256 color
  363. pcx->encoding = 1; // uncompressed
  364. pcx->bits_per_pixel = 8; // 256 color
  365. pcx->xmin = 0;
  366. pcx->ymin = 0;
  367. pcx->xmax = SHORT(width-1);
  368. pcx->ymax = SHORT(height-1);
  369. pcx->hres = SHORT(width);
  370. pcx->vres = SHORT(height);
  371. memset (pcx->palette,0,sizeof(pcx->palette));
  372. pcx->color_planes = 1; // chunky image
  373. pcx->bytes_per_line = SHORT(width);
  374. pcx->palette_type = SHORT(2); // not a grey scale
  375. memset (pcx->filler,0,sizeof(pcx->filler));
  376. // pack the image
  377. pack = &pcx->data;
  378. for (i=0 ; i<width*height ; i++)
  379. {
  380. if ( (*data & 0xc0) != 0xc0)
  381. *pack++ = *data++;
  382. else
  383. {
  384. *pack++ = 0xc1;
  385. *pack++ = *data++;
  386. }
  387. }
  388. // write the palette
  389. *pack++ = 0x0c; // palette ID byte
  390. for (i=0 ; i<768 ; i++)
  391. *pack++ = *palette++;
  392. // write output file
  393. length = pack - (byte *)pcx;
  394. M_WriteFile (filename, pcx, length);
  395. Z_Free (pcx);
  396. }
  397. //
  398. // M_ScreenShot
  399. //
  400. void M_ScreenShot (void)
  401. {
  402. int i;
  403. byte* linear;
  404. char lbmname[12];
  405. // munge planar buffer to linear
  406. linear = screens[2];
  407. I_ReadScreen (linear);
  408. // find a file name to save it to
  409. strcpy(lbmname,"DOOM00.pcx");
  410. for (i=0 ; i<=99 ; i++)
  411. {
  412. lbmname[4] = i/10 + '0';
  413. lbmname[5] = i%10 + '0';
  414. if (access(lbmname,0) == -1)
  415. break; // file doesn't exist
  416. }
  417. if (i==100)
  418. I_Error ("M_ScreenShot: Couldn't create a PCX");
  419. // save the pcx file
  420. WritePCXfile (lbmname, linear,
  421. SCREENWIDTH, SCREENHEIGHT,
  422. W_CacheLumpName ("PLAYPAL",PU_CACHE));
  423. players[consoleplayer].message = "screen shot";
  424. }