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
//	The actual span/column drawing functions.
21
//	Here find the main potential for optimization,
22
//	 e.g. inline assembly, different algorithms.
23
//
24
//-----------------------------------------------------------------------------
25
 
26
 
27
static const char
28
rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
29
 
30
 
31
#include "doomdef.h"
32
 
33
#include "i_system.h"
34
#include "z_zone.h"
35
#include "w_wad.h"
36
 
37
#include "r_local.h"
38
 
39
// Needs access to LFB (guess what).
40
#include "v_video.h"
41
 
42
// State.
43
#include "doomstat.h"
44
 
45
 
46
// ?
47
#define MAXWIDTH			1120
48
#define MAXHEIGHT			832
49
 
50
// status bar height at bottom of screen
51
#define SBARHEIGHT		32
52
 
53
//
54
// All drawing to the view buffer is accomplished in this file.
55
// The other refresh files only know about ccordinates,
56
//  not the architecture of the frame buffer.
57
// Conveniently, the frame buffer is a linear one,
58
//  and we need only the base address,
59
//  and the total size == width*height*depth/8.,
60
//
61
 
62
 
63
byte*		viewimage;
64
int		viewwidth;
65
int		scaledviewwidth;
66
int		viewheight;
67
int		viewwindowx;
68
int		viewwindowy;
69
byte*		ylookup[MAXHEIGHT];
70
int		columnofs[MAXWIDTH];
71
 
72
// Color tables for different players,
73
//  translate a limited part to another
74
//  (color ramps used for  suit colors).
75
//
76
byte		translations[3][256];
77
 
78
 
79
 
80
 
81
//
82
// R_DrawColumn
83
// Source is the top of the column to scale.
84
//
85
lighttable_t*		dc_colormap;
86
int			dc_x;
87
int			dc_yl;
88
int			dc_yh;
89
fixed_t			dc_iscale;
90
fixed_t			dc_texturemid;
91
 
92
// first pixel in a column (possibly virtual)
93
byte*			dc_source;
94
 
95
// just for profiling
96
int			dccount;
97
 
98
//
99
// A column is a vertical slice/span from a wall texture that,
100
//  given the DOOM style restrictions on the view orientation,
101
//  will always have constant z depth.
102
// Thus a special case loop for very fast rendering can
103
//  be used. It has also been used with Wolfenstein 3D.
104
//
105
void R_DrawColumn (void)
106
{
107
    int			count;
108
    byte*		dest;
109
    fixed_t		frac;
110
    fixed_t		fracstep;
111
 
112
    count = dc_yh - dc_yl;
113
 
114
    // Zero length, column does not exceed a pixel.
115
    if (count < 0)
116
	return;
117
 
118
#ifdef RANGECHECK
119
    if ((unsigned)dc_x >= SCREENWIDTH
120
	|| dc_yl < 0
121
	|| dc_yh >= SCREENHEIGHT)
122
	I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
123
#endif
124
 
125
    // Framebuffer destination address.
126
    // Use ylookup LUT to avoid multiply with ScreenWidth.
127
    // Use columnofs LUT for subwindows?
128
    dest = ylookup[dc_yl] + columnofs[dc_x];
129
 
130
    // Determine scaling,
131
    //  which is the only mapping to be done.
132
    fracstep = dc_iscale;
133
    frac = dc_texturemid + (dc_yl-centery)*fracstep;
134
 
135
    // Inner loop that does the actual texture mapping,
136
    //  e.g. a DDA-lile scaling.
137
    // This is as fast as it gets.
138
    do
139
    {
140
	// Re-map color indices from wall texture column
141
	//  using a lighting/special effects LUT.
142
	*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
143
 
144
	dest += SCREENWIDTH;
145
	frac += fracstep;
146
 
147
    } while (count--);
148
}
149
 
150
 
151
 
