]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/v_video.c
merge
[plan9front.git] / sys / src / games / doom / v_video.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 // $Log:$
18 //
19 // DESCRIPTION:
20 //      Gamma correction LUT stuff.
21 //      Functions to draw patches (by post) directly to screen.
22 //      Functions to blit a block to the screen.
23 //
24 //-----------------------------------------------------------------------------
25
26
27 static const char
28 rcsid[] = "$Id: v_video.c,v 1.5 1997/02/03 22:45:13 b1 Exp $";
29
30
31 #include "i_system.h"
32 #include "r_local.h"
33
34 #include "doomdef.h"
35 #include "doomdata.h"
36
37 #include "m_bbox.h"
38 #include "m_swap.h"
39
40 #include "v_video.h"
41
42
43 // Each screen is [SCREENWIDTH*SCREENHEIGHT]; 
44 byte*                           screens[5];     
45  
46 int                             dirtybox[4]; 
47
48
49
50 // Now where did these came from?
51 byte gammatable[5][256] =
52 {
53     {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
54      17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
55      33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
56      49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
57      65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
58      81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,
59      97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
60      113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
61      128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
62      144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
63      160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
64      176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
65      192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
66      208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
67      224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
68      240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
69
70     {2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,
71      32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,
72      56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,
73      78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,
74      99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
75      115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,
76      130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
77      146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,
78      161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,
79      175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,
80      190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,
81      205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,
82      219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,
83      233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,
84      247,248,249,250,251,252,252,253,254,255},
85
86     {4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,
87      43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,
88      70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,
89      94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,
90      113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
91      129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,
92      144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,
93      160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,
94      174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,
95      188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,
96      202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,
97      216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,
98      229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,
99      242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,
100      255},
101
102     {8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,
103      57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,
104      86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,
105      108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,
106      125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,
107      141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,
108      155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,
109      169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,
110      183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,
111      195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,
112      207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,
113      219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,
114      231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,
115      242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,
116      253,253,254,254,255},
117
118     {16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,
119      78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,
120      107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,
121      125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,
122      142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,
123      156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,
124      169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,
125      182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,
126      193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,
127      204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,
128      214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,
129      224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,
130      234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,
131      243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,
132      251,252,252,253,254,254,255,255}
133 };
134
135
136
137 int     usegamma;
138                          
139 //
140 // V_MarkRect 
141 // 
142 void
143 V_MarkRect
144 ( int           x,
145   int           y,
146   int           width,
147   int           height ) 
148
149     M_AddToBox (dirtybox, x, y); 
150     M_AddToBox (dirtybox, x+width-1, y+height-1); 
151
152  
153
154 //
155 // V_CopyRect 
156 // 
157 void
158 V_CopyRect
159 ( int           srcx,
160   int           srcy,
161   int           srcscrn,
162   int           width,
163   int           height,
164   int           destx,
165   int           desty,
166   int           destscrn ) 
167
168     byte*       src;
169     byte*       dest; 
170          
171 #ifdef RANGECHECK 
172     if (srcx<0
173         ||srcx+width >SCREENWIDTH
174         || srcy<0
175         || srcy+height>SCREENHEIGHT 
176         ||destx<0||destx+width >SCREENWIDTH
177         || desty<0
178         || desty+height>SCREENHEIGHT 
179         || (unsigned)srcscrn>4
180         || (unsigned)destscrn>4)
181     {
182         I_Error ("Bad V_CopyRect");
183     }
184 #endif 
185     V_MarkRect (destx, desty, width, height); 
186          
187     src = screens[srcscrn]+SCREENWIDTH*srcy+srcx; 
188     dest = screens[destscrn]+SCREENWIDTH*desty+destx; 
189
190     for ( ; height>0 ; height--) 
191     { 
192         memcpy (dest, src, width); 
193         src += SCREENWIDTH; 
194         dest += SCREENWIDTH; 
195     } 
196
197  
198
199 //
200 // V_DrawPatch
201 // Masks a column based masked pic to the screen. 
202 //
203 void
204 V_DrawPatch
205 ( int           x,
206   int           y,
207   int           scrn,
208   patch_t*      patch ) 
209
210
211     int         count;
212     int         col; 
213     column_t*   column; 
214     byte*       desttop;
215     byte*       dest;
216     byte*       source; 
217     int         w; 
218          
219     y -= SHORT(patch->topoffset); 
220     x -= SHORT(patch->leftoffset); 
221 #ifdef RANGECHECK 
222     if (x<0
223         ||x+SHORT(patch->width) >SCREENWIDTH
224         || y<0
225         || y+SHORT(patch->height)>SCREENHEIGHT 
226         || (unsigned)scrn>4)
227     {
228       fprintf( stderr, "Patch at %d,%d exceeds LFB\n", x,y );
229       // No I_Error abort - what is up with TNT.WAD?
230       fprintf( stderr, "V_DrawPatch: bad patch (ignored)\n");
231       return;
232     }
233 #endif 
234  
235     if (!scrn)
236         V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
237
238     col = 0; 
239     desttop = screens[scrn]+y*SCREENWIDTH+x; 
240          
241     w = SHORT(patch->width); 
242
243     for ( ; col<w ; x++, col++, desttop++)
244     { 
245         column = (column_t *)((byte *)patch + LONG(patch->columnofs[col])); 
246  
247         // step through the posts in a column 
248         while (column->topdelta != 0xff ) 
249         { 
250             source = (byte *)column + 3; 
251             dest = desttop + column->topdelta*SCREENWIDTH; 
252             count = column->length; 
253                          
254             while (count--) 
255             { 
256                 *dest = *source++; 
257                 dest += SCREENWIDTH; 
258             } 
259             column = (column_t *)(  (byte *)column + column->length 
260                                     + 4 ); 
261         } 
262     }                    
263
264  
265 //
266 // V_DrawPatchFlipped 
267 // Masks a column based masked pic to the screen.
268 // Flips horizontally, e.g. to mirror face.
269 //
270 void
271 V_DrawPatchFlipped
272 ( int           x,
273   int           y,
274   int           scrn,
275   patch_t*      patch ) 
276
277
278     int         count;
279     int         col; 
280     column_t*   column; 
281     byte*       desttop;
282     byte*       dest;
283     byte*       source; 
284     int         w; 
285          
286     y -= SHORT(patch->topoffset); 
287     x -= SHORT(patch->leftoffset); 
288 #ifdef RANGECHECK 
289     if (x<0
290         ||x+SHORT(patch->width) >SCREENWIDTH
291         || y<0
292         || y+SHORT(patch->height)>SCREENHEIGHT 
293         || (unsigned)scrn>4)
294     {
295       fprintf( stderr, "Patch origin %d,%d exceeds LFB\n", x,y );
296       I_Error ("Bad V_DrawPatch in V_DrawPatchFlipped");
297     }
298 #endif 
299  
300     if (!scrn)
301         V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
302
303     col = 0; 
304     desttop = screens[scrn]+y*SCREENWIDTH+x; 
305          
306     w = SHORT(patch->width); 
307
308     for ( ; col<w ; x++, col++, desttop++) 
309     { 
310         column = (column_t *)((byte *)patch + LONG(patch->columnofs[w-1-col])); 
311  
312         // step through the posts in a column 
313         while (column->topdelta != 0xff ) 
314         { 
315             source = (byte *)column + 3; 
316             dest = desttop + column->topdelta*SCREENWIDTH; 
317             count = column->length; 
318                          
319             while (count--) 
320             { 
321                 *dest = *source++; 
322                 dest += SCREENWIDTH; 
323             } 
324             column = (column_t *)(  (byte *)column + column->length 
325                                     + 4 ); 
326         } 
327     }                    
328
329  
330
331
332 //
333 // V_DrawPatchDirect
334 // Draws directly to the screen on the pc. 
335 //
336 void
337 V_DrawPatchDirect
338 ( int           x,
339   int           y,
340   int           scrn,
341   patch_t*      patch ) 
342 {
343     V_DrawPatch (x,y,scrn, patch); 
344
345     /*
346     int         count;
347     int         col; 
348     column_t*   column; 
349     byte*       desttop;
350     byte*       dest;
351     byte*       source; 
352     int         w; 
353          
354     y -= SHORT(patch->topoffset); 
355     x -= SHORT(patch->leftoffset); 
356
357 #ifdef RANGECHECK 
358     if (x<0
359         ||x+SHORT(patch->width) >SCREENWIDTH
360         || y<0
361         || y+SHORT(patch->height)>SCREENHEIGHT 
362         || (unsigned)scrn>4)
363     {
364         I_Error ("Bad V_DrawPatchDirect");
365     }
366 #endif 
367  
368     //  V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); 
369     desttop = destscreen + y*SCREENWIDTH/4 + (x>>2); 
370          
371     w = SHORT(patch->width); 
372     for ( col = 0 ; col<w ; col++) 
373     { 
374         outp (SC_INDEX+1,1<<(x&3)); 
375         column = (column_t *)((byte *)patch + LONG(patch->columnofs[col])); 
376  
377         // step through the posts in a column 
378          
379         while (column->topdelta != 0xff ) 
380         { 
381             source = (byte *)column + 3; 
382             dest = desttop + column->topdelta*SCREENWIDTH/4; 
383             count = column->length; 
384  
385             while (count--) 
386             { 
387                 *dest = *source++; 
388                 dest += SCREENWIDTH/4; 
389             } 
390             column = (column_t *)(  (byte *)column + column->length 
391                                     + 4 ); 
392         } 
393         if ( ((++x)&3) == 0 ) 
394             desttop++;  // go to next byte, not next plane 
395     }*/ 
396
397  
398
399
400 //
401 // V_DrawBlock
402 // Draw a linear block of pixels into the view buffer.
403 //
404 void
405 V_DrawBlock
406 ( int           x,
407   int           y,
408   int           scrn,
409   int           width,
410   int           height,
411   byte*         src ) 
412
413     byte*       dest; 
414          
415 #ifdef RANGECHECK 
416     if (x<0
417         ||x+width >SCREENWIDTH
418         || y<0
419         || y+height>SCREENHEIGHT 
420         || (unsigned)scrn>4 )
421     {
422         I_Error ("Bad V_DrawBlock");
423     }
424 #endif 
425  
426     V_MarkRect (x, y, width, height); 
427  
428     dest = screens[scrn] + y*SCREENWIDTH+x; 
429
430     while (height--) 
431     { 
432         memcpy (dest, src, width); 
433         src += width; 
434         dest += SCREENWIDTH; 
435     } 
436
437  
438
439
440 //
441 // V_GetBlock
442 // Gets a linear block of pixels from the view buffer.
443 //
444 void
445 V_GetBlock
446 ( int           x,
447   int           y,
448   int           scrn,
449   int           width,
450   int           height,
451   byte*         dest ) 
452
453     byte*       src; 
454          
455 #ifdef RANGECHECK 
456     if (x<0
457         ||x+width >SCREENWIDTH
458         || y<0
459         || y+height>SCREENHEIGHT 
460         || (unsigned)scrn>4 )
461     {
462         I_Error ("Bad V_DrawBlock");
463     }
464 #endif 
465  
466     src = screens[scrn] + y*SCREENWIDTH+x; 
467
468     while (height--) 
469     { 
470         memcpy (dest, src, width); 
471         src += SCREENWIDTH; 
472         dest += width; 
473     } 
474
475
476
477
478
479 //
480 // V_Init
481 // 
482 void V_Init (void) 
483
484     int         i;
485     byte*       base;
486                 
487     // stick these in low dos memory on PCs
488
489     base = I_AllocLow (SCREENWIDTH*SCREENHEIGHT*4);
490
491     for (i=0 ; i<4 ; i++)
492         screens[i] = base + i*SCREENWIDTH*SCREENHEIGHT;
493 }