Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 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 "m_swap.h"
32
#include "i_system.h"
33
#include "r_local.h"
34
 
35
#include "doomdef.h"
36
#include "doomdata.h"
37
 
38
#include "m_bbox.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
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
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
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 = _aligned_malloc(SCREENWIDTH*SCREENHEIGHT*4, 128);I_AllocLow (SCREENWIDTH*SCREENHEIGHT*4);
490
 
491
    for (i=0 ; i<4 ; i++)
492
	screens[i] = base + i*SCREENWIDTH*SCREENHEIGHT;
493
}