152
// UNUSED.
153
// Loop unrolled.
154
#if 0
155
void R_DrawColumn (void)
156
{
157
    int			count;
158
    byte*		source;
159
    byte*		dest;
160
    byte*		colormap;
161
 
162
    unsigned		frac;
163
    unsigned		fracstep;
164
    unsigned		fracstep2;
165
    unsigned		fracstep3;
166
    unsigned		fracstep4;
167
 
168
    count = dc_yh - dc_yl + 1;
169
 
170
    source = dc_source;
171
    colormap = dc_colormap;
172
    dest = ylookup[dc_yl] + columnofs[dc_x];
173
 
174
    fracstep = dc_iscale<<9;
175
    frac = (dc_texturemid + (dc_yl-centery)*dc_iscale)<<9;
176
 
177
    fracstep2 = fracstep+fracstep;
178
    fracstep3 = fracstep2+fracstep;
179
    fracstep4 = fracstep3+fracstep;
180
 
181
    while (count >= 8)
182
    {
183
	dest[0] = colormap[source[frac>>25]];
184
	dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]];
185
	dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]];
186
	dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]];
187
 
188
	frac += fracstep4;
189
 
190
	dest[SCREENWIDTH*4] = colormap[source[frac>>25]];
191
	dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]];
192
	dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]];
193
	dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]];
194
 
195
	frac += fracstep4;
196
	dest += SCREENWIDTH*8;
197
	count -= 8;
198
    }
199
 
200
    while (count > 0)
201
    {
202
	*dest = colormap[source[frac>>25]];
203
	dest += SCREENWIDTH;
204
	frac += fracstep;
205
	count--;
206
    }
207
}
208
#endif
209
 
210
 
211
void R_DrawColumnLow (void)
212
{
213
    int			count;
214
    byte*		dest;
215
    byte*		dest2;
216
    fixed_t		frac;
217
    fixed_t		fracstep;
218
 
219
    count = dc_yh - dc_yl;
220
 
221
    // Zero length.
222
    if (count < 0)
223
	return;
224
 
225
#ifdef RANGECHECK
226
    if ((unsigned)dc_x >= SCREENWIDTH
227
	|| dc_yl < 0
228
	|| dc_yh >= SCREENHEIGHT)
229
    {
230
 
231
	I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
232
    }
233
    //	dccount++;
234
#endif
235
    // Blocky mode, need to multiply by 2.
236
    dc_x <<= 1;
237
 
238
    dest = ylookup[dc_yl] + columnofs[dc_x];
239
    dest2 = ylookup[dc_yl] + columnofs[dc_x+1];
240
 
241
    fracstep = dc_iscale;
242
    frac = dc_texturemid + (dc_yl-centery)*fracstep;
243
 
244
    do
245
    {
246
	// Hack. Does not work corretly.
247
	*dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
248
	dest += SCREENWIDTH;
249
	dest2 += SCREENWIDTH;
250
	frac += fracstep;
251
 
252
    } while (count--);
253
}
254
 
255
 
256
//
257
// Spectre/Invisibility.
258
//
259
#define FUZZTABLE		50
260
#define FUZZOFF	(SCREENWIDTH)
261
 
262
 
263
int	fuzzoffset[FUZZTABLE] =
264
{
265
    FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
266
    FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
267
    FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
268
    FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
269
    FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
270
    FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
271
    FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
272
};
273
 
274
int	fuzzpos = 0;
275
 
276
 
