summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/v_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/v_video.c')
-rw-r--r--apps/plugins/doom/v_video.c700
1 files changed, 700 insertions, 0 deletions
diff --git a/apps/plugins/doom/v_video.c b/apps/plugins/doom/v_video.c
new file mode 100644
index 0000000000..a7dbe84d6a
--- /dev/null
+++ b/apps/plugins/doom/v_video.c
@@ -0,0 +1,700 @@
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 * Gamma correction LUT stuff.
29 * Color range translation support
30 * Functions to draw patches (by post) directly to screen.
31 * Functions to blit a block to the screen.
32 *
33 *-----------------------------------------------------------------------------
34 */
35
36#include "doomdef.h"
37#include "r_main.h"
38#include "r_draw.h"
39#include "m_bbox.h"
40#include "w_wad.h" /* needed for color translation lump lookup */
41#include "v_video.h"
42#include "i_video.h"
43#include "i_system.h"
44#include "m_swap.h"
45#include "rockmacros.h"
46// Each screen is [SCREENWIDTH*SCREENHEIGHT];
47byte *screens[6];
48int dirtybox[4];
49
50/* jff 4/24/98 initialize this at runtime */
51const byte *colrngs[CR_LIMIT];
52
53// Now where did these came from?
54const byte gammatable[5][256] = // CPhipps - const
55 {
56 {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
57 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
58 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
59 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
60 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
61 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,
62 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
63 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
64 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
65 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
66 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
67 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
68 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
69 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
70 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
71 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
72
73 {2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,
74 32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,
75 56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,
76 78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,
77 99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
78 115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,
79 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
80 146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,
81 161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,
82 175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,
83 190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,
84 205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,
85 219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,
86 233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,
87 247,248,249,250,251,252,252,253,254,255},
88
89 {4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,
90 43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,
91 70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,
92 94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,
93 113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
94 129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,
95 144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,
96 160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,
97 174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,
98 188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,
99 202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,
100 216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,
101 229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,
102 242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,
103 255},
104
105 {8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,
106 57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,
107 86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,
108 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,
109 125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,
110 141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,
111 155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,
112 169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,
113 183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,
114 195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,
115 207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,
116 219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,
117 231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,
118 242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,
119 253,253,254,254,255},
120
121 {16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,
122 78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,
123 107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,
124 125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,
125 142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,
126 156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,
127 169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,
128 182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,
129 193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,
130 204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,
131 214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,
132 224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,
133 234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,
134 243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,
135 251,252,252,253,254,254,255,255}
136 };
137
138int usegamma;
139
140/*
141 * V_InitColorTranslation
142 *
143 * Loads the color translation tables from predefined lumps at game start
144 * No return
145 *
146 * Used for translating text colors from the red palette range
147 * to other colors. The first nine entries can be used to dynamically
148 * switch the output of text color thru the HUlib_drawText routine
149 * by embedding ESCn in the text to obtain color n. Symbols for n are
150 * provided in v_video.h.
151 *
152 * cphipps - constness of crdef_t stuff fixed
153 */
154
155typedef struct {
156 const char *name;
157 const byte **map;
158} crdef_t;
159
160// killough 5/2/98: table-driven approach
161static const crdef_t crdefs[] = {
162 {"CRBRICK", &colrngs[CR_BRICK ]},
163 {"CRTAN", &colrngs[CR_TAN ]},
164 {"CRGRAY", &colrngs[CR_GRAY ]},
165 {"CRGREEN", &colrngs[CR_GREEN ]},
166 {"CRBROWN", &colrngs[CR_BROWN ]},
167 {"CRGOLD", &colrngs[CR_GOLD ]},
168 {"CRRED", &colrngs[CR_RED ]},
169 {"CRBLUE", &colrngs[CR_BLUE ]},
170 {"CRORANGE", &colrngs[CR_ORANGE]},
171 {"CRYELLOW", &colrngs[CR_YELLOW]},
172 {"CRBLUE2", &colrngs[CR_BLUE2]},
173 {NULL, NULL}
174 };
175
176// killough 5/2/98: tiny engine driven by table above
177void V_InitColorTranslation(void)
178{
179 register const crdef_t *p;
180 for (p=crdefs; p->name; p++)
181 *p->map = W_CacheLumpName(p->name);
182}
183
184//
185// V_MarkRect
186//
187// Marks a rectangular portion of the screen specified by
188// upper left origin and height and width dirty to minimize
189// the amount of screen update necessary. No return.
190//
191#ifndef GL_DOOM
192void V_MarkRect(int x, int y, int width, int height)
193{
194 M_AddToBox(dirtybox, x, y);
195 M_AddToBox(dirtybox, x+width-1, y+height-1);
196}
197#endif /* GL_DOOM */
198
199//
200// V_CopyRect
201//
202// Copies a source rectangle in a screen buffer to a destination
203// rectangle in another screen buffer. Source origin in srcx,srcy,
204// destination origin in destx,desty, common size in width and height.
205// Source buffer specfified by srcscrn, destination buffer by destscrn.
206//
207// Marks the destination rectangle on the screen dirty.
208//
209// No return.
210//
211#ifndef GL_DOOM
212void V_CopyRect(int srcx, int srcy, int srcscrn, int width,
213 int height, int destx, int desty, int destscrn,
214 enum patch_translation_e flags)
215{
216 byte *src;
217 byte *dest;
218
219 if (flags & VPT_STRETCH)
220 {
221 srcx=srcx*SCREENWIDTH/320;
222 srcy=srcy*SCREENHEIGHT/200;
223 width=width*SCREENWIDTH/320;
224 height=height*SCREENHEIGHT/200;
225 destx=destx*SCREENWIDTH/320;
226 desty=desty*SCREENHEIGHT/200;
227 }
228
229#ifdef RANGECHECK
230 if (srcx<0
231 ||srcx+width >SCREENWIDTH
232 || srcy<0
233 || srcy+height>SCREENHEIGHT
234 ||destx<0||destx+width >SCREENWIDTH
235 || desty<0
236 || desty+height>SCREENHEIGHT)
237 I_Error ("V_CopyRect: Bad arguments");
238#endif
239
240 V_MarkRect (destx, desty, width, height);
241
242 src = screens[srcscrn]+SCREENWIDTH*srcy+srcx;
243 dest = screens[destscrn]+SCREENWIDTH*desty+destx;
244
245 for ( ; height>0 ; height--)
246 {
247 memcpy (dest, src, width);
248 src += SCREENWIDTH;
249 dest += SCREENWIDTH;
250 }
251}
252#endif /* GL_DOOM */
253
254//
255// V_DrawBlock
256//
257// Draw a linear block of pixels into the view buffer.
258//
259// The bytes at src are copied in linear order to the screen rectangle
260// at x,y in screenbuffer scrn, with size width by height.
261//
262// The destination rectangle is marked dirty.
263//
264// No return.
265//
266// CPhipps - modified to take the patch translation flags. For now, only stretching is
267// implemented, to support highres in the menus
268//
269#ifndef GL_DOOM
270void V_DrawBlock(int x, int y, int scrn, int width, int height,
271 const byte *src, enum patch_translation_e flags)
272{
273 byte *dest;
274
275#ifdef RANGECHECK
276 if (x<0
277 ||x+width >((flags & VPT_STRETCH) ? 320 : SCREENWIDTH)
278 || y<0
279 || y+height>((flags & VPT_STRETCH) ? 200 : SCREENHEIGHT))
280 I_Error ("V_DrawBlock: Bad V_DrawBlock");
281
282 if (flags & (VPT_TRANS | VPT_FLIP))
283 I_Error("V_DrawBlock: Unsupported flags (%u)", flags);
284#endif
285
286 if (flags & VPT_STRETCH) {
287 byte *dest;
288 int s_width;
289 fixed_t dx = (320 << FRACBITS) / SCREENWIDTH;
290
291 x = (x * SCREENWIDTH) / 320; y = (y * SCREENHEIGHT) / 200;
292 s_width = (width * SCREENWIDTH) / 320; height = (height * SCREENHEIGHT) / 200;
293
294 if (!scrn)
295 V_MarkRect (x, y, width, height);
296
297 dest = screens[scrn] + y*SCREENWIDTH+x;
298 // x & y no longer needed
299
300 while (height--) {
301 const byte *const src_row = src + width * ((height * 200) / SCREENHEIGHT);
302 byte *const dst_row = dest + SCREENWIDTH * height;
303 fixed_t tx;
304
305 for (x=0, tx=0; x<s_width; x++, tx+=dx)
306 dst_row[x] = src_row[tx >> FRACBITS];
307 }
308 } else {
309 V_MarkRect (x, y, width, height);
310
311 dest = screens[scrn] + y*SCREENWIDTH+x;
312
313 while (height--) {
314 memcpy (dest, src, width);
315 src += width;
316 dest += SCREENWIDTH;
317 }
318 }
319}
320#endif /* GL_DOOM */
321
322/*
323 * V_DrawBackground tiles a 64x64 patch over the entire screen, providing the
324 * background for the Help and Setup screens, and plot text betwen levels.
325 * cphipps - used to have M_DrawBackground, but that was used the framebuffer
326 * directly, so this is my code from the equivalent function in f_finale.c
327 */
328#ifndef GL_DOOM
329void V_DrawBackground(const char* flatname, int scrn)
330{
331 /* erase the entire screen to a tiled background */
332 const byte *src;
333 int x,y;
334 int lump;
335
336 // killough 4/17/98:
337 src = W_CacheLumpNum(lump = firstflat + R_FlatNumForName(flatname));
338
339 V_DrawBlock(0, 0, scrn, 64, 64, src, 0);
340
341 for (y=0 ; y<SCREENHEIGHT ; y+=64)
342 for (x=y ? 0 : 64; x<SCREENWIDTH ; x+=64)
343 V_CopyRect(0, 0, scrn, ((SCREENWIDTH-x) < 64) ? (SCREENWIDTH-x) : 64,
344 ((SCREENHEIGHT-y) < 64) ? (SCREENHEIGHT-y) : 64, x, y, scrn, VPT_NONE);
345 W_UnlockLumpNum(lump);
346}
347#endif
348
349//
350// V_GetBlock
351//
352// Gets a linear block of pixels from the view buffer.
353//
354// The pixels in the rectangle at x,y in screenbuffer scrn with size
355// width by height are linearly packed into the buffer dest.
356// No return
357//
358
359#ifndef GL_DOOM
360void V_GetBlock(int x, int y, int scrn, int width, int height, byte *dest)
361{
362 byte *src;
363
364#ifdef RANGECHECK
365 if (x<0
366 ||x+width >SCREENWIDTH
367 || y<0
368 || y+height>SCREENHEIGHT)
369 I_Error ("V_GetBlock: Bad arguments");
370#endif
371
372 src = screens[scrn] + y*SCREENWIDTH+x;
373
374 while (height--)
375 {
376 memcpy (dest, src, width);
377 src += SCREENWIDTH;
378 dest += width;
379 }
380}
381#endif /* GL_DOOM */
382
383//
384// V_Init
385//
386// Allocates the 4 full screen buffers in low DOS memory
387// No return
388//
389
390void V_Init (void)
391{
392 int i;
393 // CPhipps - allocate only 2 screens all the time, the rest can be allocated as and when needed
394#define PREALLOCED_SCREENS 2
395
396 // CPhipps - no point in "stick these in low dos memory on PCs" anymore
397 // Allocate the screens individually, so I_InitGraphics can release screens[0]
398 // if e.g. it wants a MitSHM buffer instead
399
400 for (i=0 ; i<PREALLOCED_SCREENS ; i++)
401 screens[i] = calloc(SCREENWIDTH*SCREENHEIGHT, 1);
402 for (; i<4; i++) // Clear the rest (paranoia)
403 screens[i] = NULL;
404}
405
406//
407// V_DrawMemPatch
408//
409// CPhipps - unifying patch drawing routine, handles all cases and combinations
410// of stretching, flipping and translating
411//
412// This function is big, hopefully not too big that gcc can't optimise it well.
413// In fact it packs pretty well, there is no big performance lose for all this merging;
414// the inner loops themselves are just the same as they always were
415// (indeed, laziness of the people who wrote the 'clones' of the original V_DrawPatch
416// means that their inner loops weren't so well optimised, so merging code may even speed them).
417//
418#ifndef GL_DOOM
419void V_DrawMemPatch(int x, int y, int scrn, const patch_t *patch,
420 int cm, enum patch_translation_e flags)
421{
422 const byte *trans;
423
424 if (cm<CR_LIMIT)
425 trans=colrngs[cm];
426 else
427 trans=translationtables + 256*((cm-CR_LIMIT)-1);
428 y -= SHORT(patch->topoffset);
429 x -= SHORT(patch->leftoffset);
430
431 // CPhipps - auto-no-stretch if not high-res
432 if (flags & VPT_STRETCH)
433 if ((SCREENWIDTH==320) && (SCREENHEIGHT==200))
434 flags &= ~VPT_STRETCH;
435
436 // CPhipps - null translation pointer => no translation
437 if (!trans)
438 flags &= ~VPT_TRANS;
439
440 if (x<0
441 ||x+SHORT(patch->width) > ((flags & VPT_STRETCH) ? 320 : SCREENWIDTH)
442 || y<0
443 || y+SHORT(patch->height) > ((flags & VPT_STRETCH) ? 200 : SCREENHEIGHT))
444 // killough 1/19/98: improved error message:
445 I_Error("V_DrawMemPatch: Patch (%d,%d)-(%d,%d) exceeds LFB"
446 "Bad V_DrawMemPatch (flags=%u)", x, y, x+SHORT(patch->width), y+SHORT(patch->height), flags);
447
448 if (!(flags & VPT_STRETCH)) {
449 unsigned int col;
450 const column_t *column;
451 byte *desttop = screens[scrn]+y*SCREENWIDTH+x;
452 unsigned int w = SHORT(patch->width);
453
454 if (!scrn)
455 V_MarkRect (x, y, w, SHORT(patch->height));
456
457 w--; // CPhipps - note: w = width-1 now, speeds up flipping
458
459 for (col=0 ; (unsigned int)col<=w ; desttop++, col++) {
460 column = (column_t *)((byte *)patch +
461 LONG(patch->columnofs[(flags & VPT_FLIP) ? w-col : col]));
462
463 // step through the posts in a column
464 while (column->topdelta != 0xff ) {
465 // killough 2/21/98: Unrolled and performance-tuned
466
467 register const byte *source = (byte *)column + 3;
468 register byte *dest = desttop + column->topdelta*SCREENWIDTH;
469 register int count = column->length;
470
471 if (!(flags & VPT_TRANS)) {
472 if ((count-=4)>=0)
473 do {
474 register byte s0,s1;
475 s0 = source[0];
476 s1 = source[1];
477 dest[0] = s0;
478 dest[SCREENWIDTH] = s1;
479 dest += SCREENWIDTH*2;
480 s0 = source[2];
481 s1 = source[3];
482 source += 4;
483 dest[0] = s0;
484 dest[SCREENWIDTH] = s1;
485 dest += SCREENWIDTH*2;
486 } while ((count-=4)>=0);
487 if (count+=4)
488 do {
489 *dest = *source++;
490 dest += SCREENWIDTH;
491 } while (--count);
492 column = (column_t *)(source+1); //killough 2/21/98 even faster
493 } else {
494 // CPhipps - merged translation code here
495 if ((count-=4)>=0)
496 do {
497 register byte s0,s1;
498 s0 = source[0];
499 s1 = source[1];
500 s0 = trans[s0];
501 s1 = trans[s1];
502 dest[0] = s0;
503 dest[SCREENWIDTH] = s1;
504 dest += SCREENWIDTH*2;
505 s0 = source[2];
506 s1 = source[3];
507 s0 = trans[s0];
508 s1 = trans[s1];
509 source += 4;
510 dest[0] = s0;
511 dest[SCREENWIDTH] = s1;
512 dest += SCREENWIDTH*2;
513 } while ((count-=4)>=0);
514 if (count+=4)
515 do {
516 *dest = trans[*source++];
517 dest += SCREENWIDTH;
518 } while (--count);
519 column = (column_t *)(source+1);
520 }
521 }
522 }
523 }
524 else {
525 // CPhipps - move stretched patch drawing code here
526 // - reformat initialisers, move variables into inner blocks
527
528 byte *desttop;
529 int col;
530 int w = (SHORT( patch->width ) << 16) - 1; // CPhipps - -1 for faster flipping
531 int stretchx, stretchy;
532 int DX = (SCREENWIDTH<<16) / 320;
533 int DXI = (320<<16) / SCREENWIDTH;
534 int DY = (SCREENHEIGHT<<16) / 200;
535 register int DYI = (200<<16) / SCREENHEIGHT;
536 int DY2, DYI2;
537
538 stretchx = ( x * DX ) >> 16;
539 stretchy = ( y * DY ) >> 16;
540 DY2 = DY / 2;
541 DYI2 = DYI* 2;
542
543 if (!scrn)
544 V_MarkRect ( stretchx, stretchy, (SHORT( patch->width ) * DX ) >> 16,
545 (SHORT( patch->height) * DY ) >> 16 );
546
547 desttop = screens[scrn] + stretchy * SCREENWIDTH + stretchx;
548
549 for ( col = 0; col <= w; x++, col+=DXI, desttop++ ) {
550 const column_t *column;
551 {
552 unsigned int d = patch->columnofs[(flags & VPT_FLIP) ? ((w - col)>>16): (col>>16)];
553 column = (column_t*)((byte*)patch + LONG(d));
554 }
555
556 while ( column->topdelta != 0xff ) {
557 register const byte *source = ( byte* ) column + 3;
558 register byte *dest = desttop + (( column->topdelta * DY ) >> 16 ) * SCREENWIDTH;
559 register int count = ( column->length * DY ) >> 16;
560 register int srccol = 0x8000;
561
562 if (flags & VPT_TRANS)
563 while (count--) {
564 *dest = trans[source[srccol>>16]];
565 dest += SCREENWIDTH;
566 srccol+= DYI;
567 }
568 else
569 while (count--) {
570 *dest = source[srccol>>16];
571 dest += SCREENWIDTH;
572 srccol+= DYI;
573 }
574 column = ( column_t* ) (( byte* ) column + ( column->length ) + 4 );
575 }
576 }
577 }
578}
579#endif // GL_DOOM
580
581// CPhipps - some simple, useful wrappers for that function, for drawing patches from wads
582
583// CPhipps - GNU C only suppresses generating a copy of a function if it is
584// static inline; other compilers have different behaviour.
585// This inline is _only_ for the function below
586
587#ifndef GL_DOOM
588#ifdef __GNUC__
589inline
590#endif
591void V_DrawNumPatch(int x, int y, int scrn, int lump,
592 int cm, enum patch_translation_e flags)
593{
594 V_DrawMemPatch(x, y, scrn, (const patch_t*)W_CacheLumpNum(lump),
595 cm, flags);
596 W_UnlockLumpNum(lump);
597}
598#endif // GL_DOOM
599
600/* cph -
601 * V_NamePatchWidth - returns width of a patch.
602 * V_NamePatchHeight- returns height of a patch.
603 *
604 * Doesn't really belong here, but is often used in conjunction with
605 * this code.
606 * This is needed to reduce the number of patches being held locked
607 * in memory, since a lot of code was locking and holding pointers
608 * to graphics in order to get this info easily. Also, we do endian
609 * correction here, which reduces the chance of other code forgetting
610 * this.
611 */
612int V_NamePatchWidth(const char* name)
613{
614 int lump = W_GetNumForName(name);
615 int w;
616
617 w = SHORT(((const patch_t*)W_CacheLumpNum(lump))->width);
618 W_UnlockLumpNum(lump);
619 return w;
620}
621
622int V_NamePatchHeight(const char* name)
623{
624 int lump = W_GetNumForName(name);
625 int w;
626
627 w = SHORT(((const patch_t*)W_CacheLumpNum(lump))->height);
628 W_UnlockLumpNum(lump);
629 return w;
630}
631
632// CPhipps -
633// V_PatchToBlock
634//
635// Returns a simple bitmap which contains the patch. See-through parts of the
636// patch will be undefined (in fact black for now)
637
638#ifndef GL_DOOM
639byte *V_PatchToBlock(const char* name, int cm,
640 enum patch_translation_e flags,
641 unsigned short* width, unsigned short* height)
642{
643 byte *oldscr = screens[1];
644 byte *block;
645 const patch_t *patch;
646
647 screens[1] = calloc(SCREENWIDTH*SCREENHEIGHT, 1);
648
649 patch = W_CacheLumpName(name);
650 V_DrawMemPatch(SHORT(patch->leftoffset), SHORT(patch->topoffset),
651 1, patch, cm, flags);
652
653#ifdef RANGECHECK
654 if (flags & VPT_STRETCH)
655 I_Error("V_PatchToBlock: Stretching not supported");
656#endif
657
658 *width = SHORT(patch->width); *height = SHORT(patch->height);
659
660 W_UnlockLumpName(name);
661
662 V_GetBlock(0, 0, 1, *width, *height,
663 block = malloc((long)(*width) * (*height)));
664
665 free(screens[1]);
666 screens[1] = oldscr;
667 return block;
668}
669#endif /* GL_DOOM */
670
671//
672// V_SetPalette
673//
674// CPhipps - New function to set the palette to palette number pal.
675// Handles loading of PLAYPAL and calls I_SetPalette
676
677void V_SetPalette(int pal)
678{
679#ifndef GL_DOOM
680 I_SetPalette(pal);
681#else
682 // proff 11/99: update the palette
683 gld_SetPalette(pal);
684#endif
685}
686
687//
688// V_FillRect
689//
690// CPhipps - New function to fill a rectangle with a given colour
691#ifndef GL_DOOM
692void V_FillRect(int scrn, int x, int y, int width, int height, byte colour)
693{
694 byte* dest = screens[scrn] + x + y*SCREENWIDTH;
695 while (height--) {
696 memset(dest, colour, width);
697 dest += SCREENWIDTH;
698 }
699}
700#endif