diff options
Diffstat (limited to 'apps/plugins/doom/v_video.c')
-rw-r--r-- | apps/plugins/doom/v_video.c | 700 |
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]; | ||
47 | byte *screens[6]; | ||
48 | int dirtybox[4]; | ||
49 | |||
50 | /* jff 4/24/98 initialize this at runtime */ | ||
51 | const byte *colrngs[CR_LIMIT]; | ||
52 | |||
53 | // Now where did these came from? | ||
54 | const 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 | |||
138 | int 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 | |||
155 | typedef struct { | ||
156 | const char *name; | ||
157 | const byte **map; | ||
158 | } crdef_t; | ||
159 | |||
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} | ||
174 | }; | ||
175 | |||
176 | // killough 5/2/98: tiny engine driven by table above | ||
177 | void 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 | ||
192 | void 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 | ||
212 | void 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 | ||
270 | void 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 | ||
329 | void 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 | ||
360 | void 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 | |||
390 | void 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 | ||
419 | void 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__ | ||
589 | inline | ||
590 | #endif | ||
591 | void 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 | */ | ||
612 | int 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 | |||
622 | int 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 | ||
639 | byte *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 | |||
677 | void 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 | ||
692 | void 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 | ||