277
//
278
// Framebuffer postprocessing.
279
// Creates a fuzzy image by copying pixels
280
//  from adjacent ones to left and right.
281
// Used with an all black colormap, this
282
//  could create the SHADOW effect,
283
//  i.e. spectres and invisible players.
284
//
285
void R_DrawFuzzColumn (void)
286
{
287
    int			count;
288
    byte*		dest;
289
    fixed_t		frac;
290
    fixed_t		fracstep;
291
 
292
    // Adjust borders. Low...
293
    if (!dc_yl)
294
	dc_yl = 1;
295
 
296
    // .. and high.
297
    if (dc_yh == viewheight-1)
298
	dc_yh = viewheight - 2;
299
 
300
    count = dc_yh - dc_yl;
301
 
302
    // Zero length.
303
    if (count < 0)
304
	return;
305
 
306
 
307
#ifdef RANGECHECK
308
    if ((unsigned)dc_x >= SCREENWIDTH
309
	|| dc_yl < 0 || dc_yh >= SCREENHEIGHT)
310
    {
311
	I_Error ("R_DrawFuzzColumn: %i to %i at %i",
312
		 dc_yl, dc_yh, dc_x);
313
    }
314
#endif
315
 
316
 
317
    // Keep till detailshift bug in blocky mode fixed,
318
    //  or blocky mode removed.
319
    /* WATCOM code
320
    if (detailshift)
321
    {
322
	if (dc_x & 1)
323
	{
324
	    outpw (GC_INDEX,GC_READMAP+(2<<8) );
325
	    outp (SC_INDEX+1,12);
326
	}
327
	else
328
	{
329
	    outpw (GC_INDEX,GC_READMAP);
330
	    outp (SC_INDEX+1,3);
331
	}
332
	dest = destview + dc_yl*80 + (dc_x>>1);
333
    }
334
    else
335
    {
336
	outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) );
337
	outp (SC_INDEX+1,1<<(dc_x&3));
338
	dest = destview + dc_yl*80 + (dc_x>>2);
339
    }*/
340
 
341
 
342
    // Does not work with blocky mode.
343
    dest = ylookup[dc_yl] + columnofs[dc_x];
344
 
345
    // Looks familiar.
346
    fracstep = dc_iscale;
347
    frac = dc_texturemid + (dc_yl-centery)*fracstep;
348
 
349
    // Looks like an attempt at dithering,
350
    //  using the colormap #6 (of 0-31, a bit
351
    //  brighter than average).
352
    do
353
    {
354
	// Lookup framebuffer, and retrieve
355
	//  a pixel that is either one column
356
	//  left or right of the current one.
357
	// Add index from colormap to index.
358
	*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
359
 
360
	// Clamp table lookup index.
361
	if (++fuzzpos == FUZZTABLE)
362
	    fuzzpos = 0;
363
 
364
	dest += SCREENWIDTH;
365
 
366
	frac += fracstep;
367
    } while (count--);
368
}
369
 
370
 
371
 
372
 
373
//
374
// R_DrawTranslatedColumn
375
// Used to draw player sprites
376
//  with the green colorramp mapped to others.
377
// Could be used with different translation
378
//  tables, e.g. the lighter colored version
379
//  of the BaronOfHell, the HellKnight, uses
380
//  identical sprites, kinda brightened up.
381
//
382
byte*	dc_translation;
383
byte*	translationtables;
384
 
385
void R_DrawTranslatedColumn (void)
386
{
387
    int			count;
388
    byte*		dest;
389
    fixed_t		frac;
390
    fixed_t		fracstep;
391
 
392
    count = dc_yh - dc_yl;
393
    if (count < 0)
394
	return;
395
 
396
#ifdef RANGECHECK
397
    if ((unsigned)dc_x >= SCREENWIDTH
398
	|| dc_yl < 0
399
	|| dc_yh >= SCREENHEIGHT)
400
    {
401
	I_Error ( "R_DrawColumn: %i to %i at %i",
402
		  dc_yl, dc_yh, dc_x);
403
    }
404
 
405
#endif
406
 
407
 
408
    // WATCOM VGA specific.
409
    /* Keep for fixing.
410
    if (detailshift)
411
    {
412
	if (dc_x & 1)
413
	    outp (SC_INDEX+1,12);
414
	else
415
	    outp (SC_INDEX+1,3);
416
 
417
	dest = destview + dc_yl*80 + (dc_x>>1);
418
    }
419
    else
420
    {
421
	outp (SC_INDEX+1,1<<(dc_x&3));
422
 
423
	dest = destview + dc_yl*80 + (dc_x>>2);
424
    }*/
425
 
426
 
427
    // FIXME. As above.
428
    dest = ylookup[dc_yl] + columnofs[dc_x];
429
 
430
    // Looks familiar.
431
    fracstep = dc_iscale;
432
    frac = dc_texturemid + (dc_yl-centery)*fracstep;
433
 
434
    // Here we do an additional index re-mapping.
435
    do
436
    {
437
	// Translation tables are used
438
	//  to map certain colorramps to other ones,
439
	//  used with PLAY sprites.
440
	// Thus the "green" ramp of the player 0 sprite
441
	//  is mapped to gray, red, black/indigo.
442
	*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
443
	dest += SCREENWIDTH;
444
 
445
	frac += fracstep;
446
    } while (count--);
447
}
448
 
