Merge branch 'patch-refactor' into 'next'

Patch and texture refactor

See merge request STJr/SRB2!2104
This commit is contained in:
Logan Aerl Arias 2024-02-12 04:48:36 +00:00
commit bf4efe968f
30 changed files with 1476 additions and 2172 deletions

View file

@ -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);

View file

@ -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

View file

@ -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]);

View file

@ -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
// --------------------------------------------------------------------------

View file

@ -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));
}

View file

@ -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);

View file

@ -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));

View file

@ -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;
}

View file

@ -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;

View file

@ -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.

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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
*/

View file

@ -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)

View file

@ -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)

View file

@ -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);

View file

@ -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(

View file

@ -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;

View file

@ -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;

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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];
}

View file

@ -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

View file

@ -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;

View file

@ -126,8 +126,6 @@ enum
COLDRAWFUNC_SHADE,
COLDRAWFUNC_SHADOWED,
COLDRAWFUNC_TRANSTRANS,
COLDRAWFUNC_TWOSMULTIPATCH,
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
COLDRAWFUNC_FOG,
COLDRAWFUNC_MAX

View file

@ -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
//

View file

@ -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);

View file

@ -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)

View file

@ -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);