m_misc.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:19k
源码类别:

射击游戏

开发平台:

Visual C++

  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 <io.h>
  33. //#include <unistd.h>
  34. #include <direct.h>
  35. #include <ctype.h>
  36. #include "doomdef.h"
  37. #include "z_zone.h"
  38. #include "m_swap.h"
  39. #include "m_argv.h"
  40. #include "w_wad.h"
  41. #include "i_system.h"
  42. #include "i_video.h"
  43. #include "v_video.h"
  44. #include "hu_stuff.h"
  45. // State.
  46. #include "doomstat.h"
  47. // Data.
  48. #include "dstrings.h"
  49. #include "m_misc.h"
  50. //
  51. // M_DrawText
  52. // Returns the final X coordinate
  53. // HU_Init must have been called to init the font
  54. //
  55. extern patch_t* hu_font[HU_FONTSIZE];
  56. int
  57. M_DrawText
  58. ( int x,
  59.   int y,
  60.   boolean direct,
  61.   char* string )
  62. {
  63.     int  c;
  64.     int w;
  65.     while (*string)
  66.     {
  67. c = toupper(*string) - HU_FONTSTART;
  68. string++;
  69. if (c < 0 || c> HU_FONTSIZE)
  70. {
  71.     x += 4;
  72.     continue;
  73. }
  74. w = SHORT (hu_font[c]->width);
  75. if (x+w > SCREENWIDTH)
  76.     break;
  77. if (direct)
  78.     V_DrawPatchDirect(x, y, 0, hu_font[c]);
  79. else
  80.     V_DrawPatch(x, y, 0, hu_font[c]);
  81. x+=w;
  82.     }
  83.     return x;
  84. }
  85. //
  86. // M_GetFileSize
  87. //
  88. #ifndef O_BINARY
  89. #define O_BINARY 0
  90. #endif
  91. int M_GetFileSize( char const* name )
  92.    {
  93.     int handle;
  94.     int count;
  95.     handle = open ( name, O_RDWR | O_BINARY);
  96.     if (handle == -1)
  97.         return 0;
  98.     count = lseek(handle, 0, SEEK_END);
  99.     close (handle);
  100.     return count;
  101.    }
  102. //
  103. // M_WriteFile
  104. //
  105. boolean
  106. M_WriteFile
  107. ( char const* name,
  108.   void* source,
  109.   int length )
  110. {
  111.     int handle;
  112.     int count;
  113.     handle = open ( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
  114.     if (handle == -1)
  115. return false;
  116.     count = write (handle, source, length);
  117.     close (handle);
  118.     if (count < length)
  119. return false;
  120.     return true;
  121. }
  122. //
  123. // M_AppendFile
  124. //
  125. boolean M_AppendFile(char const *name, void *source, int length )
  126.    {
  127.     int handle;
  128.     int count;
  129.     handle = open( name, O_RDWR | O_BINARY);
  130.     if (handle == -1)
  131.         return false;
  132.     lseek(handle, 0L, SEEK_END);
  133.     count = write (handle, source, length);
  134.     close (handle);
  135.     if (count < length)
  136.         return false;
  137.     return true;
  138.    }
  139. //
  140. // M_ReadFile
  141. //
  142. int
  143. M_ReadFile
  144. ( char const* name,
  145.   byte** buffer )
  146. {
  147.     int handle, count, length;
  148.     struct stat fileinfo;
  149.     byte *buf;
  150.     handle = open (name, O_RDONLY | O_BINARY, 0666);
  151.     if (handle == -1)
  152. I_Error ("Couldn't read file %s", name);
  153.     if (fstat (handle,&fileinfo) == -1)
  154. I_Error ("Couldn't read file %s", name);
  155.     length = fileinfo.st_size;
  156.     buf = Z_Malloc (length, PU_STATIC, NULL);
  157.     count = read (handle, buf, length);
  158.     close (handle);
  159.     if (count < length)
  160. I_Error ("Couldn't read file %s", name);
  161.     *buffer = buf;
  162.     return length;
  163. }
  164. //
  165. // DEFAULTS
  166. //
  167. int usemouse;
  168. int usejoystick;
  169. extern int key_right;
  170. extern int key_left;
  171. extern int key_up;
  172. extern int key_down;
  173. extern int key_strafeleft;
  174. extern int key_straferight;
  175. extern int key_fire;
  176. extern int key_use;
  177. extern int key_strafe;
  178. extern int key_speed;
  179. extern int  key_mvert;
  180. extern int  always_run;
  181. extern int  swap_stereo;
  182. extern int  mvert;
  183. extern int  keylink;
  184. extern int mousebfire;
  185. extern int mousebstrafe;
  186. extern int mousebforward;
  187. extern int mouseb1;
  188. extern int mouseb2;
  189. extern int mouseb3;
  190. extern int joybfire;
  191. extern int joybstrafe;
  192. extern int joybuse;
  193. extern int joybspeed;
  194. extern int  joyb1;
  195. extern int  joyb2;
  196. extern int  joyb3;
  197. extern int  joyb4;
  198. extern int viewwidth;
  199. extern int viewheight;
  200. extern int mouseSensitivity;
  201. extern int showMessages;
  202. extern int detailLevel;
  203. extern int screenblocks;
  204. extern int showMessages;
  205. // machine-independent sound params
  206. extern int numChannels;
  207. // UNIX hack, to be removed.
  208. #ifdef SNDSERV
  209. extern char* sndserver_filename;
  210. extern int mb_used;
  211. #endif
  212. #ifdef LINUX
  213. char* mousetype;
  214. char* mousedev;
  215. #endif
  216. extern char* chat_macros[];
  217. typedef struct
  218. {
  219.     char* name;
  220.     int* location;
  221.     int defaultvalue;
  222.     int scantranslate; // PC scan code hack
  223.     int untranslated; // lousy hack
  224. } default_t;
  225. default_t defaults[] =
  226. {
  227.     {"mouse_sensitivity",&mouseSensitivity, 5},
  228.     {"sfx_volume",&snd_SfxVolume, 8},
  229.     {"music_volume",&snd_MusicVolume, 8},
  230.     {"show_messages",&showMessages, 1},
  231.     
  232. #ifdef NORMALUNIX
  233.     {"key_right",&key_right, KEY_RIGHTARROW},
  234.     {"key_left",&key_left, KEY_LEFTARROW},
  235.     {"key_up",&key_up, KEY_UPARROW},
  236.     {"key_down",&key_down, KEY_DOWNARROW},
  237.     {"key_strafeleft",&key_strafeleft, ','},
  238.     {"key_straferight",&key_straferight, '.'},
  239.     {"key_fire",&key_fire, KEY_RCTRL},
  240.     {"key_use",&key_use, ' '},
  241.     {"key_strafe",&key_strafe, KEY_RALT},
  242.     {"key_speed",&key_speed, KEY_RSHIFT},
  243. // UNIX hack, to be removed. 
  244. #ifdef SNDSERV
  245.     {"sndserver", (int *) &sndserver_filename, (int) "sndserver"},
  246.     {"mb_used", &mb_used, 2},
  247. #endif
  248.     
  249. #endif
  250. #ifdef LINUX
  251.     {"mousedev", (int*)&mousedev, (int)"/dev/ttyS0"},
  252.     {"mousetype", (int*)&mousetype, (int)"microsoft"},
  253. #endif
  254.     {"use_mouse",&usemouse, 1},
  255.     {"mouseb_fire",&mousebfire,0},
  256.     {"mouseb_strafe",&mousebstrafe,1},
  257.     {"mouseb_forward",&mousebforward,2},
  258.     {"use_joystick",&usejoystick, 0},
  259.     {"joyb_fire",&joybfire,0},
  260.     {"joyb_strafe",&joybstrafe,1},
  261.     {"joyb_use",&joybuse,3},
  262.     {"joyb_speed",&joybspeed,2},
  263.     {"screenblocks",&screenblocks, 9},
  264.     {"detaillevel",&detailLevel, 0},
  265.     {"snd_channels",&numChannels, 3},
  266.     {"usegamma",&usegamma, 0},
  267.     {"chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 },
  268.     {"chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 },
  269.     {"chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 },
  270.     {"chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 },
  271.     {"chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 },
  272.     {"chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 },
  273.     {"chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 },
  274.     {"chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 },
  275.     {"chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 },
  276.     {"chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 }
  277. };
  278. int numdefaults;
  279. char* defaultfile;
  280. char DoomDir[128], szValue[32];
  281. void GetININame(void);
  282. //
  283. // M_SaveDefaults
  284. //
  285. void M_SaveDefaults (void)
  286.    {
  287. /*
  288.     int i;
  289.     int v;
  290.     FILE* f;
  291. */
  292.     GetININame();
  293.     sprintf(szValue, "%d", mouseSensitivity);
  294.     WritePrivateProfileString("DEFAULTS", "mouse_sensitivity", szValue, DoomDir);
  295.     sprintf(szValue, "%d", snd_SfxVolume);
  296.     WritePrivateProfileString("DEFAULTS", "sfx_volume", szValue, DoomDir);
  297.     sprintf(szValue, "%d", snd_MusicVolume);
  298.     WritePrivateProfileString("DEFAULTS", "music_volume", szValue, DoomDir);
  299.     sprintf(szValue, "%d", showMessages);
  300.     WritePrivateProfileString("DEFAULTS", "show_messages", szValue, DoomDir);
  301.     sprintf(szValue, "%d", key_right);
  302.     WritePrivateProfileString("DEFAULTS", "key_right", szValue, DoomDir);
  303.     sprintf(szValue, "%d", key_left);
  304.     WritePrivateProfileString("DEFAULTS", "key_left", szValue, DoomDir);
  305.     sprintf(szValue, "%d", key_up);
  306.     WritePrivateProfileString("DEFAULTS", "key_up", szValue, DoomDir);
  307.     sprintf(szValue, "%d", key_down);
  308.     WritePrivateProfileString("DEFAULTS", "key_down", szValue, DoomDir);
  309.     sprintf(szValue, "%d", key_mvert);
  310.     WritePrivateProfileString("DEFAULTS", "key_mvert", szValue, DoomDir);
  311.     sprintf(szValue, "%d", key_strafeleft);
  312.     WritePrivateProfileString("DEFAULTS", "key_strafeleft", szValue, DoomDir);
  313.     sprintf(szValue, "%d", key_straferight);
  314.     WritePrivateProfileString("DEFAULTS", "key_straferight", szValue, DoomDir);
  315.     sprintf(szValue, "%d", key_fire);
  316.     WritePrivateProfileString("DEFAULTS", "key_fire", szValue, DoomDir);
  317.     sprintf(szValue, "%d", key_use);
  318.     WritePrivateProfileString("DEFAULTS", "key_use", szValue, DoomDir);
  319.     sprintf(szValue, "%d", key_strafe);
  320.     WritePrivateProfileString("DEFAULTS", "key_strafe", szValue, DoomDir);
  321.     sprintf(szValue, "%d", key_speed);
  322.     WritePrivateProfileString("DEFAULTS", "key_speed", szValue, DoomDir);
  323.     sprintf(szValue, "%d", always_run);
  324.     WritePrivateProfileString("DEFAULTS", "always_run", szValue, DoomDir);
  325.     sprintf(szValue, "%d", swap_stereo);
  326.     WritePrivateProfileString("DEFAULTS", "swap_stereo", szValue, DoomDir);
  327.     sprintf(szValue, "%d", mvert);
  328.     WritePrivateProfileString("DEFAULTS", "mvert", szValue, DoomDir);
  329.     sprintf(szValue, "%d", keylink);
  330.     WritePrivateProfileString("DEFAULTS", "keylink", szValue, DoomDir);
  331.     sprintf(szValue, "%d", usemouse);
  332.     WritePrivateProfileString("DEFAULTS", "use_mouse", szValue, DoomDir);
  333.     sprintf(szValue, "%d", mousebfire);
  334.     WritePrivateProfileString("DEFAULTS", "mouseb_fire", szValue, DoomDir);
  335.     sprintf(szValue, "%d", mousebstrafe);
  336.     WritePrivateProfileString("DEFAULTS", "mouseb_strafe", szValue, DoomDir);
  337.     sprintf(szValue, "%d", mousebforward);
  338.     WritePrivateProfileString("DEFAULTS", "mouseb_forward", szValue, DoomDir);
  339.     sprintf(szValue, "%d", mouseb1);
  340.     WritePrivateProfileString("DEFAULTS", "mouseb1", szValue, DoomDir);
  341.     sprintf(szValue, "%d", mouseb2);
  342.     WritePrivateProfileString("DEFAULTS", "mouseb2", szValue, DoomDir);
  343.     sprintf(szValue, "%d", mouseb3);
  344.     WritePrivateProfileString("DEFAULTS", "mouseb3", szValue, DoomDir);
  345.     sprintf(szValue, "%d", usejoystick);
  346.     WritePrivateProfileString("DEFAULTS", "use_joystick", szValue, DoomDir);
  347.     sprintf(szValue, "%d", joybfire);
  348.     WritePrivateProfileString("DEFAULTS", "joyb_fire", szValue, DoomDir);
  349.     sprintf(szValue, "%d", joybstrafe);
  350.     WritePrivateProfileString("DEFAULTS", "joyb_strafe", szValue, DoomDir);
  351.     sprintf(szValue, "%d", joybuse);
  352.     WritePrivateProfileString("DEFAULTS", "joyb_use", szValue, DoomDir);
  353.     sprintf(szValue, "%d", joybspeed);
  354.     WritePrivateProfileString("DEFAULTS", "joyb_speed", szValue, DoomDir);
  355.     sprintf(szValue, "%d", joyb1);
  356.     WritePrivateProfileString("DEFAULTS", "joyb1", szValue, DoomDir);
  357.     sprintf(szValue, "%d", joyb2);
  358.     WritePrivateProfileString("DEFAULTS", "joyb2", szValue, DoomDir);
  359.     sprintf(szValue, "%d", joyb3);
  360.     WritePrivateProfileString("DEFAULTS", "joyb3", szValue, DoomDir);
  361.     sprintf(szValue, "%d", joyb4);
  362.     WritePrivateProfileString("DEFAULTS", "joyb4", szValue, DoomDir);
  363.     sprintf(szValue, "%d", screenblocks);
  364.     WritePrivateProfileString("DEFAULTS", "screenblocks", szValue, DoomDir);
  365.     sprintf(szValue, "%d", detailLevel);
  366.     WritePrivateProfileString("DEFAULTS", "detaillevel", szValue, DoomDir);
  367.     sprintf(szValue, "%d", usegamma);
  368.     WritePrivateProfileString("DEFAULTS", "usegamma", szValue, DoomDir);
  369.     sprintf(szValue, "%d", numChannels);
  370.     WritePrivateProfileString("DEFAULTS", "snd_channels", szValue, DoomDir);
  371. /*
  372.     f = fopen (defaultfile, "w");
  373.     if (!f)
  374. return; // can't write the file, but don't complain
  375.     for (i=0 ; i<numdefaults ; i++)
  376.     {
  377. if (defaults[i].defaultvalue > -0xfff
  378.     && defaults[i].defaultvalue < 0xfff)
  379. {
  380.     v = *defaults[i].location;
  381.     fprintf (f,"%stt%in",defaults[i].name,v);
  382. } else {
  383.     fprintf (f,"%stt"%s"n",defaults[i].name,
  384.      * (char **) (defaults[i].location));
  385. }
  386.     }
  387.     fclose (f);
  388. */
  389.    }
  390. //
  391. // M_LoadDefaults
  392. //
  393. extern byte scantokey[128];
  394. void WriteDebug(char *);
  395. char MsgText[256];
  396. void GetININame()
  397.    {
  398.     GetProfileString("WINDOOM", "DIRECTORY", "", DoomDir, 128 );
  399.     if (strlen(DoomDir) == 0)
  400.        {
  401.         getcwd(DoomDir, 128);
  402.         WriteProfileString("WINDOOM", "DIRECTORY", DoomDir );
  403.        }
  404.     strcat(DoomDir, "\WinDoom.INI");
  405.    }
  406. void M_LoadDefaults (void)
  407. {
  408. /*
  409.     int i;
  410.     int len;
  411.     FILE* f;
  412.     char def[80];
  413.     char strparm[100];
  414.     char* newstring;
  415.     int parm;
  416.     boolean isstring;
  417. */    
  418.     GetININame();
  419.     mouseSensitivity = GetPrivateProfileInt("DEFAULTS", "mouse_sensitivity", 5, DoomDir);
  420.     snd_SfxVolume = GetPrivateProfileInt("DEFAULTS", "sfx_volume", 15, DoomDir);
  421.     snd_MusicVolume = GetPrivateProfileInt("DEFAULTS", "music_volume", 8, DoomDir);
  422.     showMessages = GetPrivateProfileInt("DEFAULTS", "show_messages", 1, DoomDir);
  423.     key_right = GetPrivateProfileInt("DEFAULTS", "key_right", KEY_RIGHTARROW, DoomDir);
  424.     key_left = GetPrivateProfileInt("DEFAULTS", "key_left", KEY_LEFTARROW, DoomDir);
  425.     key_up = GetPrivateProfileInt("DEFAULTS", "key_up", KEY_UPARROW, DoomDir);
  426.     key_down = GetPrivateProfileInt("DEFAULTS", "key_down", KEY_DOWNARROW, DoomDir);
  427.     key_strafeleft = GetPrivateProfileInt("DEFAULTS", "key_strafeleft", KEY_COMMA, DoomDir);
  428.     key_straferight = GetPrivateProfileInt("DEFAULTS", "key_straferight", KEY_PERIOD, DoomDir);
  429.     key_fire = GetPrivateProfileInt("DEFAULTS", "key_fire", KEY_RCTRL, DoomDir);
  430.     key_use = GetPrivateProfileInt("DEFAULTS", "key_use", KEY_SPACE, DoomDir);
  431.     key_strafe = GetPrivateProfileInt("DEFAULTS", "key_strafe", KEY_RALT, DoomDir);
  432.     key_speed = GetPrivateProfileInt("DEFAULTS", "key_speed", KEY_RSHIFT, DoomDir);
  433.     key_mvert = GetPrivateProfileInt("DEFAULTS", "key_mvert", KEY_SLASH, DoomDir);
  434.     always_run = GetPrivateProfileInt("DEFAULTS", "always_run", FALSE, DoomDir);
  435.     swap_stereo = GetPrivateProfileInt("DEFAULTS", "swap_stereo", FALSE, DoomDir);
  436.     mvert = GetPrivateProfileInt("DEFAULTS", "mvert", TRUE, DoomDir);
  437.     keylink = GetPrivateProfileInt("DEFAULTS", "keylink", TRUE, DoomDir);
  438.     usemouse = GetPrivateProfileInt("DEFAULTS", "use_mouse", TRUE, DoomDir);
  439.     mousebfire = GetPrivateProfileInt("DEFAULTS", "mouseb_fire", 0, DoomDir);
  440.     mousebstrafe = GetPrivateProfileInt("DEFAULTS", "mouseb_strafe", 1, DoomDir);
  441.     mousebforward = GetPrivateProfileInt("DEFAULTS", "mouseb_forward", 2, DoomDir);
  442.     mouseb1 = GetPrivateProfileInt("DEFAULTS", "mouseb1", key_fire, DoomDir);
  443.     mouseb2 = GetPrivateProfileInt("DEFAULTS", "mouseb2", key_strafe, DoomDir);
  444.     mouseb3 = GetPrivateProfileInt("DEFAULTS", "mouseb3", key_up, DoomDir);
  445.     usejoystick = GetPrivateProfileInt("DEFAULTS", "use_joystick", FALSE, DoomDir);
  446.     joybfire = GetPrivateProfileInt("DEFAULTS", "joyb_fire", 0, DoomDir);
  447.     joybstrafe = GetPrivateProfileInt("DEFAULTS", "joyb_strafe", 1, DoomDir);
  448.     joybuse = GetPrivateProfileInt("DEFAULTS", "joyb_use", 3, DoomDir);
  449.     joybspeed = GetPrivateProfileInt("DEFAULTS", "joyb_speed", 2, DoomDir);
  450.     joyb1 = GetPrivateProfileInt("DEFAULTS", "joyb1", key_fire, DoomDir);
  451.     joyb2 = GetPrivateProfileInt("DEFAULTS", "joyb2", key_strafe, DoomDir);
  452.     joyb3 = GetPrivateProfileInt("DEFAULTS", "joyb3", key_use, DoomDir);
  453.     joyb4 = GetPrivateProfileInt("DEFAULTS", "joyb4", key_speed, DoomDir);
  454.     screenblocks = GetPrivateProfileInt("DEFAULTS", "screenblocks", 10, DoomDir);
  455.     detailLevel = GetPrivateProfileInt("DEFAULTS", "detaillevel", 0, DoomDir);
  456.     usegamma = GetPrivateProfileInt("DEFAULTS", "usegamma", 0, DoomDir);
  457.     numChannels = GetPrivateProfileInt("DEFAULTS", "snd_channels", 256, DoomDir);
  458.    }
  459. /*
  460. snd_musicdevice 3
  461. snd_sfxdevice 3
  462. snd_sbport 544
  463. snd_sbirq 5
  464. snd_sbdma 1
  465. snd_mport 816
  466. chatmacro0 "no macro"
  467. chatmacro1 "no macro"
  468. chatmacro2 "no macro"
  469. chatmacro3 "no macro"
  470. chatmacro4 "no macro"
  471. chatmacro5 "no macro"
  472. chatmacro6 "no macro"
  473. chatmacro7 "no macro"
  474. chatmacro8 "no macro"
  475. chatmacro9 "no macro"
  476. */
  477. //
  478. // SCREEN SHOTS
  479. //
  480. typedef struct
  481. {
  482.     char manufacturer;
  483.     char version;
  484.     char encoding;
  485.     char bits_per_pixel;
  486.     unsigned short xmin;
  487.     unsigned short ymin;
  488.     unsigned short xmax;
  489.     unsigned short ymax;
  490.     
  491.     unsigned short hres;
  492.     unsigned short vres;
  493.     unsigned char palette[48];
  494.     
  495.     char reserved;
  496.     char color_planes;
  497.     unsigned short bytes_per_line;
  498.     unsigned short palette_type;
  499.     
  500.     char filler[58];
  501.     unsigned char data; // unbounded
  502. } pcx_t;
  503. //
  504. // WritePCXfile
  505. //
  506. void
  507. WritePCXfile
  508. ( char* filename,
  509.   byte* data,
  510.   int width,
  511.   int height,
  512.   byte* palette )
  513. {
  514.     int i;
  515.     int length;
  516.     pcx_t* pcx;
  517.     byte* pack;
  518.     pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
  519.     pcx->manufacturer = 0x0a; // PCX id
  520.     pcx->version = 5; // 256 color
  521.     pcx->encoding = 1; // uncompressed
  522.     pcx->bits_per_pixel = 8; // 256 color
  523.     pcx->xmin = 0;
  524.     pcx->ymin = 0;
  525.     pcx->xmax = SHORT(width-1);
  526.     pcx->ymax = SHORT(height-1);
  527.     pcx->hres = SHORT(width);
  528.     pcx->vres = SHORT(height);
  529.     memset (pcx->palette,0,sizeof(pcx->palette));
  530.     pcx->color_planes = 1; // chunky image
  531.     pcx->bytes_per_line = SHORT(width);
  532.     pcx->palette_type = SHORT(2); // not a grey scale
  533.     memset (pcx->filler,0,sizeof(pcx->filler));
  534.     // pack the image
  535.     pack = &pcx->data;
  536.     for (i=0 ; i<width*height ; i++)
  537.     {
  538. if ( (*data & 0xc0) != 0xc0)
  539.     *pack++ = *data++;
  540. else
  541. {
  542.     *pack++ = 0xc1;
  543.     *pack++ = *data++;
  544. }
  545.     }
  546.     
  547.     // write the palette
  548.     *pack++ = 0x0c; // palette ID byte
  549.     for (i=0 ; i<768 ; i++)
  550. *pack++ = gammatable[usegamma][*palette++];
  551.     
  552.     // write output file
  553.     length = pack - (byte *)pcx;
  554.     M_WriteFile (filename, pcx, length);
  555.     Z_Free (pcx);
  556. }
  557. //
  558. // M_ScreenShot
  559. //
  560. void M_ScreenShot (void)
  561. {
  562.     int i;
  563.     byte* linear;
  564.     char lbmname[12];
  565.     
  566.     // munge planar buffer to linear
  567.     linear = screens[2];
  568.     I_ReadScreen (linear);
  569.     
  570.     // find a file name to save it to
  571.     strcpy(lbmname,"DOOM00.pcx");
  572.     for (i=0 ; i<=99 ; i++)
  573.     {
  574. lbmname[4] = i/10 + '0';
  575. lbmname[5] = i%10 + '0';
  576. if (access(lbmname,0) == -1)
  577.     break; // file doesn't exist
  578.     }
  579.     if (i==100)
  580. I_Error ("M_ScreenShot: Couldn't create a PCX");
  581.     
  582.     // save the pcx file
  583.     WritePCXfile (lbmname, linear,
  584.   SCREENWIDTH, SCREENHEIGHT,
  585.   W_CacheLumpName ("PLAYPAL",PU_CACHE));
  586.     players[consoleplayer].message = "screen shot";
  587. }