mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Merge branch 'patch-refactor' into 'next'
Patch and texture refactor See merge request STJr/SRB2!2104
This commit is contained in:
commit
bf4efe968f
30 changed files with 1476 additions and 2172 deletions
|
@ -1780,10 +1780,10 @@ static void CON_DrawBackpic(void)
|
|||
// then fill the sides with a solid color.
|
||||
if (x > 0)
|
||||
{
|
||||
column_t *column = (column_t *)((UINT8 *)(con_backpic->columns) + (con_backpic->columnofs[0]));
|
||||
if (!column->topdelta)
|
||||
column_t *column = &con_backpic->columns[0];
|
||||
if (column->num_posts && !column->posts[0].topdelta)
|
||||
{
|
||||
UINT8 *source = (UINT8 *)(column) + 3;
|
||||
UINT8 *source = column->pixels;
|
||||
INT32 color = (source[0] | V_NOSCALESTART);
|
||||
// left side
|
||||
V_DrawFill(0, 0, x, con_curlines, color);
|
||||
|
|
|
@ -733,9 +733,6 @@ extern int
|
|||
#define NO_PNG_LUMPS
|
||||
#endif
|
||||
|
||||
/// Render flats on walls
|
||||
#define WALLFLATS
|
||||
|
||||
/// Maintain compatibility with older 2.2 demos
|
||||
#define OLD22DEMOCOMPAT
|
||||
|
||||
|
|
|
@ -54,7 +54,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
fixed_t yfrac, position, count;
|
||||
UINT8 *dest;
|
||||
const UINT8 *source;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
INT32 originy = 0;
|
||||
|
||||
// for writing a pixel to dest
|
||||
|
@ -68,18 +67,14 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
if (originPatch) // originPatch can be NULL here, unlike in the software version
|
||||
originy = originPatch->originy;
|
||||
|
||||
while (patchcol->topdelta != 0xff)
|
||||
for (unsigned i = 0; i < patchcol->num_posts; i++)
|
||||
{
|
||||
topdelta = patchcol->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
source = (const UINT8 *)patchcol + 3;
|
||||
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
|
||||
position = originy + topdelta;
|
||||
post_t *post = &patchcol->posts[i];
|
||||
source = patchcol->pixels + post->data_offset;
|
||||
count = ((post->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
|
||||
position = originy + post->topdelta;
|
||||
|
||||
yfrac = 0;
|
||||
//yfracstep = (patchcol->length << FRACBITS) / count;
|
||||
if (position < 0)
|
||||
{
|
||||
yfrac = -position<<FRACBITS;
|
||||
|
@ -106,22 +101,19 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
|
||||
alpha = 0x00;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap->data[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
// Alam: SRB2 uses Mingw, HUGS
|
||||
switch (bpp)
|
||||
{
|
||||
case 2 : // uhhhhhhhh..........
|
||||
case 2:
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
case 3 : colortemp = V_GetColor(texel);
|
||||
case 3:
|
||||
colortemp = V_GetColor(texel);
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
RGBA_t rgbatexel;
|
||||
|
@ -130,7 +122,8 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
case 4 : colortemp = V_GetColor(texel);
|
||||
case 4:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp.s.alpha = alpha;
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
|
@ -152,7 +145,6 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
dest += blockmodulo;
|
||||
yfrac += yfracstep;
|
||||
}
|
||||
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +157,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
fixed_t yfrac, position, count;
|
||||
UINT8 *dest;
|
||||
const UINT8 *source;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
INT32 topdelta;
|
||||
INT32 originy = 0;
|
||||
|
||||
// for writing a pixel to dest
|
||||
|
@ -177,18 +169,15 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
if (originPatch) // originPatch can be NULL here, unlike in the software version
|
||||
originy = originPatch->originy;
|
||||
|
||||
while (patchcol->topdelta != 0xff)
|
||||
for (unsigned i = 0; i < patchcol->num_posts; i++)
|
||||
{
|
||||
topdelta = patchcol->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
topdelta = patchheight-patchcol->length-topdelta;
|
||||
source = (const UINT8 *)patchcol + 3;
|
||||
count = ((patchcol->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
|
||||
post_t *post = &patchcol->posts[i];
|
||||
source = patchcol->pixels + post->data_offset;
|
||||
topdelta = patchheight-post->length-post->topdelta;
|
||||
count = ((post->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
|
||||
position = originy + topdelta;
|
||||
|
||||
yfrac = (patchcol->length-1) << FRACBITS;
|
||||
yfrac = (post->length-1) << FRACBITS;
|
||||
|
||||
if (position < 0)
|
||||
{
|
||||
|
@ -216,22 +205,19 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
|
||||
alpha = 0x00;
|
||||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap->data[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
// Alam: SRB2 uses Mingw, HUGS
|
||||
switch (bpp)
|
||||
{
|
||||
case 2 : // uhhhhhhhh..........
|
||||
case 2:
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
|
||||
texelu16 = (UINT16)((alpha<<8) | texel);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
break;
|
||||
case 3 : colortemp = V_GetColor(texel);
|
||||
case 3:
|
||||
colortemp = V_GetColor(texel);
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
RGBA_t rgbatexel;
|
||||
|
@ -240,7 +226,8 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
}
|
||||
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
break;
|
||||
case 4 : colortemp = V_GetColor(texel);
|
||||
case 4:
|
||||
colortemp = V_GetColor(texel);
|
||||
colortemp.s.alpha = alpha;
|
||||
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
|
||||
{
|
||||
|
@ -262,11 +249,9 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
dest += blockmodulo;
|
||||
yfrac -= yfracstep;
|
||||
}
|
||||
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Simplified patch caching function
|
||||
// for use by sprites and other patches that are not part of a wall texture
|
||||
// no alpha or flipping should be present since we do not want non-texture graphics to have them
|
||||
|
@ -307,7 +292,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
|||
// Draw each column to the block cache
|
||||
for (; ncols--; block += bpp, xfrac += xfracstep)
|
||||
{
|
||||
patchcol = (const column_t *)((const UINT8 *)realpatch->columns + (realpatch->columnofs[xfrac>>FRACBITS]));
|
||||
patchcol = &realpatch->columns[xfrac>>FRACBITS];
|
||||
|
||||
HWR_DrawColumnInCache(patchcol, block, mipmap,
|
||||
pblockheight, blockmodulo,
|
||||
|
@ -321,7 +306,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
|
|||
static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
||||
INT32 pblockwidth, INT32 pblockheight,
|
||||
texture_t *texture, texpatch_t *patch,
|
||||
const softwarepatch_t *realpatch)
|
||||
const patch_t *realpatch)
|
||||
{
|
||||
INT32 x, x1, x2;
|
||||
INT32 col, ncols;
|
||||
|
@ -345,8 +330,8 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
|||
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
|
||||
|
||||
x1 = patch->originx;
|
||||
width = SHORT(realpatch->width);
|
||||
height = SHORT(realpatch->height);
|
||||
width = realpatch->width;
|
||||
height = realpatch->height;
|
||||
x2 = x1 + width;
|
||||
|
||||
if (x1 > texture->width || x2 < 0)
|
||||
|
@ -372,14 +357,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
|||
col = x * pblockwidth / texture->width;
|
||||
ncols = ((x2 - x) * pblockwidth) / texture->width;
|
||||
|
||||
/*
|
||||
CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n",
|
||||
width, height,
|
||||
texture->width, texture->height,
|
||||
pblockwidth, pblockheight);
|
||||
CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x);
|
||||
*/
|
||||
|
||||
// source advance
|
||||
xfrac = 0;
|
||||
if (x1 < 0)
|
||||
|
@ -401,9 +378,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
|
|||
for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep)
|
||||
{
|
||||
if (patch->flip & 1)
|
||||
patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)]));
|
||||
patchcol = &realpatch->columns[(width-1)-(xfrac>>FRACBITS)];
|
||||
else
|
||||
patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS]));
|
||||
patchcol = &realpatch->columns[xfrac>>FRACBITS];
|
||||
|
||||
ColumnDrawerPointer(patchcol, block, mipmap,
|
||||
pblockheight, blockmodulo,
|
||||
|
@ -447,8 +424,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
UINT8 *block;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
softwarepatch_t *realpatch;
|
||||
UINT8 *pdata;
|
||||
INT32 blockwidth, blockheight, blocksize;
|
||||
|
||||
INT32 i;
|
||||
|
@ -500,30 +475,35 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
|
|||
// Composite the columns together.
|
||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||
{
|
||||
boolean dealloc = true;
|
||||
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
|
||||
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
|
||||
realpatch = (softwarepatch_t *)pdata;
|
||||
UINT16 wadnum = patch->wad;
|
||||
lumpnum_t lumpnum = patch->lump;
|
||||
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
patch_t *realpatch = NULL;
|
||||
boolean free_patch = true;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
|
||||
realpatch = (softwarepatch_t *)Picture_PNGConvert(pdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
|
||||
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
if (Picture_IsLumpPNG(pdata, lumplength))
|
||||
realpatch = (patch_t *)Picture_PNGConvert(pdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, lumplength, NULL, 0);
|
||||
else
|
||||
#endif
|
||||
#ifdef WALLFLATS
|
||||
if (texture->type == TEXTURETYPE_FLAT)
|
||||
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
|
||||
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
(void)lumplength;
|
||||
dealloc = false;
|
||||
// If this patch has already been loaded, we just use it from the cache.
|
||||
realpatch = W_GetCachedPatchNumPwad(wadnum, lumpnum);
|
||||
free_patch = false;
|
||||
|
||||
// Otherwise, we load it here.
|
||||
if (realpatch == NULL)
|
||||
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
|
||||
}
|
||||
|
||||
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
|
||||
|
||||
if (dealloc)
|
||||
Z_Unlock(realpatch);
|
||||
if (free_patch)
|
||||
Patch_Free(realpatch);
|
||||
}
|
||||
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
|
||||
if (format2bpp(grtex->mipmap.format)==4)
|
||||
|
@ -753,7 +733,7 @@ void HWR_LoadMapTextures(size_t pnumtextures)
|
|||
gl_textures = calloc(gl_numtextures, sizeof(*gl_textures));
|
||||
gl_flats = calloc(gl_numtextures, sizeof(*gl_flats));
|
||||
|
||||
if ((gl_textures == NULL) || (gl_flats == NULL))
|
||||
if (gl_textures == NULL || gl_flats == NULL)
|
||||
I_Error("HWR_LoadMapTextures: ran out of memory for OpenGL textures");
|
||||
|
||||
gl_maptexturesloaded = true;
|
||||
|
@ -818,26 +798,6 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
|
|||
W_ReadLump(flatlumpnum, Z_Malloc(size, PU_HWRCACHE, &grMipmap->data));
|
||||
}
|
||||
|
||||
static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
|
||||
{
|
||||
UINT8 *flat;
|
||||
UINT8 *converted;
|
||||
size_t size;
|
||||
|
||||
// setup the texture info
|
||||
grMipmap->format = GL_TEXFMT_P_8;
|
||||
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
|
||||
|
||||
grMipmap->width = (UINT16)textures[texturenum]->width;
|
||||
grMipmap->height = (UINT16)textures[texturenum]->height;
|
||||
size = (grMipmap->width * grMipmap->height);
|
||||
|
||||
flat = Z_Malloc(size, PU_HWRCACHE, &grMipmap->data);
|
||||
converted = (UINT8 *)Picture_TextureToFlat(texturenum);
|
||||
M_Memcpy(flat, converted, size);
|
||||
Z_Free(converted);
|
||||
}
|
||||
|
||||
// Download a Doom 'flat' to the hardware cache and make it ready for use
|
||||
void HWR_GetRawFlat(lumpnum_t flatlumpnum)
|
||||
{
|
||||
|
@ -863,96 +823,40 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
|
|||
|
||||
void HWR_GetLevelFlat(levelflat_t *levelflat)
|
||||
{
|
||||
// Who knows?
|
||||
if (levelflat == NULL)
|
||||
return;
|
||||
|
||||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
HWR_GetRawFlat(levelflat->u.flat.lumpnum);
|
||||
else if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
if (levelflat->type == LEVELFLAT_NONE)
|
||||
{
|
||||
GLMapTexture_t *grtex;
|
||||
INT32 texturenum = levelflat->u.texture.num;
|
||||
#ifdef PARANOIA
|
||||
if ((unsigned)texturenum >= gl_numtextures)
|
||||
I_Error("HWR_GetLevelFlat: texturenum >= numtextures");
|
||||
#endif
|
||||
|
||||
// Who knows?
|
||||
if (texturenum == 0 || texturenum == -1)
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Every texture in memory, stored as a 8-bit flat. Wow!
|
||||
grtex = &gl_flats[texturenum];
|
||||
INT32 texturenum = texturetranslation[levelflat->texture_id];
|
||||
if (texturenum <= 0)
|
||||
{
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate flat if missing from the cache
|
||||
if (!grtex->mipmap.data && !grtex->mipmap.downloaded)
|
||||
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum);
|
||||
GLMapTexture_t *grtex = &gl_flats[texturenum];
|
||||
GLMipmap_t *grMipmap = &grtex->mipmap;
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtex->mipmap.downloaded)
|
||||
if (!grMipmap->data && !grMipmap->downloaded)
|
||||
{
|
||||
grMipmap->format = GL_TEXFMT_P_8;
|
||||
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
|
||||
|
||||
grMipmap->width = (UINT16)textures[texturenum]->width;
|
||||
grMipmap->height = (UINT16)textures[texturenum]->height;
|
||||
|
||||
size_t size = grMipmap->width * grMipmap->height;
|
||||
memcpy(Z_Malloc(size, PU_HWRCACHE, &grMipmap->data), R_GetFlatForTexture(texturenum), size);
|
||||
}
|
||||
|
||||
if (!grMipmap->downloaded)
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
|
||||
HWR_SetCurrentTexture(&grtex->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_PATCH)
|
||||
{
|
||||
patch_t *patch = W_CachePatchNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
||||
levelflat->width = (UINT16)(patch->width);
|
||||
levelflat->height = (UINT16)(patch->height);
|
||||
HWR_GetPatch(patch);
|
||||
}
|
||||
#ifndef NO_PNG_LUMPS
|
||||
else if (levelflat->type == LEVELFLAT_PNG)
|
||||
{
|
||||
GLMipmap_t *mipmap = levelflat->mipmap;
|
||||
|
||||
// Cache the picture.
|
||||
if (!levelflat->mippic)
|
||||
{
|
||||
INT32 pngwidth = 0, pngheight = 0;
|
||||
void *pic = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0);
|
||||
|
||||
Z_ChangeTag(pic, PU_LEVEL);
|
||||
Z_SetUser(pic, &levelflat->mippic);
|
||||
|
||||
levelflat->width = (UINT16)pngwidth;
|
||||
levelflat->height = (UINT16)pngheight;
|
||||
}
|
||||
|
||||
// Make the mipmap.
|
||||
if (mipmap == NULL)
|
||||
{
|
||||
mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_STATIC, NULL);
|
||||
mipmap->format = GL_TEXFMT_P_8;
|
||||
mipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
|
||||
levelflat->mipmap = mipmap;
|
||||
}
|
||||
|
||||
if (!mipmap->data && !mipmap->downloaded)
|
||||
{
|
||||
UINT8 *flat;
|
||||
size_t size;
|
||||
|
||||
if (levelflat->mippic == NULL)
|
||||
I_Error("HWR_GetLevelFlat: levelflat->mippic == NULL");
|
||||
|
||||
mipmap->width = levelflat->width;
|
||||
mipmap->height = levelflat->height;
|
||||
|
||||
size = (mipmap->width * mipmap->height);
|
||||
flat = Z_Malloc(size, PU_LEVEL, &mipmap->data);
|
||||
M_Memcpy(flat, levelflat->mippic, size);
|
||||
}
|
||||
|
||||
// Tell the hardware driver to bind the current texture to the flat's mipmap
|
||||
HWR_SetCurrentTexture(mipmap);
|
||||
}
|
||||
#endif
|
||||
else // set no texture
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
// --------------------+
|
||||
|
@ -1066,145 +970,13 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
|
|||
Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
static const INT32 picmode2GR[] =
|
||||
{
|
||||
GL_TEXFMT_P_8, // PALETTE
|
||||
0, // INTENSITY (unsupported yet)
|
||||
GL_TEXFMT_ALPHA_INTENSITY_88, // INTENSITY_ALPHA (corona use this)
|
||||
0, // RGB24 (unsupported yet)
|
||||
GL_TEXFMT_RGBA, // RGBA32 (opengl only)
|
||||
};
|
||||
|
||||
static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheight,
|
||||
INT32 blockmodulo, pic_t *pic, INT32 bpp)
|
||||
{
|
||||
INT32 i,j;
|
||||
fixed_t posx, posy, stepx, stepy;
|
||||
UINT8 *dest, *src, texel;
|
||||
UINT16 texelu16;
|
||||
INT32 picbpp;
|
||||
RGBA_t col;
|
||||
|
||||
stepy = ((INT32)SHORT(pic->height)<<FRACBITS)/pblockheight;
|
||||
stepx = ((INT32)SHORT(pic->width)<<FRACBITS)/pblockwidth;
|
||||
picbpp = format2bpp(picmode2GR[pic->mode]);
|
||||
posy = 0;
|
||||
for (j = 0; j < pblockheight; j++)
|
||||
{
|
||||
posx = 0;
|
||||
dest = &block[j*blockmodulo];
|
||||
src = &pic->data[(posy>>FRACBITS)*SHORT(pic->width)*picbpp];
|
||||
for (i = 0; i < pblockwidth;i++)
|
||||
{
|
||||
switch (pic->mode)
|
||||
{ // source bpp
|
||||
case PALETTE :
|
||||
texel = src[(posx+FRACUNIT/2)>>FRACBITS];
|
||||
switch (bpp)
|
||||
{ // destination bpp
|
||||
case 1 :
|
||||
*dest++ = texel; break;
|
||||
case 2 :
|
||||
texelu16 = (UINT16)(texel | 0xff00);
|
||||
memcpy(dest, &texelu16, sizeof(UINT16));
|
||||
dest += sizeof(UINT16);
|
||||
break;
|
||||
case 3 :
|
||||
col = V_GetColor(texel);
|
||||
memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8));
|
||||
dest += sizeof(RGBA_t)-sizeof(UINT8);
|
||||
break;
|
||||
case 4 :
|
||||
memcpy(dest, &V_GetColor(texel), sizeof(RGBA_t));
|
||||
dest += sizeof(RGBA_t);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case INTENSITY :
|
||||
*dest++ = src[(posx+FRACUNIT/2)>>FRACBITS];
|
||||
break;
|
||||
case INTENSITY_ALPHA : // assume dest bpp = 2
|
||||
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT16), sizeof(UINT16));
|
||||
dest += sizeof(UINT16);
|
||||
break;
|
||||
case RGB24 :
|
||||
break; // not supported yet
|
||||
case RGBA32 : // assume dest bpp = 4
|
||||
dest += sizeof(UINT32);
|
||||
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT32), sizeof(UINT32));
|
||||
break;
|
||||
}
|
||||
posx += stepx;
|
||||
}
|
||||
posy += stepy;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_GetPic : Download a Doom pic (raw row encoded with no 'holes')
|
||||
// Returns :
|
||||
// -----------------+
|
||||
patch_t *HWR_GetPic(lumpnum_t lumpnum)
|
||||
{
|
||||
patch_t *patch = HWR_GetCachedGLPatch(lumpnum);
|
||||
GLPatch_t *grPatch = (GLPatch_t *)(patch->hardware);
|
||||
|
||||
if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data)
|
||||
{
|
||||
pic_t *pic;
|
||||
UINT8 *block;
|
||||
size_t len;
|
||||
|
||||
pic = W_CacheLumpNum(lumpnum, PU_CACHE);
|
||||
patch->width = SHORT(pic->width);
|
||||
patch->height = SHORT(pic->height);
|
||||
len = W_LumpLength(lumpnum) - sizeof (pic_t);
|
||||
|
||||
grPatch->mipmap->width = (UINT16)patch->width;
|
||||
grPatch->mipmap->height = (UINT16)patch->height;
|
||||
|
||||
if (pic->mode == PALETTE)
|
||||
grPatch->mipmap->format = textureformat; // can be set by driver
|
||||
else
|
||||
grPatch->mipmap->format = picmode2GR[pic->mode];
|
||||
|
||||
Z_Free(grPatch->mipmap->data);
|
||||
|
||||
// allocate block
|
||||
block = MakeBlock(grPatch->mipmap);
|
||||
|
||||
if (patch->width == SHORT(pic->width) &&
|
||||
patch->height == SHORT(pic->height) &&
|
||||
format2bpp(grPatch->mipmap->format) == format2bpp(picmode2GR[pic->mode]))
|
||||
{
|
||||
// no conversion needed
|
||||
M_Memcpy(grPatch->mipmap->data, pic->data,len);
|
||||
}
|
||||
else
|
||||
HWR_DrawPicInCache(block, SHORT(pic->width), SHORT(pic->height),
|
||||
SHORT(pic->width)*format2bpp(grPatch->mipmap->format),
|
||||
pic,
|
||||
format2bpp(grPatch->mipmap->format));
|
||||
|
||||
Z_Unlock(pic);
|
||||
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
grPatch->mipmap->flags = 0;
|
||||
grPatch->max_s = grPatch->max_t = 1.0f;
|
||||
}
|
||||
HWD.pfnSetTexture(grPatch->mipmap);
|
||||
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grPatch->mipmap->data, grPatch->mipmap->downloaded);
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
patch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
|
||||
{
|
||||
lumpcache_t *lumpcache = wadfiles[wadnum]->patchcache;
|
||||
if (!lumpcache[lumpnum])
|
||||
{
|
||||
void *ptr = Z_Calloc(sizeof(patch_t), PU_PATCH, &lumpcache[lumpnum]);
|
||||
Patch_Create(NULL, 0, ptr);
|
||||
void *ptr = Patch_Create(0, 0);
|
||||
Z_SetUser(ptr, &lumpcache[lumpnum]);
|
||||
Patch_AllocateHardwarePatch(ptr);
|
||||
}
|
||||
return (patch_t *)(lumpcache[lumpnum]);
|
||||
|
|
|
@ -127,6 +127,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
float cy = FIXED_TO_FLOAT(y);
|
||||
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
|
||||
UINT8 blendmode = ((option & V_BLENDMASK) >> V_BLENDSHIFT);
|
||||
UINT8 opacity = 0xFF;
|
||||
GLPatch_t *hwrPatch;
|
||||
|
||||
// 3--2
|
||||
|
@ -145,6 +146,14 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
|
||||
hwrPatch = ((GLPatch_t *)gpatch->hardware);
|
||||
|
||||
if (alphalevel)
|
||||
{
|
||||
if (alphalevel == 10) opacity = softwaretranstogl_lo[st_translucency]; // V_HUDTRANSHALF
|
||||
else if (alphalevel == 11) opacity = softwaretranstogl[st_translucency]; // V_HUDTRANS
|
||||
else if (alphalevel == 12) opacity = softwaretranstogl_hi[st_translucency]; // V_HUDTRANSDOUBLE
|
||||
else opacity = softwaretranstogl[10-alphalevel];
|
||||
}
|
||||
|
||||
dup = (float)vid.dup;
|
||||
|
||||
switch (option & V_SCALEPATCHMASK)
|
||||
|
@ -261,13 +270,13 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
||||
// cx and cy are possibly *slightly* off from float maths
|
||||
// This is done before here compared to software because we directly alter cx and cy to centre
|
||||
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
|
||||
if (opacity == 0xFF && cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
|
||||
{
|
||||
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
|
||||
if (!column->topdelta)
|
||||
const column_t *column = &gpatch->columns[0];
|
||||
if (column->num_posts && !column->posts[0].topdelta)
|
||||
{
|
||||
const UINT8 *source = (const UINT8 *)(column) + 3;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
|
||||
const UINT8 *source = column->pixels;
|
||||
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]);
|
||||
}
|
||||
}
|
||||
// centre screen
|
||||
|
@ -345,11 +354,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
|
|||
{
|
||||
FSurfaceInfo Surf;
|
||||
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
|
||||
|
||||
if (alphalevel == 10) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; // V_HUDTRANSHALF
|
||||
else if (alphalevel == 11) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; // V_HUDTRANS
|
||||
else if (alphalevel == 12) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; // V_HUDTRANSDOUBLE
|
||||
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
|
||||
Surf.PolyColor.s.alpha = opacity;
|
||||
flags |= PF_Modulated;
|
||||
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
|
||||
}
|
||||
|
@ -648,46 +653,10 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
|
|||
HWD.pfnDrawPolygon(NULL, v, 4, flags);
|
||||
}
|
||||
|
||||
void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
|
||||
{
|
||||
FOutVector v[4];
|
||||
const patch_t *patch;
|
||||
|
||||
// make pic ready in hardware cache
|
||||
patch = HWR_GetPic(lumpnum);
|
||||
|
||||
// 3--2
|
||||
// | /|
|
||||
// |/ |
|
||||
// 0--1
|
||||
|
||||
v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1;
|
||||
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdup))/vid.width - 1;
|
||||
v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height;
|
||||
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdup))/vid.height;
|
||||
|
||||
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
|
||||
|
||||
v[0].s = v[3].s = 0;
|
||||
v[2].s = v[1].s = ((GLPatch_t *)patch->hardware)->max_s;
|
||||
v[0].t = v[1].t = 0;
|
||||
v[2].t = v[3].t = ((GLPatch_t *)patch->hardware)->max_t;
|
||||
|
||||
|
||||
//Hurdler: Boris, the same comment as above... but maybe for pics
|
||||
// it not a problem since they don't have any transparent pixel
|
||||
// if I'm right !?
|
||||
// But then, the question is: why not 0 instead of PF_Masked ?
|
||||
// or maybe PF_Environment ??? (like what I said above)
|
||||
// BP: PF_Environment don't change anything ! and 0 is undifined
|
||||
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// V_VIDEO.C STUFF
|
||||
// ==========================================================================
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Fills a box of pixels using a flat texture as a pattern
|
||||
// --------------------------------------------------------------------------
|
||||
|
|
|
@ -428,25 +428,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
// set texture for polygon
|
||||
if (levelflat != NULL)
|
||||
{
|
||||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
unsigned flatflag = R_GetFlatSize(len);
|
||||
fflatwidth = fflatheight = (float)flatflag;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
fflatwidth = textures[levelflat->u.texture.num]->width;
|
||||
fflatheight = textures[levelflat->u.texture.num]->height;
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_PATCH || levelflat->type == LEVELFLAT_PNG)
|
||||
{
|
||||
fflatwidth = levelflat->width;
|
||||
fflatheight = levelflat->height;
|
||||
}
|
||||
}
|
||||
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)];
|
||||
fflatwidth = texture->width;
|
||||
fflatheight = texture->height;
|
||||
}
|
||||
else // set no texture
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
|
@ -2745,25 +2729,9 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
// set texture for polygon
|
||||
if (levelflat != NULL)
|
||||
{
|
||||
if (levelflat->type == LEVELFLAT_FLAT)
|
||||
{
|
||||
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
|
||||
unsigned flatflag = R_GetFlatSize(len);
|
||||
fflatwidth = fflatheight = (float)flatflag;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (levelflat->type == LEVELFLAT_TEXTURE)
|
||||
{
|
||||
fflatwidth = textures[levelflat->u.texture.num]->width;
|
||||
fflatheight = textures[levelflat->u.texture.num]->height;
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_PATCH || levelflat->type == LEVELFLAT_PNG)
|
||||
{
|
||||
fflatwidth = levelflat->width;
|
||||
fflatheight = levelflat->height;
|
||||
}
|
||||
}
|
||||
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)];
|
||||
fflatwidth = texture->width;
|
||||
fflatheight = texture->height;
|
||||
}
|
||||
else // set no texture
|
||||
HWR_SetCurrentTexture(NULL);
|
||||
|
@ -2810,8 +2778,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
}
|
||||
}
|
||||
|
||||
anglef = ANG2RAD(InvAngle(angle));
|
||||
|
||||
for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++)
|
||||
{
|
||||
// Go from the polysector's original vertex locations
|
||||
|
@ -2825,6 +2791,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
tempxsow = v3d->s;
|
||||
tempytow = v3d->t;
|
||||
|
||||
anglef = ANG2RAD(InvAngle(angle));
|
||||
|
||||
v3d->s = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));
|
||||
v3d->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
|
||||
}
|
||||
|
|
|
@ -379,7 +379,7 @@ static void md2_loadTexture(md2_t *model)
|
|||
Z_Free(grPatch->mipmap->data);
|
||||
}
|
||||
else
|
||||
model->grpatch = patch = Patch_Create(NULL, 0, NULL);
|
||||
model->grpatch = patch = Patch_Create(0, 0);
|
||||
|
||||
if (!patch->hardware)
|
||||
Patch_AllocateHardwarePatch(patch);
|
||||
|
@ -444,7 +444,7 @@ static void md2_loadBlendTexture(md2_t *model)
|
|||
Z_Free(grPatch->mipmap->data);
|
||||
}
|
||||
else
|
||||
model->blendgrpatch = patch = Patch_Create(NULL, 0, NULL);
|
||||
model->blendgrpatch = patch = Patch_Create(0, 0);
|
||||
|
||||
if (!patch->hardware)
|
||||
Patch_AllocateHardwarePatch(patch);
|
||||
|
|
|
@ -6330,19 +6330,12 @@ static void M_StopMessage(INT32 choice)
|
|||
// Defines what image is used in (menuitem_t)->text.
|
||||
// You can even put multiple images in one menu!
|
||||
static void M_DrawImageDef(void)
|
||||
{
|
||||
// Grr. Need to autodetect for pic_ts.
|
||||
pic_t *pictest = (pic_t *)W_CacheLumpName(currentMenu->menuitems[itemOn].text,PU_CACHE);
|
||||
if (!pictest->zero)
|
||||
V_DrawScaledPic(0,0,0,W_GetNumForName(currentMenu->menuitems[itemOn].text));
|
||||
else
|
||||
{
|
||||
patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text, PU_PATCH);
|
||||
if (patch->width <= BASEVIDWIDTH)
|
||||
V_DrawScaledPatch(0,0,0,patch);
|
||||
else
|
||||
V_DrawSmallScaledPatch(0,0,0,patch);
|
||||
}
|
||||
|
||||
if (currentMenu->numitems > 1)
|
||||
V_DrawString(0,192,V_TRANSLUCENT, va("PAGE %d of %hd", itemOn+1, currentMenu->numitems));
|
||||
|
|
|
@ -537,20 +537,14 @@ levelflat_t *foundflats;
|
|||
//SoM: Other files want this info.
|
||||
size_t P_PrecacheLevelFlats(void)
|
||||
{
|
||||
lumpnum_t lump;
|
||||
size_t i;
|
||||
|
||||
//SoM: 4/18/2000: New flat code to make use of levelflats.
|
||||
flatmemory = 0;
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
if (levelflats[i].type == LEVELFLAT_FLAT)
|
||||
{
|
||||
lump = levelflats[i].u.flat.lumpnum;
|
||||
if (devparm)
|
||||
flatmemory += W_LumpLength(lump);
|
||||
R_GetFlat(lump);
|
||||
}
|
||||
if (levelflats[i].type != LEVELFLAT_NONE)
|
||||
R_GetFlat(&levelflats[i]);
|
||||
}
|
||||
return flatmemory;
|
||||
}
|
||||
|
@ -562,19 +556,8 @@ or NULL if we want to allocate it now.
|
|||
static INT32
|
||||
Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
UINT8 buffer[8];
|
||||
#endif
|
||||
|
||||
lumpnum_t flatnum;
|
||||
int texturenum;
|
||||
UINT8 *flatpatch;
|
||||
size_t lumplength;
|
||||
|
||||
size_t i;
|
||||
|
||||
// Scan through the already found flats, return if it matches.
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
for (size_t i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
if (strnicmp(levelflat[i].name, flatname, 8) == 0)
|
||||
return i;
|
||||
|
@ -598,64 +581,35 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
|
|||
strlcpy(levelflat->name, flatname, sizeof (levelflat->name));
|
||||
strupr(levelflat->name);
|
||||
|
||||
/* If we can't find a flat, try looking for a texture! */
|
||||
if (( flatnum = R_GetFlatNumForName(levelflat->name) ) == LUMPERROR)
|
||||
{
|
||||
if (( texturenum = R_CheckTextureNumForName(levelflat->name) ) == -1)
|
||||
{
|
||||
// check for REDWALL
|
||||
if (( texturenum = R_CheckTextureNumForName("REDWALL") ) != -1)
|
||||
goto texturefound;
|
||||
// check for REDFLR
|
||||
else if (( flatnum = R_GetFlatNumForName("REDFLR") ) != LUMPERROR)
|
||||
goto flatfound;
|
||||
// nevermind
|
||||
levelflat->type = LEVELFLAT_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturefound:
|
||||
levelflat->type = LEVELFLAT_TEXTURE;
|
||||
levelflat->u.texture. num = texturenum;
|
||||
levelflat->u.texture.lastnum = texturenum;
|
||||
/* start out unanimated */
|
||||
levelflat->u.texture.basenum = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flatfound:
|
||||
/* This could be a flat, patch, or PNG. */
|
||||
flatpatch = W_CacheLumpNum(flatnum, PU_CACHE);
|
||||
lumplength = W_LumpLength(flatnum);
|
||||
if (Picture_CheckIfDoomPatch((softwarepatch_t *)flatpatch, lumplength))
|
||||
levelflat->type = LEVELFLAT_PATCH;
|
||||
else
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
/*
|
||||
Only need eight bytes for PNG headers.
|
||||
FIXME: Put this elsewhere.
|
||||
*/
|
||||
W_ReadLumpHeader(flatnum, buffer, 8, 0);
|
||||
if (Picture_IsLumpPNG(buffer, lumplength))
|
||||
levelflat->type = LEVELFLAT_PNG;
|
||||
else
|
||||
#endif/*NO_PNG_LUMPS*/
|
||||
levelflat->type = LEVELFLAT_FLAT;/* phew */
|
||||
}
|
||||
if (flatpatch)
|
||||
Z_Free(flatpatch);
|
||||
|
||||
levelflat->u.flat. lumpnum = flatnum;
|
||||
levelflat->u.flat.baselumpnum = LUMPERROR;
|
||||
// Look for a flat
|
||||
int texturenum = R_CheckFlatNumForName(levelflat->name);
|
||||
if (texturenum <= 0)
|
||||
{
|
||||
// If we can't find a flat, try looking for a texture!
|
||||
texturenum = R_CheckTextureNumForName(levelflat->name);
|
||||
if (texturenum <= 0)
|
||||
{
|
||||
// Use "not found" texture
|
||||
texturenum = R_CheckTextureNumForName("REDWALL");
|
||||
|
||||
// Give up?
|
||||
if (texturenum <= 0)
|
||||
{
|
||||
levelflat->type = LEVELFLAT_NONE;
|
||||
texturenum = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
levelflat->texture_id = texturenum;
|
||||
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);
|
||||
#endif
|
||||
|
||||
return ( numlevelflats++ );
|
||||
return numlevelflats++;
|
||||
}
|
||||
|
||||
// Auxiliary function. Find a flat in the active wad files,
|
||||
|
@ -3238,9 +3192,6 @@ static boolean P_LoadMapData(const virtres_t *virt)
|
|||
levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t));
|
||||
free(foundflats);
|
||||
|
||||
// search for animated flats and set up
|
||||
P_SetupLevelFlatAnims();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,6 @@ extern lumpnum_t lastloadedmaplumpnum; // for comparative savegame
|
|||
enum
|
||||
{
|
||||
LEVELFLAT_NONE,/* HOM time my friend */
|
||||
LEVELFLAT_FLAT,
|
||||
LEVELFLAT_PATCH,
|
||||
LEVELFLAT_PNG,
|
||||
LEVELFLAT_TEXTURE,
|
||||
};
|
||||
|
||||
|
@ -47,41 +44,8 @@ enum
|
|||
typedef struct
|
||||
{
|
||||
char name[9]; // resource name from wad
|
||||
|
||||
UINT8 type;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
lumpnum_t lumpnum; // lump number of the flat
|
||||
// for flat animation
|
||||
lumpnum_t baselumpnum;
|
||||
}
|
||||
flat;
|
||||
struct
|
||||
{
|
||||
INT32 num;
|
||||
INT32 lastnum; // texture number of the flat
|
||||
// for flat animation
|
||||
INT32 basenum;
|
||||
}
|
||||
texture;
|
||||
}
|
||||
u;
|
||||
|
||||
UINT16 width, height;
|
||||
|
||||
// for flat animation
|
||||
INT32 animseq; // start pos. in the anim sequence
|
||||
INT32 numpics;
|
||||
INT32 speed;
|
||||
|
||||
// for textures
|
||||
UINT8 *picture;
|
||||
#ifdef HWRENDER
|
||||
void *mipmap;
|
||||
void *mippic;
|
||||
#endif
|
||||
INT32 texture_id;
|
||||
} levelflat_t;
|
||||
|
||||
extern size_t numlevelflats;
|
||||
|
|
183
src/p_spec.c
183
src/p_spec.c
|
@ -62,17 +62,12 @@ sectorportal_t *secportals;
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
SINT8 istexture; ///< ::true for a texture, ::false for a flat
|
||||
INT32 picnum; ///< The end flat number
|
||||
INT32 basepic; ///< The start flat number
|
||||
INT32 picnum; ///< The end texture number
|
||||
INT32 basepic; ///< The start texture number
|
||||
INT32 numpics; ///< Number of frames in the animation
|
||||
tic_t speed; ///< Number of tics for which each frame is shown
|
||||
} anim_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
/** Animated texture definition.
|
||||
* Used for loading an ANIMDEFS lump from a wad.
|
||||
*
|
||||
|
@ -90,10 +85,6 @@ typedef struct
|
|||
INT32 speed; ///< Number of tics for which each frame is shown.
|
||||
} ATTRPACK animdef_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT32 count;
|
||||
|
@ -138,17 +129,32 @@ static size_t maxanims;
|
|||
|
||||
static animdef_t *animdefs = NULL;
|
||||
|
||||
// Increase the size of animdefs to make room for a new animation definition
|
||||
static void GrowAnimDefs(void)
|
||||
{
|
||||
maxanims++;
|
||||
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
// A prototype; here instead of p_spec.h, so they're "private"
|
||||
void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum);
|
||||
void P_ParseAnimationDefintion(SINT8 istexture);
|
||||
|
||||
static boolean P_FindTextureForAnimation(anim_t *anim, animdef_t *animdef)
|
||||
{
|
||||
if (R_CheckTextureNumForName(animdef->startname) == -1)
|
||||
return false;
|
||||
|
||||
anim->picnum = R_TextureNumForName(animdef->endname);
|
||||
anim->basepic = R_TextureNumForName(animdef->startname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean P_FindFlatForAnimation(anim_t *anim, animdef_t *animdef)
|
||||
{
|
||||
if (R_CheckFlatNumForName(animdef->startname) == -1)
|
||||
return false;
|
||||
|
||||
anim->picnum = R_CheckFlatNumForName(animdef->endname);
|
||||
anim->basepic = R_CheckFlatNumForName(animdef->startname);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Sets up texture and flat animations.
|
||||
*
|
||||
* Converts an ::animdef_t array loaded from a lump into
|
||||
|
@ -156,7 +162,6 @@ void P_ParseAnimationDefintion(SINT8 istexture);
|
|||
*
|
||||
* Issues an error if any animation cycles are invalid.
|
||||
*
|
||||
* \sa P_FindAnimatedFlat, P_SetupLevelFlatAnims
|
||||
* \author Steven McGranahan (original), Shadow Hog (had to rewrite it to handle multiple WADs), JTE (had to rewrite it to handle multiple WADs _correctly_)
|
||||
*/
|
||||
void P_InitPicAnims(void)
|
||||
|
@ -199,37 +204,39 @@ void P_InitPicAnims(void)
|
|||
lastanim = anims;
|
||||
for (i = 0; animdefs[i].istexture != -1; i++)
|
||||
{
|
||||
animdef_t *animdef = &animdefs[i];
|
||||
|
||||
// If this animation is for a texture, look for one first, THEN look for a flat
|
||||
if (animdefs[i].istexture)
|
||||
{
|
||||
if (R_CheckTextureNumForName(animdefs[i].startname) == -1)
|
||||
if (!P_FindTextureForAnimation(lastanim, animdef))
|
||||
{
|
||||
if (!P_FindFlatForAnimation(lastanim, animdef))
|
||||
continue;
|
||||
|
||||
lastanim->picnum = R_TextureNumForName(animdefs[i].endname);
|
||||
lastanim->basepic = R_TextureNumForName(animdefs[i].startname);
|
||||
}
|
||||
}
|
||||
// Else, if this animation is for a flat, look for one first, THEN look for a texture
|
||||
else
|
||||
{
|
||||
if ((W_CheckNumForName(animdefs[i].startname)) == LUMPERROR)
|
||||
if (!P_FindFlatForAnimation(lastanim, animdef))
|
||||
{
|
||||
if (!P_FindTextureForAnimation(lastanim, animdef))
|
||||
continue;
|
||||
|
||||
lastanim->picnum = R_GetFlatNumForName(animdefs[i].endname);
|
||||
lastanim->basepic = R_GetFlatNumForName(animdefs[i].startname);
|
||||
}
|
||||
}
|
||||
|
||||
lastanim->istexture = animdefs[i].istexture;
|
||||
lastanim->numpics = lastanim->picnum - lastanim->basepic + 1;
|
||||
|
||||
if (lastanim->numpics < 2)
|
||||
{
|
||||
free(anims);
|
||||
I_Error("P_InitPicAnims: bad cycle from %s to %s",
|
||||
animdefs[i].startname, animdefs[i].endname);
|
||||
animdef->startname, animdef->endname);
|
||||
}
|
||||
|
||||
lastanim->speed = LONG(animdefs[i].speed);
|
||||
lastanim->speed = animdef->speed;
|
||||
lastanim++;
|
||||
}
|
||||
lastanim->istexture = -1;
|
||||
R_ClearTextureNumCache(false);
|
||||
|
||||
// Clear animdefs now that we're done with it.
|
||||
|
@ -354,7 +361,8 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
if (i == maxanims)
|
||||
{
|
||||
// Increase the size to make room for the new animation definition
|
||||
GrowAnimDefs();
|
||||
maxanims++;
|
||||
animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL);
|
||||
strncpy(animdefs[i].startname, animdefsToken, 9);
|
||||
}
|
||||
|
||||
|
@ -440,83 +448,6 @@ void P_ParseAnimationDefintion(SINT8 istexture)
|
|||
}
|
||||
animdefs[i].speed = animSpeed;
|
||||
Z_Free(animdefsToken);
|
||||
|
||||
#ifdef WALLFLATS
|
||||
// hehe... uhh.....
|
||||
if (!istexture)
|
||||
{
|
||||
GrowAnimDefs();
|
||||
M_Memcpy(&animdefs[maxanims-1], &animdefs[i], sizeof(animdef_t));
|
||||
animdefs[maxanims-1].istexture = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Checks for flats in levelflats that are part of a flat animation sequence
|
||||
* and sets them up for animation.
|
||||
*
|
||||
* \param animnum Index into ::anims to find flats for.
|
||||
* \sa P_SetupLevelFlatAnims
|
||||
*/
|
||||
static inline void P_FindAnimatedFlat(INT32 animnum)
|
||||
{
|
||||
size_t i;
|
||||
lumpnum_t startflatnum, endflatnum;
|
||||
levelflat_t *foundflats;
|
||||
|
||||
foundflats = levelflats;
|
||||
startflatnum = anims[animnum].basepic;
|
||||
endflatnum = anims[animnum].picnum;
|
||||
|
||||
// note: high word of lumpnum is the wad number
|
||||
if ((startflatnum>>16) != (endflatnum>>16))
|
||||
I_Error("AnimatedFlat start %s not in same wad as end %s\n",
|
||||
animdefs[animnum].startname, animdefs[animnum].endname);
|
||||
|
||||
//
|
||||
// now search through the levelflats if this anim flat sequence is used
|
||||
//
|
||||
for (i = 0; i < numlevelflats; i++, foundflats++)
|
||||
{
|
||||
// is that levelflat from the flat anim sequence ?
|
||||
if ((anims[animnum].istexture) && (foundflats->type == LEVELFLAT_TEXTURE)
|
||||
&& ((UINT16)foundflats->u.texture.num >= startflatnum && (UINT16)foundflats->u.texture.num <= endflatnum))
|
||||
{
|
||||
foundflats->u.texture.basenum = startflatnum;
|
||||
foundflats->animseq = foundflats->u.texture.num - startflatnum;
|
||||
foundflats->numpics = endflatnum - startflatnum + 1;
|
||||
foundflats->speed = anims[animnum].speed;
|
||||
|
||||
CONS_Debug(DBG_SETUP, "animflat: #%03d name:%.8s animseq:%d numpics:%d speed:%d\n",
|
||||
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
|
||||
foundflats->numpics,foundflats->speed);
|
||||
}
|
||||
else if ((!anims[animnum].istexture) && (foundflats->type == LEVELFLAT_FLAT)
|
||||
&& (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum))
|
||||
{
|
||||
foundflats->u.flat.baselumpnum = startflatnum;
|
||||
foundflats->animseq = foundflats->u.flat.lumpnum - startflatnum;
|
||||
foundflats->numpics = endflatnum - startflatnum + 1;
|
||||
foundflats->speed = anims[animnum].speed;
|
||||
|
||||
CONS_Debug(DBG_SETUP, "animflat: #%03d name:%.8s animseq:%d numpics:%d speed:%d\n",
|
||||
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
|
||||
foundflats->numpics,foundflats->speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets up all flats used in a level.
|
||||
*
|
||||
* \sa P_InitPicAnims, P_FindAnimatedFlat
|
||||
*/
|
||||
void P_SetupLevelFlatAnims(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// the original game flat anim sequences
|
||||
for (i = 0; anims[i].istexture != -1; i++)
|
||||
P_FindAnimatedFlat(i);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -5405,13 +5336,6 @@ void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable)
|
|||
*/
|
||||
void P_UpdateSpecials(void)
|
||||
{
|
||||
anim_t *anim;
|
||||
INT32 i;
|
||||
INT32 pic;
|
||||
size_t j;
|
||||
|
||||
levelflat_t *foundflats; // for flat animation
|
||||
|
||||
// LEVEL TIMER
|
||||
P_CheckTimeLimit();
|
||||
|
||||
|
@ -5419,37 +5343,18 @@ void P_UpdateSpecials(void)
|
|||
P_CheckPointLimit();
|
||||
|
||||
// ANIMATE TEXTURES
|
||||
for (anim = anims; anim < lastanim; anim++)
|
||||
for (anim_t *anim = anims; anim < lastanim; anim++)
|
||||
{
|
||||
for (i = 0; i < anim->numpics; i++)
|
||||
for (INT32 i = 0; i < anim->numpics; i++)
|
||||
{
|
||||
pic = anim->basepic + ((leveltime/anim->speed + i) % anim->numpics);
|
||||
if (anim->istexture)
|
||||
INT32 pic = anim->basepic + ((leveltime/anim->speed + i) % anim->numpics);
|
||||
texturetranslation[anim->basepic+i] = pic;
|
||||
}
|
||||
}
|
||||
|
||||
// ANIMATE FLATS
|
||||
/// \todo do not check the non-animate flat.. link the animated ones?
|
||||
/// \note its faster than the original anywaysince it animates only
|
||||
/// flats used in the level, and there's usually very few of them
|
||||
foundflats = levelflats;
|
||||
for (j = 0; j < numlevelflats; j++, foundflats++)
|
||||
{
|
||||
if (foundflats->speed) // it is an animated flat
|
||||
{
|
||||
// update the levelflat texture number
|
||||
if ((foundflats->type == LEVELFLAT_TEXTURE) && (foundflats->u.texture.basenum != -1))
|
||||
foundflats->u.texture.num = foundflats->u.texture.basenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
// update the levelflat lump number
|
||||
else if ((foundflats->type == LEVELFLAT_FLAT) && (foundflats->u.flat.baselumpnum != LUMPERROR))
|
||||
foundflats->u.flat.lumpnum = foundflats->u.flat.baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Floor over floors (FOFs), 3Dfloors, 3Dblocks, fake floors (ffloors), rovers, or whatever you want to call them
|
||||
// 3D floors
|
||||
//
|
||||
|
||||
/** Gets the ID number for a 3Dfloor in its target sector.
|
||||
|
|
|
@ -502,9 +502,6 @@ typedef enum
|
|||
// at game start
|
||||
void P_InitPicAnims(void);
|
||||
|
||||
// at map load (sectors)
|
||||
void P_SetupLevelFlatAnims(void);
|
||||
|
||||
// at map load
|
||||
void P_InitSpecials(void);
|
||||
void P_ApplyFlatAlignment(sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling);
|
||||
|
|
43
src/r_defs.h
43
src/r_defs.h
|
@ -775,14 +775,26 @@ typedef struct
|
|||
{
|
||||
UINT8 topdelta; // -1 is the last post in a column
|
||||
UINT8 length; // length data bytes follows
|
||||
} ATTRPACK post_t;
|
||||
} ATTRPACK doompost_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
// column_t is a list of 0 or more post_t, (UINT8)-1 terminated
|
||||
typedef post_t column_t;
|
||||
typedef struct
|
||||
{
|
||||
unsigned topdelta;
|
||||
unsigned length;
|
||||
size_t data_offset;
|
||||
} post_t;
|
||||
|
||||
// column_t is a list of 0 or more post_t
|
||||
typedef struct
|
||||
{
|
||||
unsigned num_posts;
|
||||
post_t *posts;
|
||||
UINT8 *pixels;
|
||||
} column_t;
|
||||
|
||||
//
|
||||
// OTHER TYPES
|
||||
|
@ -859,8 +871,9 @@ typedef struct
|
|||
INT16 width, height;
|
||||
INT16 leftoffset, topoffset;
|
||||
|
||||
INT32 *columnofs; // Column offsets. This is relative to patch->columns
|
||||
UINT8 *columns; // Software column data
|
||||
UINT8 *pixels;
|
||||
column_t *columns;
|
||||
post_t *posts;
|
||||
|
||||
void *hardware; // OpenGL patch, allocated whenever necessary
|
||||
void *flats[4]; // The patch as flats
|
||||
|
@ -884,26 +897,6 @@ typedef struct
|
|||
// the [0] is &columnofs[width]
|
||||
} ATTRPACK softwarepatch_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4200)
|
||||
#endif
|
||||
|
||||
// a pic is an unmasked block of pixels, stored in horizontal way
|
||||
typedef struct
|
||||
{
|
||||
INT16 width;
|
||||
UINT8 zero; // set to 0 allow autodetection of pic_t
|
||||
// mode instead of patch or raw
|
||||
UINT8 mode; // see pic_mode_t above
|
||||
INT16 height;
|
||||
INT16 reserved1; // set to 0
|
||||
UINT8 data[0];
|
||||
} ATTRPACK pic_t;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4200)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
|
|
@ -192,8 +192,6 @@ void R_DrawTranslucentColumn_8(void);
|
|||
void R_DrawDropShadowColumn_8(void);
|
||||
void R_DrawTranslatedColumn_8(void);
|
||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||
void R_Draw2sMultiPatchColumn_8(void);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void);
|
||||
void R_DrawFogColumn_8(void);
|
||||
void R_DrawColumnShadowed_8(void);
|
||||
|
||||
|
|
193
src/r_draw8.c
193
src/r_draw8.c
|
@ -105,199 +105,6 @@ void R_DrawColumn_8(void)
|
|||
}
|
||||
}
|
||||
|
||||
void R_Draw2sMultiPatchColumn_8(void)
|
||||
{
|
||||
INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
// Use ylookup LUT to avoid multiply with ScreenWidth.
|
||||
// Use columnofs LUT for subwindows?
|
||||
|
||||
//dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
|
||||
count++;
|
||||
|
||||
// Determine scaling, which is the only mapping to be done.
|
||||
fracstep = dc_iscale;
|
||||
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
||||
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
|
||||
|
||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register const UINT8 *source = dc_source;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
heightmask <<= FRACBITS;
|
||||
|
||||
if (frac < 0)
|
||||
while ((frac += heightmask) < 0);
|
||||
else
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
|
||||
do
|
||||
{
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
// Avoid overflow.
|
||||
if (fracstep > 0x7FFFFFFF - frac)
|
||||
frac += fracstep - heightmask;
|
||||
else
|
||||
frac += fracstep;
|
||||
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = colormap[val];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||
{
|
||||
INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Framebuffer destination address.
|
||||
// Use ylookup LUT to avoid multiply with ScreenWidth.
|
||||
// Use columnofs LUT for subwindows?
|
||||
|
||||
//dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
|
||||
count++;
|
||||
|
||||
// Determine scaling, which is the only mapping to be done.
|
||||
fracstep = dc_iscale;
|
||||
//frac = dc_texturemid + (dc_yl - centery)*fracstep;
|
||||
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
|
||||
|
||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register const UINT8 *source = dc_source;
|
||||
register const UINT8 *transmap = dc_transmap;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
heightmask <<= FRACBITS;
|
||||
|
||||
if (frac < 0)
|
||||
while ((frac += heightmask) < 0);
|
||||
else
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
|
||||
do
|
||||
{
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
// Avoid overflow.
|
||||
if (fracstep > 0x7FFFFFFF - frac)
|
||||
frac += fracstep - heightmask;
|
||||
else
|
||||
frac += fracstep;
|
||||
|
||||
while (frac >= heightmask)
|
||||
frac -= heightmask;
|
||||
} while (--count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((count -= 2) >= 0) // texture height is a power of 2
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
frac += fracstep;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
val = source[(frac>>FRACBITS) & heightmask];
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
*dest = *(transmap + (colormap[val]<<8) + (*dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief The R_DrawShadeColumn_8 function
|
||||
Experiment to make software go faster. Taken from the Boom source
|
||||
*/
|
||||
|
|
107
src/r_patch.c
107
src/r_patch.c
|
@ -21,46 +21,103 @@
|
|||
|
||||
//
|
||||
// Creates a patch.
|
||||
// Assumes a PU_PATCH zone memory tag and no user, but can always be set later
|
||||
//
|
||||
|
||||
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
|
||||
patch_t *Patch_Create(INT16 width, INT16 height)
|
||||
{
|
||||
patch_t *patch = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest);
|
||||
patch_t *patch = Z_Calloc(sizeof(patch_t), PU_PATCH, NULL);
|
||||
patch->width = width;
|
||||
patch->height = height;
|
||||
return patch;
|
||||
}
|
||||
|
||||
if (source)
|
||||
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source)
|
||||
{
|
||||
INT32 col, colsize;
|
||||
size_t size = sizeof(INT32) * SHORT(source->width);
|
||||
size_t offs = (sizeof(INT16) * 4) + size;
|
||||
patch_t *patch = Patch_Create(0, 0);
|
||||
if (!source)
|
||||
return patch;
|
||||
|
||||
patch->width = SHORT(source->width);
|
||||
patch->height = SHORT(source->height);
|
||||
patch->leftoffset = SHORT(source->leftoffset);
|
||||
patch->topoffset = SHORT(source->topoffset);
|
||||
patch->columnofs = Z_Calloc(size, PU_PATCH_DATA, NULL);
|
||||
|
||||
for (col = 0; col < source->width; col++)
|
||||
{
|
||||
// This makes the column offsets relative to the column data itself,
|
||||
// instead of the entire patch data
|
||||
patch->columnofs[col] = LONG(source->columnofs[col]) - offs;
|
||||
}
|
||||
size_t total_pixels = 0;
|
||||
size_t total_posts = 0;
|
||||
|
||||
if (!srcsize)
|
||||
I_Error("Patch_Create: no source size!");
|
||||
Patch_CalcDataSizes(source, &total_pixels, &total_posts);
|
||||
|
||||
colsize = (INT32)(srcsize) - (INT32)offs;
|
||||
if (colsize <= 0)
|
||||
I_Error("Patch_Create: no column data!");
|
||||
patch->columns = Z_Calloc(sizeof(column_t) * patch->width, PU_PATCH_DATA, NULL);
|
||||
patch->posts = Z_Calloc(sizeof(post_t) * total_posts, PU_PATCH_DATA, NULL);
|
||||
patch->pixels = Z_Calloc(sizeof(UINT8) * total_pixels, PU_PATCH_DATA, NULL);
|
||||
|
||||
patch->columns = Z_Calloc(colsize, PU_PATCH_DATA, NULL);
|
||||
M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize);
|
||||
}
|
||||
Patch_MakeColumns(source, patch->width, patch->width, patch->pixels, patch->columns, patch->posts, false);
|
||||
|
||||
return patch;
|
||||
}
|
||||
|
||||
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts)
|
||||
{
|
||||
for (INT32 i = 0; i < source->width; i++)
|
||||
{
|
||||
doompost_t *src_posts = (doompost_t*)((UINT8 *)source + LONG(source->columnofs[i]));
|
||||
for (doompost_t *post = src_posts; post->topdelta != 0xff ;)
|
||||
{
|
||||
(*total_posts)++;
|
||||
(*total_pixels) += post->length;
|
||||
post = (doompost_t *)((UINT8 *)post + post->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, INT16 width, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip)
|
||||
{
|
||||
column_t *column = flip ? columns + (num_columns - 1) : columns;
|
||||
|
||||
for (size_t i = 0; i < num_columns; i++)
|
||||
{
|
||||
size_t prevdelta = 0;
|
||||
size_t data_offset = 0;
|
||||
|
||||
column->pixels = pixels;
|
||||
column->posts = posts;
|
||||
column->num_posts = 0;
|
||||
|
||||
if (i >= (unsigned)width)
|
||||
continue;
|
||||
|
||||
doompost_t *src_posts = (doompost_t*)((UINT8 *)source + LONG(source->columnofs[i]));
|
||||
|
||||
for (doompost_t *post = src_posts; post->topdelta != 0xff ;)
|
||||
{
|
||||
size_t topdelta = post->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
posts->topdelta = topdelta;
|
||||
posts->length = (size_t)post->length;
|
||||
posts->data_offset = data_offset;
|
||||
|
||||
memcpy(pixels, (UINT8 *)post + 3, post->length);
|
||||
|
||||
data_offset += posts->length;
|
||||
pixels += posts->length;
|
||||
|
||||
column->num_posts++;
|
||||
|
||||
posts++;
|
||||
|
||||
post = (doompost_t *)((UINT8 *)post + post->length + 4);
|
||||
}
|
||||
|
||||
if (flip)
|
||||
column--;
|
||||
else
|
||||
column++;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Frees a patch from memory.
|
||||
//
|
||||
|
@ -96,10 +153,12 @@ static void Patch_FreeData(patch_t *patch)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (patch->columnofs)
|
||||
Z_Free(patch->columnofs);
|
||||
if (patch->pixels)
|
||||
Z_Free(patch->pixels);
|
||||
if (patch->columns)
|
||||
Z_Free(patch->columns);
|
||||
if (patch->posts)
|
||||
Z_Free(patch->posts);
|
||||
}
|
||||
|
||||
void Patch_Free(patch_t *patch)
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
#include "doomdef.h"
|
||||
|
||||
// Patch functions
|
||||
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
|
||||
patch_t *Patch_Create(INT16 width, INT16 height);
|
||||
patch_t *Patch_CreateFromDoomPatch(softwarepatch_t *source);
|
||||
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts);
|
||||
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, INT16 width, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip);
|
||||
void Patch_Free(patch_t *patch);
|
||||
|
||||
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
|
||||
|
|
|
@ -51,8 +51,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static unsigned char imgbuf[1<<26];
|
||||
|
||||
#ifdef PICTURE_PNG_USELOOKUP
|
||||
static colorlookup_t png_colorlookup;
|
||||
#endif
|
||||
|
@ -86,22 +84,148 @@ void *Picture_Convert(
|
|||
else if (informat == outformat)
|
||||
I_Error("Picture_Convert: input and output formats were the same!");
|
||||
|
||||
(void)insize;
|
||||
|
||||
if (Picture_IsPatchFormat(outformat))
|
||||
return Picture_PatchConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
|
||||
return Picture_PatchConvert(informat, picture, outformat, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
|
||||
else if (Picture_IsFlatFormat(outformat))
|
||||
return Picture_FlatConvert(informat, picture, outformat, insize, outsize, inwidth, inheight, inleftoffset, intopoffset, flags);
|
||||
return Picture_FlatConvert(informat, picture, outformat, outsize, inwidth, intopoffset, flags);
|
||||
else
|
||||
I_Error("Picture_Convert: unsupported input format!");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *ReadPixelFunc_Patch(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
|
||||
{
|
||||
(void)inwidth;
|
||||
(void)inheight;
|
||||
return Picture_GetPatchPixel((patch_t*)picture, informat, x, y, flags);
|
||||
}
|
||||
|
||||
static void *ReadPixelFunc_Flat_8bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
|
||||
{
|
||||
(void)informat;
|
||||
(void)flags;
|
||||
(void)inheight;
|
||||
return (UINT8 *)picture + ((y * inwidth) + x);
|
||||
}
|
||||
|
||||
static void *ReadPixelFunc_Flat_16bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
|
||||
{
|
||||
(void)informat;
|
||||
(void)flags;
|
||||
(void)inheight;
|
||||
return (UINT16 *)picture + ((y * inwidth) + x);
|
||||
}
|
||||
|
||||
static void *ReadPixelFunc_Flat_32bpp(void *picture, pictureformat_t informat, INT32 x, INT32 y, INT32 inwidth, INT32 inheight, pictureflags_t flags)
|
||||
{
|
||||
(void)informat;
|
||||
(void)flags;
|
||||
(void)inheight;
|
||||
return (UINT32 *)picture + ((y * inwidth) + x);
|
||||
}
|
||||
|
||||
static UINT8 GetAlphaFunc_32bpp(void *input, pictureflags_t flags)
|
||||
{
|
||||
(void)flags;
|
||||
RGBA_t px = *(RGBA_t *)input;
|
||||
return px.s.alpha;
|
||||
}
|
||||
|
||||
static UINT8 GetAlphaFunc_16bpp(void *input, pictureflags_t flags)
|
||||
{
|
||||
(void)flags;
|
||||
UINT16 px = *(UINT16 *)input;
|
||||
return (px & 0xFF00) >> 8;
|
||||
}
|
||||
|
||||
static UINT8 GetAlphaFunc_8bpp(void *input, pictureflags_t flags)
|
||||
{
|
||||
UINT8 px = *(UINT8 *)input;
|
||||
if (px == TRANSPARENTPIXEL && (flags & PICFLAGS_USE_TRANSPARENTPIXEL))
|
||||
return 0;
|
||||
else
|
||||
return 255;
|
||||
}
|
||||
|
||||
// input 32bpp output 32bpp
|
||||
static void *WritePatchPixel_i32o32(void *ptr, void *input)
|
||||
{
|
||||
RGBA_t px = *(RGBA_t *)input;
|
||||
WRITEUINT32(ptr, px.rgba);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 16bpp output 32bpp
|
||||
static void *WritePatchPixel_i16o32(void *ptr, void *input)
|
||||
{
|
||||
RGBA_t px = pMasterPalette[*((UINT16 *)input) & 0xFF];
|
||||
WRITEUINT32(ptr, px.rgba);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 8bpp output 32bpp
|
||||
static void *WritePatchPixel_i8o32(void *ptr, void *input)
|
||||
{
|
||||
RGBA_t px = pMasterPalette[*((UINT8 *)input) & 0xFF];
|
||||
WRITEUINT32(ptr, px.rgba);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 32bpp output 16bpp
|
||||
static void *WritePatchPixel_i32o16(void *ptr, void *input)
|
||||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
WRITEUINT16(ptr, (0xFF00 | px));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 16bpp output 16bpp
|
||||
static void *WritePatchPixel_i16o16(void *ptr, void *input)
|
||||
{
|
||||
WRITEUINT16(ptr, *(UINT16 *)input);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 8bpp output 16bpp
|
||||
static void *WritePatchPixel_i8o16(void *ptr, void *input)
|
||||
{
|
||||
WRITEUINT16(ptr, (0xFF00 | (*(UINT8 *)input)));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 32bpp output 8bpp
|
||||
static void *WritePatchPixel_i32o8(void *ptr, void *input)
|
||||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 px = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
WRITEUINT8(ptr, px);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 16bpp output 8bpp
|
||||
static void *WritePatchPixel_i16o8(void *ptr, void *input)
|
||||
{
|
||||
UINT16 px = *(UINT16 *)input;
|
||||
WRITEUINT8(ptr, (px & 0xFF));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// input 8bpp output 8bpp
|
||||
static void *WritePatchPixel_i8o8(void *ptr, void *input)
|
||||
{
|
||||
WRITEUINT8(ptr, *(UINT8 *)input);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/** Converts a picture to a patch.
|
||||
*
|
||||
* \param informat Input picture format.
|
||||
* \param picture Input picture data.
|
||||
* \param outformat Output picture format.
|
||||
* \param insize Input picture size.
|
||||
* \param outsize Output picture size, as a pointer.
|
||||
* \param inwidth Input picture width.
|
||||
* \param inheight Input picture height.
|
||||
|
@ -112,34 +236,37 @@ void *Picture_Convert(
|
|||
*/
|
||||
void *Picture_PatchConvert(
|
||||
pictureformat_t informat, void *picture, pictureformat_t outformat,
|
||||
size_t insize, size_t *outsize,
|
||||
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
|
||||
size_t *outsize,
|
||||
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
|
||||
pictureflags_t flags)
|
||||
{
|
||||
INT16 x, y;
|
||||
UINT8 *img;
|
||||
UINT8 *imgptr = imgbuf;
|
||||
UINT8 *colpointers, *startofspan;
|
||||
size_t size = 0;
|
||||
patch_t *inpatch = NULL;
|
||||
INT32 inbpp = Picture_FormatBPP(informat);
|
||||
// Shortcut: If converting a Doom patch into a regular patch, use Patch_Create
|
||||
if (informat == PICFMT_DOOMPATCH && outformat == PICFMT_PATCH && flags == 0)
|
||||
{
|
||||
if (outsize != NULL)
|
||||
*outsize = sizeof(patch_t);
|
||||
return Patch_CreateFromDoomPatch(picture);
|
||||
}
|
||||
|
||||
(void)insize; // ignore
|
||||
INT32 outbpp = Picture_FormatBPP(outformat);
|
||||
INT32 inbpp = Picture_FormatBPP(informat);
|
||||
patch_t *inpatch = NULL;
|
||||
|
||||
if (informat == PICFMT_NONE)
|
||||
I_Error("Picture_PatchConvert: input format was PICFMT_NONE!");
|
||||
else if (outformat == PICFMT_NONE)
|
||||
I_Error("Picture_PatchConvert: output format was PICFMT_NONE!");
|
||||
else if (Picture_IsDoomPatchFormat(outformat))
|
||||
I_Error("Picture_PatchConvert: cannot convert to Doom patch!");
|
||||
else if (informat == outformat)
|
||||
I_Error("Picture_PatchConvert: input and output formats were the same!");
|
||||
|
||||
if (inbpp == PICDEPTH_NONE)
|
||||
I_Error("Picture_PatchConvert: unknown input bits per pixel?!");
|
||||
if (Picture_FormatBPP(outformat) == PICDEPTH_NONE)
|
||||
I_Error("Picture_PatchConvert: unknown output bits per pixel?!");
|
||||
I_Error("Picture_PatchConvert: unknown input bits per pixel!");
|
||||
if (outbpp == PICDEPTH_NONE)
|
||||
I_Error("Picture_PatchConvert: unknown output bits per pixel!");
|
||||
|
||||
// If it's a patch, you can just figure out
|
||||
// the dimensions from the header.
|
||||
// If it's a patch, we can just figure out the dimensions from the header.
|
||||
if (Picture_IsPatchFormat(informat))
|
||||
{
|
||||
inpatch = (patch_t *)picture;
|
||||
|
@ -160,48 +287,24 @@ void *Picture_PatchConvert(
|
|||
}
|
||||
}
|
||||
|
||||
// Write image size and offset
|
||||
WRITEINT16(imgptr, inwidth);
|
||||
WRITEINT16(imgptr, inheight);
|
||||
WRITEINT16(imgptr, inleftoffset);
|
||||
WRITEINT16(imgptr, intopoffset);
|
||||
void *(*readPixelFunc)(void *, pictureformat_t, INT32, INT32, INT32, INT32, pictureflags_t) = NULL;
|
||||
UINT8 (*getAlphaFunc)(void *, pictureflags_t) = NULL;
|
||||
void *(*writePatchPixel)(void *, void *) = NULL;
|
||||
|
||||
// Leave placeholder to column pointers
|
||||
colpointers = imgptr;
|
||||
imgptr += inwidth*4;
|
||||
|
||||
// Write columns
|
||||
for (x = 0; x < inwidth; x++)
|
||||
{
|
||||
int lastStartY = 0;
|
||||
int spanSize = 0;
|
||||
startofspan = NULL;
|
||||
|
||||
// Write column pointer
|
||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
||||
|
||||
// Write pixels
|
||||
for (y = 0; y < inheight; y++)
|
||||
{
|
||||
void *input = NULL;
|
||||
boolean opaque = false;
|
||||
|
||||
// Read pixel
|
||||
if (Picture_IsPatchFormat(informat))
|
||||
input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
|
||||
readPixelFunc = ReadPixelFunc_Patch;
|
||||
else if (Picture_IsFlatFormat(informat))
|
||||
{
|
||||
size_t offs = ((y * inwidth) + x);
|
||||
switch (informat)
|
||||
{
|
||||
case PICFMT_FLAT32:
|
||||
input = (UINT32 *)picture + offs;
|
||||
readPixelFunc = ReadPixelFunc_Flat_32bpp;
|
||||
break;
|
||||
case PICFMT_FLAT16:
|
||||
input = (UINT16 *)picture + offs;
|
||||
readPixelFunc = ReadPixelFunc_Flat_16bpp;
|
||||
break;
|
||||
case PICFMT_FLAT:
|
||||
input = (UINT8 *)picture + offs;
|
||||
readPixelFunc = ReadPixelFunc_Flat_8bpp;
|
||||
break;
|
||||
default:
|
||||
I_Error("Picture_PatchConvert: unsupported flat input format!");
|
||||
|
@ -211,167 +314,143 @@ void *Picture_PatchConvert(
|
|||
else
|
||||
I_Error("Picture_PatchConvert: unsupported input format!");
|
||||
|
||||
// Determine opacity
|
||||
if (input != NULL)
|
||||
{
|
||||
UINT8 alpha = 0xFF;
|
||||
if (inbpp == PICDEPTH_32BPP)
|
||||
{
|
||||
RGBA_t px = *(RGBA_t *)input;
|
||||
alpha = px.s.alpha;
|
||||
}
|
||||
getAlphaFunc = GetAlphaFunc_32bpp;
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
{
|
||||
UINT16 px = *(UINT16 *)input;
|
||||
alpha = (px & 0xFF00) >> 8;
|
||||
}
|
||||
getAlphaFunc = GetAlphaFunc_16bpp;
|
||||
else if (inbpp == PICDEPTH_8BPP)
|
||||
{
|
||||
UINT8 px = *(UINT8 *)input;
|
||||
if (px == TRANSPARENTPIXEL)
|
||||
alpha = 0;
|
||||
}
|
||||
opaque = (alpha > 1);
|
||||
}
|
||||
getAlphaFunc = GetAlphaFunc_8bpp;
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
startofspan = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start new column if we need to
|
||||
if (!startofspan || spanSize == 255)
|
||||
{
|
||||
int writeY = y;
|
||||
|
||||
// If we reached the span size limit, finish the previous span
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
|
||||
if (y > 254)
|
||||
{
|
||||
// Make sure we're aligned to 254
|
||||
if (lastStartY < 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
lastStartY = 254;
|
||||
}
|
||||
|
||||
// Write stopgap empty spans if needed
|
||||
writeY = y - lastStartY;
|
||||
|
||||
while (writeY > 254)
|
||||
{
|
||||
WRITEUINT8(imgptr, 254);
|
||||
WRITEUINT8(imgptr, 0);
|
||||
imgptr += 2;
|
||||
writeY -= 254;
|
||||
}
|
||||
}
|
||||
|
||||
startofspan = imgptr;
|
||||
WRITEUINT8(imgptr, writeY);
|
||||
imgptr += 2;
|
||||
spanSize = 0;
|
||||
|
||||
lastStartY = y;
|
||||
}
|
||||
|
||||
// Write the pixel
|
||||
switch (outformat)
|
||||
{
|
||||
case PICFMT_PATCH32:
|
||||
case PICFMT_DOOMPATCH32:
|
||||
{
|
||||
if (inbpp == PICDEPTH_32BPP)
|
||||
{
|
||||
RGBA_t out = *(RGBA_t *)input;
|
||||
WRITEUINT32(imgptr, out.rgba);
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i32o32;
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
{
|
||||
RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
|
||||
WRITEUINT32(imgptr, out.rgba);
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i16o32;
|
||||
else // PICFMT_PATCH
|
||||
{
|
||||
RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
|
||||
WRITEUINT32(imgptr, out.rgba);
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i8o32;
|
||||
break;
|
||||
}
|
||||
case PICFMT_PATCH16:
|
||||
case PICFMT_DOOMPATCH16:
|
||||
if (inbpp == PICDEPTH_32BPP)
|
||||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
WRITEUINT16(imgptr, (0xFF00 | out));
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i32o16;
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
WRITEUINT16(imgptr, *(UINT16 *)input);
|
||||
writePatchPixel = WritePatchPixel_i16o16;
|
||||
else // PICFMT_PATCH
|
||||
WRITEUINT16(imgptr, (0xFF00 | (*(UINT8 *)input)));
|
||||
writePatchPixel = WritePatchPixel_i8o16;
|
||||
break;
|
||||
default: // PICFMT_PATCH
|
||||
{
|
||||
if (inbpp == PICDEPTH_32BPP)
|
||||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
WRITEUINT8(imgptr, out);
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i32o8;
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
{
|
||||
UINT16 out = *(UINT16 *)input;
|
||||
WRITEUINT8(imgptr, (out & 0xFF));
|
||||
}
|
||||
writePatchPixel = WritePatchPixel_i16o8;
|
||||
else // PICFMT_PATCH
|
||||
WRITEUINT8(imgptr, *(UINT8 *)input);
|
||||
writePatchPixel = WritePatchPixel_i8o8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spanSize++;
|
||||
startofspan[1] = spanSize;
|
||||
}
|
||||
patch_t *out = Z_Calloc(sizeof(patch_t), PU_PATCH, NULL);
|
||||
|
||||
if (startofspan)
|
||||
WRITEUINT8(imgptr, 0);
|
||||
out->width = inwidth;
|
||||
out->height = inheight;
|
||||
out->leftoffset = inleftoffset;
|
||||
out->topoffset = intopoffset;
|
||||
|
||||
WRITEUINT8(imgptr, 0xFF);
|
||||
}
|
||||
size_t max_pixels = out->width * out->height;
|
||||
unsigned num_posts = 0;
|
||||
|
||||
size = imgptr-imgbuf;
|
||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
||||
memcpy(img, imgbuf, size);
|
||||
out->columns = Z_Calloc(sizeof(column_t) * out->width, PU_PATCH_DATA, NULL);
|
||||
out->pixels = Z_Calloc(max_pixels * (outbpp / 8), PU_PATCH_DATA, NULL);
|
||||
out->posts = NULL;
|
||||
|
||||
if (Picture_IsInternalPatchFormat(outformat))
|
||||
UINT8 *imgptr = out->pixels;
|
||||
|
||||
unsigned *column_posts = Z_Calloc(sizeof(unsigned) * inwidth, PU_STATIC, NULL);
|
||||
|
||||
// Write columns
|
||||
for (INT32 x = 0; x < inwidth; x++)
|
||||
{
|
||||
patch_t *converted = Patch_Create((softwarepatch_t *)img, size, NULL);
|
||||
post_t *post;
|
||||
size_t post_data_offset = 0;
|
||||
boolean was_opaque = false;
|
||||
|
||||
#ifdef HWRENDER
|
||||
Patch_CreateGL(converted);
|
||||
#endif
|
||||
column_t *column = &out->columns[x];
|
||||
column->pixels = imgptr;
|
||||
column->posts = NULL;
|
||||
column->num_posts = 0;
|
||||
|
||||
Z_Free(img);
|
||||
column_posts[x] = (unsigned)-1;
|
||||
|
||||
// Write pixels
|
||||
for (INT32 y = 0; y < inheight; y++)
|
||||
{
|
||||
boolean opaque = false;
|
||||
|
||||
// Read pixel
|
||||
void *input = readPixelFunc(picture, informat, x, y, inwidth, inheight, flags);
|
||||
|
||||
// Determine opacity
|
||||
if (input != NULL)
|
||||
opaque = getAlphaFunc(input, flags) > 0;
|
||||
|
||||
// End span if we have a transparent pixel
|
||||
if (!opaque)
|
||||
{
|
||||
was_opaque = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!was_opaque)
|
||||
{
|
||||
num_posts++;
|
||||
|
||||
out->posts = Z_Realloc(out->posts, sizeof(post_t) * num_posts, PU_PATCH_DATA, NULL);
|
||||
post = &out->posts[num_posts - 1];
|
||||
post->topdelta = (size_t)y;
|
||||
post->length = 0;
|
||||
post->data_offset = post_data_offset;
|
||||
if (column_posts[x] == (unsigned)-1)
|
||||
column_posts[x] = num_posts - 1;
|
||||
column->num_posts++;
|
||||
}
|
||||
|
||||
was_opaque = true;
|
||||
|
||||
// Write the pixel
|
||||
UINT8 *last_ptr = imgptr;
|
||||
imgptr = writePatchPixel(last_ptr, input);
|
||||
|
||||
post->length++;
|
||||
post_data_offset += imgptr - last_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 *old_pixels = out->pixels;
|
||||
size_t total_pixels = imgptr - out->pixels;
|
||||
if (total_pixels != max_pixels)
|
||||
out->pixels = Z_Realloc(out->pixels, total_pixels, PU_PATCH_DATA, NULL);
|
||||
|
||||
for (INT16 x = 0; x < inwidth; x++)
|
||||
{
|
||||
column_t *column = &out->columns[x];
|
||||
if (column->num_posts > 0)
|
||||
column->posts = &out->posts[column_posts[x]];
|
||||
if (old_pixels != out->pixels)
|
||||
column->pixels = out->pixels + (column->pixels - old_pixels);
|
||||
}
|
||||
|
||||
Z_Free(column_posts);
|
||||
|
||||
if (outsize != NULL)
|
||||
*outsize = sizeof(patch_t);
|
||||
return converted;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outsize != NULL)
|
||||
*outsize = size;
|
||||
return img;
|
||||
}
|
||||
|
||||
return (void *)out;
|
||||
}
|
||||
|
||||
/** Converts a picture to a flat.
|
||||
|
@ -379,19 +458,16 @@ void *Picture_PatchConvert(
|
|||
* \param informat Input picture format.
|
||||
* \param picture Input picture data.
|
||||
* \param outformat Output picture format.
|
||||
* \param insize Input picture size.
|
||||
* \param outsize Output picture size, as a pointer.
|
||||
* \param inwidth Input picture width.
|
||||
* \param inheight Input picture height.
|
||||
* \param inleftoffset Input picture left offset, for patches.
|
||||
* \param intopoffset Input picture top offset, for patches.
|
||||
* \param flags Input picture flags.
|
||||
* \return A pointer to the converted picture.
|
||||
*/
|
||||
void *Picture_FlatConvert(
|
||||
pictureformat_t informat, void *picture, pictureformat_t outformat,
|
||||
size_t insize, size_t *outsize,
|
||||
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
|
||||
size_t *outsize,
|
||||
INT32 inwidth, INT32 inheight,
|
||||
pictureflags_t flags)
|
||||
{
|
||||
void *outflat;
|
||||
|
@ -401,10 +477,6 @@ void *Picture_FlatConvert(
|
|||
INT32 x, y;
|
||||
size_t size;
|
||||
|
||||
(void)insize; // ignore
|
||||
(void)inleftoffset; // ignore
|
||||
(void)intopoffset; // ignore
|
||||
|
||||
if (informat == PICFMT_NONE)
|
||||
I_Error("Picture_FlatConvert: input format was PICFMT_NONE!");
|
||||
else if (outformat == PICFMT_NONE)
|
||||
|
@ -448,13 +520,22 @@ void *Picture_FlatConvert(
|
|||
for (x = 0; x < inwidth; x++)
|
||||
{
|
||||
void *input = NULL;
|
||||
size_t offs = ((y * inwidth) + x);
|
||||
int sx = x;
|
||||
int sy = y;
|
||||
|
||||
if (flags & PICFLAGS_XFLIP)
|
||||
sx = inwidth - x - 1;
|
||||
if (flags & PICFLAGS_YFLIP)
|
||||
sy = inheight - y - 1;
|
||||
|
||||
size_t in_offs = ((sy * inwidth) + sx);
|
||||
size_t out_offs = ((y * inwidth) + x);
|
||||
|
||||
// Read pixel
|
||||
if (Picture_IsPatchFormat(informat))
|
||||
input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
|
||||
input = Picture_GetPatchPixel(inpatch, informat, sx, sy, 0);
|
||||
else if (Picture_IsFlatFormat(informat))
|
||||
input = (UINT8 *)picture + (offs * (inbpp / 8));
|
||||
input = (UINT8 *)picture + (in_offs * (inbpp / 8));
|
||||
else
|
||||
I_Error("Picture_FlatConvert: unsupported input format!");
|
||||
|
||||
|
@ -469,17 +550,17 @@ void *Picture_FlatConvert(
|
|||
if (inbpp == PICDEPTH_32BPP)
|
||||
{
|
||||
RGBA_t out = *(RGBA_t *)input;
|
||||
f32[offs] = out.rgba;
|
||||
f32[out_offs] = out.rgba;
|
||||
}
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
{
|
||||
RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
|
||||
f32[offs] = out.rgba;
|
||||
f32[out_offs] = out.rgba;
|
||||
}
|
||||
else // PICFMT_PATCH
|
||||
{
|
||||
RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
|
||||
f32[offs] = out.rgba;
|
||||
f32[out_offs] = out.rgba;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -490,12 +571,12 @@ void *Picture_FlatConvert(
|
|||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
f16[offs] = (0xFF00 | out);
|
||||
f16[out_offs] = (0xFF00 | out);
|
||||
}
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
f16[offs] = *(UINT16 *)input;
|
||||
f16[out_offs] = *(UINT16 *)input;
|
||||
else // PICFMT_PATCH
|
||||
f16[offs] = (0xFF00 | *((UINT8 *)input));
|
||||
f16[out_offs] = (0xFF00 | *((UINT8 *)input));
|
||||
break;
|
||||
}
|
||||
case PICFMT_FLAT:
|
||||
|
@ -505,15 +586,15 @@ void *Picture_FlatConvert(
|
|||
{
|
||||
RGBA_t in = *(RGBA_t *)input;
|
||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||
f8[offs] = out;
|
||||
f8[out_offs] = out;
|
||||
}
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
{
|
||||
UINT16 out = *(UINT16 *)input;
|
||||
f8[offs] = (out & 0xFF);
|
||||
f8[out_offs] = (out & 0xFF);
|
||||
}
|
||||
else // PICFMT_PATCH
|
||||
f8[offs] = *(UINT8 *)input;
|
||||
f8[out_offs] = *(UINT8 *)input;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -538,44 +619,43 @@ void *Picture_GetPatchPixel(
|
|||
INT32 x, INT32 y,
|
||||
pictureflags_t flags)
|
||||
{
|
||||
fixed_t ofs;
|
||||
column_t *column;
|
||||
INT32 inbpp = Picture_FormatBPP(informat);
|
||||
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
|
||||
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
|
||||
INT16 width;
|
||||
|
||||
if (patch == NULL)
|
||||
I_Error("Picture_GetPatchPixel: patch == NULL");
|
||||
|
||||
width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
|
||||
INT16 width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
|
||||
INT16 height = (isdoompatch ? SHORT(doompatch->height) : patch->height);
|
||||
|
||||
if (x >= 0 && x < width)
|
||||
{
|
||||
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]);
|
||||
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||
return NULL;
|
||||
|
||||
// Column offsets are pointers, so no casting is required.
|
||||
if (isdoompatch)
|
||||
column = (column_t *)((UINT8 *)doompatch + colofs);
|
||||
else
|
||||
column = (column_t *)((UINT8 *)patch->columns + colofs);
|
||||
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
INT32 sx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
|
||||
INT32 sy = (flags & PICFLAGS_YFLIP) ? (height-1)-y : y;
|
||||
UINT8 *s8 = NULL;
|
||||
UINT16 *s16 = NULL;
|
||||
UINT32 *s32 = NULL;
|
||||
|
||||
topdelta = column->topdelta;
|
||||
if (isdoompatch)
|
||||
{
|
||||
INT32 prevdelta = -1;
|
||||
INT32 colofs = LONG(doompatch->columnofs[sx]);
|
||||
|
||||
// Column offsets are pointers, so no casting is required.
|
||||
doompost_t *column = (doompost_t *)((UINT8 *)doompatch + colofs);
|
||||
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
INT32 topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
ofs = (y - topdelta);
|
||||
size_t ofs = sy - topdelta;
|
||||
|
||||
if (y >= topdelta && ofs < column->length)
|
||||
if (sy >= topdelta && ofs < column->length)
|
||||
{
|
||||
s8 = (UINT8 *)(column) + 3;
|
||||
switch (inbpp)
|
||||
|
@ -592,12 +672,38 @@ void *Picture_GetPatchPixel(
|
|||
}
|
||||
|
||||
if (inbpp == PICDEPTH_32BPP)
|
||||
column = (column_t *)((UINT32 *)column + column->length);
|
||||
column = (doompost_t *)((UINT32 *)column + column->length);
|
||||
else if (inbpp == PICDEPTH_16BPP)
|
||||
column = (column_t *)((UINT16 *)column + column->length);
|
||||
column = (doompost_t *)((UINT16 *)column + column->length);
|
||||
else
|
||||
column = (column_t *)((UINT8 *)column + column->length);
|
||||
column = (column_t *)((UINT8 *)column + 4);
|
||||
column = (doompost_t *)((UINT8 *)column + column->length);
|
||||
column = (doompost_t *)((UINT8 *)column + 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
column_t *column = &patch->columns[sx];
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
post_t *post = &column->posts[i];
|
||||
|
||||
size_t ofs = sy - post->topdelta;
|
||||
|
||||
if (sy >= (INT32)post->topdelta && ofs < post->length)
|
||||
{
|
||||
s8 = column->pixels + post->data_offset;
|
||||
switch (inbpp)
|
||||
{
|
||||
case PICDEPTH_32BPP:
|
||||
s32 = (UINT32 *)s8;
|
||||
return &s32[ofs];
|
||||
case PICDEPTH_16BPP:
|
||||
s16 = (UINT16 *)s8;
|
||||
return &s16[ofs];
|
||||
default: // PICDEPTH_8BPP
|
||||
return &s8[ofs];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,74 +844,49 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
|
|||
|
||||
/** Converts a texture to a flat.
|
||||
*
|
||||
* \param trickytex The texture number.
|
||||
* \param texnum The texture number.
|
||||
* \return The converted flat.
|
||||
*/
|
||||
void *Picture_TextureToFlat(size_t trickytex)
|
||||
void *Picture_TextureToFlat(size_t texnum)
|
||||
{
|
||||
texture_t *texture;
|
||||
size_t tex;
|
||||
|
||||
UINT8 *converted;
|
||||
size_t flatsize;
|
||||
fixed_t col, ofs;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststop;
|
||||
UINT8 *source;
|
||||
|
||||
if (trickytex >= (unsigned)numtextures)
|
||||
if (texnum >= (unsigned)numtextures)
|
||||
I_Error("Picture_TextureToFlat: invalid texture number!");
|
||||
|
||||
// Check the texture cache
|
||||
// If the texture's not there, it'll be generated right now
|
||||
tex = trickytex;
|
||||
texture = textures[tex];
|
||||
R_CheckTextureCache(tex);
|
||||
texture = textures[texnum];
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
// Allocate the flat
|
||||
flatsize = (texture->width * texture->height);
|
||||
flatsize = texture->width * texture->height;
|
||||
converted = Z_Malloc(flatsize, PU_STATIC, NULL);
|
||||
memset(converted, TRANSPARENTPIXEL, flatsize);
|
||||
|
||||
// Now we're gonna write to it
|
||||
desttop = converted;
|
||||
deststop = desttop + flatsize;
|
||||
for (col = 0; col < texture->width; col++, desttop++)
|
||||
{
|
||||
// no post_t info
|
||||
if (!texture->holes)
|
||||
{
|
||||
column = (column_t *)(R_GetColumn(tex, col));
|
||||
source = (UINT8 *)(column);
|
||||
dest = desttop;
|
||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
|
||||
while (column->topdelta != 0xff)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
|
||||
dest = desttop + (topdelta * texture->width);
|
||||
source = (UINT8 *)column + 3;
|
||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
||||
for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
|
||||
{
|
||||
column_t *column = (column_t *)R_GetColumn(texnum, col);
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
post_t *post = &column->posts[i];
|
||||
dest = desttop + (post->topdelta * texture->width);
|
||||
source = column->pixels + post->data_offset;
|
||||
for (size_t ofs = 0; dest < deststop && ofs < post->length; ofs++)
|
||||
{
|
||||
if (source[ofs] != TRANSPARENTPIXEL)
|
||||
*dest = source[ofs];
|
||||
dest += texture->width;
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -820,7 +901,7 @@ void *Picture_TextureToFlat(size_t trickytex)
|
|||
*/
|
||||
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s)
|
||||
{
|
||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
||||
if (s < 67) // https://web.archive.org/web/20230524232139/http://garethrees.org/2007/11/14/pngcrush/
|
||||
return false;
|
||||
// Check for PNG file signature using memcmp
|
||||
// As it may be faster on CPUs with slow unaligned memory access
|
||||
|
@ -877,7 +958,6 @@ static int PNG_ChunkReader(png_structp png_ptr, png_unknown_chunkp chonk)
|
|||
static void PNG_error(png_structp PNG, png_const_charp pngtext)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "libpng error at %p: %s", PNG, pngtext);
|
||||
//I_Error("libpng error at %p: %s", PNG, pngtext);
|
||||
}
|
||||
|
||||
static void PNG_warn(png_structp PNG, png_const_charp pngtext)
|
||||
|
@ -944,7 +1024,7 @@ static png_bytep *PNG_Read(
|
|||
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
|
||||
|
||||
memset(&chunk, 0x00, sizeof(png_chunk_t));
|
||||
chunkname = grAb_chunk; // I want to read a grAb chunk
|
||||
chunkname = grAb_chunk;
|
||||
|
||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, PNG_ChunkReader);
|
||||
|
@ -1293,7 +1373,7 @@ void *Picture_PNGConvert(
|
|||
}
|
||||
|
||||
// Now, convert it!
|
||||
converted = Picture_PatchConvert(informat, flat, outformat, insize, outsize, (INT16)width, (INT16)height, *leftoffset, *topoffset, flags);
|
||||
converted = Picture_PatchConvert(informat, flat, outformat, outsize, (INT32)width, (INT32)height, *leftoffset, *topoffset, flags);
|
||||
Z_Free(flat);
|
||||
return converted;
|
||||
}
|
||||
|
@ -1329,13 +1409,17 @@ boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *to
|
|||
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
|
||||
if (!png_ptr)
|
||||
I_Error("Picture_PNGDimensions: Couldn't initialize libpng!");
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Picture_PNGDimensions: Couldn't initialize libpng!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
png_info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!png_info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
I_Error("Picture_PNGDimensions: libpng couldn't allocate memory!");
|
||||
CONS_Alert(CONS_ERROR, "Picture_PNGDimensions: libpng couldn't allocate memory!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
|
@ -1345,7 +1429,8 @@ boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *to
|
|||
#endif
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
||||
I_Error("Picture_PNGDimensions: libpng load error!");
|
||||
CONS_Alert(CONS_ERROR, "Picture_PNGDimensions: libpng load error!\n");
|
||||
return false;
|
||||
}
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf);
|
||||
|
@ -1357,7 +1442,7 @@ boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *to
|
|||
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
|
||||
|
||||
memset(&chunk, 0x00, sizeof(png_chunk_t));
|
||||
chunkname = grAb_chunk; // I want to read a grAb chunk
|
||||
chunkname = grAb_chunk;
|
||||
|
||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, PNG_ChunkReader);
|
||||
|
|
|
@ -43,7 +43,8 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
PICFLAGS_XFLIP = 1,
|
||||
PICFLAGS_YFLIP = 1<<1
|
||||
PICFLAGS_YFLIP = 1<<1,
|
||||
PICFLAGS_USE_TRANSPARENTPIXEL = 1<<2
|
||||
} pictureflags_t;
|
||||
|
||||
enum
|
||||
|
@ -62,20 +63,20 @@ void *Picture_Convert(
|
|||
|
||||
void *Picture_PatchConvert(
|
||||
pictureformat_t informat, void *picture, pictureformat_t outformat,
|
||||
size_t insize, size_t *outsize,
|
||||
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
|
||||
size_t *outsize,
|
||||
INT32 inwidth, INT32 inheight, INT32 inleftoffset, INT32 intopoffset,
|
||||
pictureflags_t flags);
|
||||
void *Picture_FlatConvert(
|
||||
pictureformat_t informat, void *picture, pictureformat_t outformat,
|
||||
size_t insize, size_t *outsize,
|
||||
INT16 inwidth, INT16 inheight, INT16 inleftoffset, INT16 intopoffset,
|
||||
size_t *outsize,
|
||||
INT32 inwidth, INT32 inheight,
|
||||
pictureflags_t flags);
|
||||
void *Picture_GetPatchPixel(
|
||||
patch_t *patch, pictureformat_t informat,
|
||||
INT32 x, INT32 y,
|
||||
pictureflags_t flags);
|
||||
|
||||
void *Picture_TextureToFlat(size_t trickytex);
|
||||
void *Picture_TextureToFlat(size_t texnum);
|
||||
|
||||
INT32 Picture_FormatBPP(pictureformat_t format);
|
||||
boolean Picture_IsPatchFormat(pictureformat_t format);
|
||||
|
@ -103,10 +104,10 @@ typedef struct
|
|||
boolean available;
|
||||
} spriteinfo_t;
|
||||
|
||||
// Portable Network Graphics
|
||||
#define PNG_HEADER_SIZE (8)
|
||||
// PNG support
|
||||
#define PNG_HEADER_SIZE 8
|
||||
|
||||
boolean Picture_IsLumpPNG(const UINT8 *d, size_t s);
|
||||
#define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
void *Picture_PNGConvert(
|
||||
|
|
|
@ -624,37 +624,31 @@ void R_DrawPlanes(void)
|
|||
//
|
||||
static void R_DrawSkyPlane(visplane_t *pl)
|
||||
{
|
||||
INT32 x;
|
||||
INT32 angle;
|
||||
INT32 texture = texturetranslation[skytexture];
|
||||
|
||||
// Reset column drawer function (note: couldn't we just call walldrawerfunc directly?)
|
||||
// (that is, unless we'll need to switch drawers in future for some reason)
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
||||
// use correct aspect ratio scale
|
||||
dc_iscale = skyscale;
|
||||
|
||||
// Sky is always drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant).
|
||||
dc_colormap = colormaps;
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
for (x = pl->minx; x <= pl->maxx; x++)
|
||||
dc_texheight = textureheight[texture]>>FRACBITS;
|
||||
|
||||
R_CheckTextureCache(texture);
|
||||
|
||||
for (INT32 x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
|
||||
if (dc_yl <= dc_yh)
|
||||
{
|
||||
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
|
||||
INT32 angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
|
||||
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
|
||||
dc_x = x;
|
||||
dc_source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
dc_source = R_GetColumn(texture, -angle)->pixels; // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
colfunc();
|
||||
}
|
||||
}
|
||||
|
@ -1004,31 +998,22 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
{
|
||||
levelflat_t *levelflat = &levelflats[pl->picnum];
|
||||
|
||||
/* :james: */
|
||||
switch (levelflat->type)
|
||||
{
|
||||
case LEVELFLAT_NONE:
|
||||
// Get the texture
|
||||
ds_source = (UINT8 *)R_GetFlat(levelflat);
|
||||
if (ds_source == NULL)
|
||||
return;
|
||||
case LEVELFLAT_FLAT:
|
||||
ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
|
||||
R_SetFlatVars(W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
|
||||
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)];
|
||||
ds_flatwidth = texture->width;
|
||||
ds_flatheight = texture->height;
|
||||
|
||||
if (R_CheckSolidColorFlat())
|
||||
ds_solidcolor = true;
|
||||
else
|
||||
ds_powersoftwo = true;
|
||||
break;
|
||||
default:
|
||||
ds_source = (UINT8 *)R_GetLevelFlat(levelflat);
|
||||
if (!ds_source)
|
||||
return;
|
||||
else if (R_CheckSolidColorFlat())
|
||||
ds_solidcolor = true;
|
||||
else if (R_CheckPowersOfTwo())
|
||||
{
|
||||
R_SetFlatVars(ds_flatwidth * ds_flatheight);
|
||||
ds_powersoftwo = true;
|
||||
}
|
||||
}
|
||||
|
||||
mapfunc = R_MapPlane;
|
||||
|
||||
|
|
126
src/r_segs.c
126
src/r_segs.c
|
@ -96,49 +96,6 @@ void R_ClearSegTables(void)
|
|||
// R_RenderMaskedSegRange
|
||||
// ==========================================================================
|
||||
|
||||
// If we have a multi-patch texture on a 2sided wall (rare) then we draw
|
||||
// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
|
||||
// way we don't have to store extra post_t info with each column for
|
||||
// multi-patch textures. They are not normally needed as multi-patch
|
||||
// textures don't have holes in it. At least not for now.
|
||||
|
||||
static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||
{
|
||||
INT32 topscreen, bottomscreen;
|
||||
|
||||
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
|
||||
bottomscreen = topscreen + spryscale * lengthcol;
|
||||
|
||||
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
|
||||
dc_yh = (windowbottom - 1)>>FRACBITS;
|
||||
}
|
||||
|
||||
if (dc_yh >= mfloorclip[dc_x])
|
||||
dc_yh = mfloorclip[dc_x] - 1;
|
||||
if (dc_yl <= mceilingclip[dc_x])
|
||||
dc_yl = mceilingclip[dc_x] + 1;
|
||||
|
||||
if (dc_yl >= vid.height || dc_yh < 0)
|
||||
return;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
|
||||
if (colfunc == colfuncs[BASEDRAWFUNC])
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
|
||||
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
|
||||
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])();
|
||||
else
|
||||
colfunc();
|
||||
}
|
||||
}
|
||||
|
||||
transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
||||
{
|
||||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
|
@ -152,12 +109,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
fixed_t height, realbot;
|
||||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
void (*colfunc_2s)(column_t *);
|
||||
void (*colfunc_2s)(column_t *, unsigned);
|
||||
line_t *ldef;
|
||||
sector_t *front, *back;
|
||||
INT32 times, repeats;
|
||||
INT64 overflow_test;
|
||||
INT32 range;
|
||||
unsigned lengthcol;
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
|
@ -214,26 +172,15 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
rw_scalestep = scalestep;
|
||||
spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
|
||||
// Texture must be cached before setting colfunc_2s,
|
||||
// otherwise texture[texnum]->holes may be false when it shouldn't be
|
||||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info in SRB2
|
||||
if (textures[texnum]->holes)
|
||||
{
|
||||
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
{
|
||||
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
else
|
||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
}
|
||||
else
|
||||
{
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
|
||||
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
|
||||
// Setup lighting based on the presence/lack-of 3D floors.
|
||||
dc_numlights = 0;
|
||||
|
@ -405,7 +352,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
windowbottom = realbot;
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
|
||||
col = R_GetColumn(texnum, maskedtexturecol[dc_x] >> FRACBITS);
|
||||
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
|
@ -444,7 +391,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
if (windowbottom >= realbot)
|
||||
{
|
||||
windowbottom = realbot;
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, lengthcol);
|
||||
for (i++; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
|
@ -453,13 +400,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
continue;
|
||||
}
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, lengthcol);
|
||||
windowtop = windowbottom + 1;
|
||||
dc_colormap = rlight->rcolormap;
|
||||
}
|
||||
windowbottom = realbot;
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s(col);
|
||||
colfunc_2s(col, lengthcol);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
|
@ -480,8 +427,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley);
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3);
|
||||
colfunc_2s(col);
|
||||
col = R_GetColumn(texnum, maskedtexturecol[dc_x] >> FRACBITS);
|
||||
colfunc_2s(col, lengthcol);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
|
@ -490,10 +437,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
|
||||
// Loop through R_DrawMaskedColumn calls
|
||||
static void R_DrawRepeatMaskedColumn(column_t *col)
|
||||
static void R_DrawRepeatMaskedColumn(column_t *col, unsigned lengthcol)
|
||||
{
|
||||
while (sprtopscreen < sprbotscreen) {
|
||||
R_DrawMaskedColumn(col);
|
||||
R_DrawMaskedColumn(col, lengthcol);
|
||||
if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow
|
||||
sprtopscreen = INT32_MAX;
|
||||
else
|
||||
|
@ -501,10 +448,10 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
|
|||
}
|
||||
}
|
||||
|
||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
|
||||
static void R_DrawRepeatFlippedMaskedColumn(column_t *col, unsigned lengthcol)
|
||||
{
|
||||
do {
|
||||
R_DrawFlippedMaskedColumn(col);
|
||||
R_DrawFlippedMaskedColumn(col, lengthcol);
|
||||
sprtopscreen += dc_texheight*spryscale;
|
||||
} while (sprtopscreen < sprbotscreen);
|
||||
}
|
||||
|
@ -554,8 +501,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
boolean do_texture_skew;
|
||||
boolean dont_peg_bottom;
|
||||
fixed_t wall_scalex, wall_scaley;
|
||||
unsigned lengthcol;
|
||||
|
||||
void (*colfunc_2s) (column_t *);
|
||||
void (*colfunc_2s) (column_t *, unsigned);
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
|
@ -788,26 +736,15 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
dc_texturemid += offsetvalue;
|
||||
|
||||
// Texture must be cached before setting colfunc_2s,
|
||||
// otherwise texture[texnum]->holes may be false when it shouldn't be
|
||||
// Texture must be cached
|
||||
R_CheckTextureCache(texnum);
|
||||
//faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
|
||||
// are not stored per-column with post info anymore in Doom Legacy
|
||||
if (textures[texnum]->holes)
|
||||
{
|
||||
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
{
|
||||
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
else
|
||||
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
}
|
||||
else
|
||||
{
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
|
||||
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
|
||||
// Set heights according to plane, or slope, whichever
|
||||
{
|
||||
|
@ -873,7 +810,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
|
||||
|
||||
// Get data for the column
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)) - 3);
|
||||
col = R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS));
|
||||
|
||||
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
|
||||
// will (hopefully) put less strain on the stack.
|
||||
|
@ -965,7 +902,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
{
|
||||
windowbottom = sprbotscreen;
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, lengthcol);
|
||||
for (i++; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
|
@ -976,7 +913,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
continue;
|
||||
}
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, lengthcol);
|
||||
if (solid)
|
||||
windowtop = bheight;
|
||||
else
|
||||
|
@ -987,7 +924,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
windowbottom = sprbotscreen;
|
||||
// draw the texture, if there is any space left
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, lengthcol);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
|
@ -1007,7 +944,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
||||
// draw the texture
|
||||
colfunc_2s (col);
|
||||
colfunc_2s (col, lengthcol);
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
@ -1078,6 +1015,13 @@ static void R_RenderSegLoop (void)
|
|||
INT32 bottom;
|
||||
INT32 i;
|
||||
|
||||
if (midtexture)
|
||||
R_CheckTextureCache(midtexture);
|
||||
if (toptexture)
|
||||
R_CheckTextureCache(toptexture);
|
||||
if (bottomtexture)
|
||||
R_CheckTextureCache(bottomtexture);
|
||||
|
||||
for (; rw_x < rw_stopx; rw_x++)
|
||||
{
|
||||
// mark floor / ceiling areas
|
||||
|
@ -1309,7 +1253,7 @@ static void R_RenderSegLoop (void)
|
|||
dc_yh = yh;
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_midtexturescaley);
|
||||
dc_source = R_GetColumn(midtexture, offset >> FRACBITS);
|
||||
dc_source = R_GetColumn(midtexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[midtexture]>>FRACBITS;
|
||||
|
||||
//profile stuff ---------------------------------------------------------
|
||||
|
@ -1378,7 +1322,7 @@ static void R_RenderSegLoop (void)
|
|||
dc_yh = mid;
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_toptexturescaley);
|
||||
dc_source = R_GetColumn(toptexture, offset >> FRACBITS);
|
||||
dc_source = R_GetColumn(toptexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[toptexture]>>FRACBITS;
|
||||
colfunc();
|
||||
ceilingclip[rw_x] = (INT16)mid;
|
||||
|
@ -1426,7 +1370,7 @@ static void R_RenderSegLoop (void)
|
|||
dc_yh = yh;
|
||||
dc_texturemid = rw_bottomtexturemid;
|
||||
dc_iscale = FixedMul(0xffffffffu / (unsigned)rw_scale, rw_bottomtexturescaley);
|
||||
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS);
|
||||
dc_source = R_GetColumn(bottomtexture, offset >> FRACBITS)->pixels;
|
||||
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
|
||||
colfunc();
|
||||
floorclip[rw_x] = (INT16)mid;
|
||||
|
|
871
src/r_textures.c
871
src/r_textures.c
File diff suppressed because it is too large
Load diff
|
@ -42,9 +42,7 @@ enum
|
|||
TEXTURETYPE_UNKNOWN,
|
||||
TEXTURETYPE_SINGLEPATCH,
|
||||
TEXTURETYPE_COMPOSITE,
|
||||
#ifdef WALLFLATS
|
||||
TEXTURETYPE_FLAT,
|
||||
#endif
|
||||
TEXTURETYPE_FLAT
|
||||
};
|
||||
|
||||
// A texture_t describes a rectangular texture,
|
||||
|
@ -55,9 +53,8 @@ typedef struct
|
|||
// Keep name for switch changing, etc.
|
||||
char name[8];
|
||||
UINT32 hash;
|
||||
UINT8 type; // TEXTURETYPE_
|
||||
UINT8 type; // TEXTURETYPE_*
|
||||
INT16 width, height;
|
||||
boolean holes;
|
||||
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
|
||||
void *flat; // The texture, as a flat.
|
||||
|
||||
|
@ -72,7 +69,7 @@ extern texture_t **textures;
|
|||
extern INT32 *texturewidth;
|
||||
extern fixed_t *textureheight; // needed for texture pegging
|
||||
|
||||
extern UINT32 **texturecolumnofs; // column offset lookup table for each texture
|
||||
extern column_t **texturecolumns; // columns for each texture
|
||||
extern UINT8 **texturecache; // graphics data for each generated full-size texture
|
||||
|
||||
// Load TEXTURES definitions, create lookup tables
|
||||
|
@ -82,15 +79,16 @@ void R_FlushTextureCache(void);
|
|||
|
||||
// Texture generation
|
||||
UINT8 *R_GenerateTexture(size_t texnum);
|
||||
UINT8 *R_GenerateTextureAsFlat(size_t texnum);
|
||||
UINT8 *R_GetFlatForTexture(size_t texnum);
|
||||
INT32 R_GetTextureNum(INT32 texnum);
|
||||
void R_CheckTextureCache(INT32 tex);
|
||||
void R_ClearTextureNumCache(boolean btell);
|
||||
|
||||
// Retrieve texture data.
|
||||
void *R_GetLevelFlat(levelflat_t *levelflat);
|
||||
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
|
||||
void *R_GetFlat(lumpnum_t flatnum);
|
||||
column_t *R_GetColumn(fixed_t tex, INT32 col);
|
||||
void *R_GetFlat(levelflat_t *levelflat);
|
||||
|
||||
INT32 R_GetTextureNumForFlat(levelflat_t *levelflat);
|
||||
|
||||
boolean R_CheckPowersOfTwo(void);
|
||||
boolean R_CheckSolidColorFlat(void);
|
||||
|
@ -102,7 +100,7 @@ void R_SetFlatVars(size_t length);
|
|||
// Returns the texture number for the texture name.
|
||||
INT32 R_TextureNumForName(const char *name);
|
||||
INT32 R_CheckTextureNumForName(const char *name);
|
||||
lumpnum_t R_GetFlatNumForName(const char *name);
|
||||
INT32 R_CheckFlatNumForName(const char *name);
|
||||
|
||||
// Returns the texture name for the texture number (in case you ever needed it)
|
||||
const char *R_CheckTextureNameForNum(INT32 num);
|
||||
|
|
178
src/r_things.c
178
src/r_things.c
|
@ -257,7 +257,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
UINT8 frame;
|
||||
UINT8 rotation;
|
||||
lumpinfo_t *lumpinfo;
|
||||
softwarepatch_t patch;
|
||||
UINT16 numadded = 0;
|
||||
|
||||
memset(sprtemp,0xFF, sizeof (sprtemp));
|
||||
|
@ -285,11 +284,8 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
{
|
||||
if (memcmp(lumpinfo[l].name,sprname,4)==0)
|
||||
{
|
||||
INT32 width, height;
|
||||
INT16 width, height;
|
||||
INT16 topoffset, leftoffset;
|
||||
#ifndef NO_PNG_LUMPS
|
||||
boolean isPNG = false;
|
||||
#endif
|
||||
|
||||
frame = R_Char2Frame(lumpinfo[l].name[4]);
|
||||
rotation = R_Char2Rotation(lumpinfo[l].name[5]);
|
||||
|
@ -304,33 +300,12 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
|
|||
if (W_LumpLengthPwad(wadnum,l)<=8)
|
||||
continue;
|
||||
|
||||
// Get the patch's dimensions only
|
||||
if (!W_ReadPatchHeaderPwad(wadnum, l, &width, &height, &topoffset, &leftoffset))
|
||||
continue;
|
||||
|
||||
// store sprite info in lookup tables
|
||||
//FIXME : numspritelumps do not duplicate sprite replacements
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
{
|
||||
softwarepatch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC);
|
||||
size_t len = W_LumpLengthPwad(wadnum, l);
|
||||
|
||||
if (Picture_IsLumpPNG((UINT8 *)png, len))
|
||||
{
|
||||
Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len);
|
||||
isPNG = true;
|
||||
}
|
||||
|
||||
Z_Free(png);
|
||||
}
|
||||
|
||||
if (!isPNG)
|
||||
#endif
|
||||
{
|
||||
W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof(INT16) * 4, 0);
|
||||
width = (INT32)(SHORT(patch.width));
|
||||
height = (INT32)(SHORT(patch.height));
|
||||
topoffset = (INT16)(SHORT(patch.topoffset));
|
||||
leftoffset = (INT16)(SHORT(patch.leftoffset));
|
||||
}
|
||||
|
||||
spritecachedinfo[numspritelumps].width = width<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].offset = leftoffset<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].topoffset = topoffset<<FRACBITS;
|
||||
|
@ -635,25 +610,18 @@ INT16 *mceilingclip;
|
|||
fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0;
|
||||
fixed_t windowtop = 0, windowbottom = 0;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column)
|
||||
void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
fixed_t basetexturemid;
|
||||
INT32 topdelta, prevdelta = 0;
|
||||
fixed_t basetexturemid = dc_texturemid;
|
||||
|
||||
basetexturemid = dc_texturemid;
|
||||
(void)lengthcol;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
// calculate unclipped screen coordinates
|
||||
// for post
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
topscreen = sprtopscreen + spryscale*topdelta;
|
||||
bottomscreen = topscreen + spryscale*column->length;
|
||||
post_t *post = &column->posts[i];
|
||||
|
||||
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
|
||||
INT32 bottomscreen = topscreen + spryscale*post->length;
|
||||
|
||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
@ -677,48 +645,36 @@ void R_DrawMaskedColumn(column_t *column)
|
|||
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
dc_source = column->pixels + post->data_offset;
|
||||
dc_texturemid = basetexturemid - (post->topdelta<<FRACBITS);
|
||||
|
||||
// Drawn by R_DrawColumn.
|
||||
// This stuff is a likely cause of the splitscreen water crash bug.
|
||||
// FIXTHIS: Figure out what "something more proper" is and do it.
|
||||
// quick fix... something more proper should be done!!!
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
#endif
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
}
|
||||
|
||||
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||
static UINT8 *flippedcol = NULL;
|
||||
static size_t flippedcolsize = 0;
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column)
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
fixed_t basetexturemid = dc_texturemid;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
UINT8 *d,*s;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
// calculate unclipped screen coordinates
|
||||
// for post
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
topdelta = lengthcol-column->length-topdelta;
|
||||
post_t *post = &column->posts[i];
|
||||
if (!post->length)
|
||||
continue;
|
||||
|
||||
INT32 topdelta = lengthcol-post->length-post->topdelta;
|
||||
topscreen = sprtopscreen + spryscale*topdelta;
|
||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
|
||||
: sprbotscreen + spryscale*column->length;
|
||||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
|
||||
: sprbotscreen + spryscale*post->length;
|
||||
|
||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
@ -742,21 +698,19 @@ void R_DrawFlippedMaskedColumn(column_t *column)
|
|||
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
{
|
||||
dc_source = ZZ_Alloc(column->length);
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||
if (post->length > flippedcolsize)
|
||||
{
|
||||
flippedcolsize = post->length;
|
||||
flippedcol = Z_Realloc(flippedcol, flippedcolsize, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
for (s = column->pixels+post->data_offset+post->length, d = flippedcol; d < flippedcol+post->length; --s)
|
||||
*d++ = *s;
|
||||
dc_source = flippedcol;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Still drawn by R_DrawColumn.
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
#endif
|
||||
Z_Free(dc_source);
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
|
@ -816,14 +770,14 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
void (*localcolfunc)(column_t *);
|
||||
INT32 texturecolumn;
|
||||
void (*localcolfunc)(column_t *, unsigned);
|
||||
INT32 pwidth;
|
||||
fixed_t frac;
|
||||
patch_t *patch = vis->patch;
|
||||
fixed_t this_scale = vis->thingscale;
|
||||
INT32 x1, x2;
|
||||
INT64 overflow_test;
|
||||
unsigned lengthcol;
|
||||
|
||||
if (!patch)
|
||||
return;
|
||||
|
@ -942,7 +896,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += scalestep)
|
||||
{
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / horzscale;
|
||||
INT32 texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / horzscale;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
continue;
|
||||
|
@ -953,9 +907,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
column = &patch->columns[texturecolumn];
|
||||
|
||||
localcolfunc (column);
|
||||
localcolfunc (column, lengthcol);
|
||||
}
|
||||
}
|
||||
else if (vis->cut & SC_SHEAR)
|
||||
|
@ -967,17 +921,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
// Vertically sheared sprite
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, dc_texturemid -= vis->shear.tan)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
|
||||
column = &patch->columns[frac>>FRACBITS];
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
localcolfunc (column);
|
||||
localcolfunc (column, lengthcol);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -989,15 +935,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
localcolfunc (column);
|
||||
column = &patch->columns[frac>>FRACBITS];
|
||||
localcolfunc (column, lengthcol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1011,21 +950,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
// Special precipitation drawer Tails 08-18-2002
|
||||
static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column;
|
||||
#ifdef RANGECHECK
|
||||
INT32 texturecolumn;
|
||||
#endif
|
||||
fixed_t frac;
|
||||
patch_t *patch;
|
||||
INT64 overflow_test;
|
||||
|
||||
//Fab : R_InitSprites now sets a wad lump number
|
||||
patch = vis->patch;
|
||||
patch_t *patch = vis->patch;
|
||||
if (!patch)
|
||||
return;
|
||||
|
||||
// Check for overflow
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*vis->scale)>>FRACBITS);
|
||||
INT64 overflow_test = (INT64)centeryfrac - (((INT64)vis->texturemid*vis->scale)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // fixed point mult would overflow
|
||||
|
||||
|
@ -1041,31 +971,19 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
dc_texturemid = vis->texturemid;
|
||||
dc_texheight = 0;
|
||||
|
||||
frac = vis->startfrac;
|
||||
spryscale = vis->scale;
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
|
||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||
|
||||
if (vis->x1 < 0)
|
||||
vis->x1 = 0;
|
||||
|
||||
if (vis->x2 >= vid.width)
|
||||
vis->x2 = vid.width-1;
|
||||
|
||||
fixed_t frac = vis->startfrac;
|
||||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
{
|
||||
#ifdef RANGECHECK
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= patch->width)
|
||||
I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn");
|
||||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
#else
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
|
||||
#endif
|
||||
R_DrawMaskedColumn(column);
|
||||
}
|
||||
R_DrawMaskedColumn(&patch->columns[frac>>FRACBITS], patch->height);
|
||||
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
}
|
||||
|
|
|
@ -45,10 +45,9 @@ extern fixed_t sprtopscreen;
|
|||
extern fixed_t sprbotscreen;
|
||||
extern fixed_t windowtop;
|
||||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column);
|
||||
void R_DrawMaskedColumn(column_t *column, unsigned lengthcol);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol);
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
|
|
|
@ -116,8 +116,6 @@ void SCR_SetDrawFuncs(void)
|
|||
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
|
||||
colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8;
|
||||
colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
|
||||
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
|
||||
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
|
||||
|
||||
spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;
|
||||
|
|
|
@ -126,8 +126,6 @@ enum
|
|||
COLDRAWFUNC_SHADE,
|
||||
COLDRAWFUNC_SHADOWED,
|
||||
COLDRAWFUNC_TRANSTRANS,
|
||||
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||
COLDRAWFUNC_FOG,
|
||||
|
||||
COLDRAWFUNC_MAX
|
||||
|
|
102
src/v_video.c
102
src/v_video.c
|
@ -506,7 +506,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
|
||||
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
|
||||
INT32 dup;
|
||||
const column_t *column;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest, *deststart, *destend;
|
||||
const UINT8 *source, *deststop;
|
||||
fixed_t pwidth; // patch width
|
||||
|
@ -686,12 +686,12 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
if (!(scrn & V_SCALEPATCHMASK))
|
||||
{
|
||||
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
|
||||
if (x == 0 && patch->width == BASEVIDWIDTH && y == 0 && patch->height == BASEVIDHEIGHT)
|
||||
if (!v_translevel && x == 0 && patch->width == BASEVIDWIDTH && y == 0 && patch->height == BASEVIDHEIGHT)
|
||||
{
|
||||
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[0]));
|
||||
if (!column->topdelta)
|
||||
column = &patch->columns[0];
|
||||
if (column->num_posts && !column->posts[0].topdelta)
|
||||
{
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
source = column->pixels;
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]);
|
||||
}
|
||||
}
|
||||
|
@ -741,7 +741,6 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
|
||||
for (col = 0; (col>>FRACBITS) < patch->width; col += colfrac, ++offx, desttop++)
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
if (scrn & V_FLIP) // offx is measured from right edge instead of left
|
||||
{
|
||||
if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
|
||||
|
@ -756,27 +755,24 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
|
|||
if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
|
||||
break;
|
||||
}
|
||||
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
|
||||
|
||||
while (column->topdelta != 0xff)
|
||||
column = &patch->columns[col>>FRACBITS];
|
||||
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
post_t *post = &column->posts[i];
|
||||
source = column->pixels + post->data_offset;
|
||||
dest = desttop;
|
||||
if (scrn & V_FLIP)
|
||||
dest = deststart + (destend - desttop);
|
||||
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*vid.width;
|
||||
dest += FixedInt(FixedMul(post->topdelta<<FRACBITS,vdup))*vid.width;
|
||||
|
||||
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
|
||||
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < post->length; ofs += rowfrac)
|
||||
{
|
||||
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
|
||||
*dest = patchdrawfunc(dest, source, ofs);
|
||||
dest += vid.width;
|
||||
}
|
||||
column = (const column_t *)((const UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -791,7 +787,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
|
|||
|
||||
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
|
||||
INT32 dup;
|
||||
const column_t *column;
|
||||
column_t *column;
|
||||
UINT8 *desttop, *dest;
|
||||
const UINT8 *source, *deststop;
|
||||
|
||||
|
@ -1020,20 +1016,18 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
|
|||
|
||||
for (col = sx; (col>>FRACBITS) < patch->width && (col - sx) < w; col += colfrac, ++x, desttop++)
|
||||
{
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
|
||||
continue;
|
||||
if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
|
||||
break;
|
||||
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
|
||||
|
||||
while (column->topdelta != 0xff)
|
||||
column = &patch->columns[col>>FRACBITS];
|
||||
|
||||
for (unsigned i = 0; i < column->num_posts; i++)
|
||||
{
|
||||
topdelta = column->topdelta;
|
||||
if (topdelta <= prevdelta)
|
||||
topdelta += prevdelta;
|
||||
prevdelta = topdelta;
|
||||
source = (const UINT8 *)(column) + 3;
|
||||
post_t *post = &column->posts[i];
|
||||
INT32 topdelta = post->topdelta;
|
||||
source = column->pixels + post->data_offset;
|
||||
dest = desttop;
|
||||
if ((topdelta<<FRACBITS)-sy > 0)
|
||||
{
|
||||
|
@ -1043,13 +1037,12 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
|
|||
else
|
||||
ofs = sy-(topdelta<<FRACBITS);
|
||||
|
||||
for (; dest < deststop && (ofs>>FRACBITS) < column->length && ((ofs - sy) + (topdelta<<FRACBITS)) < h; ofs += rowfrac)
|
||||
for (; dest < deststop && (size_t)(ofs>>FRACBITS) < post->length && ((ofs - sy) + (topdelta<<FRACBITS)) < h; ofs += rowfrac)
|
||||
{
|
||||
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
|
||||
*dest = patchdrawfunc(dest, source, ofs);
|
||||
dest += vid.width;
|
||||
}
|
||||
column = (const column_t *)((const UINT8 *)column + column->length + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1101,61 +1094,6 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
|
|||
}
|
||||
}
|
||||
|
||||
static void V_BlitScaledPic(INT32 px1, INT32 py1, INT32 scrn, pic_t *pic);
|
||||
// Draw a linear pic, scaled, TOTALLY CRAP CODE!!! OPTIMISE AND ASM!!
|
||||
//
|
||||
void V_DrawScaledPic(INT32 rx1, INT32 ry1, INT32 scrn, INT32 lumpnum)
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
{
|
||||
HWR_DrawPic(rx1, ry1, lumpnum);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
V_BlitScaledPic(rx1, ry1, scrn, W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
}
|
||||
|
||||
static void V_BlitScaledPic(INT32 rx1, INT32 ry1, INT32 scrn, pic_t * pic)
|
||||
{
|
||||
INT32 dupx, dupy;
|
||||
INT32 x, y;
|
||||
UINT8 *src, *dest;
|
||||
INT32 width, height;
|
||||
|
||||
width = SHORT(pic->width);
|
||||
height = SHORT(pic->height);
|
||||
scrn &= V_PARAMMASK;
|
||||
|
||||
if (pic->mode != 0)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "pic mode %d not supported in Software\n", pic->mode);
|
||||
return;
|
||||
}
|
||||
|
||||
dest = screens[scrn] + max(0, ry1 * vid.width) + max(0, rx1);
|
||||
// y cliping to the screen
|
||||
if (ry1 + height * vid.dup >= vid.width)
|
||||
height = (vid.width - ry1) / vid.dup - 1;
|
||||
// WARNING no x clipping (not needed for the moment)
|
||||
|
||||
for (y = max(0, -ry1 / vid.dup); y < height; y++)
|
||||
{
|
||||
for (dupy = vid.dup; dupy; dupy--)
|
||||
{
|
||||
src = pic->data + y * width;
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
for (dupx = vid.dup; dupx; dupx--)
|
||||
*dest++ = *src;
|
||||
src++;
|
||||
}
|
||||
dest += vid.width - vid.dup * width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Fills a box of pixels with a single color, NOTE: scaled to screen size
|
||||
//
|
||||
|
|
|
@ -178,9 +178,6 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 ski
|
|||
// Draw a linear block of pixels into the view buffer.
|
||||
void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src);
|
||||
|
||||
// draw a pic_t, SCALED
|
||||
void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum);
|
||||
|
||||
// fill a box with a single color
|
||||
void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c);
|
||||
void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c);
|
||||
|
|
203
src/w_wad.c
203
src/w_wad.c
|
@ -1351,6 +1351,74 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
return i;
|
||||
}
|
||||
|
||||
void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps)
|
||||
{
|
||||
size_t name_length = strlen(name);
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo;
|
||||
|
||||
UINT16 capacity = list_capacity ? *list_capacity : 0;
|
||||
UINT16 count = *numlumps;
|
||||
|
||||
for (UINT16 i = 0; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
{
|
||||
if (strlen(lump_p->fullname) > name_length
|
||||
&& lump_p->longname[0] != '\0')
|
||||
{
|
||||
if (!capacity || count >= capacity)
|
||||
{
|
||||
capacity = capacity ? (capacity * 2) : 16;
|
||||
*list = Z_Realloc(*list, capacity * sizeof(UINT32), PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
(*list)[count] = (wad << 16) + i;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (list_capacity)
|
||||
(*list_capacity) = capacity;
|
||||
(*numlumps) = count;
|
||||
}
|
||||
|
||||
void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps)
|
||||
{
|
||||
for (UINT16 i = 0; i < numwadfiles; i++)
|
||||
W_GetFolderLumpsPwad(name, i, list, list_capacity, numlumps);
|
||||
}
|
||||
|
||||
UINT32 W_CountFolderLumpsPwad(const char *name, UINT16 wad)
|
||||
{
|
||||
size_t name_length = strlen(name);
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo;
|
||||
|
||||
UINT32 count = 0;
|
||||
|
||||
for (UINT16 i = 0; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
{
|
||||
if (strnicmp(name, lump_p->fullname, name_length) == 0)
|
||||
{
|
||||
if (strlen(lump_p->fullname) > name_length
|
||||
&& lump_p->longname[0] != '\0')
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
UINT32 W_CountFolderLumps(const char *name)
|
||||
{
|
||||
UINT32 count = 0;
|
||||
|
||||
for (UINT16 i = 0; i < numwadfiles; i++)
|
||||
count += W_CountFolderLumpsPwad(name, i);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// In a PK3 type of resource file, it looks for an entry with the specified full name.
|
||||
// Returns lump position in PK3's lumpinfo, or INT16_MAX if not found.
|
||||
UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
||||
|
@ -1700,6 +1768,10 @@ void zerr(int ret)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
#define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename)
|
||||
#endif
|
||||
|
||||
/** Reads bytes from the head of a lump.
|
||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||
*
|
||||
|
@ -1780,10 +1852,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
bytesread = fread(dest, 1, size, handle);
|
||||
if (wadfiles[wad]->type == RET_FOLDER)
|
||||
fclose(handle);
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)dest, bytesread))
|
||||
Picture_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
#endif
|
||||
return bytesread;
|
||||
case CM_LZF: // Is it LZF compressed? Used by ZWADs.
|
||||
{
|
||||
|
@ -1819,10 +1887,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
M_Memcpy(dest, decData + offset, size);
|
||||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)dest, size))
|
||||
Picture_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
#endif
|
||||
return size;
|
||||
#else
|
||||
//I_Error("ZWAD files not supported on this platform.");
|
||||
|
@ -1882,10 +1946,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
|||
Z_Free(rawData);
|
||||
Z_Free(decData);
|
||||
|
||||
#ifdef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)dest, size))
|
||||
Picture_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
@ -2004,8 +2064,7 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr)
|
|||
// If a patch is already cached return true, otherwise
|
||||
// return false.
|
||||
//
|
||||
// no outside code uses the PWAD form, for now
|
||||
static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
||||
boolean W_IsPatchCachedPwad(UINT16 wad, UINT16 lump, void *ptr)
|
||||
{
|
||||
void *lcache;
|
||||
|
||||
|
@ -2027,7 +2086,7 @@ static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
|
|||
|
||||
boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr)
|
||||
{
|
||||
return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
|
||||
return W_IsPatchCachedPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
|
@ -2042,18 +2101,10 @@ void *W_CacheLumpName(const char *name, INT32 tag)
|
|||
// CACHING OF GRAPHIC PATCH RESOURCES
|
||||
// ==========================================================================
|
||||
|
||||
// Graphic 'patches' are loaded, and if necessary, converted into the format
|
||||
// the most useful for the current rendermode. For software renderer, the
|
||||
// graphic patches are kept as is. For the hardware renderer, graphic patches
|
||||
// are 'unpacked', and are kept into the cache in that unpacked format, and
|
||||
// the heap memory cache then acts as a 'level 2' cache just after the
|
||||
// graphics card memory.
|
||||
|
||||
//
|
||||
// Cache a patch into heap memory, convert the patch format as necessary
|
||||
//
|
||||
|
||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
static void *W_GetPatchPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
{
|
||||
lumpcache_t *lumpcache = NULL;
|
||||
|
||||
|
@ -2071,15 +2122,25 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
|
||||
ptr = lumpdata;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
|
||||
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_PATCH, NULL, NULL, NULL, NULL, len, &len, 0);
|
||||
Z_ChangeTag(ptr, tag);
|
||||
Z_SetUser(ptr, &lumpcache[lump]);
|
||||
Z_Free(lumpdata);
|
||||
return lumpcache[lump];
|
||||
#else
|
||||
Picture_ThrowPNGError(W_CheckNameForNumPwad(wad, lump), wadfiles[wad]->filename);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
|
||||
Patch_Create(ptr, len, dest);
|
||||
|
||||
dest = Patch_CreateFromDoomPatch(ptr);
|
||||
Z_Free(ptr);
|
||||
|
||||
Z_ChangeTag(dest, tag);
|
||||
Z_SetUser(dest, &lumpcache[lump]);
|
||||
}
|
||||
else
|
||||
Z_ChangeTag(lumpcache[lump], tag);
|
||||
|
@ -2087,30 +2148,19 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
return lumpcache[lump];
|
||||
}
|
||||
|
||||
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
|
||||
{
|
||||
return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
|
||||
}
|
||||
|
||||
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
{
|
||||
patch_t *patch;
|
||||
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
|
||||
patch = W_CacheSoftwarePatchNumPwad(wad, lump, tag);
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Software-only compile cache the data without conversion
|
||||
if (rendermode == render_soft || rendermode == render_none)
|
||||
#endif
|
||||
return (void *)patch;
|
||||
patch_t *patch = W_GetPatchPwad(wad, lump, tag);
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
Patch_CreateGL(patch);
|
||||
return (void *)patch;
|
||||
#endif
|
||||
|
||||
return (void *)patch;
|
||||
}
|
||||
|
||||
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
|
||||
|
@ -2118,6 +2168,71 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
|
|||
return W_CachePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
|
||||
}
|
||||
|
||||
void *W_GetCachedPatchNumPwad(UINT16 wad, UINT16 lump)
|
||||
{
|
||||
if (!TestValidLump(wad, lump))
|
||||
return NULL;
|
||||
|
||||
return wadfiles[wad]->patchcache[lump];
|
||||
}
|
||||
|
||||
boolean W_ReadPatchHeaderPwad(UINT16 wadnum, UINT16 lumpnum, INT16 *width, INT16 *height, INT16 *topoffset, INT16 *leftoffset)
|
||||
{
|
||||
UINT8 header[PNG_HEADER_SIZE];
|
||||
|
||||
if (!TestValidLump(wadnum, lumpnum))
|
||||
return false;
|
||||
|
||||
W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0);
|
||||
|
||||
size_t len = W_LumpLengthPwad(wadnum, lumpnum);
|
||||
|
||||
if (Picture_IsLumpPNG(header, len))
|
||||
{
|
||||
#ifndef NO_PNG_LUMPS
|
||||
UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
|
||||
|
||||
INT32 pwidth = 0, pheight = 0;
|
||||
|
||||
if (!Picture_PNGDimensions(png, &pwidth, &pheight, topoffset, leftoffset, len))
|
||||
{
|
||||
Z_Free(png);
|
||||
return false;
|
||||
}
|
||||
|
||||
*width = (INT16)pwidth;
|
||||
*height = (INT16)pheight;
|
||||
|
||||
Z_Free(png);
|
||||
|
||||
return true;
|
||||
#else
|
||||
Picture_ThrowPNGError(W_CheckNameForNumPwad(wadnum, lumpnum), wadfiles[wadnum]->filename);
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
softwarepatch_t patch;
|
||||
|
||||
if (!W_ReadLumpHeaderPwad(wadnum, lumpnum, &patch, sizeof(INT16) * 4, 0))
|
||||
return false;
|
||||
|
||||
*width = SHORT(patch.width);
|
||||
*height = SHORT(patch.height);
|
||||
if (topoffset)
|
||||
*topoffset = SHORT(patch.topoffset);
|
||||
if (leftoffset)
|
||||
*leftoffset = SHORT(patch.leftoffset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean W_ReadPatchHeader(lumpnum_t lumpnum, INT16 *width, INT16 *height, INT16 *topoffset, INT16 *leftoffset)
|
||||
{
|
||||
return W_ReadPatchHeaderPwad(WADFILENUM(lumpnum), LUMPNUM(lumpnum), width, height, topoffset, leftoffset);
|
||||
}
|
||||
|
||||
void W_UnlockCachedPatch(void *patch)
|
||||
{
|
||||
if (!patch)
|
||||
|
|
15
src/w_wad.h
15
src/w_wad.h
|
@ -181,6 +181,11 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump);
|
|||
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump);
|
||||
|
||||
void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
|
||||
void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
|
||||
UINT32 W_CountFolderLumpsPwad(const char *name, UINT16 wad);
|
||||
UINT32 W_CountFolderLumps(const char *name);
|
||||
|
||||
lumpnum_t W_CheckNumForMap(const char *name);
|
||||
lumpnum_t W_CheckNumForName(const char *name);
|
||||
lumpnum_t W_CheckNumForLongName(const char *name);
|
||||
|
@ -210,20 +215,18 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag);
|
|||
|
||||
boolean W_IsLumpCached(lumpnum_t lump, void *ptr);
|
||||
boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
|
||||
boolean W_IsPatchCachedPwad(UINT16 wad, UINT16 lump, void *ptr);
|
||||
|
||||
void *W_CacheLumpName(const char *name, INT32 tag);
|
||||
void *W_CachePatchName(const char *name, INT32 tag);
|
||||
void *W_CachePatchLongName(const char *name, INT32 tag);
|
||||
|
||||
// Returns either a Software patch, or an OpenGL patch.
|
||||
// Performs any necessary conversions from PNG images.
|
||||
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
|
||||
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
|
||||
void *W_GetCachedPatchNumPwad(UINT16 wad, UINT16 lump);
|
||||
|
||||
// Returns a Software patch.
|
||||
// Performs any necessary conversions from PNG images.
|
||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
|
||||
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag);
|
||||
boolean W_ReadPatchHeaderPwad(UINT16 wadnum, UINT16 lumpnum, INT16 *width, INT16 *height, INT16 *topoffset, INT16 *leftoffset);
|
||||
boolean W_ReadPatchHeader(lumpnum_t lumpnum, INT16 *width, INT16 *height, INT16 *topoffset, INT16 *leftoffset);
|
||||
|
||||
void W_UnlockCachedPatch(void *patch);
|
||||
|
||||
|
|
Loading…
Reference in a new issue