]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/m_misc.c
games/doom: implement filelength() (thanks quux)
[plan9front.git] / sys / src / games / doom / m_misc.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
27 static const char
28 rcsid[] = "$Id: m_misc.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
29
30
31 #include "doomdef.h"
32
33 #include "z_zone.h"
34
35 #include "m_swap.h"
36 #include "m_argv.h"
37
38 #include "w_wad.h"
39
40 #include "i_system.h"
41 #include "i_video.h"
42 #include "v_video.h"
43
44 #include "hu_stuff.h"
45
46 // State.
47 #include "doomstat.h"
48
49 // Data.
50 #include "dstrings.h"
51
52 #include "m_misc.h"
53
54 //
55 // M_DrawText
56 // Returns the final X coordinate
57 // HU_Init must have been called to init the font
58 //
59 extern patch_t*         hu_font[HU_FONTSIZE];
60
61 int
62 M_DrawText
63 ( int           x,
64   int           y,
65   boolean       direct,
66   char*         string )
67 {
68     int         c;
69     int         w;
70
71     while (*string)
72     {
73         c = toupper(*string) - HU_FONTSTART;
74         string++;
75         if (c < 0 || c> HU_FONTSIZE)
76         {
77             x += 4;
78             continue;
79         }
80                 
81         w = SHORT (hu_font[c]->width);
82         if (x+w > SCREENWIDTH)
83             break;
84         if (direct)
85             V_DrawPatchDirect(x, y, 0, hu_font[c]);
86         else
87             V_DrawPatch(x, y, 0, hu_font[c]);
88         x+=w;
89     }
90
91     return x;
92 }
93
94
95
96
97 //
98 // M_WriteFile
99 //
100 boolean
101 M_WriteFile
102 ( char const*   name,
103   void*         source,
104   int           length )
105 {
106         int fd, n;
107
108         if((fd = create(name, OWRITE, 0644)) < 0)
109                 return false;
110         n = write(fd, source, length);
111         close(fd);
112         return n == length;
113 }
114
115
116 //
117 // M_ReadFile
118 //
119 int
120 M_ReadFile
121 ( char const*   name,
122   byte**        buffer )
123 {
124         int fd, length;
125         Dir *d;
126         byte *buf;
127
128         if((fd = open(name, OREAD)) < 0)
129                 I_Error ("Couldn't open file %s", name);
130         if((d = dirfstat(fd)) == nil)
131                 I_Error ("Couldn't stat file %s", name);
132         length = d->length;
133         free(d);
134
135         buf = Z_Malloc(length, PU_STATIC, NULL);
136         if(readn(fd, buf, length) != length)
137                 I_Error ("Couldn't read file %s", name);
138         close(fd);
139         *buffer = buf;
140         return length;
141 }
142
143
144 //
145 // DEFAULTS
146 //
147 int             usemouse;
148 int             usejoystick;
149
150 extern int      key_right;
151 extern int      key_left;
152 extern int      key_up;
153 extern int      key_down;
154
155 extern int      key_strafeleft;
156 extern int      key_straferight;
157
158 extern int      key_fire;
159 extern int      key_use;
160 extern int      key_strafe;
161 extern int      key_speed;
162
163 extern int      mousebfire;
164 extern int      mousebstrafe;
165 extern int      mousebforward;
166
167 extern int      joybfire;
168 extern int      joybstrafe;
169 extern int      joybuse;
170 extern int      joybspeed;
171
172 extern int      viewwidth;
173 extern int      viewheight;
174
175 extern int      mouseSensitivity;
176 extern int      showMessages;
177
178 extern int      detailLevel;
179
180 extern int      screenblocks;
181
182 extern int      showMessages;
183
184 // machine-independent sound params
185 extern  int     numChannels;
186
187 extern char*    chat_macros[];
188
189 typedef struct
190 {
191     char*       name;
192     void*       location;
193     int         defaultvalue;
194     char*       defaultstring;
195 } default_t;
196
197 default_t       defaults[] =
198 {
199     {"mouse_sensitivity",&mouseSensitivity, 5},
200     {"sfx_volume",&snd_SfxVolume, 8},
201     {"music_volume",&snd_MusicVolume, 8},
202     {"show_messages",&showMessages, 1},
203     
204
205     {"key_right",&key_right, KEY_RIGHTARROW},
206     {"key_left",&key_left, KEY_LEFTARROW},
207     {"key_up",&key_up, KEY_UPARROW},
208     {"key_down",&key_down, KEY_DOWNARROW},
209     {"key_strafeleft",&key_strafeleft, ','},
210     {"key_straferight",&key_straferight, '.'},
211
212     {"key_fire",&key_fire, KEY_RCTRL},
213     {"key_use",&key_use, ' '},
214     {"key_strafe",&key_strafe, KEY_RALT},
215     {"key_speed",&key_speed, KEY_RSHIFT},
216
217     {"use_mouse",&usemouse, 1},
218     {"mouseb_fire",&mousebfire,0},
219     {"mouseb_strafe",&mousebstrafe,1},
220     {"mouseb_forward",&mousebforward,2},
221
222     {"use_joystick",&usejoystick, 0},
223     {"joyb_fire",&joybfire,0},
224     {"joyb_strafe",&joybstrafe,1},
225     {"joyb_use",&joybuse,3},
226     {"joyb_speed",&joybspeed,2},
227
228     {"screenblocks",&screenblocks, 9},
229     {"detaillevel",&detailLevel, 0},
230
231     {"snd_channels",&numChannels, 3},
232
233     {"usegamma",&usegamma, 0},
234
235     {"chatmacro0",&chat_macros[0], 0, HUSTR_CHATMACRO0 },
236     {"chatmacro1",&chat_macros[1], 0, HUSTR_CHATMACRO1 },
237     {"chatmacro2",&chat_macros[2], 0, HUSTR_CHATMACRO2 },
238     {"chatmacro3",&chat_macros[3], 0, HUSTR_CHATMACRO3 },
239     {"chatmacro4",&chat_macros[4], 0, HUSTR_CHATMACRO4 },
240     {"chatmacro5",&chat_macros[5], 0, HUSTR_CHATMACRO5 },
241     {"chatmacro6",&chat_macros[6], 0, HUSTR_CHATMACRO6 },
242     {"chatmacro7",&chat_macros[7], 0, HUSTR_CHATMACRO7 },
243     {"chatmacro8",&chat_macros[8], 0, HUSTR_CHATMACRO8 },
244     {"chatmacro9",&chat_macros[9], 0, HUSTR_CHATMACRO9 }
245
246 };
247
248 int     numdefaults;
249 char*   defaultfile;
250
251 //
252 // M_SaveDefaults
253 //
254 void M_SaveDefaults (void)
255 {
256     int         i;
257     FILE*       f;
258         
259     f = fopen (defaultfile, "w");
260     if (!f)
261         return; // can't write the file, but don't complain
262                 
263     for (i=0 ; i<numdefaults ; i++)
264     {
265         if (defaults[i].defaultstring == 0)
266         {
267             fprintf (f,"%s\t\t%i\n",defaults[i].name,
268                 *((int*)defaults[i].location));
269         } else {
270             fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
271                 *((char**)defaults[i].location));
272         }
273     }
274         
275     fclose (f);
276 }
277
278
279 //
280 // M_LoadDefaults
281 //
282 void M_LoadDefaults (void)
283 {
284     int         i;
285     int         len;
286     FILE*       f;
287     char        def[80];
288     char        strparm[100];
289     char*       newstring;
290     int         parm;
291     
292     // set everything to base values
293     numdefaults = sizeof(defaults)/sizeof(defaults[0]);
294     for (i=0 ; i<numdefaults ; i++)
295         if(defaults[i].defaultstring == 0)
296             *((int*)defaults[i].location) = defaults[i].defaultvalue;
297         else
298             *((char**)defaults[i].location) = defaults[i].defaultstring;
299     
300     // check for a custom default file
301     i = M_CheckParm ("-config");
302     if (i && i<myargc-1)
303     {
304         defaultfile = myargv[i+1];
305         printf ("       default file: %s\n",defaultfile);
306     }
307     else
308         defaultfile = basedefault;
309     
310     // read the file in, overriding any set defaults
311     f = fopen (defaultfile, "r");
312     if (f)
313     {
314         while (!feof(f))
315         {
316             if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
317             {
318                 parm = 0;
319                 newstring = 0;
320                 if (strparm[0] == '"')
321                 {
322                     // get a string default
323                     len = strlen(strparm);
324                     newstring = (char *) malloc(len);
325                     strparm[len-1] = 0;
326                     strcpy(newstring, strparm+1);
327                 }
328                 else if (strparm[0] == '0' && strparm[1] == 'x')
329                     sscanf(strparm+2, "%x", &parm);
330                 else
331                     sscanf(strparm, "%i", &parm);
332                 for (i=0 ; i<numdefaults ; i++)
333                     if (!strcmp(def, defaults[i].name))
334                     {
335                         if (defaults[i].defaultstring == 0)
336                             *((int*)defaults[i].location) = parm;
337                         else if(newstring)
338                             *((char**)defaults[i].location) = newstring;
339                         break;
340                     }
341             }
342         }
343                 
344         fclose (f);
345     }
346 }
347
348
349 //
350 // SCREEN SHOTS
351 //
352
353
354 typedef struct
355 {
356     char                manufacturer;
357     char                version;
358     char                encoding;
359     char                bits_per_pixel;
360
361     unsigned short      xmin;
362     unsigned short      ymin;
363     unsigned short      xmax;
364     unsigned short      ymax;
365     
366     unsigned short      hres;
367     unsigned short      vres;
368
369     unsigned char       palette[48];
370     
371     char                reserved;
372     char                color_planes;
373     unsigned short      bytes_per_line;
374     unsigned short      palette_type;
375     
376     char                filler[58];
377     unsigned char       data;           // unbounded
378 } pcx_t;
379
380
381 //
382 // WritePCXfile
383 //
384 void
385 WritePCXfile
386 ( char*         filename,
387   byte*         data,
388   int           width,
389   int           height,
390   byte*         palette )
391 {
392     int         i;
393     int         length;
394     pcx_t*      pcx;
395     byte*       pack;
396         
397     pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
398
399     pcx->manufacturer = 0x0a;           // PCX id
400     pcx->version = 5;                   // 256 color
401     pcx->encoding = 1;                  // uncompressed
402     pcx->bits_per_pixel = 8;            // 256 color
403     pcx->xmin = 0;
404     pcx->ymin = 0;
405     pcx->xmax = SHORT(width-1);
406     pcx->ymax = SHORT(height-1);
407     pcx->hres = SHORT(width);
408     pcx->vres = SHORT(height);
409     memset (pcx->palette,0,sizeof(pcx->palette));
410     pcx->color_planes = 1;              // chunky image
411     pcx->bytes_per_line = SHORT(width);
412     pcx->palette_type = SHORT(2);       // not a grey scale
413     memset (pcx->filler,0,sizeof(pcx->filler));
414
415
416     // pack the image
417     pack = &pcx->data;
418         
419     for (i=0 ; i<width*height ; i++)
420     {
421         if ( (*data & 0xc0) != 0xc0)
422             *pack++ = *data++;
423         else
424         {
425             *pack++ = 0xc1;
426             *pack++ = *data++;
427         }
428     }
429     
430     // write the palette
431     *pack++ = 0x0c;     // palette ID byte
432     for (i=0 ; i<768 ; i++)
433         *pack++ = *palette++;
434     
435     // write output file
436     length = pack - (byte *)pcx;
437     M_WriteFile (filename, pcx, length);
438
439     Z_Free (pcx);
440 }
441
442
443 //
444 // M_ScreenShot
445 //
446 void M_ScreenShot (void)
447 {
448     int         i;
449     byte*       linear;
450     char        lbmname[12];
451     
452     // munge planar buffer to linear
453     linear = screens[2];
454     I_ReadScreen (linear);
455     
456     // find a file name to save it to
457     strcpy(lbmname,"DOOM00.pcx");
458                 
459     for (i=0 ; i<=99 ; i++)
460     {
461         lbmname[4] = i/10 + '0';
462         lbmname[5] = i%10 + '0';
463         if (!I_FileExists (lbmname))
464             break;
465     }
466     if (i==100)
467         I_Error ("M_ScreenShot: Couldn't create a PCX");
468     
469     // save the pcx file
470     WritePCXfile (lbmname, linear,
471                   SCREENWIDTH, SCREENHEIGHT,
472                   W_CacheLumpName ("PLAYPAL",PU_CACHE));
473         
474     players[consoleplayer].message = "screen shot";
475 }
476
477