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