Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • pastel/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Hanicef/SRB2Classic
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
118 results
Show changes
Commits on Source (4)
Showing with 638 additions and 777 deletions
......@@ -16,7 +16,7 @@
// The texture for the next polygon given to HWR_ProcessPolygon.
// Set with HWR_SetCurrentTexture.
GLMipmap_t *current_texture = NULL;
static GLMipmap_t *current_texture = NULL;
boolean currently_batching = false;
......@@ -42,10 +42,10 @@ int unsortedVertexArrayAllocSize = 65536;
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
// init arrays if that has not been done yet
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
......@@ -55,7 +55,7 @@ void HWR_StartBatching(void)
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
currently_batching = true;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
......@@ -63,14 +63,17 @@ void HWR_StartBatching(void)
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
current_texture = texture;
if (!currently_batching)
{
HWD.pfnSetTexture(texture);
}
}
GLMipmap_t *HWR_GetCurrentTexture(void)
{
return current_texture;
}
// If batching is enabled, this function collects the polygon data and the chosen texture
......@@ -78,7 +81,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial)
{
if (currently_batching)
if (currently_batching)
{
if (!pSurf)
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
......@@ -123,10 +126,10 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
}
else
{
if (shader)
HWD.pfnSetShader(shader);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
if (shader)
HWD.pfnSetShader(shader);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
static int comparePolygons(const void *p1, const void *p2)
......@@ -219,7 +222,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
// the rendering backend to draw them.
void HWR_RenderBatches(void)
{
int finalVertexWritePos = 0;// position in finalVertexArray
int finalVertexWritePos = 0;// position in finalVertexArray
int finalIndexWritePos = 0;// position in finalVertexIndexArray
int polygonReadPos = 0;// position in polygonIndexArray
......@@ -235,7 +238,7 @@ void HWR_RenderBatches(void)
int i;
if (!currently_batching)
if (!currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
nextSurfaceInfo.LightInfo.fade_end = 0;
......@@ -290,8 +293,8 @@ void HWR_RenderBatches(void)
if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
HWD.pfnSetTexture(currentTexture);
else
HWD.pfnSetTexture(currentTexture);
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
{
......@@ -406,7 +409,7 @@ void HWR_RenderBatches(void)
if (changeState || stopFlag)
{
// execute draw call
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
// update stats
ps_hw_numcalls++;
ps_hw_numverts += finalIndexWritePos;
......@@ -431,7 +434,7 @@ void HWR_RenderBatches(void)
if (changeTexture)
{
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
HWD.pfnSetTexture(nextTexture);
currentTexture = nextTexture;
changeTexture = false;
......
......@@ -29,8 +29,10 @@ typedef struct
} PolygonArrayEntry;
void HWR_StartBatching(void);
void HWR_SetCurrentTexture(GLMipmap_t *texture);
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial);
void HWR_RenderBatches(void);
void HWR_SetCurrentTexture(GLMipmap_t *texture);
GLMipmap_t *HWR_GetCurrentTexture(void);
#endif
......@@ -29,6 +29,9 @@
#include "../r_picformats.h"
#include "../p_setup.h"
// Values set after a call to HWR_ResizeBlock()
static INT32 blocksize, blockwidth, blockheight;
INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes
INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole
......@@ -288,13 +291,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (pwidth <= 0 || pheight <= 0)
return;
ncols = pwidth;
ncols = (pwidth * pblockwidth) / pwidth;
// source advance
xfrac = 0;
xfracstep = FRACUNIT;
yfracstep = FRACUNIT;
scale_y = FRACUNIT;
xfracstep = (pwidth << FRACBITS) / pblockwidth;
yfracstep = (pheight << FRACBITS) / pblockheight;
scale_y = (pblockheight << FRACBITS) / pheight;
bpp = format2bpp(mipmap->format);
......@@ -302,7 +305,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp;
blockmodulo = blockwidth*bpp;
// Draw each column to the block cache
for (; ncols--; block += bpp, xfrac += xfracstep)
......@@ -395,7 +398,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = pblockwidth*bpp;
blockmodulo = blockwidth*bpp;
// Draw each column to the block cache
for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep)
......@@ -413,6 +416,32 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
}
}
static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, boolean powersoftwo)
{
if (powersoftwo)
{
blockwidth = 1;
while (blockwidth < originalwidth)
blockwidth <<= 1;
blockheight = 1;
while (blockheight < originalheight)
blockheight <<= 1;
}
else
{
blockwidth = originalwidth;
blockheight = originalheight;
}
if (blockwidth > 8192)
blockwidth = 8192;
if (blockheight > 8192)
blockheight = 8192;
blocksize = blockwidth * blockheight;
}
static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
{
UINT8 *block;
......@@ -445,58 +474,22 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
{
UINT8 *block;
texture_t *texture;
texture_t *texture = textures[texnum];
texpatch_t *patch;
softwarepatch_t *realpatch;
UINT8 *pdata;
INT32 blockwidth, blockheight, blocksize;
INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
texture = textures[texnum];
HWR_ResizeBlock(texture->width, texture->height, true);
// hack the Legacy skies..
if (texture->name[0] == 'S' &&
texture->name[1] == 'K' &&
texture->name[2] == 'Y' &&
(texture->name[4] == 0 ||
texture->name[5] == 0)
)
{
skyspecial = true;
grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky
}
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
grtex->mipmap.width = (UINT16)blockwidth;
grtex->mipmap.height = (UINT16)blockheight;
grtex->mipmap.format = textureformat;
grtex->mipmap.flags = TF_POWERSOFTWO | TF_WRAPXY | TF_CHROMAKEYED;
blockwidth = texture->width;
blockheight = texture->height;
blocksize = (blockwidth * blockheight);
block = MakeBlock(&grtex->mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
{
INT32 j;
RGBA_t col;
col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX);
for (j = 0; j < blockheight; j++)
{
for (i = 0; i < blockwidth; i++)
{
block[4*(j*blockwidth+i)+0] = col.s.red;
block[4*(j*blockwidth+i)+1] = col.s.green;
block[4*(j*blockwidth+i)+2] = col.s.blue;
block[4*(j*blockwidth+i)+3] = 0xff;
}
}
}
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
......@@ -547,19 +540,23 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
{
if (grMipmap->width == 0)
{
grMipmap->width = grMipmap->height = 1;
while (grMipmap->width < patch->width) grMipmap->width <<= 1;
while (grMipmap->height < patch->height) grMipmap->height <<= 1;
// no wrap around, no chroma key
grMipmap->flags = 0;
HWR_ResizeBlock(patch->width, patch->height, grMipmap->flags & TF_POWERSOFTWO);
grMipmap->width = (UINT16)blockwidth;
grMipmap->height = (UINT16)blockheight;
// setup the texture info
grMipmap->format = patchformat;
grMipmap->flags |= TF_WRAPXY;
grPatch->max_s = (float)patch->width / (float)grMipmap->width;
grPatch->max_t = (float)patch->height / (float)grMipmap->height;
}
else
{
blockwidth = grMipmap->width;
blockheight = grMipmap->height;
blocksize = blockwidth * blockheight;
}
Z_Free(grMipmap->data);
grMipmap->data = NULL;
......@@ -569,7 +566,7 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap,
grMipmap->width, grMipmap->height,
min(patch->width, blockwidth), min(patch->height, blockheight),
patch->width, patch->height,
patch);
}
......@@ -582,7 +579,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
static size_t gl_numtextures = 0; // Texture count
static GLMapTexture_t *gl_textures; // For all textures
static GLMapTexture_t *gl_flats; // For all (texture) flats, as normal flats don't need to be cached
boolean gl_maptexturesloaded = false;
void HWR_FreeTextureData(patch_t *patch)
......@@ -710,7 +706,6 @@ void HWR_FreeColormapCache(void)
void HWR_InitMapTextures(void)
{
gl_textures = NULL;
gl_flats = NULL;
gl_maptexturesloaded = false;
}
......@@ -727,19 +722,13 @@ void HWR_FreeMapTextures(void)
size_t i;
for (i = 0; i < gl_numtextures; i++)
{
FreeMapTexture(&gl_textures[i]);
FreeMapTexture(&gl_flats[i]);
}
// now the heap don't have any 'user' pointing to our
// texturecache info, we can free it
if (gl_textures)
free(gl_textures);
if (gl_flats)
free(gl_flats);
gl_textures = NULL;
gl_flats = NULL;
gl_numtextures = 0;
gl_maptexturesloaded = false;
}
......@@ -751,9 +740,8 @@ void HWR_LoadMapTextures(size_t pnumtextures)
gl_numtextures = 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)
I_Error("HWR_LoadMapTextures: ran out of memory for OpenGL textures");
gl_maptexturesloaded = true;
......@@ -804,65 +792,18 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex)
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{
size_t size, pflatsize;
size_t size = W_LumpLength(flatlumpnum);
UINT16 pflatsize = R_GetFlatSize(size);
// setup the texture info
grMipmap->format = GL_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
grMipmap->flags = TF_POWERSOFTWO | TF_WRAPXY | TF_CHROMAKEYED;
size = W_LumpLength(flatlumpnum);
switch (size)
{
case 4194304: // 2048x2048 lump
pflatsize = 2048;
break;
case 1048576: // 1024x1024 lump
pflatsize = 1024;
break;
case 262144:// 512x512 lump
pflatsize = 512;
break;
case 65536: // 256x256 lump
pflatsize = 256;
break;
case 16384: // 128x128 lump
pflatsize = 128;
break;
case 1024: // 32x32 lump
pflatsize = 32;
break;
default: // 64x64 lump
pflatsize = 64;
break;
}
grMipmap->width = (UINT16)pflatsize;
grMipmap->height = (UINT16)pflatsize;
grMipmap->width = pflatsize;
grMipmap->height = pflatsize;
// the flat raw data needn't be converted with palettized textures
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
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);
W_ReadLump(flatlumpnum, Z_Malloc(size, PU_HWRCACHE, &grMipmap->data));
}
// Download a Doom 'flat' to the hardware cache and make it ready for use
......@@ -890,94 +831,17 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum)
void HWR_GetLevelFlat(levelflat_t *levelflat)
{
// Who knows?
if (levelflat == NULL)
return;
if (levelflat->type == LEVELFLAT_FLAT)
else if (levelflat->type == LEVELFLAT_FLAT)
HWR_GetRawFlat(levelflat->u.flat.lumpnum);
else if (levelflat->type == LEVELFLAT_TEXTURE)
{
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)
return;
// Every texture in memory, stored as a 8-bit flat. Wow!
grtex = &gl_flats[texturenum];
// Generate flat if missing from the cache
if (!grtex->mipmap.data && !grtex->mipmap.downloaded)
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.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)
HWR_GetTexture(levelflat->u.texture.num);
else if (levelflat->type == LEVELFLAT_PATCH || levelflat->type == LEVELFLAT_PNG)
{
patch_t *patch = W_CachePatchNum(levelflat->u.flat.lumpnum, PU_CACHE);
levelflat->width = (UINT16)(patch->width);
levelflat->height = (UINT16)(patch->height);
HWR_GetPatch(patch);
HWR_GetNPO2Patch(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);
}
......@@ -1066,6 +930,7 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
return;
}
}
// not found, create it!
// If we are here, the sprite with the current colormap is not already in hardware memory
......@@ -1085,6 +950,52 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
HWR_LoadPatchMipmap(patch, newMipmap);
}
// -------------------+
// HWR_GetNPO2Patch : Same as HWR_GetPatch for NPO2 patches
// -------------------+
void HWR_GetNPO2Patch(patch_t *patch)
{
GLPatch_t *grPatch;
GLMipmap_t *grMipmap, *newMipmap;
if (!patch->hardware)
Patch_CreateGL(patch);
grPatch = patch->hardware;
grMipmap = grPatch->mipmap;
// use the first mipmap if it already is NPO2
if (!(grMipmap->flags & TF_POWERSOFTWO))
{
HWR_GetPatch(patch);
return;
}
// search for the mipmap, skip the first
for (; grMipmap->nextcolormap; )
{
grMipmap = grMipmap->nextcolormap;
if (grMipmap->flags & TF_POWERSOFTWO)
continue;
if (grMipmap->colormap)
continue;
HWR_LoadPatchMipmap(patch, grMipmap);
return;
}
// not found, create it!
newMipmap = calloc(1, sizeof (*newMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetNPO2Patch");
grMipmap->nextcolormap = newMipmap;
newMipmap->flags = (grPatch->mipmap->flags & ~TF_POWERSOFTWO);
HWR_LoadPatchMipmap(patch, newMipmap);
}
void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
{
if (!gpatch)
......@@ -1187,8 +1098,9 @@ patch_t *HWR_GetPic(lumpnum_t lumpnum)
patch->height = SHORT(pic->height);
len = W_LumpLength(lumpnum) - sizeof (pic_t);
grPatch->mipmap->width = (UINT16)patch->width;
grPatch->mipmap->height = (UINT16)patch->height;
HWR_ResizeBlock(patch->width, patch->height, false);
grPatch->mipmap->width = (UINT16)blockwidth;
grPatch->mipmap->height = (UINT16)blockheight;
if (pic->mode == PALETTE)
grPatch->mipmap->format = textureformat; // can be set by driver
......@@ -1248,7 +1160,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
{
INT32 i,j;
fixed_t posx, posy, stepx, stepy;
UINT8 *block = mipmap->data; // places the data directly into here
UINT8 *block = mipmap->data; // places the data directly into here, it already has the space allocated from HWR_ResizeBlock
UINT8 *flat;
UINT8 *dest, *src, texel;
RGBA_t col;
......@@ -1317,12 +1229,13 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
}
// Thankfully, this will still work for this scenario
grMipmap->width = fmwidth;
grMipmap->height = fmheight;
HWR_ResizeBlock(fmwidth, fmheight, false);
grMipmap->width = blockwidth;
grMipmap->height = blockheight;
MakeBlock(grMipmap);
HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight);
HWR_DrawFadeMaskInCache(grMipmap, blockwidth, blockheight, fademasklumpnum, fmwidth, fmheight);
// I DO need to convert this because it isn't power of 2 and we need the alpha
}
......
......@@ -253,6 +253,7 @@ enum ETextureFlags
TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy
TF_CHROMAKEYED = 0x00000010,
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
TF_POWERSOFTWO = 0x00000080, // powers of two sized texture
};
struct FTextureInfo
......
......@@ -575,42 +575,10 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
// --------------------------------------------------------------------------
void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
{
FOutVector v[4];
double dflatsize;
INT32 flatflag;
FOutVector v[4];
const size_t len = W_LumpLength(flatlumpnum);
switch (len)
{
case 4194304: // 2048x2048 lump
dflatsize = 2048.0f;
flatflag = 2047;
break;
case 1048576: // 1024x1024 lump
dflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144:// 512x512 lump
dflatsize = 512.0f;
flatflag = 511;
break;
case 65536: // 256x256 lump
dflatsize = 256.0f;
flatflag = 255;
break;
case 16384: // 128x128 lump
dflatsize = 128.0f;
flatflag = 127;
break;
case 1024: // 32x32 lump
dflatsize = 32.0f;
flatflag = 31;
break;
default: // 64x64 lump
dflatsize = 64.0f;
flatflag = 63;
break;
}
UINT16 flatflag = R_GetFlatSize(len) - 1;
double dflatsize = (double)(flatflag + 1);
// 3--2
// | /|
......@@ -624,7 +592,6 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
// flat is 64x64 lod and texture offsets are [0.0, 1.0]
v[0].s = v[3].s = (float)((x & flatflag)/dflatsize);
v[2].s = v[1].s = (float)(v[0].s + w/dflatsize);
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize);
......
......@@ -113,6 +113,8 @@ patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetPatch(patch_t *patch);
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetNPO2Patch(patch_t *patch);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
patch_t *HWR_GetPic(lumpnum_t lumpnum);
......
......@@ -356,32 +356,38 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta)
// -----------------+
// HWR_RenderPlane : Render a floor or ceiling convex polygon
// -----------------+
static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap)
static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap)
{
polyvertex_t * pv;
float height; //constant y for all points on the convex flat polygon
FOutVector *v3d;
INT32 nrPlaneVerts; //verts original define of convex flat polygon
INT32 i;
float flatxref,flatyref;
float fflatwidth = 64.0f, fflatheight = 64.0f;
INT32 flatflag = 63;
boolean texflat = false;
float scrollx = 0.0f, scrolly = 0.0f, anglef = 0.0f;
angle_t angle = 0;
FSurfaceInfo Surf;
float tempxsow, tempytow;
FSurfaceInfo Surf;
FOutVector *v3d;
polyvertex_t *pv;
pslope_t *slope = NULL;
INT32 shader = SHADER_DEFAULT;
size_t nrPlaneVerts;
INT32 i;
float height; // constant y for all points on the convex flat polygon
float fflatwidth, fflatheight;
float tempxsow, tempytow;
float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0;
float anglef = 0.0f;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
INT32 shader = SHADER_DEFAULT;
// no convex poly were generated for this subsector
if (!xsub->planepoly)
return;
pv = xsub->planepoly->pts;
nrPlaneVerts = xsub->planepoly->numpts;
if (nrPlaneVerts < 3) // not even a triangle?
return;
// Get the slope pointer to simplify future code
if (FOFsector)
{
......@@ -404,12 +410,6 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
height = FIXED_TO_FLOAT(fixedheight);
pv = xsub->planepoly->pts;
nrPlaneVerts = xsub->planepoly->numpts;
if (nrPlaneVerts < 3) //not even a triangle ?
return;
// Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
{
......@@ -418,59 +418,19 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
}
// set texture for polygon
if (levelflat != NULL)
// Set texture size
if (PolyFlags & PF_NoTexture)
{
if (levelflat->type == LEVELFLAT_FLAT)
{
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
switch (len)
{
case 4194304: // 2048x2048 lump
fflatwidth = fflatheight = 2048.0f;
break;
case 1048576: // 1024x1024 lump
fflatwidth = fflatheight = 1024.0f;
break;
case 262144:// 512x512 lump
fflatwidth = fflatheight = 512.0f;
break;
case 65536: // 256x256 lump
fflatwidth = fflatheight = 256.0f;
break;
case 16384: // 128x128 lump
fflatwidth = fflatheight = 128.0f;
break;
case 1024: // 32x32 lump
fflatwidth = fflatheight = 32.0f;
break;
default: // 64x64 lump
fflatwidth = fflatheight = 64.0f;
break;
}
flatflag = ((INT32)fflatwidth)-1;
}
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;
}
texflat = true;
}
}
else // set no texture
fflatwidth = fflatheight = 1.0f;
HWR_SetCurrentTexture(NULL);
}
else
{
GLMipmap_t *grMipmap = HWR_GetCurrentTexture();
// reference point for flat texture coord for each vertex around the polygon
flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight);
fflatwidth = (float)grMipmap->width;
fflatheight = (float)grMipmap->height;
}
// transform
if (FOFsector != NULL)
......@@ -505,30 +465,13 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
}
if (angle) // Only needs to be done if there's an altered angle
{
tempxsow = flatxref;
tempytow = flatyref;
anglef = ANG2RAD(InvAngle(angle));
flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));
flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
}
#define SETUP3DVERT(vert, vx, vy) {\
/* Hurdler: add scrolling texture on floor/ceiling */\
if (texflat)\
{\
vert->s = (float)((vx) / fflatwidth) + scrollx;\
vert->t = -(float)((vy) / fflatheight) + scrolly;\
}\
else\
{\
vert->s = (float)(((vx) / fflatwidth) - flatxref + scrollx);\
vert->t = (float)(flatyref - ((vy) / fflatheight) + scrolly);\
}\
vert->s = (float)((vx) / fflatwidth) + scrollx;\
vert->t = -(float)((vy) / fflatheight) + scrolly;\
\
/* Need to rotate before translate */\
/* Rotation is done after translation */\
if (angle) /* Only needs to be done if there's an altered angle */\
{\
tempxsow = vert->s;\
......@@ -548,7 +491,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
}\
}
for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++)
for (i = 0, v3d = planeVerts; i < (INT32)nrPlaneVerts; i++,v3d++,pv++)
SETUP3DVERT(v3d, pv->x, pv->y);
if (slope)
......@@ -2696,7 +2639,7 @@ static inline void HWR_AddPolyObjectSegs(void)
}
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector,
FBITFIELD PolyFlags, UINT8 lightlevel, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap)
{
FSurfaceInfo Surf;
......@@ -2707,15 +2650,12 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
INT32 i;
float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon
float flatxref, flatyref;
float fflatwidth = 64.0f, fflatheight = 64.0f;
INT32 flatflag = 63;
boolean texflat = false;
float tempxsow, tempytow;
float scrollx = 0.0f, scrolly = 0.0f;
angle_t angle = 0;
fixed_t tempxs, tempyt;
float anglef = 0.0f;
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
......@@ -2736,62 +2676,19 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
Z_Malloc(numAllocedPlaneVerts * sizeof (FOutVector), PU_LEVEL, &planeVerts);
}
// set texture for polygon
if (levelflat != NULL)
// Set texture size
if (PolyFlags & PF_NoTexture)
{
if (levelflat->type == LEVELFLAT_FLAT)
{
size_t len = W_LumpLength(levelflat->u.flat.lumpnum);
switch (len)
{
case 4194304: // 2048x2048 lump
fflatwidth = fflatheight = 2048.0f;
break;
case 1048576: // 1024x1024 lump
fflatwidth = fflatheight = 1024.0f;
break;
case 262144:// 512x512 lump
fflatwidth = fflatheight = 512.0f;
break;
case 65536: // 256x256 lump
fflatwidth = fflatheight = 256.0f;
break;
case 16384: // 128x128 lump
fflatwidth = fflatheight = 128.0f;
break;
case 1024: // 32x32 lump
fflatwidth = fflatheight = 32.0f;
break;
default: // 64x64 lump
fflatwidth = fflatheight = 64.0f;
break;
}
flatflag = ((INT32)fflatwidth)-1;
}
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;
}
texflat = true;
}
}
else // set no texture
fflatwidth = fflatheight = 1.0f;
HWR_SetCurrentTexture(NULL);
}
else
{
GLMipmap_t *grMipmap = HWR_GetCurrentTexture();
// reference point for flat texture coord for each vertex around the polygon
flatxref = FIXED_TO_FLOAT(polysector->origVerts[0].x);
flatyref = FIXED_TO_FLOAT(polysector->origVerts[0].y);
flatxref = (float)(((fixed_t)flatxref & (~flatflag)) / fflatwidth);
flatyref = (float)(((fixed_t)flatyref & (~flatflag)) / fflatheight);
fflatwidth = (float)grMipmap->width;
fflatheight = (float)grMipmap->height;
}
// transform
v3d = planeVerts;
......@@ -2828,45 +2725,23 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
}
if (angle) // Only needs to be done if there's an altered angle
{
angle = (InvAngle(angle))>>ANGLETOFINESHIFT;
// This needs to be done so that it scrolls in a different direction after rotation like software
/*tempxs = FLOAT_TO_FIXED(scrollx);
tempyt = FLOAT_TO_FIXED(scrolly);
scrollx = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle))));
scrolly = (FIXED_TO_FLOAT(FixedMul(tempxs, FINESINE(angle)) + FixedMul(tempyt, FINECOSINE(angle))));*/
// This needs to be done so everything aligns after rotation
// It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does
tempxs = FLOAT_TO_FIXED(flatxref);
tempyt = FLOAT_TO_FIXED(flatyref);
flatxref = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle))));
flatyref = (FIXED_TO_FLOAT(FixedMul(tempxs, FINESINE(angle)) + FixedMul(tempyt, FINECOSINE(angle))));
}
anglef = ANG2RAD(InvAngle(angle));
for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++)
{
// Go from the polysector's original vertex locations
// Means the flat is offset based on the original vertex locations
if (texflat)
{
v3d->s = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx;
v3d->t = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly;
}
else
{
v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx);
v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly);
}
v3d->s = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx;
v3d->t = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly;
// Need to rotate before translate
// Rotation is done after translation
if (angle) // Only needs to be done if there's an altered angle
{
tempxs = FLOAT_TO_FIXED(v3d->s);
tempyt = FLOAT_TO_FIXED(v3d->t);
v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxs, FINECOSINE(angle)) - FixedMul(tempyt, FINESINE(angle))));
v3d->t = (FIXED_TO_FLOAT(FixedMul(tempxs, FINESINE(angle)) + FixedMul(tempyt, FINECOSINE(angle))));
tempxsow = v3d->s;
tempytow = v3d->t;
v3d->s = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));
v3d->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));
}
v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x);
......@@ -2876,21 +2751,21 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
HWR_Lighting(&Surf, lightlevel, planecolormap);
if (blendmode & PF_Translucent)
if (PolyFlags & PF_Translucent)
{
Surf.PolyColor.s.alpha = (UINT8)alpha;
blendmode |= PF_Modulated|PF_Occlude;
PolyFlags |= PF_Modulated|PF_Occlude;
}
else
blendmode |= PF_Masked|PF_Modulated;
PolyFlags |= PF_Masked|PF_Modulated;
if (HWR_UseShader())
{
shader = SHADER_FLOOR;
blendmode |= PF_ColorMapped;
PolyFlags |= PF_ColorMapped;
}
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, shader, false);
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
}
static void HWR_AddPolyObjectPlanes(void)
......@@ -2930,7 +2805,7 @@ static void HWR_AddPolyObjectPlanes(void)
{
HWR_GetLevelFlat(&levelflats[polyobjsector->floorpic]);
HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic],
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel),
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap));
}
}
......@@ -2953,7 +2828,7 @@ static void HWR_AddPolyObjectPlanes(void)
{
HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]);
HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic],
(light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel),
polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : *gl_frontsector->lightlist[light].extra_colormap));
}
}
......@@ -3072,7 +2947,7 @@ static void HWR_Subsector(size_t num)
// Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, floorlightlevel, &levelflats[gl_frontsector->floorpic], NULL, 255, floorcolormap);
PF_Occlude, floorlightlevel, NULL, 255, floorcolormap);
}
}
else
......@@ -3094,7 +2969,7 @@ static void HWR_Subsector(size_t num)
// Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering.
PF_Occlude, ceilinglightlevel, &levelflats[gl_frontsector->ceilingpic], NULL, 255, ceilingcolormap);
PF_Occlude, ceilinglightlevel, NULL, 255, ceilingcolormap);
}
}
else
......@@ -3166,7 +3041,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetLevelFlat(&levelflats[*rover->bottompic]);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel,
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
}
}
......@@ -3211,7 +3086,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetLevelFlat(&levelflats[*rover->toppic]);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel,
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
}
}
......@@ -4791,7 +4666,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat);
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap);
sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap);
}
else if (sortnode[sortindex[i]].polyplane)
{
......@@ -4801,7 +4676,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat);
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
}
else if (sortnode[sortindex[i]].wall)
{
......
......@@ -1119,11 +1119,6 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
// If here, the blended texture has not been created
// So we create it
//BP: WARNING: don't free it manually without clearing the cache of harware renderer
// (it have a liste of mipmap)
// this malloc is cleared in HWR_FreeColormapCache
// (...) unfortunately z_malloc fragment alot the memory :(so malloc is better
newMipmap = calloc(1, sizeof (*newMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetBlendedTexture");
......
......@@ -539,8 +539,7 @@ size_t P_PrecacheLevelFlats(void)
}
/*
levelflat refers to an array of level flats,
or NULL if we want to allocate it now.
levelflat refers to an array of level flats.
*/
static INT32
Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
......@@ -551,8 +550,9 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
lumpnum_t flatnum;
int texturenum;
UINT8 *flatpatch;
size_t lumplength;
UINT8 *flatlump = NULL;
size_t lumplength;
size_t i;
......@@ -586,19 +586,47 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
{
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
#ifdef PATCHFLATS
// If the texture wasn't found, search for patches.
flatnum = W_CheckNumForName(levelflat->name);
// If the patch wasn't found, use a default texture.
if (flatnum == LUMPERROR)
#endif
{
// Try using REDWALL.
if (( texturenum = R_CheckTextureNumForName("REDWALL") ) != -1)
goto texturefound;
// If REDWALL wasn't found, try using REDFLR.
else if (( flatnum = R_GetFlatNumForName("REDFLR") ) != LUMPERROR)
goto flatfound;
}
#ifdef PATCHFLATS
// Found a patch.
flatlump = W_CacheLumpNum(flatnum, PU_CACHE);
lumplength = W_LumpLength(flatnum);
if (Picture_CheckIfDoomPatch((softwarepatch_t *)flatlump, lumplength))
{
softwarepatch_t *patch = (softwarepatch_t *)flatlump;
levelflat->width = (UINT16)SHORT(patch->width);
levelflat->height = (UINT16)SHORT(patch->height);
levelflat->type = LEVELFLAT_PATCH;
goto flatdone;
}
#endif
// Nothing was found.
levelflat->type = LEVELFLAT_NONE;
levelflat->width = levelflat->height = 1;
}
else
{
texturefound:
levelflat->type = LEVELFLAT_TEXTURE;
levelflat->width = textures[texturenum]->width;
levelflat->height = textures[texturenum]->height;
levelflat->u.texture. num = texturenum;
levelflat->u.texture.lastnum = texturenum;
/* start out unanimated */
......@@ -608,27 +636,38 @@ texturefound:
else
{
flatfound:
/* This could be a flat, patch, or PNG. */
flatpatch = W_CacheLumpNum(flatnum, PU_CACHE);
/* This could be a flat, or a PNG. */
flatlump = 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
/*
Only need eight bytes for PNG headers.
FIXME: Put this elsewhere.
*/
W_ReadLumpHeader(flatnum, buffer, 8, 0);
if (Picture_IsLumpPNG(buffer, lumplength))
{
INT32 width, height;
Picture_PNGDimensions(flatlump, &width, &height, NULL, NULL, lumplength);
levelflat->width = (UINT16)width;
levelflat->height = (UINT16)height;
levelflat->type = LEVELFLAT_PNG;
}
else
#endif/*NO_PNG_LUMPS*/
levelflat->type = LEVELFLAT_FLAT;/* phew */
{
/* phew */
size_t len = W_LumpLength(flatnum);
levelflat->width = levelflat->height = R_GetFlatSize(len);
levelflat->type = LEVELFLAT_FLAT;
}
if (flatpatch)
Z_Free(flatpatch);
#ifdef PATCHFLATS
flatdone:
#endif
if (flatlump)
Z_Free(flatlump);
levelflat->u.flat. lumpnum = flatnum;
levelflat->u.flat.baselumpnum = LUMPERROR;
......@@ -3235,7 +3274,7 @@ static void P_ConvertBinaryMap(void)
lines[i].args[4] |= TMSC_BACKTOFRONTCEILING;
lines[i].special = 720;
break;
case 900: //Translucent wall (10%)
case 901: //Translucent wall (20%)
case 902: //Translucent wall (30%)
......
......@@ -70,18 +70,12 @@ typedef struct
u;
UINT16 width, height;
UINT8 *picture;
// 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
} levelflat_t;
extern size_t numlevelflats;
......
......@@ -668,7 +668,11 @@ typedef struct
UINT8 *columns; // Software column data
void *hardware; // OpenGL patch, allocated whenever necessary
void *flats[4]; // The patch as flats
struct
{
void *p8[4];
void *p8a8[4];
} flats; // The patch as flats
#ifdef ROTSPRITE
rotsprite_t *rotated; // Rotated patches
......
......@@ -106,7 +106,7 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
INT32 ds_waterofs, ds_bgofs;
UINT16 ds_flatwidth, ds_flatheight;
boolean ds_powersoftwo;
boolean ds_powersoftwo, ds_solidcolor;
UINT8 *ds_source; // points to the start of a flat
UINT8 *ds_transmap; // one of the translucency tables
......@@ -883,6 +883,39 @@ void R_DrawViewBorder(void)
}
#endif
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static INT32 tiltlighting[MAXVIDWIDTH];
static void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
INT32 i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
// Lighting is simple. It's just linear interpolation from start to end
#define CALC_SLOPE_LIGHT { \
float planelightfloat = PLANELIGHTFLOAT; \
float lightstart, lightend; \
lightend = (iz + ds_szp->x*width) * planelightfloat; \
lightstart = iz * planelightfloat; \
R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend)); \
}
// ==========================================================================
// INCLUDE 8bpp DRAWING CODE HERE
// ==========================================================================
......
......@@ -61,7 +61,7 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern INT32 ds_waterofs, ds_bgofs;
extern UINT16 ds_flatwidth, ds_flatheight;
extern boolean ds_powersoftwo;
extern boolean ds_powersoftwo, ds_solidcolor;
extern UINT8 *ds_source;
extern UINT8 *ds_transmap;
......@@ -193,13 +193,11 @@ void R_DrawTranslucentFloorSprite_8(void);
void R_DrawTiltedFloorSprite_8(void);
void R_DrawTiltedTranslucentFloorSprite_8(void);
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
extern INT32 tiltlighting[MAXVIDWIDTH];
void R_DrawTranslucentWaterSpan_8(void);
void R_DrawTiltedTranslucentWaterSpan_8(void);
void R_DrawWaterSpan_8(void);
void R_DrawTiltedWaterSpan_8(void);
void R_DrawFogSpan_8(void);
void R_DrawTiltedFogSpan_8(void);
// Lactozilla: Non-powers-of-two
void R_DrawSpan_NPO2_8(void);
......@@ -216,8 +214,15 @@ void R_DrawTranslucentFloorSprite_NPO2_8(void);
void R_DrawTiltedFloorSprite_NPO2_8(void);
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void);
void R_DrawTranslucentWaterSpan_NPO2_8(void);
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
void R_DrawWaterSpan_NPO2_8(void);
void R_DrawTiltedWaterSpan_NPO2_8(void);
void R_DrawColorSpan_8(void);
void R_DrawTransColorSpan_8(void);
void R_DrawTiltedColorSpan_8(void);
void R_DrawTiltedTransColorSpan_8(void);
void R_DrawWaterColorSpan_8(void);
void R_DrawTiltedWaterColorSpan_8(void);
#ifdef USEASM
void ASMCALL R_DrawColumn_8_ASM(void);
......
......@@ -623,29 +623,6 @@ void R_DrawSpan_8 (void)
}
}
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
INT32 tiltlighting[MAXVIDWIDTH];
void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
INT32 i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
/** \brief The R_DrawTiltedSpan_8 function
Draw slopes! Holy sheit!
*/
......@@ -668,17 +645,7 @@ void R_DrawTiltedSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -801,17 +768,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -911,10 +868,10 @@ void R_DrawTiltedTranslucentSpan_8(void)
#endif
}
/** \brief The R_DrawTiltedTranslucentWaterSpan_8 function
/** \brief The R_DrawTiltedWaterSpan_8 function
Like DrawTiltedTranslucentSpan, but for water
*/
void R_DrawTiltedTranslucentWaterSpan_8(void)
void R_DrawTiltedWaterSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
......@@ -934,17 +891,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -1066,17 +1013,7 @@ void R_DrawTiltedSplat_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -1923,7 +1860,7 @@ void R_DrawTranslucentSpan_8 (void)
}
}
void R_DrawTranslucentWaterSpan_8(void)
void R_DrawWaterSpan_8(void)
{
UINT32 xposition;
UINT32 yposition;
......@@ -2034,6 +1971,144 @@ void R_DrawFogSpan_8(void)
}
}
/** \brief The R_DrawTiltedFogSpan_8 function
Draws a tilted span with fogging.
*/
void R_DrawTiltedFogSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
CALC_SLOPE_LIGHT
do
{
UINT8 *colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*dest];
dest++;
} while (--width >= 0);
}
/** \brief The R_DrawColorSpan_8 function
Draws a solid color span.
*/
void R_DrawColorSpan_8(void)
{
size_t count = (ds_x2 - ds_x1 + 1);
UINT8 source = ds_colormap[ds_source[0]];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
memset(dest, source, count);
}
/** \brief The R_DrawTransColorSpan_8 function
Draws a translucent solid color span.
*/
void R_DrawTransColorSpan_8(void)
{
size_t count = (ds_x2 - ds_x1 + 1);
UINT8 source = ds_colormap[ds_source[0]];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
while (count-- && dest <= deststop)
{
*dest = *(ds_transmap + (source << 8) + *dest);
dest++;
}
}
/** \brief The R_DrawTiltedColorSpan_8 function
Draws a tilted solid color span.
*/
void R_DrawTiltedColorSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
CALC_SLOPE_LIGHT
do
{
UINT8 *colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest++ = colormap[source];
} while (--width >= 0);
}
/** \brief The R_DrawTiltedTransColorSpan_8 function
Draws a tilted and translucent solid color span.
*/
void R_DrawTiltedTransColorSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
CALC_SLOPE_LIGHT
do
{
UINT8 *colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = *(ds_transmap + (colormap[source] << 8) + *dest);
dest++;
} while (--width >= 0);
}
/** \brief The R_DrawWaterColorSpan_8 function
Draws a water solid color span.
*/
void R_DrawWaterColorSpan_8(void)
{
UINT8 source = ds_source[0];
UINT8 *colormap = ds_colormap;
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
size_t count = (ds_x2 - ds_x1 + 1);
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
while (count-- && dest <= deststop)
{
*dest = colormap[*(ds_transmap + (source << 8) + *dsrc++)];
dest++;
}
}
/** \brief The R_DrawTiltedWaterColorSpan_8 function
Draws a tilted water solid color span.
*/
void R_DrawTiltedWaterColorSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 source = ds_source[0];
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
UINT8 *dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
CALC_SLOPE_LIGHT
do
{
UINT8 *colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest++ = *(ds_transmap + (colormap[source] << 8) + *dsrc++);
} while (--width >= 0);
}
/** \brief The R_DrawFogColumn_8 function
Fog wall.
*/
......
......@@ -111,17 +111,7 @@ void R_DrawTiltedSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -311,17 +301,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -509,17 +489,7 @@ void R_DrawTiltedSplat_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......@@ -1338,7 +1308,7 @@ void R_DrawTranslucentSpan_NPO2_8 (void)
}
}
void R_DrawTranslucentWaterSpan_NPO2_8(void)
void R_DrawWaterSpan_NPO2_8(void)
{
fixed_t xposition;
fixed_t yposition;
......@@ -1401,10 +1371,10 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void)
}
}
/** \brief The R_DrawTiltedTranslucentWaterSpan_NPO2_8 function
/** \brief The R_DrawTiltedWaterSpan_NPO2_8 function
Like DrawTiltedTranslucentSpan_NPO2, but for water
*/
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void)
void R_DrawTiltedWaterSpan_NPO2_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
......@@ -1427,17 +1397,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
......
......@@ -16,6 +16,7 @@
#include "z_zone.h"
#ifdef HWRENDER
#include "hardware/hw_defs.h"
#include "hardware/hw_glob.h"
#endif
......@@ -76,8 +77,10 @@ static void Patch_FreeData(patch_t *patch)
for (i = 0; i < 4; i++)
{
if (patch->flats[i])
Z_Free(patch->flats[i]);
if (patch->flats.p8[i])
Z_Free(patch->flats.p8[i]);
if (patch->flats.p8a8[i])
Z_Free(patch->flats.p8a8[i]);
}
#ifdef ROTSPRITE
......@@ -124,11 +127,24 @@ void Patch_FreeTags(INT32 lowtag, INT32 hightag)
Z_IterateTags(lowtag, hightag, Patch_FreeTagsCallback);
}
void Patch_GenerateFlat(patch_t *patch, pictureflags_t flags)
void Patch_GenerateFlat(patch_t *patch, pictureflags_t flags, pictureformat_t format)
{
UINT8 flip = (flags & (PICFLAGS_XFLIP | PICFLAGS_YFLIP));
if (patch->flats[flip] == NULL)
patch->flats[flip] = Picture_Convert(PICFMT_PATCH, patch, PICFMT_FLAT16, 0, NULL, 0, 0, 0, 0, flags);
UINT8 store = 0;
if (flip & PICFLAGS_XFLIP)
store |= 1;
if (flip & PICFLAGS_YFLIP)
store |= 2;
#define CONVERT Picture_Convert(PICFMT_PATCH, patch, format, 0, NULL, 0, 0, 0, 0, flags)
if (format == PICFMT_FLAT && patch->flats.p8[store] == NULL)
patch->flats.p8[store] = CONVERT;
else if (format == PICFMT_FLAT16 && patch->flats.p8a8[store] == NULL)
patch->flats.p8a8[store] = CONVERT;
#undef CONVERT
}
#ifdef HWRENDER
......@@ -142,7 +158,9 @@ void *Patch_AllocateHardwarePatch(patch_t *patch)
{
GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, &patch->hardware);
grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, &grPatch->mipmap);
grPatch->mipmap->flags = TF_POWERSOFTWO;
}
return (void *)(patch->hardware);
}
......
......@@ -23,7 +23,7 @@ void Patch_Free(patch_t *patch);
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)
void Patch_FreeTags(INT32 lowtag, INT32 hightag);
void Patch_GenerateFlat(patch_t *patch, pictureflags_t flags);
void Patch_GenerateFlat(patch_t *patch, pictureflags_t flags, pictureformat_t format);
#ifdef HWRENDER
void *Patch_AllocateHardwarePatch(patch_t *patch);
......
......@@ -736,82 +736,6 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
return result;
}
/** Converts a texture to a flat.
*
* \param trickytex The texture number.
* \return The converted flat.
*/
void *Picture_TextureToFlat(size_t trickytex)
{
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)
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);
// Allocate the flat
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++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
}
}
return converted;
}
/** Returns true if the lump is a valid PNG.
*
* \param d The lump to be checked.
......
......@@ -75,8 +75,6 @@ void *Picture_GetPatchPixel(
INT32 x, INT32 y,
pictureflags_t flags);
void *Picture_TextureToFlat(size_t trickytex);
INT32 Picture_FormatBPP(pictureformat_t format);
boolean Picture_IsPatchFormat(pictureformat_t format);
boolean Picture_IsInternalPatchFormat(pictureformat_t format);
......
......@@ -143,15 +143,6 @@ static void R_UpdatePlaneRipple(void)
planeripple.offset = (leveltime * 140);
}
//
// R_MapPlane
//
// Uses global vars:
// planeheight
// basexscale
// baseyscale
// centerx
static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
{
angle_t angle, planecos, planesin;
......@@ -222,6 +213,7 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
pindex = MAXLIGHTZ - 1;
ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
......@@ -271,6 +263,50 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2)
spanfunc();
}
static void R_MapFogPlane(INT32 y, INT32 x1, INT32 x2)
{
#ifdef RANGECHECK
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight)
I_Error("R_MapFogPlane: %d, %d at %d", x1, x2, y);
#endif
if (x1 >= vid.width)
x1 = vid.width - 1;
if (!currentplane->slope)
{
fixed_t distance = 0;
size_t pindex;
if (planeheight != cachedheight[y])
distance = FixedMul(planeheight, yslope[y]);
else
distance = cacheddistance[y];
pindex = distance >> LIGHTZSHIFT;
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
}
else
{
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap;
else
ds_colormap = colormaps;
}
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
spanfunc();
}
void R_ClearFFloorClips (void)
{
INT32 i, p;
......@@ -578,33 +614,7 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
}
static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
{
// Alam: from r_splats's R_RasterizeFloorSplat
if (t1 >= vid.height) t1 = vid.height-1;
if (b1 >= vid.height) b1 = vid.height-1;
if (t2 >= vid.height) t2 = vid.height-1;
if (b2 >= vid.height) b2 = vid.height-1;
if (x-1 >= vid.width) x = vid.width;
while (t1 < t2 && t1 <= b1)
{
R_MapPlane(t1, spanstart[t1], x - 1);
t1++;
}
while (b1 > b2 && b1 >= t1)
{
R_MapPlane(b1, spanstart[b1], x - 1);
b1--;
}
while (t2 < t1 && t2 <= b2)
spanstart[t2++] = x;
while (b2 > b1 && b2 >= t2)
spanstart[b2--] = x;
}
static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
{
// Alam: from r_splats's R_RasterizeFloorSplat
if (t1 >= vid.height) t1 = vid.height-1;
......@@ -615,12 +625,12 @@ static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
while (t1 < t2 && t1 <= b1)
{
R_MapTiltedPlane(t1, spanstart[t1], x - 1);
mapfunc(t1, spanstart[t1], x - 1);
t1++;
}
while (b1 > b2 && b1 >= t1)
{
R_MapTiltedPlane(b1, spanstart[b1], x - 1);
mapfunc(b1, spanstart[b1], x - 1);
b1--;
}
......@@ -801,6 +811,9 @@ d->z = (v1.x * v2.y) - (v1.y * v2.x)
ds_svp->z *= focallengthf;
ds_szp->z *= focallengthf;
if (ds_solidcolor)
return;
// Premultiply the texture vectors with the scale factors
if (ds_powersoftwo)
sfmult *= (1 << nflatshiftup);
......@@ -870,8 +883,9 @@ void R_DrawSinglePlane(visplane_t *pl)
INT32 x;
INT32 stop, angle;
ffloor_t *rover;
INT32 type;
INT32 spanfunctype = BASEDRAWFUNC;
void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane;
boolean fog = false;
if (!(pl->minx <= pl->maxx))
return;
......@@ -883,8 +897,8 @@ void R_DrawSinglePlane(visplane_t *pl)
return;
}
levelflat = &levelflats[pl->picnum];
planeripple.active = false;
spanfunc = spanfuncs[BASEDRAWFUNC];
if (pl->polyobj)
{
......@@ -962,10 +976,11 @@ void R_DrawSinglePlane(visplane_t *pl)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
fog = true;
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (pl->ffloor->flags & FF_RIPPLE)
if (pl->ffloor->flags & FF_RIPPLE && !fog)
{
INT32 top, bottom;
......@@ -995,28 +1010,56 @@ void R_DrawSinglePlane(visplane_t *pl)
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
currentplane = pl;
levelflat = &levelflats[pl->picnum];
ds_powersoftwo = false;
ds_solidcolor = false;
/* :james: */
type = levelflat->type;
switch (type)
switch (levelflat->type)
{
case LEVELFLAT_NONE:
return;
case LEVELFLAT_FLAT:
ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
// Raw flats always have dimensions that are powers-of-two numbers.
ds_powersoftwo = true;
R_SetFlatVars(W_LumpLength(levelflat->u.flat.lumpnum));
if (!fog)
{
if (R_CheckSolidColorFlat())
ds_solidcolor = true;
else
ds_powersoftwo = true;
}
break;
default:
ds_source = (UINT8 *)R_GetLevelFlat(levelflat);
if (!ds_source)
return;
// Check if this texture or patch has power-of-two dimensions.
if (R_CheckPowersOfTwo())
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
else if (!fog)
{
if (R_CheckSolidColorFlat())
ds_solidcolor = true;
else if (R_CheckPowersOfTwo())
{
R_SetFlatVars(ds_flatwidth * ds_flatheight);
ds_powersoftwo = true;
}
}
}
if (ds_solidcolor)
{
switch (spanfunctype)
{
case SPANDRAWFUNC_WATER:
spanfunctype = SPANDRAWFUNC_WATERSOLID;
break;
case SPANDRAWFUNC_TRANS:
spanfunctype = SPANDRAWFUNC_TRANSSOLID;
break;
default:
spanfunctype = SPANDRAWFUNC_SOLID;
break;
}
}
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
......@@ -1040,7 +1083,12 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->slope)
{
if (!pl->plangle)
if (fog)
mapfunc = R_MapFogPlane;
else
mapfunc = R_MapTiltedPlane;
if (!pl->plangle && !ds_solidcolor && !fog)
{
if (ds_powersoftwo)
R_AdjustSlopeCoordinates(&pl->slope->o);
......@@ -1075,6 +1123,18 @@ void R_DrawSinglePlane(visplane_t *pl)
case SPANDRAWFUNC_SPLAT:
spanfunctype = SPANDRAWFUNC_TILTEDSPLAT;
break;
case SPANDRAWFUNC_SOLID:
spanfunctype = SPANDRAWFUNC_TILTEDSOLID;
break;
case SPANDRAWFUNC_TRANSSOLID:
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSOLID;
break;
case SPANDRAWFUNC_WATERSOLID:
spanfunctype = SPANDRAWFUNC_TILTEDWATERSOLID;
break;
case SPANDRAWFUNC_FOG:
spanfunctype = SPANDRAWFUNC_TILTEDFOG;
break;
default:
spanfunctype = SPANDRAWFUNC_TILTED;
break;
......@@ -1088,7 +1148,7 @@ void R_DrawSinglePlane(visplane_t *pl)
planezlight = zlight[light];
}
// Use the correct span drawer depending on the powers-of-twoness
// Set the span drawer
if (!ds_powersoftwo)
{
if (spanfuncs_npo2[spanfunctype])
......@@ -1105,18 +1165,11 @@ void R_DrawSinglePlane(visplane_t *pl)
pl->bottom[pl->maxx+1] = 0x0000;
pl->bottom[pl->minx-1] = 0x0000;
currentplane = pl;
stop = pl->maxx + 1;
if (pl->slope)
{
for (x = pl->minx; x <= stop; x++)
R_MakeTiltedSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
}
else
{
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
}
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
/*
QUINCUNX anti-aliasing technique (sort of)
......@@ -1183,7 +1236,7 @@ using the palette colors.
stop = pl->maxx + 1;
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1],
R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1],
pl->top[x], pl->bottom[x]);
}
}
......