449
 
450
 
451
 
452
//
453
// R_InitTranslationTables
454
// Creates the translation tables to map
455
//  the green color ramp to gray, brown, red.
456
// Assumes a given structure of the PLAYPAL.
457
// Could be read from a lump instead.
458
//
459
void R_InitTranslationTables (void)
460
{
461
    int		i;
462
 
463
    translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
464
    translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
465
 
466
    // translate just the 16 green colors
467
    for (i=0 ; i<256 ; i++)
468
    {
469
	if (i >= 0x70 && i<= 0x7f)
470
	{
471
	    // map green ramp to gray, brown, red
472
	    translationtables[i] = 0x60 + (i&0xf);
473
	    translationtables [i+256] = 0x40 + (i&0xf);
474
	    translationtables [i+512] = 0x20 + (i&0xf);
475
	}
476
	else
477
	{
478
	    // Keep all other colors as is.
479
	    translationtables[i] = translationtables[i+256]
480
		= translationtables[i+512] = i;
481
	}
482
    }
483
}
484
 
485
 
486
 
487
 
488
//
489
// R_DrawSpan
490
// With DOOM style restrictions on view orientation,
491
//  the floors and ceilings consist of horizontal slices
492
//  or spans with constant z depth.
493
// However, rotation around the world z axis is possible,
494
//  thus this mapping, while simpler and faster than
495
//  perspective correct texture mapping, has to traverse
496
//  the texture at an angle in all but a few cases.
497
// In consequence, flats are not stored by column (like walls),
498
//  and the inner loop has to step in texture space u and v.
499
//
500
int			ds_y;
501
int			ds_x1;
502
int			ds_x2;
503
 
504
lighttable_t*		ds_colormap;
505
 
506
fixed_t			ds_xfrac;
507
fixed_t			ds_yfrac;
508
fixed_t			ds_xstep;
509
fixed_t			ds_ystep;
510
 
511
// start of a 64*64 tile image
512
byte*			ds_source;
513
 
514
// just for profiling
515
int			dscount;
516
 
517
 
518
//
519
// Draws the actual span.
520
void R_DrawSpan (void)
521
{
522
    fixed_t		xfrac;
523
    fixed_t		yfrac;
524
    byte*		dest;
525
    int			count;
526
    int			spot;
527
 
528
#ifdef RANGECHECK
529
    if (ds_x2 < ds_x1
530
	|| ds_x1<0
531
	|| ds_x2>=SCREENWIDTH
532
	|| (unsigned)ds_y>SCREENHEIGHT)
533
    {
534
	I_Error( "R_DrawSpan: %i to %i at %i",
535
		 ds_x1,ds_x2,ds_y);
536
    }
537
//	dscount++;
538
#endif
539
 
540
 
541
    xfrac = ds_xfrac;
542
    yfrac = ds_yfrac;
543
 
544
    dest = ylookup[ds_y] + columnofs[ds_x1];
545
 
546
    // We do not check for zero spans here?
547
    count = ds_x2 - ds_x1;
548
 
549
    do
550
    {
551
	// Current texture index in u,v.
552
	spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
553
 
554
	// Lookup pixel from flat texture tile,
555
	//  re-index using light/colormap.
556
	*dest++ = ds_colormap[ds_source[spot]];
557
 
558
	// Next step in u,v.
559
	xfrac += ds_xstep;
560
	yfrac += ds_ystep;
561
 
562
    } while (count--);
563
}
564
 
565
 
566
 
