diff options
Diffstat (limited to 'apps/plugins/doom/r_draw.c')
-rw-r--r-- | apps/plugins/doom/r_draw.c | 677 |
1 files changed, 677 insertions, 0 deletions
diff --git a/apps/plugins/doom/r_draw.c b/apps/plugins/doom/r_draw.c new file mode 100644 index 0000000000..df682776cd --- /dev/null +++ b/apps/plugins/doom/r_draw.c | |||
@@ -0,0 +1,677 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
25 | * 02111-1307, USA. | ||
26 | * | ||
27 | * DESCRIPTION: | ||
28 | * The actual span/column drawing functions. | ||
29 | * Here find the main potential for optimization, | ||
30 | * e.g. inline assembly, different algorithms. | ||
31 | * | ||
32 | *-----------------------------------------------------------------------------*/ | ||
33 | |||
34 | #include "doomstat.h" | ||
35 | #include "w_wad.h" | ||
36 | #include "r_main.h" | ||
37 | #include "v_video.h" | ||
38 | #include "st_stuff.h" | ||
39 | #include "g_game.h" | ||
40 | #include "am_map.h" | ||
41 | //#include "lprintf.h" | ||
42 | #include "rockmacros.h" | ||
43 | |||
44 | #define MAXWIDTH 1120 | ||
45 | #define MAXHEIGHT 832 | ||
46 | |||
47 | // status bar height at bottom of screen | ||
48 | #define SBARHEIGHT 32 | ||
49 | |||
50 | // | ||
51 | // All drawing to the view buffer is accomplished in this file. | ||
52 | // The other refresh files only know about ccordinates, | ||
53 | // not the architecture of the frame buffer. | ||
54 | // Conveniently, the frame buffer is a linear one, | ||
55 | // and we need only the base address, | ||
56 | // and the total size == width*height*depth/8., | ||
57 | // | ||
58 | |||
59 | //byte* viewimage; | ||
60 | int viewwidth; | ||
61 | int scaledviewwidth; | ||
62 | int viewheight; | ||
63 | int viewwindowx; | ||
64 | int viewwindowy; | ||
65 | |||
66 | byte *topleft IBSS_ATTR; | ||
67 | |||
68 | // Color tables for different players, | ||
69 | // translate a limited part to another | ||
70 | // (color ramps used for suit colors). | ||
71 | // | ||
72 | |||
73 | // CPhipps - made const*'s | ||
74 | const byte *tranmap IBSS_ATTR; // translucency filter maps 256x256 // phares | ||
75 | const byte *main_tranmap IBSS_ATTR; // killough 4/11/98 | ||
76 | |||
77 | // | ||
78 | // R_DrawColumn | ||
79 | // Source is the top of the column to scale. | ||
80 | // | ||
81 | |||
82 | lighttable_t *dc_colormap IBSS_ATTR; | ||
83 | int dc_x IBSS_ATTR; | ||
84 | int dc_yl IBSS_ATTR; | ||
85 | int dc_yh IBSS_ATTR; | ||
86 | fixed_t dc_iscale IBSS_ATTR; | ||
87 | fixed_t dc_texturemid IBSS_ATTR; | ||
88 | int dc_texheight IBSS_ATTR; // killough | ||
89 | const byte *dc_source IBSS_ATTR; // first pixel in a column (possibly virtual) | ||
90 | |||
91 | |||
92 | // | ||
93 | // A column is a vertical slice/span from a wall texture that, | ||
94 | // given the DOOM style restrictions on the view orientation, | ||
95 | // will always have constant z depth. | ||
96 | // Thus a special case loop for very fast rendering can | ||
97 | // be used. It has also been used with Wolfenstein 3D. | ||
98 | // | ||
99 | void R_DrawColumn (void) | ||
100 | { | ||
101 | int count; | ||
102 | register byte *dest; // killough | ||
103 | register fixed_t frac; // killough | ||
104 | |||
105 | // leban 1/17/99: | ||
106 | // removed the + 1 here, adjusted the if test, and added an increment | ||
107 | // later. this helps a compiler pipeline a bit better. the x86 | ||
108 | // assembler also does this. | ||
109 | count = dc_yh - dc_yl; | ||
110 | |||
111 | // Zero length, column does not exceed a pixel. | ||
112 | if (count < 0) | ||
113 | return; | ||
114 | |||
115 | #ifdef RANGECHECK | ||
116 | if ((unsigned)dc_x >= SCREENWIDTH | ||
117 | || dc_yl < 0 | ||
118 | || dc_yh >= SCREENHEIGHT) | ||
119 | I_Error ("R_DrawColumn: %d to %d at %d", dc_yl, dc_yh, dc_x); | ||
120 | #endif | ||
121 | |||
122 | count++; | ||
123 | |||
124 | // Framebuffer destination address. | ||
125 | dest = topleft + dc_yl*SCREENWIDTH + dc_x; | ||
126 | |||
127 | // Determine scaling, | ||
128 | // which is the only mapping to be done. | ||
129 | #define fracstep dc_iscale | ||
130 | frac = dc_texturemid + (dc_yl-centery)*fracstep; | ||
131 | |||
132 | // Inner loop that does the actual texture mapping, | ||
133 | // e.g. a DDA-lile scaling. | ||
134 | // This is as fast as it gets. (Yeah, right!!! -- killough) | ||
135 | // | ||
136 | // killough 2/1/98: more performance tuning | ||
137 | |||
138 | if (dc_texheight == 128) { | ||
139 | while(count--) | ||
140 | { | ||
141 | *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; | ||
142 | frac += fracstep; | ||
143 | dest += SCREENWIDTH; | ||
144 | } | ||
145 | } else if (dc_texheight == 0) { | ||
146 | /* cph - another special case */ | ||
147 | while (count--) { | ||
148 | *dest = dc_colormap[dc_source[frac>>FRACBITS]]; | ||
149 | frac += fracstep; | ||
150 | dest += SCREENWIDTH; | ||
151 | } | ||
152 | } else { | ||
153 | register unsigned heightmask = dc_texheight-1; // CPhipps - specify type | ||
154 | if (! (dc_texheight & heightmask) ) // power of 2 -- killough | ||
155 | { | ||
156 | while (count>0) // texture height is a power of 2 -- killough | ||
157 | { | ||
158 | *dest = dc_colormap[dc_source[(frac>>FRACBITS) & heightmask]]; | ||
159 | dest += SCREENWIDTH; | ||
160 | frac += fracstep; | ||
161 | count--; | ||
162 | } | ||
163 | } | ||
164 | else | ||
165 | { | ||
166 | heightmask++; | ||
167 | heightmask <<= FRACBITS; | ||
168 | |||
169 | if (frac < 0) | ||
170 | while ((frac += heightmask) < 0); | ||
171 | else | ||
172 | while (frac >= (int)heightmask) | ||
173 | frac -= heightmask; | ||
174 | |||
175 | while(count>0) | ||
176 | { | ||
177 | // Re-map color indices from wall texture column | ||
178 | // using a lighting/special effects LUT. | ||
179 | |||
180 | // heightmask is the Tutti-Frutti fix -- killough | ||
181 | |||
182 | *dest = dc_colormap[dc_source[frac>>FRACBITS]]; | ||
183 | dest += SCREENWIDTH; | ||
184 | if ((frac += fracstep) >= (int)heightmask) | ||
185 | frac -= heightmask; | ||
186 | count--; | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | #undef fracstep | ||
192 | |||
193 | // Here is the version of R_DrawColumn that deals with translucent // phares | ||
194 | // textures and sprites. It's identical to R_DrawColumn except // | | ||
195 | // for the spot where the color index is stuffed into *dest. At // V | ||
196 | // that point, the existing color index and the new color index | ||
197 | // are mapped through the TRANMAP lump filters to get a new color | ||
198 | // index whose RGB values are the average of the existing and new | ||
199 | // colors. | ||
200 | // | ||
201 | // Since we're concerned about performance, the 'translucent or | ||
202 | // opaque' decision is made outside this routine, not down where the | ||
203 | // actual code differences are. | ||
204 | |||
205 | void R_DrawTLColumn (void) | ||
206 | { | ||
207 | int count; | ||
208 | register byte *dest; // killough | ||
209 | register fixed_t frac; // killough | ||
210 | |||
211 | count = dc_yh - dc_yl + 1; | ||
212 | |||
213 | // Zero length, column does not exceed a pixel. | ||
214 | if (count <= 0) | ||
215 | return; | ||
216 | |||
217 | #ifdef RANGECHECK | ||
218 | if ((unsigned)dc_x >= (unsigned)SCREENWIDTH | ||
219 | || dc_yl < 0 | ||
220 | || dc_yh >= SCREENHEIGHT) | ||
221 | I_Error("R_DrawTLColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); | ||
222 | #endif | ||
223 | |||
224 | // Framebuffer destination address. | ||
225 | dest = topleft + dc_yl*SCREENWIDTH + dc_x; | ||
226 | |||
227 | // Determine scaling, | ||
228 | // which is the only mapping to be done. | ||
229 | #define fracstep dc_iscale | ||
230 | frac = dc_texturemid + (dc_yl-centery)*fracstep; | ||
231 | |||
232 | // Inner loop that does the actual texture mapping, | ||
233 | // e.g. a DDA-lile scaling. | ||
234 | // This is as fast as it gets. (Yeah, right!!! -- killough) | ||
235 | // | ||
236 | // killough 2/1/98, 2/21/98: more performance tuning | ||
237 | |||
238 | { | ||
239 | register const byte *source = dc_source; | ||
240 | register const lighttable_t *colormap = dc_colormap; | ||
241 | register unsigned heightmask = dc_texheight-1; // CPhipps - specify type | ||
242 | if (dc_texheight & heightmask) // not a power of 2 -- killough | ||
243 | { | ||
244 | heightmask++; | ||
245 | heightmask <<= FRACBITS; | ||
246 | |||
247 | if (frac < 0) | ||
248 | while ((frac += heightmask) < 0); | ||
249 | else | ||
250 | while (frac >= (int)heightmask) | ||
251 | frac -= heightmask; | ||
252 | |||
253 | do | ||
254 | { | ||
255 | // Re-map color indices from wall texture column | ||
256 | // using a lighting/special effects LUT. | ||
257 | |||
258 | // heightmask is the Tutti-Frutti fix -- killough | ||
259 | |||
260 | *dest = tranmap[(*dest<<8)+colormap[source[frac>>FRACBITS]]]; // phares | ||
261 | dest += SCREENWIDTH; | ||
262 | if ((frac += fracstep) >= (int)heightmask) | ||
263 | frac -= heightmask; | ||
264 | } | ||
265 | while (--count); | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | while ((count-=2)>=0) // texture height is a power of 2 -- killough | ||
270 | { | ||
271 | *dest = tranmap[(*dest<<8)+colormap[source[(frac>>FRACBITS) & heightmask]]]; // phares | ||
272 | dest += SCREENWIDTH; | ||
273 | frac += fracstep; | ||
274 | *dest = tranmap[(*dest<<8)+colormap[source[(frac>>FRACBITS) & heightmask]]]; // phares | ||
275 | dest += SCREENWIDTH; | ||
276 | frac += fracstep; | ||
277 | } | ||
278 | if (count & 1) | ||
279 | *dest = tranmap[(*dest<<8)+colormap[source[(frac>>FRACBITS) & heightmask]]]; // phares | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | #undef fracstep | ||
284 | |||
285 | // | ||
286 | // Spectre/Invisibility. | ||
287 | // | ||
288 | |||
289 | #define FUZZTABLE 50 | ||
290 | // proff 08/17/98: Changed for high-res | ||
291 | //#define FUZZOFF (SCREENWIDTH) | ||
292 | #define FUZZOFF 1 | ||
293 | |||
294 | static const int fuzzoffset_org[FUZZTABLE] ICONST_ATTR = { | ||
295 | FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, | ||
296 | FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, | ||
297 | FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF, | ||
298 | FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, | ||
299 | FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF, | ||
300 | FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF, | ||
301 | FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF | ||
302 | } ; | ||
303 | |||
304 | static int fuzzoffset[FUZZTABLE] IBSS_ATTR; | ||
305 | |||
306 | static int fuzzpos IBSS_ATTR = 0; | ||
307 | |||
308 | // | ||
309 | // Framebuffer postprocessing. | ||
310 | // Creates a fuzzy image by copying pixels | ||
311 | // from adjacent ones to left and right. | ||
312 | // Used with an all black colormap, this | ||
313 | // could create the SHADOW effect, | ||
314 | // i.e. spectres and invisible players. | ||
315 | // | ||
316 | |||
317 | void R_DrawFuzzColumn(void) | ||
318 | { | ||
319 | int count; | ||
320 | byte *dest; | ||
321 | fixed_t frac; | ||
322 | fixed_t fracstep; | ||
323 | |||
324 | // Adjust borders. Low... | ||
325 | if (!dc_yl) | ||
326 | dc_yl = 1; | ||
327 | |||
328 | // .. and high. | ||
329 | if (dc_yh == viewheight-1) | ||
330 | dc_yh = viewheight - 2; | ||
331 | |||
332 | count = dc_yh - dc_yl; | ||
333 | |||
334 | // Zero length. | ||
335 | if (count < 0) | ||
336 | return; | ||
337 | |||
338 | #ifdef RANGECHECK | ||
339 | if ((unsigned) dc_x >= (unsigned)SCREENWIDTH | ||
340 | || dc_yl < 0 | ||
341 | || (unsigned)dc_yh >= (unsigned)SCREENHEIGHT) | ||
342 | I_Error("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); | ||
343 | #endif | ||
344 | |||
345 | // Keep till detailshift bug in blocky mode fixed, | ||
346 | // or blocky mode removed. | ||
347 | |||
348 | // Does not work with blocky mode. | ||
349 | dest = topleft + dc_yl*SCREENWIDTH + dc_x; | ||
350 | |||
351 | // Looks familiar. | ||
352 | fracstep = dc_iscale; | ||
353 | frac = dc_texturemid + (dc_yl-centery)*fracstep; | ||
354 | |||
355 | // Looks like an attempt at dithering, | ||
356 | // using the colormap #6 (of 0-31, a bit brighter than average). | ||
357 | |||
358 | do | ||
359 | { | ||
360 | // Lookup framebuffer, and retrieve | ||
361 | // a pixel that is either one column | ||
362 | // left or right of the current one. | ||
363 | // Add index from colormap to index. | ||
364 | // killough 3/20/98: use fullcolormap instead of colormaps | ||
365 | |||
366 | *dest = fullcolormap[6*256+dest[fuzzoffset[fuzzpos]]]; | ||
367 | |||
368 | // Some varying invisibility effects can be gotten by playing // phares | ||
369 | // with this logic. For example, try // phares | ||
370 | // // phares | ||
371 | // *dest = fullcolormap[0*256+dest[FUZZOFF]]; // phares | ||
372 | |||
373 | // Clamp table lookup index. | ||
374 | if (++fuzzpos == FUZZTABLE) | ||
375 | fuzzpos = 0; | ||
376 | |||
377 | dest += SCREENWIDTH; | ||
378 | |||
379 | frac += fracstep; | ||
380 | } while (count--); | ||
381 | } | ||
382 | |||
383 | // | ||
384 | // R_DrawTranslatedColumn | ||
385 | // Used to draw player sprites | ||
386 | // with the green colorramp mapped to others. | ||
387 | // Could be used with different translation | ||
388 | // tables, e.g. the lighter colored version | ||
389 | // of the BaronOfHell, the HellKnight, uses | ||
390 | // identical sprites, kinda brightened up. | ||
391 | // | ||
392 | |||
393 | byte *dc_translation, *translationtables; | ||
394 | |||
395 | void R_DrawTranslatedColumn (void) | ||
396 | { | ||
397 | int count; | ||
398 | byte *dest; | ||
399 | fixed_t frac; | ||
400 | fixed_t fracstep; | ||
401 | |||
402 | count = dc_yh - dc_yl; | ||
403 | if (count < 0) | ||
404 | return; | ||
405 | |||
406 | #ifdef RANGECHECK | ||
407 | if ((unsigned)dc_x >= (unsigned)SCREENWIDTH | ||
408 | || dc_yl < 0 | ||
409 | || (unsigned)dc_yh >= (unsigned)SCREENHEIGHT) | ||
410 | I_Error("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); | ||
411 | #endif | ||
412 | |||
413 | // FIXME. As above. | ||
414 | dest = topleft + dc_yl*SCREENWIDTH + dc_x; | ||
415 | |||
416 | // Looks familiar. | ||
417 | fracstep = dc_iscale; | ||
418 | frac = dc_texturemid + (dc_yl-centery)*fracstep; | ||
419 | |||
420 | // Here we do an additional index re-mapping. | ||
421 | do | ||
422 | { | ||
423 | // Translation tables are used | ||
424 | // to map certain colorramps to other ones, | ||
425 | // used with PLAY sprites. | ||
426 | // Thus the "green" ramp of the player 0 sprite | ||
427 | // is mapped to gray, red, black/indigo. | ||
428 | |||
429 | *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; | ||
430 | dest += SCREENWIDTH; | ||
431 | |||
432 | frac += fracstep; | ||
433 | } | ||
434 | while (count--); | ||
435 | } | ||
436 | |||
437 | // | ||
438 | // R_InitTranslationTables | ||
439 | // Creates the translation tables to map | ||
440 | // the green color ramp to gray, brown, red. | ||
441 | // Assumes a given structure of the PLAYPAL. | ||
442 | // Could be read from a lump instead. | ||
443 | // | ||
444 | |||
445 | byte playernumtotrans[MAXPLAYERS]; | ||
446 | extern lighttable_t *(*c_zlight)[LIGHTLEVELS][MAXLIGHTZ]; | ||
447 | |||
448 | void R_InitTranslationTables (void) | ||
449 | { | ||
450 | int i, j; | ||
451 | #define MAXTRANS 3 | ||
452 | byte transtocolour[MAXTRANS]; | ||
453 | |||
454 | // killough 5/2/98: | ||
455 | // Remove dependency of colormaps aligned on 256-byte boundary | ||
456 | |||
457 | if (translationtables == NULL) // CPhipps - allow multiple calls | ||
458 | translationtables = Z_Malloc(256*MAXTRANS, PU_STATIC, 0); | ||
459 | |||
460 | for (i=0; i<MAXTRANS; i++) transtocolour[i] = 255; | ||
461 | |||
462 | for (i=0; i<MAXPLAYERS; i++) { | ||
463 | byte wantcolour = mapcolor_plyr[i]; | ||
464 | playernumtotrans[i] = 0; | ||
465 | if (wantcolour != 0x70) // Not green, would like translation | ||
466 | for (j=0; j<MAXTRANS; j++) | ||
467 | if (transtocolour[j] == 255) { | ||
468 | transtocolour[j] = wantcolour; playernumtotrans[i] = j+1; break; | ||
469 | } | ||
470 | } | ||
471 | |||
472 | // translate just the 16 green colors | ||
473 | for (i=0; i<256; i++) | ||
474 | if (i >= 0x70 && i<= 0x7f) | ||
475 | { | ||
476 | // CPhipps - configurable player colours | ||
477 | translationtables[i] = colormaps[0][((i&0xf)<<9) + transtocolour[0]]; | ||
478 | translationtables[i+256] = colormaps[0][((i&0xf)<<9) + transtocolour[1]]; | ||
479 | translationtables[i+512] = colormaps[0][((i&0xf)<<9) + transtocolour[2]]; | ||
480 | } | ||
481 | else // Keep all other colors as is. | ||
482 | translationtables[i]=translationtables[i+256]=translationtables[i+512]=i; | ||
483 | } | ||
484 | |||
485 | // | ||
486 | // R_DrawSpan | ||
487 | // With DOOM style restrictions on view orientation, | ||
488 | // the floors and ceilings consist of horizontal slices | ||
489 | // or spans with constant z depth. | ||
490 | // However, rotation around the world z axis is possible, | ||
491 | // thus this mapping, while simpler and faster than | ||
492 | // perspective correct texture mapping, has to traverse | ||
493 | // the texture at an angle in all but a few cases. | ||
494 | // In consequence, flats are not stored by column (like walls), | ||
495 | // and the inner loop has to step in texture space u and v. | ||
496 | // | ||
497 | |||
498 | int ds_y IBSS_ATTR; | ||
499 | int ds_x1 IBSS_ATTR; | ||
500 | int ds_x2 IBSS_ATTR; | ||
501 | |||
502 | lighttable_t *ds_colormap IBSS_ATTR; | ||
503 | |||
504 | fixed_t ds_xfrac IBSS_ATTR; | ||
505 | fixed_t ds_yfrac IBSS_ATTR; | ||
506 | fixed_t ds_xstep IBSS_ATTR; | ||
507 | fixed_t ds_ystep IBSS_ATTR; | ||
508 | |||
509 | // start of a 64*64 tile image | ||
510 | byte *ds_source IBSS_ATTR; | ||
511 | |||
512 | void R_DrawSpan (void) | ||
513 | { | ||
514 | register unsigned count,xfrac = ds_xfrac,yfrac = ds_yfrac; | ||
515 | |||
516 | byte *source; | ||
517 | byte *colormap; | ||
518 | byte *dest; | ||
519 | |||
520 | source = ds_source; | ||
521 | colormap = ds_colormap; | ||
522 | dest = topleft + ds_y*SCREENWIDTH + ds_x1; | ||
523 | count = ds_x2 - ds_x1 + 1; | ||
524 | |||
525 | while (count) | ||
526 | { | ||
527 | register unsigned xtemp = xfrac >> 16; | ||
528 | register unsigned ytemp = yfrac >> 10; | ||
529 | register unsigned spot; | ||
530 | ytemp &= 4032; | ||
531 | xtemp &= 63; | ||
532 | spot = xtemp | ytemp; | ||
533 | xfrac += ds_xstep; | ||
534 | yfrac += ds_ystep; | ||
535 | *dest++ = colormap[source[spot]]; | ||
536 | count--; | ||
537 | } | ||
538 | } | ||
539 | |||
540 | // | ||
541 | // R_InitBuffer | ||
542 | // Creats lookup tables that avoid | ||
543 | // multiplies and other hazzles | ||
544 | // for getting the framebuffer address | ||
545 | // of a pixel to draw. | ||
546 | // | ||
547 | |||
548 | void R_InitBuffer(int width, int height) | ||
549 | { | ||
550 | int i=0; | ||
551 | // Handle resize, | ||
552 | // e.g. smaller view windows | ||
553 | // with border and/or status bar. | ||
554 | |||
555 | viewwindowx = (SCREENWIDTH-width) >> 1; | ||
556 | |||
557 | // Same with base row offset. | ||
558 | |||
559 | viewwindowy = width==SCREENWIDTH ? 0 : (SCREENHEIGHT-(ST_SCALED_HEIGHT-1)-height)>>1; | ||
560 | |||
561 | topleft = screens[0] + viewwindowy*SCREENWIDTH + viewwindowx; | ||
562 | |||
563 | // Preclaculate all row offsets. | ||
564 | // CPhipps - merge viewwindowx into here | ||
565 | for (i=0; i<FUZZTABLE; i++) | ||
566 | fuzzoffset[i] = fuzzoffset_org[i]*SCREENWIDTH; | ||
567 | } | ||
568 | |||
569 | |||
570 | // | ||
571 | // R_FillBackScreen | ||
572 | // Fills the back screen with a pattern | ||
573 | // for variable screen sizes | ||
574 | // Also draws a beveled edge. | ||
575 | // | ||
576 | // CPhipps - patch drawing updated | ||
577 | |||
578 | void R_FillBackScreen (void) | ||
579 | { | ||
580 | int x,y; | ||
581 | |||
582 | if (scaledviewwidth == SCREENWIDTH) | ||
583 | return; | ||
584 | |||
585 | V_DrawBackground(gamemode == commercial ? "GRNROCK" : "FLOOR7_2", 1); | ||
586 | |||
587 | for (x=0 ; x<scaledviewwidth ; x+=8) | ||
588 | V_DrawNamePatch(viewwindowx+x,viewwindowy-8,1,"brdr_t", CR_DEFAULT, VPT_NONE); | ||
589 | |||
590 | for (x=0 ; x<scaledviewwidth ; x+=8) | ||
591 | V_DrawNamePatch(viewwindowx+x,viewwindowy+viewheight,1,"brdr_b", CR_DEFAULT, VPT_NONE); | ||
592 | |||
593 | for (y=0 ; y<viewheight ; y+=8) | ||
594 | V_DrawNamePatch(viewwindowx-8,viewwindowy+y,1,"brdr_l", CR_DEFAULT, VPT_NONE); | ||
595 | |||
596 | for (y=0 ; y<viewheight ; y+=8) | ||
597 | V_DrawNamePatch(viewwindowx+scaledviewwidth,viewwindowy+y,1,"brdr_r", CR_DEFAULT, VPT_NONE); | ||
598 | |||
599 | // Draw beveled edge. | ||
600 | V_DrawNamePatch(viewwindowx-8,viewwindowy-8,1,"brdr_tl", CR_DEFAULT, VPT_NONE); | ||
601 | |||
602 | V_DrawNamePatch(viewwindowx+scaledviewwidth,viewwindowy-8,1,"brdr_tr", CR_DEFAULT, VPT_NONE); | ||
603 | |||
604 | V_DrawNamePatch(viewwindowx-8,viewwindowy+viewheight,1,"brdr_bl", CR_DEFAULT, VPT_NONE); | ||
605 | |||
606 | V_DrawNamePatch(viewwindowx+scaledviewwidth,viewwindowy+viewheight,1,"brdr_br", CR_DEFAULT, VPT_NONE); | ||
607 | } | ||
608 | |||
609 | // | ||
610 | // Copy a screen buffer. | ||
611 | // | ||
612 | |||
613 | void R_VideoErase(unsigned ofs, int count) | ||
614 | { | ||
615 | memcpy(screens[0]+ofs, screens[1]+ofs, count); // LFB copy. | ||
616 | } | ||
617 | |||
618 | |||
619 | // | ||
620 | // R_DrawViewBorder | ||
621 | // Draws the border around the view | ||
622 | // for different size windows? | ||
623 | // | ||
624 | |||
625 | void R_DrawViewBorder(void) | ||
626 | { | ||
627 | int top, side, ofs, i; | ||
628 | // proff/nicolas 09/20/98: Added for high-res (inspired by DosDOOM) | ||
629 | int side2; | ||
630 | |||
631 | // proff/nicolas 09/20/98: Removed for high-res | ||
632 | // if (scaledviewwidth == SCREENWIDTH) | ||
633 | // return; | ||
634 | |||
635 | // proff/nicolas 09/20/98: Added for high-res (inspired by DosDOOM) | ||
636 | if ((SCREENHEIGHT != viewheight) || | ||
637 | ((automapmode & am_active) && ! (automapmode & am_overlay))) | ||
638 | { | ||
639 | ofs = ( SCREENHEIGHT - ST_SCALED_HEIGHT ) * SCREENWIDTH; | ||
640 | side= ( SCREENWIDTH - ST_SCALED_WIDTH ) / 2; | ||
641 | side2 = side * 2; | ||
642 | |||
643 | R_VideoErase ( ofs, side ); | ||
644 | |||
645 | ofs += ( SCREENWIDTH - side ); | ||
646 | for ( i = 1; i < ST_SCALED_HEIGHT; i++ ) | ||
647 | { | ||
648 | R_VideoErase ( ofs, side2 ); | ||
649 | ofs += SCREENWIDTH; | ||
650 | } | ||
651 | |||
652 | R_VideoErase ( ofs, side ); | ||
653 | } | ||
654 | |||
655 | if ( viewheight >= ( SCREENHEIGHT - ST_SCALED_HEIGHT )) | ||
656 | return; // if high-res, donŽt go any further! | ||
657 | |||
658 | top = ((SCREENHEIGHT-ST_SCALED_HEIGHT)-viewheight)/2; | ||
659 | side = (SCREENWIDTH-scaledviewwidth)/2; | ||
660 | |||
661 | // copy top and one line of left side | ||
662 | R_VideoErase (0, top*SCREENWIDTH+side); | ||
663 | |||
664 | // copy one line of right side and bottom | ||
665 | ofs = (viewheight+top)*SCREENWIDTH-side; | ||
666 | R_VideoErase (ofs, top*SCREENWIDTH+side); | ||
667 | |||
668 | // copy sides using wraparound | ||
669 | ofs = top*SCREENWIDTH + SCREENWIDTH-side; | ||
670 | side <<= 1; | ||
671 | |||
672 | for (i=1 ; i<viewheight ; i++) | ||
673 | { | ||
674 | R_VideoErase (ofs, side); | ||
675 | ofs += SCREENWIDTH; | ||
676 | } | ||
677 | } | ||