Add headers to dummy *-target.h files
[kugel-rb.git] / apps / plugins / doom / v_video.c
blob76993ea5eefc86d260ee042c5788b6274a2a826c
1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
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
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.
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.
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.
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.
33 *-----------------------------------------------------------------------------
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];
47 byte *d_screens[6] IBSS_ATTR;
48 int dirtybox[4];
50 /* jff 4/24/98 initialize this at runtime */
51 const byte *colrngs[CR_LIMIT];
53 // Now where did these came from?
54 const byte gammatable[5][256] = // CPhipps - const
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},
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},
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},
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},
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}
138 int usegamma;
141 * V_InitColorTranslation
143 * Loads the color translation tables from predefined lumps at game start
144 * No return
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.
152 * cphipps - constness of crdef_t stuff fixed
155 typedef struct {
156 const char *name;
157 const byte **map;
158 } crdef_t;
160 // killough 5/2/98: table-driven approach
161 static 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}
176 // killough 5/2/98: tiny engine driven by table above
177 void V_InitColorTranslation(void)
179 register const crdef_t *p;
180 for (p=crdefs; p->name; p++)
181 *p->map = W_CacheLumpName(p->name);
185 // V_MarkRect
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.
191 void V_MarkRect(int x, int y, int width, int height)
193 M_AddToBox(dirtybox, x, y);
194 M_AddToBox(dirtybox, x+width-1, y+height-1);
198 // V_CopyRect
200 // Copies a source rectangle in a screen buffer to a destination
201 // rectangle in another screen buffer. Source origin in srcx,srcy,
202 // destination origin in destx,desty, common size in width and height.
203 // Source buffer specfified by srcscrn, destination buffer by destscrn.
205 // Marks the destination rectangle on the screen dirty.
207 // No return.
209 void V_CopyRect(int srcx, int srcy, int srcscrn, int width,
210 int height, int destx, int desty, int destscrn,
211 patch_translation_e flags)
213 byte *src;
214 byte *dest;
216 if (flags & VPT_STRETCH)
218 srcx=srcx*SCREENWIDTH/320;
219 srcy=srcy*SCREENHEIGHT/200;
220 width=width*SCREENWIDTH/320;
221 height=height*SCREENHEIGHT/200;
222 destx=destx*SCREENWIDTH/320;
223 desty=desty*SCREENHEIGHT/200;
226 #ifdef RANGECHECK
227 if (srcx<0
228 ||srcx+width >SCREENWIDTH
229 || srcy<0
230 || srcy+height>SCREENHEIGHT
231 ||destx<0||destx+width >SCREENWIDTH
232 || desty<0
233 || desty+height>SCREENHEIGHT)
234 I_Error ("V_CopyRect: Bad arguments");
235 #endif
237 V_MarkRect (destx, desty, width, height);
239 src = d_screens[srcscrn]+SCREENWIDTH*srcy+srcx;
240 dest = d_screens[destscrn]+SCREENWIDTH*desty+destx;
242 for ( ; height>0 ; height--)
244 memcpy (dest, src, width);
245 src += SCREENWIDTH;
246 dest += SCREENWIDTH;
251 // V_DrawBlock
253 // Draw a linear block of pixels into the view buffer.
255 // The bytes at src are copied in linear order to the screen rectangle
256 // at x,y in screenbuffer scrn, with size width by height.
258 // The destination rectangle is marked dirty.
260 // No return.
262 // CPhipps - modified to take the patch translation flags. For now, only stretching is
263 // implemented, to support highres in the menus
265 void V_DrawBlock(int x, int y, int scrn, int width, int height,
266 const byte *src, patch_translation_e flags)
268 byte *dest;
270 #ifdef RANGECHECK
271 if (x<0
272 ||x+width >((flags & VPT_STRETCH) ? 320 : SCREENWIDTH)
273 || y<0
274 || y+height>((flags & VPT_STRETCH) ? 200 : SCREENHEIGHT))
275 I_Error ("V_DrawBlock: Bad V_DrawBlock");
277 if (flags & (VPT_TRANS | VPT_FLIP))
278 I_Error("V_DrawBlock: Unsupported flags (%u)", flags);
279 #endif
281 if (flags & VPT_STRETCH) {
282 byte *dest;
283 int s_width;
284 fixed_t dx = (320 << FRACBITS) / SCREENWIDTH;
286 x = (x * SCREENWIDTH) / 320; y = (y * SCREENHEIGHT) / 200;
287 s_width = (width * SCREENWIDTH) / 320; height = (height * SCREENHEIGHT) / 200;
289 if (!scrn)
290 V_MarkRect (x, y, width, height);
292 dest = d_screens[scrn] + y*SCREENWIDTH+x;
293 // x & y no longer needed
295 while (height--) {
296 const byte *const src_row = src + width * ((height * 200) / SCREENHEIGHT);
297 byte *const dst_row = dest + SCREENWIDTH * height;
298 fixed_t tx;
300 for (x=0, tx=0; x<s_width; x++, tx+=dx)
301 dst_row[x] = src_row[tx >> FRACBITS];
303 } else {
304 V_MarkRect (x, y, width, height);
306 dest = d_screens[scrn] + y*SCREENWIDTH+x;
308 while (height--) {
309 memcpy (dest, src, width);
310 src += width;
311 dest += SCREENWIDTH;
317 * V_DrawBackground tiles a 64x64 patch over the entire screen, providing the
318 * background for the Help and Setup screens, and plot text betwen levels.
319 * cphipps - used to have M_DrawBackground, but that was used the framebuffer
320 * directly, so this is my code from the equivalent function in f_finale.c
322 void V_DrawBackground(const char* flatname, int scrn)
324 /* erase the entire screen to a tiled background */
325 const byte *src;
326 int x,y;
327 int lump;
329 // killough 4/17/98:
330 src = W_CacheLumpNum(lump = firstflat + R_FlatNumForName(flatname));
332 V_DrawBlock(0, 0, scrn, 64, 64, src, 0);
334 for (y=0 ; y<SCREENHEIGHT ; y+=64)
335 for (x=y ? 0 : 64; x<SCREENWIDTH ; x+=64)
336 V_CopyRect(0, 0, scrn, ((SCREENWIDTH-x) < 64) ? (SCREENWIDTH-x) : 64,
337 ((SCREENHEIGHT-y) < 64) ? (SCREENHEIGHT-y) : 64, x, y, scrn, VPT_NONE);
338 W_UnlockLumpNum(lump);
342 // V_GetBlock
344 // Gets a linear block of pixels from the view buffer.
346 // The pixels in the rectangle at x,y in screenbuffer scrn with size
347 // width by height are linearly packed into the buffer dest.
348 // No return
351 void V_GetBlock(int x, int y, int scrn, int width, int height, byte *dest)
353 byte *src;
355 #ifdef RANGECHECK
356 if (x<0
357 ||x+width >SCREENWIDTH
358 || y<0
359 || y+height>SCREENHEIGHT)
360 I_Error ("V_GetBlock: Bad arguments");
361 #endif
363 src = d_screens[scrn] + y*SCREENWIDTH+x;
365 while (height--)
367 memcpy (dest, src, width);
368 src += SCREENWIDTH;
369 dest += width;
374 // V_Init
376 // Allocates the 4 full screen buffers in low DOS memory
377 // No return
380 void V_Init (void)
382 int i;
383 // CPhipps - allocate only 2 screens all the time, the rest can be allocated as and when needed
384 #define PREALLOCED_SCREENS 2
386 // CPhipps - no point in "stick these in low dos memory on PCs" anymore
387 // Allocate the screens individually, so I_InitGraphics can release d_screens[0]
388 // if e.g. it wants a MitSHM buffer instead
390 for (i=0 ; i<PREALLOCED_SCREENS ; i++)
391 d_screens[i] = calloc(SCREENWIDTH*SCREENHEIGHT, 1);
392 for (; i<4; i++) // Clear the rest (paranoia)
393 d_screens[i] = NULL;
397 // V_DrawMemPatch
399 // CPhipps - unifying patch drawing routine, handles all cases and combinations
400 // of stretching, flipping and translating
402 // This function is big, hopefully not too big that gcc can't optimise it well.
403 // In fact it packs pretty well, there is no big performance lose for all this merging;
404 // the inner loops themselves are just the same as they always were
405 // (indeed, laziness of the people who wrote the 'clones' of the original V_DrawPatch
406 // means that their inner loops weren't so well optimised, so merging code may even speed them).
408 void V_DrawMemPatch(int x, int y, int scrn, const patch_t *patch,
409 int cm, patch_translation_e flags)
411 const byte *trans;
413 if (cm<CR_LIMIT)
414 trans=colrngs[cm];
415 else
416 trans=translationtables + 256*((cm-CR_LIMIT)-1);
417 y -= SHORT(patch->topoffset);
418 x -= SHORT(patch->leftoffset);
420 // CPhipps - auto-no-stretch if not high-res
421 if (flags & VPT_STRETCH)
422 if ((SCREENWIDTH==320) && (SCREENHEIGHT==200))
423 flags &= ~VPT_STRETCH;
425 // CPhipps - null translation pointer => no translation
426 if (!trans)
427 flags &= ~VPT_TRANS;
429 if (x<0
430 ||x+SHORT(patch->width) > ((flags & VPT_STRETCH) ? 320 : SCREENWIDTH)
431 || y<0
432 || y+SHORT(patch->height) > ((flags & VPT_STRETCH) ? 200 : SCREENHEIGHT))
434 rb->splash(HZ*2, "This wad does not follow standard doom graphics!");
435 // killough 1/19/98: improved error message:
436 I_Error("V_DrawMemPatch: Patch (%d,%d)-(%d,%d) exceeds LFB Bad V_DrawMemPatch (flags=%u)",
437 x, y, x+SHORT(patch->width), y+SHORT(patch->height), flags);
440 if (!(flags & VPT_STRETCH)) {
441 unsigned int col;
442 const column_t *column;
443 byte *desttop = d_screens[scrn]+y*SCREENWIDTH+x;
444 unsigned int w = SHORT(patch->width);
446 if (!scrn)
447 V_MarkRect (x, y, w, SHORT(patch->height));
449 w--; // CPhipps - note: w = width-1 now, speeds up flipping
451 for (col=0 ; (unsigned int)col<=w ; desttop++, col++) {
452 column = (column_t *)((byte *)patch +
453 LONG(patch->columnofs[(flags & VPT_FLIP) ? w-col : col]));
455 // step through the posts in a column
456 while (column->topdelta != 0xff ) {
457 // killough 2/21/98: Unrolled and performance-tuned
459 register const byte *source = (byte *)column + 3;
460 register byte *dest = desttop + column->topdelta*SCREENWIDTH;
461 register int count = column->length;
463 if (!(flags & VPT_TRANS)) {
464 if ((count-=4)>=0)
465 do {
466 register byte s0,s1;
467 s0 = source[0];
468 s1 = source[1];
469 dest[0] = s0;
470 dest[SCREENWIDTH] = s1;
471 dest += SCREENWIDTH*2;
472 s0 = source[2];
473 s1 = source[3];
474 source += 4;
475 dest[0] = s0;
476 dest[SCREENWIDTH] = s1;
477 dest += SCREENWIDTH*2;
478 } while ((count-=4)>=0);
479 if (count+=4)
480 do {
481 *dest = *source++;
482 dest += SCREENWIDTH;
483 } while (--count);
484 column = (column_t *)(source+1); //killough 2/21/98 even faster
485 } else {
486 // CPhipps - merged translation code here
487 if ((count-=4)>=0)
488 do {
489 register byte s0,s1;
490 s0 = source[0];
491 s1 = source[1];
492 s0 = trans[s0];
493 s1 = trans[s1];
494 dest[0] = s0;
495 dest[SCREENWIDTH] = s1;
496 dest += SCREENWIDTH*2;
497 s0 = source[2];
498 s1 = source[3];
499 s0 = trans[s0];
500 s1 = trans[s1];
501 source += 4;
502 dest[0] = s0;
503 dest[SCREENWIDTH] = s1;
504 dest += SCREENWIDTH*2;
505 } while ((count-=4)>=0);
506 if (count+=4)
507 do {
508 *dest = trans[*source++];
509 dest += SCREENWIDTH;
510 } while (--count);
511 column = (column_t *)(source+1);
516 else {
517 // CPhipps - move stretched patch drawing code here
518 // - reformat initialisers, move variables into inner blocks
520 byte *desttop;
521 int col;
522 int w = (SHORT( patch->width ) << 16) -1; // CPhipps - -1 for faster flipping
523 int stretchx, stretchy;
524 int DX = (SCREENWIDTH<<16) / 320;
525 int DXI = (320<<16) / SCREENWIDTH;
526 int DY = (SCREENHEIGHT<<16) / 200;
527 register int DYI = (200<<16) / SCREENHEIGHT;
528 int DY2, DYI2;
530 stretchx = ( x * DX ) >> 16;
531 stretchy = ( y * DY ) >> 16;
532 DY2 = DY / 2;
533 DYI2 = DYI* 2;
535 if (!scrn)
536 V_MarkRect ( stretchx, stretchy, (SHORT( patch->width ) * DX ) >> 16,
537 (SHORT( patch->height) * DY ) >> 16 );
539 desttop = d_screens[scrn] + stretchy * SCREENWIDTH + stretchx;
541 // Clamp down the screenwidth
542 if(w>>16>=319)
543 w=(SCREENWIDTH-1)*DXI;
545 for ( col = 0; col <= w; x++, col+=DXI, desttop++ ) {
546 const column_t *column;
548 unsigned int d = patch->columnofs[(flags & VPT_FLIP) ? ((w - col)>>16): (col>>16)];
549 column = (column_t*)((byte*)patch + LONG(d));
552 while ( column->topdelta != 0xff ) {
553 register const byte *source = ( byte* ) column + 3;
554 register byte *dest = desttop + (( column->topdelta * DY ) >> 16 ) * SCREENWIDTH;
555 register int count = ( column->length * DY ) >> 16;
556 register int srccol = 0x8000;
558 count = (count>SCREENHEIGHT)?SCREENHEIGHT:count; // Bounds checking allows those messed up
559 // GP32 mods to work (they're using patch->
560 // height values of 240, this code cuts off
561 // thier bottom few pixels
563 if (flags & VPT_TRANS)
564 while (count--) {
565 *dest = trans[source[srccol>>16]];
566 dest += SCREENWIDTH;
567 srccol+= DYI;
569 else
570 while (count--) {
571 *dest = source[srccol>>16];
572 dest += SCREENWIDTH;
573 srccol+= DYI;
575 column = ( column_t* ) (( byte* ) column + ( column->length ) + 4 );
581 // CPhipps - some simple, useful wrappers for that function, for drawing patches from wads
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
587 #ifdef __GNUC__
588 inline
589 #endif
590 void V_DrawNumPatch(int x, int y, int scrn, int lump,
591 int cm, patch_translation_e flags)
593 V_DrawMemPatch(x, y, scrn, (const patch_t*)W_CacheLumpNum(lump),
594 cm, flags);
595 W_UnlockLumpNum(lump);
598 /* cph -
599 * V_NamePatchWidth - returns width of a patch.
600 * V_NamePatchHeight- returns height of a patch.
602 * Doesn't really belong here, but is often used in conjunction with
603 * this code.
604 * This is needed to reduce the number of patches being held locked
605 * in memory, since a lot of code was locking and holding pointers
606 * to graphics in order to get this info easily. Also, we do endian
607 * correction here, which reduces the chance of other code forgetting
608 * this.
610 int V_NamePatchWidth(const char* name)
612 int lump = W_GetNumForName(name);
613 int w;
615 w = SHORT(((const patch_t*)W_CacheLumpNum(lump))->width);
616 W_UnlockLumpNum(lump);
617 return w;
620 int V_NamePatchHeight(const char* name)
622 int lump = W_GetNumForName(name);
623 int w;
625 w = SHORT(((const patch_t*)W_CacheLumpNum(lump))->height);
626 W_UnlockLumpNum(lump);
627 return w;
630 // CPhipps -
631 // V_PatchToBlock
633 // Returns a simple bitmap which contains the patch. See-through parts of the
634 // patch will be undefined (in fact black for now)
636 byte *V_PatchToBlock(const char* name, int cm,
637 patch_translation_e flags,
638 unsigned short* width, unsigned short* height)
640 (void)cm;
641 (void)flags;
642 byte *oldscr = d_screens[1];
643 byte *block;
644 const patch_t *patch;
646 d_screens[1] = calloc(SCREENWIDTH*SCREENHEIGHT, 1);
648 patch = W_CacheLumpName(name);
649 // One of those odd things that don't seem to have a purpose other then rangechecking
650 // On screens smaller than 320X200 this line causes problems.
651 // V_DrawMemPatch(SHORT(patch->leftoffset), SHORT(patch->topoffset),
652 // 1, patch, cm, flags);
654 #ifdef RANGECHECK
655 if (flags & VPT_STRETCH)
656 I_Error("V_PatchToBlock: Stretching not supported");
657 #endif
659 *width = SHORT(patch->width); *height = SHORT(patch->height);
661 W_UnlockLumpName(name);
663 V_GetBlock(0, 0, 1, *width, *height,
664 block = malloc((long)(*width) * (*height)));
666 free(d_screens[1]);
667 d_screens[1] = oldscr;
668 return block;
672 // V_SetPalette
674 // CPhipps - New function to set the palette to palette number pal.
675 // Handles loading of PLAYPAL and calls I_SetPalette
677 void V_SetPalette(int pal)
679 I_SetPalette(pal);
683 // V_FillRect
685 // CPhipps - New function to fill a rectangle with a given colour
686 void V_FillRect(int scrn, int x, int y, int width, int height, byte colour)
688 byte* dest = d_screens[scrn] + x + y*SCREENWIDTH;
689 while (height--) {
690 memset(dest, colour, width);
691 dest += SCREENWIDTH;