567
// UNUSED.
568
// Loop unrolled by 4.
569
#if 0
570
void R_DrawSpan (void)
571
{
572
    unsigned	position, step;
573
 
574
    byte*	source;
575
    byte*	colormap;
576
    byte*	dest;
577
 
578
    unsigned	count;
579
    usingned	spot;
580
    unsigned	value;
581
    unsigned	temp;
582
    unsigned	xtemp;
583
    unsigned	ytemp;
584
 
585
    position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
586
    step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
587
 
588
    source = ds_source;
589
    colormap = ds_colormap;
590
    dest = ylookup[ds_y] + columnofs[ds_x1];
591
    count = ds_x2 - ds_x1 + 1;
592
 
593
    while (count >= 4)
594
    {
595
	ytemp = position>>4;
596
	ytemp = ytemp & 4032;
597
	xtemp = position>>26;
598
	spot = xtemp | ytemp;
599
	position += step;
600
	dest[0] = colormap[source[spot]];
601
 
602
	ytemp = position>>4;
603
	ytemp = ytemp & 4032;
604
	xtemp = position>>26;
605
	spot = xtemp | ytemp;
606
	position += step;
607
	dest[1] = colormap[source[spot]];
608
 
609
	ytemp = position>>4;
610
	ytemp = ytemp & 4032;
611
	xtemp = position>>26;
612
	spot = xtemp | ytemp;
613
	position += step;
614
	dest[2] = colormap[source[spot]];
615
 
616
	ytemp = position>>4;
617
	ytemp = ytemp & 4032;
618
	xtemp = position>>26;
619
	spot = xtemp | ytemp;
620
	position += step;
621
	dest[3] = colormap[source[spot]];
622
 
623
	count -= 4;
624
	dest += 4;
625
    }
626
    while (count > 0)
627
    {
628
	ytemp = position>>4;
629
	ytemp = ytemp & 4032;
630
	xtemp = position>>26;
631
	spot = xtemp | ytemp;
632
	position += step;
633
	*dest++ = colormap[source[spot]];
634
	count--;
635
    }
636
}
637
#endif
638
 
639
 
640
//
641
// Again..
642
//
643
void R_DrawSpanLow (void)
644
{
645
    fixed_t		xfrac;
646
    fixed_t		yfrac;
647
    byte*		dest;
648
    int			count;
649
    int			spot;
650
 
651
#ifdef RANGECHECK
652
    if (ds_x2 < ds_x1
653
	|| ds_x1<0
654
	|| ds_x2>=SCREENWIDTH
655
	|| (unsigned)ds_y>SCREENHEIGHT)
656
    {
657
	I_Error( "R_DrawSpan: %i to %i at %i",
658
		 ds_x1,ds_x2,ds_y);
659
    }
660
//	dscount++;
661
#endif
662
 
663
    xfrac = ds_xfrac;
664
    yfrac = ds_yfrac;
665
 
666
    // Blocky mode, need to multiply by 2.
667
    ds_x1 <<= 1;
668
    ds_x2 <<= 1;
669
 
670
    dest = ylookup[ds_y] + columnofs[ds_x1];
671
 
672
 
673
    count = ds_x2 - ds_x1;
674
    do
675
    {
676
	spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
677
	// Lowres/blocky mode does it twice,
678
	//  while scale is adjusted appropriately.
679
	*dest++ = ds_colormap[ds_source[spot]];
680
	*dest++ = ds_colormap[ds_source[spot]];
681
 
682
	xfrac += ds_xstep;
683
	yfrac += ds_ystep;
684
 
685
    } while (count--);
686
}
687
 
688
//
689
// R_InitBuffer
690
// Creats lookup tables that avoid
691
//  multiplies and other hazzles
692
//  for getting the framebuffer address
693
//  of a pixel to draw.
694
//
695
void
696
R_InitBuffer
697
( int		width,
698
  int		height )
