]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/m_misc.c
games/doom: add /sys/games/lib/doom as default wad path
[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 #ifndef O_BINARY
101 #define O_BINARY 0
102 #endif
103
104 boolean
105 M_WriteFile
106 ( char const*   name,
107   void*         source,
108   int           length )
109 {
110         int fd, n;
111
112         if((fd = create(name, OWRITE | OTRUNC, 0666)) < 0)
113                 return false;
114         n = write(fd, source, length);
115         close(fd);
116         return n == length;
117 }
118
119
120 //
121 // M_ReadFile
122 //
123 int
124 M_ReadFile
125 ( char const*   name,
126   byte**        buffer )
127 {
128         int fd, length;
129         Dir *d;
130         byte *buf;
131
132         if((fd = open(name, OREAD)) < 0)
133                 I_Error ("Couldn't open file %s", name);
134         if((d = dirfstat(fd)) == nil)
135                 I_Error ("Couldn't stat file %s", name);
136         length = d->length;
137         free(d);
138
139         buf = Z_Malloc(length, PU_STATIC, NULL);
140         if(readn(fd, buf, length) != length)
141                 I_Error ("Couldn't read file %s", name);
142         close(fd);
143         *buffer = buf;
144         return length;
145 }
146
147
148 //
149 // DEFAULTS
150 //
151 int             usemouse;
152 int             usejoystick;
153
154 extern int      key_right;
155 extern int      key_left;
156 extern int      key_up;
157 extern int      key_down;
158
159 extern int      key_strafeleft;
160 extern int      key_straferight;
161
162 extern int      key_fire;
163 extern int      key_use;
164 extern int      key_strafe;
165 extern int      key_speed;
166
167 extern int      mousebfire;
168 extern int      mousebstrafe;
169 extern int      mousebforward;
170
171 extern int      joybfire;
172 extern int      joybstrafe;
173 extern int      joybuse;
174 extern int      joybspeed;
175
176 extern int      viewwidth;
177 extern int      viewheight;
178
179 extern int      mouseSensitivity;
180 extern int      showMessages;
181
182 extern int      detailLevel;
183
184 extern int      screenblocks;
185
186 extern int      showMessages;
187
188 // machine-independent sound params
189 extern  int     numChannels;
190
191
192 // UNIX hack, to be removed.
193 #ifdef SNDSERV
194 extern char*    sndserver_filename;
195 extern int      mb_used;
196 #endif
197
198 #ifdef LINUX
199 char*           mousetype;
200 char*           mousedev;
201 #endif
202
203 extern char*    chat_macros[];
204
205
206
207 typedef struct
208 {
209     char*       name;
210     int*        location;
211     int         defaultvalue;
212     int         scantranslate;          // PC scan code hack
213     int         untranslated;           // lousy hack
214 } default_t;
215
216 default_t       defaults[] =
217 {
218     {"mouse_sensitivity",&mouseSensitivity, 5},
219     {"sfx_volume",&snd_SfxVolume, 8},
220     {"music_volume",&snd_MusicVolume, 8},
221     {"show_messages",&showMessages, 1},
222     
223
224     {"key_right",&key_right, KEY_RIGHTARROW},
225     {"key_left",&key_left, KEY_LEFTARROW},
226     {"key_up",&key_up, KEY_UPARROW},
227     {"key_down",&key_down, KEY_DOWNARROW},
228     {"key_strafeleft",&key_strafeleft, ','},
229     {"key_straferight",&key_straferight, '.'},
230
231     {"key_fire",&key_fire, KEY_RCTRL},
232     {"key_use",&key_use, ' '},
233     {"key_strafe",&key_strafe, KEY_RALT},
234     {"key_speed",&key_speed, KEY_RSHIFT},
235
236 // UNIX hack, to be removed. 
237 #ifdef SNDSERV
238     {"sndserver", (int *) &sndserver_filename, (int) "sndserver"},
239     {"mb_used", &mb_used, 2},
240 #endif
241
242 #ifdef LINUX
243     {"mousedev", (int*)&mousedev, (int)"/dev/ttyS0"},
244     {"mousetype", (int*)&mousetype, (int)"microsoft"},
245 #endif
246
247     {"use_mouse",&usemouse, 1},
248     {"mouseb_fire",&mousebfire,0},
249     {"mouseb_strafe",&mousebstrafe,1},
250     {"mouseb_forward",&mousebforward,2},
251
252     {"use_joystick",&usejoystick, 0},
253     {"joyb_fire",&joybfire,0},
254     {"joyb_strafe",&joybstrafe,1},
255     {"joyb_use",&joybuse,3},
256     {"joyb_speed",&joybspeed,2},
257
258     {"screenblocks",&screenblocks, 9},
259     {"detaillevel",&detailLevel, 0},
260
261     {"snd_channels",&numChannels, 3},
262
263
264
265     {"usegamma",&usegamma, 0},
266
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 };
279
280 int     numdefaults;
281 char*   defaultfile;
282
283
284 //
285 // M_SaveDefaults
286 //
287 void M_SaveDefaults (void)
288 {
289     int         i;
290     int         v;
291     FILE*       f;
292         
293     f = fopen (defaultfile, "w");
294     if (!f)
295         return; // can't write the file, but don't complain
296                 
297     for (i=0 ; i<numdefaults ; i++)
298     {
299         if (defaults[i].defaultvalue > -0xfff
300             && defaults[i].defaultvalue < 0xfff)
301         {
302             v = *defaults[i].location;
303             fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
304         } else {
305             fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
306                      * (char **) (defaults[i].location));
307         }
308     }
309         
310     fclose (f);
311 }
312
313
314 //
315 // M_LoadDefaults
316 //
317 extern byte     scantokey[128];
318
319 void M_LoadDefaults (void)
320 {
321     int         i;
322     int         len;
323     FILE*       f;
324     char        def[80];
325     char        strparm[100];
326     char*       newstring = (char *)0;
327     int         parm;
328     boolean     isstring;
329     
330     // set everything to base values
331     numdefaults = sizeof(defaults)/sizeof(defaults[0]);
332     for (i=0 ; i<numdefaults ; i++)
333         *defaults[i].location = defaults[i].defaultvalue;
334     
335     // check for a custom default file
336     i = M_CheckParm ("-config");
337     if (i && i<myargc-1)
338     {
339         defaultfile = myargv[i+1];
340         printf ("       default file: %s\n",defaultfile);
341     }
342     else
343         defaultfile = basedefault;
344     
345     // read the file in, overriding any set defaults
346     f = fopen (defaultfile, "r");
347     if (f)
348     {
349         while (!feof(f))
350         {
351             isstring = false;
352             if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2)
353             {
354                 if (strparm[0] == '"')
355                 {
356                     // get a string default
357                     isstring = true;
358                     len = strlen(strparm);
359                     newstring = (char *) malloc(len);
360                     strparm[len-1] = 0;
361                     strcpy(newstring, strparm+1);
362                 }
363                 else if (strparm[0] == '0' && strparm[1] == 'x')
364                     sscanf(strparm+2, "%x", &parm);
365                 else
366                     sscanf(strparm, "%i", &parm);
367                 for (i=0 ; i<numdefaults ; i++)
368                     if (!strcmp(def, defaults[i].name))
369                     {
370                         if (!isstring)
371                             *defaults[i].location = parm;
372                         else
373                             *defaults[i].location =
374                                 (int) newstring;
375                         break;
376                     }
377             }
378         }
379                 
380         fclose (f);
381     }
382 }
383
384
385 //
386 // SCREEN SHOTS
387 //
388
389
390 typedef struct
391 {
392     char                manufacturer;
393     char                version;
394     char                encoding;
395     char                bits_per_pixel;
396
397     unsigned short      xmin;
398     unsigned short      ymin;
399     unsigned short      xmax;
400     unsigned short      ymax;
401     
402     unsigned short      hres;
403     unsigned short      vres;
404
405     unsigned char       palette[48];
406     
407     char                reserved;
408     char                color_planes;
409     unsigned short      bytes_per_line;
410     unsigned short      palette_type;
411     
412     char                filler[58];
413     unsigned char       data;           // unbounded
414 } pcx_t;
415
416
417 //
418 // WritePCXfile
419 //
420 void
421 WritePCXfile
422 ( char*         filename,
423   byte*         data,
424   int           width,
425   int           height,
426   byte*         palette )
427 {
428     int         i;
429     int         length;
430     pcx_t*      pcx;
431     byte*       pack;
432         
433     pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
434
435     pcx->manufacturer = 0x0a;           // PCX id
436     pcx->version = 5;                   // 256 color
437     pcx->encoding = 1;                  // uncompressed
438     pcx->bits_per_pixel = 8;            // 256 color
439     pcx->xmin = 0;
440     pcx->ymin = 0;
441     pcx->xmax = SHORT(width-1);
442     pcx->ymax = SHORT(height-1);
443     pcx->hres = SHORT(width);
444     pcx->vres = SHORT(height);
445     memset (pcx->palette,0,sizeof(pcx->palette));
446     pcx->color_planes = 1;              // chunky image
447     pcx->bytes_per_line = SHORT(width);
448     pcx->palette_type = SHORT(2);       // not a grey scale
449     memset (pcx->filler,0,sizeof(pcx->filler));
450
451
452     // pack the image
453     pack = &pcx->data;
454         
455     for (i=0 ; i<width*height ; i++)
456     {
457         if ( (*data & 0xc0) != 0xc0)
458             *pack++ = *data++;
459         else
460         {
461             *pack++ = 0xc1;
462             *pack++ = *data++;
463         }
464     }
465     
466     // write the palette
467     *pack++ = 0x0c;     // palette ID byte
468     for (i=0 ; i<768 ; i++)
469         *pack++ = *palette++;
470     
471     // write output file
472     length = pack - (byte *)pcx;
473     M_WriteFile (filename, pcx, length);
474
475     Z_Free (pcx);
476 }
477
478
479 //
480 // M_ScreenShot
481 //
482 void M_ScreenShot (void)
483 {
484     int         i;
485     byte*       linear;
486     char        lbmname[12];
487     
488     // munge planar buffer to linear
489     linear = screens[2];
490     I_ReadScreen (linear);
491     
492     // find a file name to save it to
493     strcpy(lbmname,"DOOM00.pcx");
494                 
495     for (i=0 ; i<=99 ; i++)
496     {
497         lbmname[4] = i/10 + '0';
498         lbmname[5] = i%10 + '0';
499         if (access(lbmname,0) == -1)
500             break;      // file doesn't exist
501     }
502     if (i==100)
503         I_Error ("M_ScreenShot: Couldn't create a PCX");
504     
505     // save the pcx file
506     WritePCXfile (lbmname, linear,
507                   SCREENWIDTH, SCREENHEIGHT,
508                   W_CacheLumpName ("PLAYPAL",PU_CACHE));
509         
510     players[consoleplayer].message = "screen shot";
511 }
512
513