699
{
700
    int		i;
701
 
702
    // Handle resize,
703
    //  e.g. smaller view windows
704
    //  with border and/or status bar.
705
    viewwindowx = (SCREENWIDTH-width) >> 1;
706
 
707
    // Column offset. For windows.
708
    for (i=0 ; i
709
	columnofs[i] = viewwindowx + i;
710
 
711
    // Samw with base row offset.
712
    if (width == SCREENWIDTH)
713
	viewwindowy = 0;
714
    else
715
	viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
716
 
717
    // Preclaculate all row offsets.
718
    for (i=0 ; i
719
	ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH;
720
}
721
 
722
 
723
 
724
 
725
//
726
// R_FillBackScreen
727
// Fills the back screen with a pattern
728
//  for variable screen sizes
729
// Also draws a beveled edge.
730
//
731
void R_FillBackScreen (void)
732
{
733
    byte*	src;
734
    byte*	dest;
735
    int		x;
736
    int		y;
737
    patch_t*	patch;
738
 
739
    // DOOM border patch.
740
    char	name1[] = "FLOOR7_2";
741
 
742
    // DOOM II border patch.
743
    char	name2[] = "GRNROCK";
744
 
745
    char*	name;
746
 
747
    if (scaledviewwidth == 320)
748
	return;
749
 
750
    if ( gamemode == commercial)
751
	name = name2;
752
    else
753
	name = name1;
754
 
755
    src = W_CacheLumpName (name, PU_CACHE);
756
    dest = screens[1];
757
 
758
    for (y=0 ; y
759
    {
760
	for (x=0 ; x
761
	{
762
	    memcpy (dest, src+((y&63)<<6), 64);
763
	    dest += 64;
764
	}
765
 
766
	if (SCREENWIDTH&63)
767
	{
768
	    memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
769
	    dest += (SCREENWIDTH&63);
770
	}
771
    }
772
 
773
    patch = W_CacheLumpName ("brdr_t",PU_CACHE);
774
 
775
    for (x=0 ; x
776
	V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
777
    patch = W_CacheLumpName ("brdr_b",PU_CACHE);
778
 
779
    for (x=0 ; x
780
	V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
781
    patch = W_CacheLumpName ("brdr_l",PU_CACHE);
782
 
783
    for (y=0 ; y
784
	V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
785
    patch = W_CacheLumpName ("brdr_r",PU_CACHE);
786
 
787
    for (y=0 ; y
788
	V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
789
 
790
 
791
    // Draw beveled edge.
792
    V_DrawPatch (viewwindowx-8,
793
		 viewwindowy-8,
794
		 1,
795
		 W_CacheLumpName ("brdr_tl",PU_CACHE));
796
 
797
    V_DrawPatch (viewwindowx+scaledviewwidth,
798
		 viewwindowy-8,
799
		 1,
800
		 W_CacheLumpName ("brdr_tr",PU_CACHE));
801
 
802
    V_DrawPatch (viewwindowx-8,
803
		 viewwindowy+viewheight,
804
		 1,
805
		 W_CacheLumpName ("brdr_bl",PU_CACHE));
806
 
807
    V_DrawPatch (viewwindowx+scaledviewwidth,
808
		 viewwindowy+viewheight,
809
		 1,
810
		 W_CacheLumpName ("brdr_br",PU_CACHE));
811
}
812
 
813
 
814
//
815
// Copy a screen buffer.
816
//
817
void
818
R_VideoErase
819
( unsigned	ofs,
820
  int		count )
821
{
822
  // LFB copy.
823
  // This might not be a good idea if memcpy
824
  //  is not optiomal, e.g. byte by byte on
825
  //  a 32bit CPU, as GNU GCC/Linux libc did
826
  //  at one point.
827
    memcpy (screens[0]+ofs, screens[1]+ofs, count);
828
}
829
 
830
 
831
//
832
// R_DrawViewBorder
833
// Draws the border around the view
834
//  for different size windows?
835
//
836
void
837
V_MarkRect
838
( int		x,
839
  int		y,
840
  int		width,
841
  int		height );
842
 
843
void R_DrawViewBorder (void)
844
{
845
    int		top;
846
    int		side;
847
    int		ofs;
848
    int		i;
849
 
850
    if (scaledviewwidth == SCREENWIDTH)
851
	return;
852
 
853
    top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2;
854
    side = (SCREENWIDTH-scaledviewwidth)/2;
855
 
856
    // copy top and one line of left side
857
    R_VideoErase (0, top*SCREENWIDTH+side);
858
 
859
    // copy one line of right side and bottom
860
    ofs = (viewheight+top)*SCREENWIDTH-side;
861
    R_VideoErase (ofs, top*SCREENWIDTH+side);
862
 
863
    // copy sides using wraparound
864
    ofs = top*SCREENWIDTH + SCREENWIDTH-side;
865
    side <<= 1;
866
 
867
    for (i=1 ; i
868
    {
869
	R_VideoErase (ofs, side);
870
	ofs += SCREENWIDTH;
871
    }
872
 
873
    // ?
874
    V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT);
875
}
876
 
877