From 91ed56ef40e96629d65a28201ff9b6589e641f2a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 8 Aug 2020 05:16:47 -0300 Subject: [PATCH] Refactor patch loading --- src/console.c | 5 +- src/d_main.c | 37 +---- src/dehacked.c | 2 +- src/f_finale.c | 25 +--- src/hardware/hw_cache.c | 244 ++++++++++++++----------------- src/hardware/hw_data.h | 15 +- src/hardware/hw_draw.c | 93 ++++++------ src/hardware/hw_drv.h | 2 + src/hardware/hw_glob.h | 27 ++-- src/hardware/hw_main.c | 58 ++++---- src/hardware/hw_main.h | 6 +- src/hardware/hw_md2.c | 205 +++++++++++++++----------- src/hardware/r_opengl/r_opengl.c | 15 +- src/hu_stuff.c | 3 - src/lua_infolib.c | 4 +- src/m_menu.c | 43 +----- src/r_data.c | 6 +- src/r_defs.h | 22 ++- src/r_main.c | 8 - src/r_main.h | 1 - src/r_patch.c | 220 ++++++++++++++++------------ src/r_patch.h | 20 ++- src/r_segs.c | 2 +- src/r_things.c | 18 +-- src/screen.c | 3 - src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 5 +- src/st_stuff.c | 3 - src/v_video.c | 10 +- src/w_wad.c | 71 +++------ src/w_wad.h | 7 - src/win32/win_dll.c | 2 + src/y_inter.c | 73 +-------- src/z_zone.c | 27 ---- src/z_zone.h | 6 - 35 files changed, 557 insertions(+), 732 deletions(-) diff --git a/src/console.c b/src/console.c index aac94d473..280dc4f22 100644 --- a/src/console.c +++ b/src/console.c @@ -1555,7 +1555,7 @@ static void CON_DrawBackpic(void) // then fill the sides with a solid color. if (x > 0) { - column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0])); + column_t *column = (column_t *)((UINT8 *)(con_backpic->columns) + (con_backpic->columnofs[0])); if (!column->topdelta) { UINT8 *source = (UINT8 *)(column) + 3; @@ -1648,9 +1648,6 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; - if (needpatchrecache) - HU_LoadGraphics(); - if (con_recalc) { CON_RecalcSize(); diff --git a/src/d_main.c b/src/d_main.c index 6bc42da14..ee3ce699c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -110,8 +110,6 @@ boolean devparm = false; // started game with -devparm boolean singletics = false; // timedemo boolean lastdraw = false; -static void D_CheckRendererState(void); - postimg_t postimgtype = postimg_none; INT32 postimgparam; postimg_t postimgtype2 = postimg_none; @@ -245,9 +243,7 @@ static void D_Display(void) // create plane polygons, if necessary. // 3. Functions related to switching video // modes (resolution) are called. - // 4. Patch data is freed from memory, - // and recached if necessary. - // 5. The frame is ready to be drawn! + // 4. The frame is ready to be drawn! // stop movie if needs to change renderer if (setrenderneeded && (moviemode == MM_APNG)) @@ -284,9 +280,6 @@ static void D_Display(void) forcerefresh = true; // force background redraw } - // Lactozilla: Renderer switching - D_CheckRendererState(); - // draw buffered stuff to screen // Used only by linux GGI version I_UpdateNoBlit(); @@ -679,26 +672,6 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer rs_swaptime = I_GetTimeMicros() - rs_swaptime; } - - needpatchflush = false; - needpatchrecache = false; -} - -// Check the renderer's state -// after a possible renderer switch. -void D_CheckRendererState(void) -{ - // flush all patches from memory - if (needpatchflush) - { - Z_FlushCachedPatches(); - needpatchflush = false; - } - - // some patches have been freed, - // so cache them again - if (needpatchrecache) - R_ReloadHUDGraphics(); } // ========================================================================= @@ -1433,18 +1406,10 @@ void D_SRB2Main(void) if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) { CONS_Printf(M_GetText("Switching the renderer...\n")); - Z_PreparePatchFlush(); - - // set needpatchflush / needpatchrecache true for D_CheckRendererState - needpatchflush = true; - needpatchrecache = true; // Set cv_renderer to the new render mode VID_CheckRenderer(); SCR_ChangeRendererCVars(rendermode); - - // check the renderer's state - D_CheckRendererState(); } wipegamestate = gamestate; diff --git a/src/dehacked.c b/src/dehacked.c index 9d6729dc2..c801dcde9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1046,7 +1046,7 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2) #ifdef ROTSPRITE if ((sprites != NULL) && (!sprite2)) - R_FreeSingleRotSprite(&sprites[num]); + R_FreeRotSprite(&sprites[num]); #endif do diff --git a/src/f_finale.c b/src/f_finale.c index 8d39a7533..7cc5467c2 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1901,13 +1901,6 @@ void F_EndingDrawer(void) INT32 x, y, i, j, parallaxticker; patch_t *rockpat; - if (needpatchrecache) - { - F_CacheEnding(); - if (goodending && finalecount >= INFLECTIONPOINT) // time to swap some assets - F_CacheGoodEnding(); - } - if (!goodending || finalecount < INFLECTIONPOINT) rockpat = W_CachePatchName("ROID0000", PU_PATCH); else @@ -2706,17 +2699,12 @@ static void F_FigureActiveTtScale(void) SINT8 newttscale = max(1, min(6, vid.dupx)); SINT8 oldttscale = activettscale; - if (needpatchrecache) - ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0; - else - { - if (newttscale == testttscale) - return; + if (newttscale == testttscale) + return; - // We have a new ttscale, so load gfx - if(oldttscale > 0) - F_UnloadAlacroixGraphics(oldttscale); - } + // We have a new ttscale, so load gfx + if(oldttscale > 0) + F_UnloadAlacroixGraphics(oldttscale); testttscale = newttscale; @@ -2750,9 +2738,6 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. - if (needpatchrecache && (curttmode != TTMODE_ALACROIX)) - F_CacheTitleScreen(); - // Draw that sky! if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index ed3b6afee..a26721169 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -309,7 +309,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 + LONG(realpatch->columnofs[xfrac>>FRACBITS])); + patchcol = (const column_t *)((const UINT8 *)realpatch->columns + (realpatch->columnofs[xfrac>>FRACBITS])); HWR_DrawColumnInCache(patchcol, block, mipmap, pblockheight, blockmodulo, @@ -323,7 +323,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 patch_t *realpatch) + const softwarepatch_t *realpatch) { INT32 x, x1, x2; INT32 col, ncols; @@ -394,7 +394,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, bpp = format2bpp(mipmap->format); if (bpp < 1 || bpp > 4) - I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp); + I_Error("HWR_DrawTexturePatchInCache: no drawer defined for this bpp (%d)\n",bpp); // NOTE: should this actually be pblockwidth*bpp? blockmodulo = pblockwidth*bpp; @@ -449,7 +449,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) UINT8 *block; texture_t *texture; texpatch_t *patch; - patch_t *realpatch; + softwarepatch_t *realpatch; UINT8 *pdata; INT32 blockwidth, blockheight, blocksize; @@ -505,7 +505,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) boolean dealloc = true; size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - realpatch = (patch_t *)pdata; + realpatch = (softwarepatch_t *)pdata; #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) @@ -547,36 +547,20 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) // patch may be NULL if grMipmap has been initialised already and makebitmap is false void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) { -#ifndef NO_PNG_LUMPS - // lump is a png so convert it - size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum); - if ((patch != NULL) && R_IsLumpPNG((const UINT8 *)patch, len)) - patch = R_PNGToPatch((const UINT8 *)patch, len, NULL); -#endif - - // don't do it twice (like a cache) if (grMipmap->width == 0) { - // save the original patch header so that the GLPatch can be casted - // into a standard patch_t struct and the existing code can get the - // orginal patch dimensions and offsets. - grPatch->width = SHORT(patch->width); - grPatch->height = SHORT(patch->height); - grPatch->leftoffset = SHORT(patch->leftoffset); - grPatch->topoffset = SHORT(patch->topoffset); - grMipmap->width = grMipmap->height = 1; - while (grMipmap->width < grPatch->width) grMipmap->width <<= 1; - while (grMipmap->height < grPatch->height) 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; + // setup the texture info grMipmap->format = patchformat; - //grPatch->max_s = grPatch->max_t = 1.0f; - grPatch->max_s = (float)grPatch->width / (float)grMipmap->width; - grPatch->max_t = (float)grPatch->height / (float)grMipmap->height; + grPatch->max_s = (float)patch->width / (float)grMipmap->width; + grPatch->max_t = (float)patch->height / (float)grMipmap->height; } Z_Free(grMipmap->data); @@ -588,7 +572,7 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm HWR_DrawPatchInCache(grMipmap, grMipmap->width, grMipmap->height, - grPatch->width, grPatch->height, + patch->width, patch->height, patch); } } @@ -608,13 +592,33 @@ void HWR_InitTextureCache(void) gl_flats = NULL; } -// Callback function for HWR_FreeTextureCache. -static void FreeMipmapColormap(INT32 patchnum, void *patch) +void HWR_FreeTexture(patch_t *patch) { - GLPatch_t* const pat = patch; - (void)patchnum; //unused + if (patch->hardware) + { + GLPatch_t *grPatch = patch->hardware; + + HWR_FreeTextureColormaps(patch); + + if (grPatch->mipmap && (rendermode == render_opengl)) + HWD.pfnDeleteTexture(grPatch->mipmap); + + Z_Free(patch->hardware); + } + + patch->hardware = NULL; +} + +// Called by HWR_FreeTextureCache. +void HWR_FreeTextureColormaps(patch_t *patch) +{ + GLPatch_t *pat; // The patch must be valid, obviously + if (!patch) + return; + + pat = patch->hardware; if (!pat) return; @@ -642,6 +646,7 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) if (next->data) Z_Free(next->data); next->data = NULL; + HWD.pfnDeleteTexture(next); // Free the old colormap mipmap from memory. free(next); @@ -663,7 +668,11 @@ void HWR_FreeMipmapCache(void) // Alam: free the Z_Blocks before freeing it's users // free all patch colormaps after each level: must be done after ClearMipMapCache! for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); + { + INT32 j = 0; + for (; j < wadfiles[i]->numlumps; j++) + HWR_FreeTextureColormaps(wadfiles[i]->patchcache[j]); + } } void HWR_FreeTextureCache(void) @@ -733,7 +742,6 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex) // 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. @@ -809,14 +817,13 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum) if (flatlumpnum == LUMPERROR) return; - grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap; + grmip = ((GLPatch_t *)HWR_GetCachedGLPatch(flatlumpnum)->hardware)->mipmap; if (!grmip->downloaded && !grmip->data) HWR_CacheFlat(grmip, flatlumpnum); // If hardware does not have the texture, then call pfnSetTexture to upload it if (!grmip->downloaded) HWD.pfnSetTexture(grmip); - HWR_SetCurrentTexture(grmip); // The system-memory data can be purged now. @@ -854,7 +861,6 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) // 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. @@ -864,89 +870,61 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) HWR_SetCurrentTexture(NULL); } -// -// HWR_LoadMappedPatch(): replace the skin color of the sprite in cache -// : load it first in doom cache if not already -// -static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) +// --------------------+ +// HWR_LoadPatchMipmap : Generates a patch into a mipmap, usually the mipmap inside the patch itself +// --------------------+ +static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap) { - if (!grmip->downloaded && !grmip->data) - { - patch_t *patch = gpatch->rawpatch; - if (!patch) - patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - HWR_MakePatch(patch, gpatch, grmip, true); - - // You can't free rawpatch for some reason? - // (Obviously I can't, sprite rotation needs that...) - if (!gpatch->rawpatch) - Z_Free(patch); - } + GLPatch_t *grPatch = patch->hardware; + if (!grMipmap->downloaded && !grMipmap->data) + HWR_MakePatch(patch, grPatch, grMipmap, true); // If hardware does not have the texture, then call pfnSetTexture to upload it - if (!grmip->downloaded) - HWD.pfnSetTexture(grmip); - - HWR_SetCurrentTexture(grmip); + if (!grMipmap->downloaded) + HWD.pfnSetTexture(grMipmap); + HWR_SetCurrentTexture(grMipmap); // The system-memory data can be purged now. - Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); } // -----------------+ // HWR_GetPatch : Download a patch to the hardware cache and make it ready for use // -----------------+ -void HWR_GetPatch(GLPatch_t *gpatch) +void HWR_GetPatch(patch_t *patch) { - // is it in hardware cache - if (!gpatch->mipmap->downloaded && !gpatch->mipmap->data) - { - // load the software patch, PU_STATIC or the Z_Malloc for hardware patch will - // flush the software patch before the conversion! oh yeah I suffered - patch_t *ptr = gpatch->rawpatch; - if (!ptr) - ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - HWR_MakePatch(ptr, gpatch, gpatch->mipmap, true); - - // this is inefficient.. but the hardware patch in heap is purgeable so it should - // not fragment memory, and besides the REAL cache here is the hardware memory - if (!gpatch->rawpatch) - Z_Free(ptr); - } - - // If hardware does not have the texture, then call pfnSetTexture to upload it - if (!gpatch->mipmap->downloaded) - HWD.pfnSetTexture(gpatch->mipmap); - - HWR_SetCurrentTexture(gpatch->mipmap); - - // The system-memory patch data can be purged now. - Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED); + if (!patch->hardware) + Patch_CreateGL(patch); + HWR_LoadPatchMipmap(patch, ((GLPatch_t *)patch->hardware)->mipmap); } - // -------------------+ // HWR_GetMappedPatch : Same as HWR_GetPatch for sprite color // -------------------+ -void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) +void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) { - GLMipmap_t *grmip, *newmip; + GLPatch_t *grPatch; + GLMipmap_t *grMipmap, *newMipmap; + + if (!patch->hardware) + Patch_CreateGL(patch); + grPatch = patch->hardware; if (colormap == colormaps || colormap == NULL) { - // Load the default (green) color in doom cache (temporary?) AND hardware cache - HWR_GetPatch(gpatch); + // Load the default (green) color in hardware cache + HWR_GetPatch(patch); return; } // search for the mimmap // skip the first (no colormap translated) - for (grmip = gpatch->mipmap; grmip->nextcolormap; ) + for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) { - grmip = grmip->nextcolormap; - if (grmip->colormap == colormap) + grMipmap = grMipmap->nextcolormap; + if (grMipmap->colormap == colormap) { - HWR_LoadMappedPatch(grmip, gpatch); + HWR_LoadPatchMipmap(patch, grMipmap); return; } } @@ -957,13 +935,13 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) // (it have a liste of mipmap) // this malloc is cleared in HWR_FreeTextureCache // (...) unfortunately z_malloc fragment alot the memory :(so malloc is better - newmip = calloc(1, sizeof (*newmip)); - if (newmip == NULL) + newMipmap = calloc(1, sizeof (*newMipmap)); + if (newMipmap == NULL) I_Error("%s: Out of memory", "HWR_GetMappedPatch"); - grmip->nextcolormap = newmip; + grMipmap->nextcolormap = newMipmap; - newmip->colormap = colormap; - HWR_LoadMappedPatch(newmip, gpatch); + newMipmap->colormap = colormap; + HWR_LoadPatchMipmap(patch, newMipmap); } void HWR_UnlockCachedPatch(GLPatch_t *gpatch) @@ -1053,79 +1031,73 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig // HWR_GetPic : Download a Doom pic (raw row encoded with no 'holes') // Returns : // -----------------+ -GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) +patch_t *HWR_GetPic(lumpnum_t lumpnum) { - GLPatch_t *grpatch = HWR_GetCachedGLPatch(lumpnum); - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) + 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); - grpatch->width = SHORT(pic->width); - grpatch->height = SHORT(pic->height); + patch->width = SHORT(pic->width); + patch->height = SHORT(pic->height); len = W_LumpLength(lumpnum) - sizeof (pic_t); - grpatch->leftoffset = 0; - grpatch->topoffset = 0; - - grpatch->mipmap->width = (UINT16)grpatch->width; - grpatch->mipmap->height = (UINT16)grpatch->height; + 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 + grPatch->mipmap->format = textureformat; // can be set by driver else - grpatch->mipmap->format = picmode2GR[pic->mode]; + grPatch->mipmap->format = picmode2GR[pic->mode]; - Z_Free(grpatch->mipmap->data); + Z_Free(grPatch->mipmap->data); // allocate block - block = MakeBlock(grpatch->mipmap); + block = MakeBlock(grPatch->mipmap); - if (grpatch->width == SHORT(pic->width) && - grpatch->height == SHORT(pic->height) && - format2bpp(grpatch->mipmap->format) == format2bpp(picmode2GR[pic->mode])) + 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); + 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), + SHORT(pic->width)*format2bpp(grPatch->mipmap->format), pic, - format2bpp(grpatch->mipmap->format)); + 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; + 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); + HWD.pfnSetTexture(grPatch->mipmap); + //CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grPatch->mipmap->data, grPatch->mipmap->downloaded); - return grpatch; + return patch; } -GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) +patch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) { - aatree_t *hwrcache = wadfiles[wadnum]->hwrcache; - GLPatch_t *grpatch; - - if (!(grpatch = M_AATreeGet(hwrcache, lumpnum))) + lumpcache_t *lumpcache = wadfiles[wadnum]->patchcache; + if (!lumpcache[lumpnum]) { - grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grpatch->wadnum = wadnum; - grpatch->lumpnum = lumpnum; - grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - M_AATreeSet(hwrcache, lumpnum, grpatch); + void *ptr = Z_Calloc(sizeof(patch_t), PU_PATCH, &lumpcache[lumpnum]); + Patch_Create(NULL, 0, ptr); + Patch_AllocateHardwarePatch(ptr); } - - return grpatch; + return (patch_t *)(lumpcache[lumpnum]); } -GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum) +patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum) { return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); } @@ -1218,7 +1190,7 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { - GLMipmap_t *grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; + GLMipmap_t *grmip = ((GLPatch_t *)HWR_GetCachedGLPatch(fademasklumpnum)->hardware)->mipmap; if (!grmip->downloaded && !grmip->data) HWR_CacheFadeMask(grmip, fademasklumpnum); diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index e5477d729..6a872d258 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -73,23 +73,10 @@ struct GLMapTexture_s typedef struct GLMapTexture_s GLMapTexture_t; -// a cached patch as converted to hardware format, holding the original patch_t -// header so that the existing code can retrieve ->width, ->height as usual -// This is returned by W_CachePatchNum()/W_CachePatchName(), when rendermode -// is 'render_opengl'. Else it returns the normal patch_t data. - +// a cached patch as converted to hardware format struct GLPatch_s { - // the 4 first fields come right away from the original patch_t - INT16 width; - INT16 height; - INT16 leftoffset; // pixels to the left of origin - INT16 topoffset; // pixels below the origin - // float max_s,max_t; - UINT16 wadnum; // the software patch lump num for when the hardware patch - UINT16 lumpnum; // was flushed, and we need to re-create it - void *rawpatch; // :^) GLMipmap_t *mipmap; } ATTRPACK; typedef struct GLPatch_s GLPatch_t; diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f5a984d5d..a4e1df496 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -68,10 +68,11 @@ static UINT8 softwaretranstogl_lo[11] = { 0, 12, 24, 36, 48, 60, 71, 83, 95,111 // Notes : x,y : positions relative to the original Doom resolution // : textes(console+score) + menus + status bar // -----------------+ -void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) +void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option) { FOutVector v[4]; FBITFIELD flags; + GLPatch_t *hwrPatch; // 3--2 // | /| @@ -84,6 +85,7 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) // make patch ready in hardware cache HWR_GetPatch(gpatch); + hwrPatch = ((GLPatch_t *)gpatch->hardware); switch (option & V_SCALEPATCHMASK) { @@ -103,17 +105,17 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) if (option & V_NOSCALESTART) sdupx = sdupy = 2.0f; - v[0].x = v[3].x = (x*sdupx-SHORT(gpatch->leftoffset)*pdupx)/vid.width - 1; - v[2].x = v[1].x = (x*sdupx+(SHORT(gpatch->width)-SHORT(gpatch->leftoffset))*pdupx)/vid.width - 1; - v[0].y = v[1].y = 1-(y*sdupy-SHORT(gpatch->topoffset)*pdupy)/vid.height; - v[2].y = v[3].y = 1-(y*sdupy+(SHORT(gpatch->height)-SHORT(gpatch->topoffset))*pdupy)/vid.height; + v[0].x = v[3].x = (x*sdupx-(gpatch->leftoffset)*pdupx)/vid.width - 1; + v[2].x = v[1].x = (x*sdupx+(gpatch->width-gpatch->leftoffset)*pdupx)/vid.width - 1; + v[0].y = v[1].y = 1-(y*sdupy-(gpatch->topoffset)*pdupy)/vid.height; + v[2].y = v[3].y = 1-(y*sdupy+(gpatch->height-gpatch->topoffset)*pdupy)/vid.height; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].s = v[3].s = 0.0f; - v[2].s = v[1].s = gpatch->max_s; + v[2].s = v[1].s = hwrPatch->max_s; v[0].t = v[1].t = 0.0f; - v[2].t = v[3].t = gpatch->max_t; + v[2].t = v[3].t = hwrPatch->max_t; flags = PF_Translucent|PF_NoDepthTest; @@ -126,13 +128,14 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) HWD.pfnDrawPolygon(NULL, v, 4, flags); } -void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap) +void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap) { FOutVector v[4]; FBITFIELD flags; float cx = FIXED_TO_FLOAT(x); float cy = FIXED_TO_FLOAT(y); UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT); + GLPatch_t *hwrPatch; // 3--2 // | /| @@ -151,6 +154,8 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t else HWR_GetMappedPatch(gpatch, colormap); + hwrPatch = ((GLPatch_t *)gpatch->hardware); + dupx = (float)vid.dupx; dupy = (float)vid.dupy; @@ -181,13 +186,13 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t // left offset if (option & V_FLIP) - offsetx = (float)(SHORT(gpatch->width) - SHORT(gpatch->leftoffset)) * fscalew; + offsetx = (float)(gpatch->width - gpatch->leftoffset) * fscalew; else - offsetx = (float)SHORT(gpatch->leftoffset) * fscalew; + offsetx = (float)(gpatch->leftoffset) * fscalew; // top offset // TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!? - offsety = (float)SHORT(gpatch->topoffset) * fscaleh; + offsety = (float)(gpatch->topoffset) * fscaleh; if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs { @@ -277,17 +282,14 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t // 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 && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + if (cx >= -0.1f && cx <= 0.1f && (gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { - // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0])); if (!column->topdelta) { const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } - Z_Free(realpatch); } // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) @@ -317,13 +319,13 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER)) { - fwidth = (float)SHORT(gpatch->width) * fscalew * dupx; - fheight = (float)SHORT(gpatch->height) * fscaleh * dupy; + fwidth = (float)(gpatch->width) * fscalew * dupx; + fheight = (float)(gpatch->height) * fscaleh * dupy; } else { - fwidth = (float)SHORT(gpatch->width) * dupx; - fheight = (float)SHORT(gpatch->height) * dupy; + fwidth = (float)(gpatch->width) * dupx; + fheight = (float)(gpatch->height) * dupy; } // positions of the cx, cy, are between 0 and vid.width/vid.height now, we need them to be between -1 and 1 @@ -345,17 +347,17 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t if (option & V_FLIP) { - v[0].s = v[3].s = gpatch->max_s; + v[0].s = v[3].s = hwrPatch->max_s; v[2].s = v[1].s = 0.0f; } else { v[0].s = v[3].s = 0.0f; - v[2].s = v[1].s = gpatch->max_s; + v[2].s = v[1].s = hwrPatch->max_s; } v[0].t = v[1].t = 0.0f; - v[2].t = v[3].t = gpatch->max_t; + v[2].t = v[3].t = hwrPatch->max_t; flags = PF_Translucent|PF_NoDepthTest; @@ -380,13 +382,14 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t HWD.pfnDrawPolygon(NULL, v, 4, flags); } -void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) +void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) { FOutVector v[4]; FBITFIELD flags; float cx = FIXED_TO_FLOAT(x); float cy = FIXED_TO_FLOAT(y); UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT); + GLPatch_t *hwrPatch; // 3--2 // | /| @@ -399,6 +402,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // make patch ready in hardware cache HWR_GetPatch(gpatch); + hwrPatch = ((GLPatch_t *)gpatch->hardware); dupx = (float)vid.dupx; dupy = (float)vid.dupy; @@ -438,15 +442,12 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // This is done before here compared to software because we directly alter cx and cy to centre if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { - // Need to temporarily cache the real patch to get the colour of the top left pixel - patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0])); + const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0])); if (!column->topdelta) { const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); } - Z_Free(realpatch); } // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) @@ -469,11 +470,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal fwidth = w; fheight = h; - if (fwidth > SHORT(gpatch->width)) - fwidth = SHORT(gpatch->width); + if (fwidth > gpatch->width) + fwidth = gpatch->width; - if (fheight > SHORT(gpatch->height)) - fheight = SHORT(gpatch->height); + if (fheight > gpatch->height) + fheight = gpatch->height; if (pscale != FRACUNIT) { @@ -503,17 +504,17 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].s = v[3].s = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s; - if (sx + w > SHORT(gpatch->width)) - v[2].s = v[1].s = gpatch->max_s; + v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s; + if (sx + w > gpatch->width) + v[2].s = v[1].s = hwrPatch->max_s; else - v[2].s = v[1].s = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; - v[0].t = v[1].t = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t; - if (sy + h > SHORT(gpatch->height)) - v[2].t = v[3].t = gpatch->max_t; + v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t; + if (sy + h > gpatch->height) + v[2].t = v[3].t = hwrPatch->max_t; else - v[2].t = v[3].t = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t; + v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; flags = PF_Translucent|PF_NoDepthTest; @@ -541,7 +542,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) { FOutVector v[4]; - const GLPatch_t *patch; + const patch_t *patch; // make pic ready in hardware cache patch = HWR_GetPic(lumpnum); @@ -558,10 +559,10 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) 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 = patch->max_s; - v[0].t = v[1].t = 0; - v[2].t = v[3].t = patch->max_t; + 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 @@ -934,7 +935,7 @@ void HWR_DrawViewBorder(INT32 clearlines) INT32 top, side; INT32 baseviewwidth, baseviewheight; INT32 basewindowx, basewindowy; - GLPatch_t *patch; + patch_t *patch; // if (gl_viewwidth == vid.width) // return; diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 6f039cc3a..cc1354909 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -42,6 +42,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo); +EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -96,6 +97,7 @@ struct hwdriver_s ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; UpdateTexture pfnUpdateTexture; + DeleteTexture pfnDeleteTexture; ReadRect pfnReadRect; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 6ede8448b..94c553535 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -64,8 +64,7 @@ typedef struct gl_vissprite_s float x1, x2; float tz, ty; float tracertz; // for MF2_LINKDRAW sprites, this contains tracer's tz for use in sorting - //lumpnum_t patchlumpnum; - GLPatch_t *gpatch; + patch_t *gpatch; boolean flip; UINT8 translucency; //alpha level 0-255 mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out. @@ -86,25 +85,33 @@ extern size_t addsubsector; void HWR_InitPolyPool(void); void HWR_FreePolyPool(void); +void HWR_FreeExtraSubsectors(void); + // -------- // hw_cache.c // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); void HWR_FreeMipmapCache(void); -void HWR_FreeExtraSubsectors(void); +patch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); +patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); + +void HWR_GetPatch(patch_t *patch); +void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap); +void HWR_GetFadeMask(lumpnum_t fademasklumpnum); +patch_t *HWR_GetPic(lumpnum_t lumpnum); + +GLMapTexture_t *HWR_GetTexture(INT32 tex); void HWR_GetLevelFlat(levelflat_t *levelflat); void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum); -GLMapTexture_t *HWR_GetTexture(INT32 tex); -void HWR_GetPatch(GLPatch_t *gpatch); -void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); + +void HWR_FreeTexture(patch_t *patch); +void HWR_FreeTextureColormaps(patch_t *patch); void HWR_UnlockCachedPatch(GLPatch_t *gpatch); -GLPatch_t *HWR_GetPic(lumpnum_t lumpnum); + void HWR_SetPalette(RGBA_t *palette); -GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); -GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); -void HWR_GetFadeMask(lumpnum_t fademasklumpnum); + // -------- // hw_draw.c diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ddc935f0d..7ba7f911c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -706,7 +706,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) { FOutVector wallVerts[4]; wallsplat_t *splat; - GLPatch_t *gpatch; + patch_t *gpatch; fixed_t i; // seg bbox fixed_t segbbox[4]; @@ -3549,7 +3549,7 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) { - GLPatch_t *gpatch; + patch_t *gpatch; FOutVector shadowVerts[4]; FSurfaceInfo sSurf; float fscale; float fx; float fy; float offset; @@ -3575,12 +3575,12 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) if (alpha >= 255) return; alpha = 255 - alpha; - gpatch = (GLPatch_t *)W_CachePatchName("DSHADOW", PU_CACHE); - if (!(gpatch && gpatch->mipmap->format)) return; + gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_CACHE); + if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return; HWR_GetPatch(gpatch); scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height)); + scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(thing->x); @@ -3592,9 +3592,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) // 0--1 if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) - offset = (SHORT(gpatch->height)/2) * fscale; + offset = ((gpatch->height)/2) * fscale; else - offset = (float)(SHORT(gpatch->height)/2); + offset = (float)((gpatch->height)/2); shadowVerts[2].x = shadowVerts[3].x = fx + offset; shadowVerts[1].x = shadowVerts[0].x = fx - offset; @@ -3624,10 +3624,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) } shadowVerts[0].s = shadowVerts[3].s = 0; - shadowVerts[2].s = shadowVerts[1].s = gpatch->max_s; + shadowVerts[2].s = shadowVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s; shadowVerts[3].t = shadowVerts[2].t = 0; - shadowVerts[0].t = shadowVerts[1].t = gpatch->max_t; + shadowVerts[0].t = shadowVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; if (thing->subsector->sector->numlights) { @@ -3687,7 +3687,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) float this_scale = 1.0f; FOutVector wallVerts[4]; FOutVector baseWallVerts[4]; // This is what the verts should end up as - GLPatch_t *gpatch; + patch_t *gpatch; FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); extracolormap_t *colormap; @@ -3715,7 +3715,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) if (hires) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); - gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = spr->gpatch; // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -3740,25 +3740,25 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) if (spr->flip) { - baseWallVerts[0].s = baseWallVerts[3].s = gpatch->max_s; + baseWallVerts[0].s = baseWallVerts[3].s = ((GLPatch_t *)gpatch->hardware)->max_s; baseWallVerts[2].s = baseWallVerts[1].s = 0; } else { baseWallVerts[0].s = baseWallVerts[3].s = 0; - baseWallVerts[2].s = baseWallVerts[1].s = gpatch->max_s; + baseWallVerts[2].s = baseWallVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - baseWallVerts[3].t = baseWallVerts[2].t = gpatch->max_t; + baseWallVerts[3].t = baseWallVerts[2].t = ((GLPatch_t *)gpatch->hardware)->max_t; baseWallVerts[0].t = baseWallVerts[1].t = 0; } else { baseWallVerts[3].t = baseWallVerts[2].t = 0; - baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; + baseWallVerts[0].t = baseWallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; } // if it has a dispoffset, push it a little towards the camera @@ -3963,7 +3963,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) { float this_scale = 1.0f; FOutVector wallVerts[4]; - GLPatch_t *gpatch; // sprite patch converted to hardware + patch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); //const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE)); @@ -3990,7 +3990,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) // sure to do it the right way. So actually, we keep normal sprite // in memory and we add the md2 model if it exists for that sprite - gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = spr->gpatch; #ifdef ALAM_LIGHTING if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || @@ -4021,21 +4021,21 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) if (spr->flip) { - wallVerts[0].s = wallVerts[3].s = gpatch->max_s; + wallVerts[0].s = wallVerts[3].s = ((GLPatch_t *)gpatch->hardware)->max_s; wallVerts[2].s = wallVerts[1].s = 0; }else{ wallVerts[0].s = wallVerts[3].s = 0; - wallVerts[2].s = wallVerts[1].s = gpatch->max_s; + wallVerts[2].s = wallVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - wallVerts[3].t = wallVerts[2].t = gpatch->max_t; + wallVerts[3].t = wallVerts[2].t = ((GLPatch_t *)gpatch->hardware)->max_t; wallVerts[0].t = wallVerts[1].t = 0; }else{ wallVerts[3].t = wallVerts[2].t = 0; - wallVerts[0].t = wallVerts[1].t = gpatch->max_t; + wallVerts[0].t = wallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; } // cache the patch in the graphics card memory @@ -4121,7 +4121,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) { FBITFIELD blend = 0; FOutVector wallVerts[4]; - GLPatch_t *gpatch; // sprite patch converted to hardware + patch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; if (!spr->mobj) @@ -4131,7 +4131,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) return; // cache sprite graphics - gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = spr->gpatch; // create the sprite billboard // @@ -4153,10 +4153,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) HWR_RotateSpritePolyToAim(spr, wallVerts, true); wallVerts[0].s = wallVerts[3].s = 0; - wallVerts[2].s = wallVerts[1].s = gpatch->max_s; + wallVerts[2].s = wallVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s; wallVerts[3].t = wallVerts[2].t = 0; - wallVerts[0].t = wallVerts[1].t = gpatch->max_t; + wallVerts[0].t = wallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -5014,13 +5014,12 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->tz = tz; // Keep tz for the simple sprite sorting that happens vis->tracertz = tracertz; vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST - //vis->patchlumpnum = sprframe->lumppat[rot]; #ifdef ROTSPRITE if (rotsprite) - vis->gpatch = (GLPatch_t *)rotsprite; + vis->gpatch = (patch_t *)rotsprite; else #endif - vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE); + vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE); vis->flip = flip; vis->mobj = thing; vis->z1 = z1; @@ -5155,8 +5154,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->z2 = z2; vis->tz = tz; vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST - //vis->patchlumpnum = sprframe->lumppat[rot]; - vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE); + vis->gpatch = (patch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE); vis->flip = flip; vis->mobj = (mobj_t *)thing; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index ddb3696b6..3bcef05de 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -35,9 +35,9 @@ void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); void HWR_InitTextureMapping(void); void HWR_SetViewSize(void); -void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); -void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap); -void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); +void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option); +void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap); +void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index fa5156758..caef0a02d 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -348,48 +348,53 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, // -----------------+ static void md2_loadTexture(md2_t *model) { - GLPatch_t *grpatch; + patch_t *patch; + GLPatch_t *grPatch = NULL; const char *filename = model->filename; if (model->grpatch) { - grpatch = model->grpatch; - Z_Free(grpatch->mipmap->data); + patch = model->grpatch; + grPatch = (GLPatch_t *)(patch->hardware); + if (grPatch) + Z_Free(grPatch->mipmap->data); } else - { - grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, - &(model->grpatch)); - grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); - } + model->grpatch = patch = Patch_Create(NULL, 0, NULL); - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) + if (!patch->hardware) + Patch_AllocateHardwarePatch(patch); + + if (grPatch == NULL) + grPatch = (GLPatch_t *)(patch->hardware); + + if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data) { int w = 0, h = 0; UINT32 size; RGBA_t *image; #ifdef HAVE_PNG - grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + grPatch->mipmap->format = PNG_Load(filename, &w, &h, grPatch); + if (grPatch->mipmap->format == 0) #endif - grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + grPatch->mipmap->format = PCX_Load(filename, &w, &h, grPatch); + if (grPatch->mipmap->format == 0) { model->notexturefile = true; // mark it so its not searched for again repeatedly return; } - grpatch->mipmap->downloaded = 0; - grpatch->mipmap->flags = 0; + grPatch->mipmap->downloaded = 0; + grPatch->mipmap->flags = 0; - grpatch->width = (INT16)w; - grpatch->height = (INT16)h; - grpatch->mipmap->width = (UINT16)w; - grpatch->mipmap->height = (UINT16)h; + patch->width = (INT16)w; + patch->height = (INT16)h; + grPatch->mipmap->width = (UINT16)w; + grPatch->mipmap->height = (UINT16)h; // Lactozilla: Apply colour cube - image = grpatch->mipmap->data; + image = grPatch->mipmap->data; size = w*h; while (size--) { @@ -397,7 +402,7 @@ static void md2_loadTexture(md2_t *model) image++; } } - HWD.pfnSetTexture(grpatch->mipmap); + HWD.pfnSetTexture(grPatch->mipmap); } // -----------------+ @@ -405,48 +410,53 @@ static void md2_loadTexture(md2_t *model) // -----------------+ static void md2_loadBlendTexture(md2_t *model) { - GLPatch_t *grpatch; + patch_t *patch; + GLPatch_t *grPatch = NULL; char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL); - strcpy(filename, model->filename); + strcpy(filename, model->filename); FIL_ForceExtension(filename, "_blend.png"); if (model->blendgrpatch) { - grpatch = model->blendgrpatch; - Z_Free(grpatch->mipmap->data); + patch = model->blendgrpatch; + grPatch = (GLPatch_t *)(patch->hardware); + if (grPatch) + Z_Free(grPatch->mipmap->data); } else - { - grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, - &(model->blendgrpatch)); - grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); - } + model->blendgrpatch = patch = Patch_Create(NULL, 0, NULL); - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) + if (!patch->hardware) + Patch_AllocateHardwarePatch(patch); + + if (grPatch == NULL) + grPatch = (GLPatch_t *)(patch->hardware); + + if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + grPatch->mipmap->format = PNG_Load(filename, &w, &h, grPatch); + if (grPatch->mipmap->format == 0) #endif - grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + grPatch->mipmap->format = PCX_Load(filename, &w, &h, grPatch); + if (grPatch->mipmap->format == 0) { model->noblendfile = true; // mark it so its not searched for again repeatedly Z_Free(filename); return; } - grpatch->mipmap->downloaded = 0; - grpatch->mipmap->flags = 0; + grPatch->mipmap->downloaded = 0; + grPatch->mipmap->flags = 0; - grpatch->width = (INT16)w; - grpatch->height = (INT16)h; - grpatch->mipmap->width = (UINT16)w; - grpatch->mipmap->height = (UINT16)h; + patch->width = (INT16)w; + patch->height = (INT16)h; + grPatch->mipmap->width = (UINT16)w; + grPatch->mipmap->height = (UINT16)h; } - HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary + HWD.pfnSetTexture(grPatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary Z_Free(filename); } @@ -664,8 +674,10 @@ spritemodelfound: #define SETBRIGHTNESS(brightness,r,g,b) \ brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) -static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolornum_t color) +static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMipmap_t *grMipmap, INT32 skinnum, skincolornum_t color) { + GLPatch_t *hwrPatch = gpatch->hardware; + GLPatch_t *hwrBlendPatch = blendgpatch->hardware; UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; @@ -678,28 +690,29 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, memset(translation, 0, sizeof(translation)); memset(cutoff, 0, sizeof(cutoff)); - if (grmip->width == 0) + if (grMipmap->width == 0) { - grmip->width = gpatch->width; - grmip->height = gpatch->height; + grMipmap->width = gpatch->width; + grMipmap->height = gpatch->height; // no wrap around, no chroma key - grmip->flags = 0; + grMipmap->flags = 0; + // setup the texture info - grmip->format = GL_TEXFMT_RGBA; + grMipmap->format = GL_TEXFMT_RGBA; } - if (grmip->data) + if (grMipmap->data) { - Z_Free(grmip->data); - grmip->data = NULL; + Z_Free(grMipmap->data); + grMipmap->data = NULL; } - cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grmip->data); + cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grMipmap->data); memset(cur, 0x00, size*4); - image = gpatch->mipmap->data; - blendimage = blendgpatch->mipmap->data; + image = hwrPatch->mipmap->data; + blendimage = hwrBlendPatch->mipmap->data; // TC_METALSONIC includes an actual skincolor translation, on top of its flashing. if (skinnum == TC_METALSONIC) @@ -1038,37 +1051,39 @@ skippixel: #undef SETBRIGHTNESS -static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolornum_t color) +static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 skinnum, const UINT8 *colormap, skincolornum_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment - GLMipmap_t *grmip, *newmip; + GLPatch_t *grPatch = patch->hardware; + GLPatch_t *grBlendPatch = NULL; + GLMipmap_t *grMipmap, *newMipmap; - if (colormap == colormaps || colormap == NULL) + if (blendpatch == NULL || colormap == colormaps || colormap == NULL) { // Don't do any blending - HWD.pfnSetTexture(gpatch->mipmap); + HWD.pfnSetTexture(grPatch->mipmap); return; } - if ((blendgpatch && blendgpatch->mipmap->format) - && (gpatch->width != blendgpatch->width || gpatch->height != blendgpatch->height)) + if ((blendpatch && (grBlendPatch = blendpatch->hardware) && grBlendPatch->mipmap->format) + && (patch->width != blendpatch->width || patch->height != blendpatch->height)) { // Blend image exists, but it's bad. - HWD.pfnSetTexture(gpatch->mipmap); + HWD.pfnSetTexture(grPatch->mipmap); return; } // search for the mipmap // skip the first (no colormap translated) - for (grmip = gpatch->mipmap; grmip->nextcolormap; ) + for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) { - grmip = grmip->nextcolormap; - if (grmip->colormap == colormap) + grMipmap = grMipmap->nextcolormap; + if (grMipmap->colormap == colormap) { - if (grmip->downloaded && grmip->data) + if (grMipmap->downloaded && grMipmap->data) { - HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture - Z_ChangeTag(grmip->data, PU_HWRMODELTEXTURE_UNLOCKED); + HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture + Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); return; } } @@ -1081,16 +1096,16 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // (it have a liste of mipmap) // this malloc is cleared in HWR_FreeTextureCache // (...) unfortunately z_malloc fragment alot the memory :(so malloc is better - newmip = calloc(1, sizeof (*newmip)); - if (newmip == NULL) + newMipmap = calloc(1, sizeof (*newMipmap)); + if (newMipmap == NULL) I_Error("%s: Out of memory", "HWR_GetBlendedTexture"); - grmip->nextcolormap = newmip; - newmip->colormap = colormap; + grMipmap->nextcolormap = newMipmap; + newMipmap->colormap = colormap; - HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); + HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color); - HWD.pfnSetTexture(newmip); - Z_ChangeTag(newmip->data, PU_HWRMODELTEXTURE_UNLOCKED); + HWD.pfnSetTexture(newMipmap); + Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); } #define NORMALFOG 0x00000000 @@ -1177,9 +1192,11 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t return spr2; } -static void adjustTextureCoords(model_t *model, GLPatch_t *gpatch) +static void adjustTextureCoords(model_t *model, patch_t *patch) { int i; + GLPatch_t *gpatch = ((GLPatch_t *)patch->hardware); + for (i = 0; i < model->numMeshes; i++) { int j; @@ -1264,7 +1281,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) // Look at HWR_ProjectSprite for more { - GLPatch_t *gpatch; + patch_t *gpatch, *blendgpatch; + GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; //mdlframe_t *next = NULL; @@ -1309,14 +1327,26 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) // texture loading before model init, so it knows if sprite graphics are used, which // means that texture coordinates have to be adjusted gpatch = md2->grpatch; - if (!gpatch || ((!gpatch->mipmap->format || !gpatch->mipmap->downloaded) && !md2->notexturefile)) - md2_loadTexture(md2); - gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... + if (gpatch) + hwrPatch = ((GLPatch_t *)gpatch->hardware); - if ((gpatch && gpatch->mipmap->format) // don't load the blend texture if the base texture isn't available - && (!md2->blendgrpatch - || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) - && !md2->noblendfile))) + if (!gpatch || !hwrPatch + || ((!hwrPatch->mipmap->format || !hwrPatch->mipmap->downloaded) && !md2->notexturefile)) + md2_loadTexture(md2); + + // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... + gpatch = md2->grpatch; + if (gpatch) + hwrPatch = ((GLPatch_t *)gpatch->hardware); + + // Load blend texture + blendgpatch = md2->blendgrpatch; + if (blendgpatch) + hwrBlendPatch = ((GLPatch_t *)blendgpatch->hardware); + + if ((gpatch && hwrPatch && hwrPatch->mipmap->format) // don't load the blend texture if the base texture isn't available + && (!blendgpatch || !hwrBlendPatch + || ((!hwrBlendPatch->mipmap->format || !hwrBlendPatch->mipmap->downloaded) && !md2->noblendfile))) md2_loadBlendTexture(md2); if (md2->error) @@ -1332,7 +1362,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) md2_printModelInfo(md2->model); // if model uses sprite patch as texture, then // adjust texture coordinates to take power of two textures into account - if (!gpatch || !gpatch->mipmap->format) + if (!gpatch || !hwrPatch->mipmap->format) adjustTextureCoords(md2->model, spr->gpatch); HWD.pfnCreateModelVBOs(md2->model); } @@ -1352,7 +1382,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy - if (gpatch && gpatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture + if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { INT32 skinnum = TC_DEFAULT; @@ -1385,13 +1415,12 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } // Translation or skin number found - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolornum_t)spr->mobj->color); + HWR_GetBlendedTexture(gpatch, blendgpatch, skinnum, spr->colormap, (skincolornum_t)spr->mobj->color); } else { // Sprite - gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE); - HWR_GetMappedPatch(gpatch, spr->colormap); + HWR_GetMappedPatch(spr->gpatch, spr->colormap); } if (spr->mobj->frame & FF_ANIMATE) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 461966224..fbe65bc17 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1317,6 +1317,17 @@ void SetStates(void) } +// -----------------+ +// DeleteTexture : Deletes a texture from the GPU and frees its data +// -----------------+ +EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *pTexInfo) +{ + if (pTexInfo->downloaded) + pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded); + pTexInfo->downloaded = 0; +} + + // -----------------+ // Flush : flush OpenGL textures // : Clear list of downloaded mipmaps @@ -1327,9 +1338,7 @@ void Flush(void) while (gl_cachehead) { - if (gl_cachehead->downloaded) - pglDeleteTextures(1, (GLuint *)&gl_cachehead->downloaded); - gl_cachehead->downloaded = 0; + DeleteTexture(gl_cachehead); gl_cachehead = gl_cachehead->nextmipmap; } gl_cachetail = gl_cachehead = NULL; //Hurdler: well, gl_cachehead is already NULL diff --git a/src/hu_stuff.c b/src/hu_stuff.c index b61192533..ff9f274fc 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2038,9 +2038,6 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 830d97625..712983cac 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -379,7 +379,7 @@ static int lib_setSpriteInfo(lua_State *L) return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1); #ifdef ROTSPRITE if (sprites != NULL) - R_FreeSingleRotSprite(&sprites[i]); + R_FreeRotSprite(&sprites[i]); #endif info = &spriteinfo[i]; // get the spriteinfo to assign to. } @@ -464,7 +464,7 @@ static int spriteinfo_set(lua_State *L) #ifdef ROTSPRITE if (sprites != NULL) - R_FreeSingleRotSprite(&sprites[sprinfo-spriteinfo]); + R_FreeRotSprite(&sprites[sprinfo-spriteinfo]); #endif if (fastcmp(field, "pivot")) diff --git a/src/m_menu.c b/src/m_menu.c index 59d297e1a..3d6b1c0fa 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1490,7 +1490,7 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41}, - + {IT_STRING | IT_CVAR, NULL, "Music Preference", &cv_musicpref, 51}, {IT_HEADER, NULL, "Miscellaneous", NULL, 61}, @@ -5593,9 +5593,6 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo if (map <= 0) return; - if (needpatchrecache) - M_CacheLevelPlatter(); - // A 564x100 image of the level as entry MAPxxW if (!(levelselect.rows[row].mapavailable[col])) { @@ -5627,9 +5624,6 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea if (map <= 0) return; - if (needpatchrecache) - M_CacheLevelPlatter(); - // A 160x100 image of the level as entry MAPxxP if (!(levelselect.rows[row].mapavailable[col])) { @@ -6452,10 +6446,6 @@ static void M_DrawAddons(void) return; } - // Lactozilla: Load addons menu patches. - if (needpatchrecache) - M_LoadAddonsPatches(); - if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems."); else @@ -7610,9 +7600,6 @@ static void M_DrawSoundTest(void) fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0; UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY}; - if (needpatchrecache) - M_CacheSoundTest(); - // let's handle the ticker first. ideally we'd tick this somewhere else, BUT... if (curplaying) { @@ -8260,9 +8247,6 @@ static void M_DrawLoadGameData(void) if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); - if (needpatchrecache) - M_CacheLoadGameData(); - for (i = -2; i <= 2; i++) { savetodraw = (saveSlotSelected + i + numsaves)%numsaves; @@ -8966,7 +8950,6 @@ void M_ForceSaveSlotSelected(INT32 sslot) // CHARACTER SELECT // ================ -// lactozilla: sometimes the renderer changes and these patches don't exist anymore static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) { if (!(description[i].picname[0])) @@ -8987,22 +8970,6 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH); } -static void M_CacheCharacterSelect(void) -{ - INT32 i, skinnum; - - for (i = 0; i < MAXSKINS; i++) - { - if (!description[i].used) - continue; - - // Already set in M_SetupChoosePlayer - skinnum = description[i].skinnum[0]; - if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) - M_CacheCharacterSelectEntry(i, skinnum); - } -} - static UINT8 M_SetupChoosePlayerDirect(INT32 choice) { INT32 skinnum; @@ -9209,10 +9176,6 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 x, y; INT32 w = (vid.width/vid.dupx); - // lactozilla: the renderer changed so recache patches - if (needpatchrecache) - M_CacheCharacterSelect(); - if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); else // close enough. @@ -10584,10 +10547,6 @@ void M_DrawMarathon(void) angle_t fa; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy), xspan = (vid.width/dupz), yspan = (vid.height/dupz), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy; - // lactozilla: the renderer changed so recache patches - if (needpatchrecache) - M_CacheCharacterSelect(); - curbgxspeed = 0; curbgyspeed = 18; diff --git a/src/r_data.c b/src/r_data.c index befb73c20..4b2ff7484 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -482,7 +482,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) UINT8 *blocktex; texture_t *texture; texpatch_t *patch; - patch_t *realpatch; + softwarepatch_t *realpatch; UINT8 *pdata; int x, x1, x2, i, width, height; size_t blocksize; @@ -512,7 +512,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); - realpatch = (patch_t *)pdata; + realpatch = (softwarepatch_t *)pdata; #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) @@ -608,7 +608,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); lumplength = W_LumpLengthPwad(wadnum, lumpnum); - realpatch = (patch_t *)pdata; + realpatch = (softwarepatch_t *)pdata; dealloc = true; #ifndef NO_PNG_LUMPS diff --git a/src/r_defs.h b/src/r_defs.h index 132106bc8..10fc99ccd 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -652,16 +652,26 @@ typedef enum RGBA32 = 4, // 32 bit rgba } pic_mode_t; -#if defined(_MSC_VER) -#pragma pack(1) -#endif - // Patches. // A patch holds one or more columns. // Patches are used for sprites and all masked pictures, and we compose // textures from the TEXTURES list of patches. // -// WARNING: this structure is cloned in GLPatch_t +typedef struct +{ + INT16 width, height; + INT16 leftoffset, topoffset; + + INT32 *columnofs; // Column offsets. This is relative to patch->columns + UINT8 *columns; // Software column data + + void *hardware; // OpenGL patch, allocated whenever necessary +} patch_t; + +#if defined(_MSC_VER) +#pragma pack(1) +#endif + typedef struct { INT16 width; // bounding box size @@ -670,7 +680,7 @@ typedef struct INT16 topoffset; // pixels below the origin INT32 columnofs[8]; // only [width] used // the [0] is &columnofs[width] -} ATTRPACK patch_t; +} ATTRPACK softwarepatch_t; #ifdef _MSC_VER #pragma warning(disable : 4200) diff --git a/src/r_main.c b/src/r_main.c index 4f79dd8db..b70e6f25f 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1572,14 +1572,6 @@ void R_InitHardwareMode(void) } #endif -void R_ReloadHUDGraphics(void) -{ - CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n"); - ST_LoadGraphics(); - HU_LoadGraphics(); - ST_ReloadSkinFaceGraphics(); -} - // ========================================================================= // ENGINE COMMANDS & VARS // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 729ec6973..cc098462d 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -115,7 +115,6 @@ void R_Init(void); #ifdef HWRENDER void R_InitHardwareMode(void); #endif -void R_ReloadHUDGraphics(void); void R_CheckViewMorph(void); void R_ApplyViewMorph(void); diff --git a/src/r_patch.c b/src/r_patch.c index 8980eda58..783c1fbec 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -50,6 +50,98 @@ static unsigned char imgbuf[1<<26]; +// +// 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 = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest); + + if (source) + { + INT32 col, colsize; + size_t size = sizeof(INT32) * source->width; + size_t offs = (sizeof(INT16) * 4) + size; + + patch->width = source->width; + patch->height = source->height; + patch->leftoffset = source->leftoffset; + patch->topoffset = source->topoffset; + patch->columnofs = Z_Calloc(size, PU_PATCH, 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; + } + + if (!srcsize) + I_Error("R_CreatePatch: no source size!"); + + colsize = (INT32)(srcsize) - (INT32)offs; + if (colsize <= 0) + I_Error("R_CreatePatch: no column data!"); + + patch->columns = Z_Calloc(colsize, PU_PATCH, NULL); + M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize); + } + + if (patch->hardware) + I_Error("wtf?\n"); + + return patch; +} + +// +// Frees a patch from memory. +// + +void Patch_Free(patch_t *patch) +{ +#ifdef HWRENDER + if (patch->hardware) + HWR_FreeTexture(patch); +#endif + + if (patch->columnofs) + Z_Free(patch->columnofs); + if (patch->columns) + Z_Free(patch->columns); + + Z_Free(patch); +} + +#ifdef HWRENDER +// +// Allocates a hardware patch. +// + +void *Patch_AllocateHardwarePatch(patch_t *patch) +{ + if (!patch->hardware) + { + GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, &patch->hardware); + grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, &grPatch->mipmap); + } + return (void *)(patch->hardware); +} + +// +// Creates a hardware patch. +// + +void *Patch_CreateGL(patch_t *patch) +{ + GLPatch_t *grPatch = (GLPatch_t *)Patch_AllocateHardwarePatch(patch); + if (!grPatch->mipmap->data) // Run HWR_MakePatch in all cases, to recalculate some things + HWR_MakePatch(patch, grPatch, grPatch->mipmap, false); + return grPatch; +} +#endif // HWRENDER + // // R_CheckIfPatch // @@ -177,7 +269,7 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat) for (col = 0; col < SHORT(patch->width); col++, desttop++) { INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[col])); while (column->topdelta != 0xff) { @@ -220,7 +312,7 @@ void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip) for (col = 0; col < SHORT(patch->width); col++, desttop++) { INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-col) : col])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[flip ? (patch->width-1-col) : col])); while (column->topdelta != 0xff) { topdelta = column->topdelta; @@ -244,7 +336,7 @@ void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip) // // Convert a flat to a patch. // -patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency) +softwarepatch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency) { UINT32 x, y; UINT8 *img; @@ -350,7 +442,7 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse if (destsize != NULL) *destsize = size; - return (patch_t *)img; + return (softwarepatch_t *)img; } // @@ -359,7 +451,7 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse // Convert a masked flat to a patch. // Explanation of "masked" flats in R_PatchToMaskedFlat. // -patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) +softwarepatch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) { UINT32 x, y; UINT8 *img; @@ -464,7 +556,7 @@ patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 le if (destsize != NULL) *destsize = size; - return (patch_t *)img; + return (softwarepatch_t *)img; } // @@ -736,7 +828,7 @@ UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size) // // Convert a PNG to a patch. // -patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize) +softwarepatch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize) { UINT16 width, height; INT16 topoffset = 0, leftoffset = 0; @@ -981,7 +1073,7 @@ static void R_ParseSpriteInfo(boolean spr2) #ifdef ROTSPRITE if ((sprites != NULL) && (!spr2)) - R_FreeSingleRotSprite(&sprites[sprnum]); + R_FreeRotSprite(&sprites[sprnum]); #endif // Left Curly Brace @@ -1143,10 +1235,10 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) column_t *column; UINT8 *source; - if (x >= 0 && x < SHORT(patch->width)) + if (x >= 0 && x < patch->width) { INT32 topdelta, prevdelta = -1; - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-x) : x])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[flip ? (patch->width-1-x) : x])); while (column->topdelta != 0xff) { topdelta = column->topdelta; @@ -1194,8 +1286,8 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp { UINT32 i; INT32 angle; - patch_t *patch; - patch_t *newpatch; + patch_t *patch, *newpatch; + softwarepatch_t *swpatch; UINT16 *rawdst; size_t size; INT32 bflip = (flip != 0x00); @@ -1212,28 +1304,14 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp INT32 width, height, leftoffset; fixed_t ca, sa; lumpnum_t lump = sprframe->lumppat[rot]; -#ifndef NO_PNG_LUMPS - size_t lumplength; -#endif if (lump == LUMPERROR) return; - patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); -#ifndef NO_PNG_LUMPS - lumplength = W_LumpLength(lump); - - if (R_IsLumpPNG((UINT8 *)patch, lumplength)) - patch = R_PNGToPatch((UINT8 *)patch, lumplength, NULL); - else -#endif - // Because there's something wrong with SPR_DFLM, I guess - if (!R_CheckIfPatch(lump)) - return; - - width = SHORT(patch->width); - height = SHORT(patch->height); - leftoffset = SHORT(patch->leftoffset); + patch = (patch_t *)W_CachePatchNum(lump, PU_STATIC); + width = patch->width; + height = patch->height; + leftoffset = patch->leftoffset; // rotation pivot px = SPRITE_XCENTER; @@ -1345,37 +1423,33 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp } // make patch - newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); + swpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); { - newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); - newpatch->topoffset = (newpatch->height / 2) + (SHORT(patch->topoffset) - py); + swpatch->leftoffset = (swpatch->width / 2) + (leftoffset - px); + swpatch->topoffset = (swpatch->height / 2) + (patch->topoffset - py); } //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer if (rendermode != render_none) // not for psprite - newpatch->topoffset += FEETADJUST>>FRACBITS; + swpatch->topoffset += FEETADJUST>>FRACBITS; // P_PrecacheLevel if (devparm) spritememory += size; // convert everything to little-endian, for big-endian support - newpatch->width = SHORT(newpatch->width); - newpatch->height = SHORT(newpatch->height); - newpatch->leftoffset = SHORT(newpatch->leftoffset); - newpatch->topoffset = SHORT(newpatch->topoffset); + swpatch->width = SHORT(swpatch->width); + swpatch->height = SHORT(swpatch->height); + swpatch->leftoffset = SHORT(swpatch->leftoffset); + swpatch->topoffset = SHORT(swpatch->topoffset); + + newpatch = Patch_Create(swpatch, size, NULL); #ifdef HWRENDER if (rendermode == render_opengl) - { - GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - grPatch->rawpatch = newpatch; - sprframe->rotsprite.patch[rot][angle] = (patch_t *)grPatch; - HWR_MakePatch(newpatch, grPatch, grPatch->mipmap, false); - } - else -#endif // HWRENDER - sprframe->rotsprite.patch[rot][angle] = newpatch; + Patch_CreateGL(newpatch); +#endif + + sprframe->rotsprite.patch[rot][angle] = newpatch; // free rotated image data Z_Free(rawdst); @@ -1386,6 +1460,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp // free image data Z_Free(patch); + Z_Free(swpatch); } #undef SPRITE_XCENTER #undef SPRITE_YCENTER @@ -1394,11 +1469,11 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp } // -// R_FreeSingleRotSprite +// R_FreeRotSprite // // Free sprite rotation data from memory, for a single spritedef. // -void R_FreeSingleRotSprite(spritedef_t *spritedef) +void R_FreeRotSprite(spritedef_t *spritedef) { UINT8 frame; INT32 rot, ang; @@ -1414,30 +1489,8 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef) { patch_t *rotsprite = sprframe->rotsprite.patch[rot][ang]; if (rotsprite) - { -#ifdef HWRENDER - if (rendermode == render_opengl) - { - GLPatch_t *grPatch = (GLPatch_t *)rotsprite; - if (grPatch->rawpatch) - { - Z_Free(grPatch->rawpatch); - grPatch->rawpatch = NULL; - } - if (grPatch->mipmap) - { - if (grPatch->mipmap->data) - { - Z_Free(grPatch->mipmap->data); - grPatch->mipmap->data = NULL; - } - Z_Free(grPatch->mipmap); - grPatch->mipmap = NULL; - } - } -#endif - Z_Free(rotsprite); - } + Patch_Free(rotsprite); + rotsprite = NULL; } sprframe->rotsprite.cached &= ~(1<sprites; for (i = 0; i < NUMPLAYERSPRITES*2; i++) { - R_FreeSingleRotSprite(skinsprites); + R_FreeRotSprite(skinsprites); skinsprites++; } } - -// -// R_FreeAllRotSprite -// -// Free ALL sprite rotation data from memory. -// -void R_FreeAllRotSprite(void) -{ - INT32 i; - size_t s; - for (s = 0; s < numsprites; s++) - R_FreeSingleRotSprite(&sprites[s]); - for (i = 0; i < numskins; ++i) - R_FreeSkinRotSprite(i); -} #endif diff --git a/src/r_patch.h b/src/r_patch.h index a2db6320c..de4981fba 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -37,21 +37,30 @@ typedef struct boolean available; } spriteinfo_t; +// Patch functions +patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest); +void Patch_Free(patch_t *patch); + +#ifdef HWRENDER +void *Patch_AllocateHardwarePatch(patch_t *patch); +void *Patch_CreateGL(patch_t *patch); +#endif + // Conversions between patches / flats / textures... boolean R_CheckIfPatch(lumpnum_t lump); void R_TextureToFlat(size_t tex, UINT8 *flat); void R_PatchToFlat(patch_t *patch, UINT8 *flat); void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip); -patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); -patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); +softwarepatch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); +softwarepatch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); -// Portable Network Graphics +// PNGs boolean R_IsLumpPNG(const UINT8 *d, size_t s); #define W_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 UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size); -patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize); +softwarepatch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize); boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size); #endif @@ -64,11 +73,10 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); #ifdef ROTSPRITE INT32 R_GetRollAngle(angle_t rollangle); void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); -void R_FreeSingleRotSprite(spritedef_t *spritedef); +void R_FreeRotSprite(spritedef_t *spritedef); void R_FreeSkinRotSprite(size_t skinnum); extern fixed_t rollcosang[ROTANGLES]; extern fixed_t rollsinang[ROTANGLES]; -void R_FreeAllRotSprite(void); #endif #endif // __R_PATCH__ diff --git a/src/r_segs.c b/src/r_segs.c index d9fc75838..177827892 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -217,7 +217,7 @@ static void R_DrawWallSplats(void) continue; // draw the texture - col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + col = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); R_DrawSplatColumn(col); } } // next splat diff --git a/src/r_things.c b/src/r_things.c index c0795acd5..0636a880d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -228,7 +228,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 UINT8 frame; UINT8 rotation; lumpinfo_t *lumpinfo; - patch_t patch; + softwarepatch_t patch; UINT8 numadded = 0; memset(sprtemp,0xFF, sizeof (sprtemp)); @@ -241,7 +241,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 if (spritedef->numframes) // (then spriteframes is not null) { #ifdef ROTSPRITE - R_FreeSingleRotSprite(spritedef); + R_FreeRotSprite(spritedef); #endif // copy the already defined sprite frames M_Memcpy(sprtemp, spritedef->spriteframes, @@ -277,7 +277,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 W_ReadLumpHeaderPwad(wadnum, l, &patch, sizeof (patch_t), 0); #ifndef NO_PNG_LUMPS { - patch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC); + softwarepatch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC); size_t len = W_LumpLengthPwad(wadnum, l); // lump is a png so convert it if (R_IsLumpPNG((UINT8 *)png, len)) @@ -398,7 +398,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 spritedef->numframes < maxframe) // more frames are defined ? { #ifdef ROTSPRITE - R_FreeSingleRotSprite(spritedef); + R_FreeRotSprite(spritedef); #endif Z_Free(spritedef->spriteframes); spritedef->spriteframes = NULL; @@ -910,7 +910,7 @@ static void R_DrawVisSprite(vissprite_t *vis) sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); localcolfunc (column); } @@ -928,9 +928,9 @@ static void R_DrawVisSprite(vissprite_t *vis) 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 + LONG(patch->columnofs[texturecolumn])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); #else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif localcolfunc (column); } @@ -995,9 +995,9 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn"); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); #else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); + column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif R_DrawMaskedColumn(column); } diff --git a/src/screen.c b/src/screen.c index e7ff9e735..f5d19cada 100644 --- a/src/screen.c +++ b/src/screen.c @@ -202,9 +202,6 @@ void SCR_SetMode(void) // Lactozilla: Renderer switching if (setrenderneeded) { - Z_PreparePatchFlush(); - needpatchflush = true; - needpatchrecache = true; VID_CheckRenderer(); if (!setmodeneeded) VID_SetMode(vid.modenum); diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 416c8d2f5..e1845fac8 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -86,6 +86,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ClearBuffer); GETFUNC(SetTexture); GETFUNC(UpdateTexture); + GETFUNC(DeleteTexture); GETFUNC(ReadRect); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 01194a02f..1bb48e468 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1660,7 +1660,7 @@ static void Impl_SetWindowName(const char *title) static void Impl_SetWindowIcon(void) { if (window && icoSurface) - SDL_SetWindowIcon(window, icoSurface); + SDL_SetWindowIcon(window, icoSurface); } static void Impl_VideoSetupSDLBuffer(void) @@ -1770,7 +1770,7 @@ void I_StartupGraphics(void) // Window icon #ifdef HAVE_IMAGE icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif +#endif // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows @@ -1836,6 +1836,7 @@ void VID_StartupOpenGL(void) HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); + HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL); HWD.pfnReadRect = hwSym("ReadRect",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); diff --git a/src/st_stuff.c b/src/st_stuff.c index d5aa5fbac..f6ba94fcc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2755,9 +2755,6 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/v_video.c b/src/v_video.c index b88c4838b..7f07852fa 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -531,7 +531,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca //if (rendermode != render_soft && !con_startup) // Why? if (rendermode == render_opengl) { - HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap); + HWR_DrawStretchyFixedPatch(patch, x, y, pscale, vscale, scrn, colormap); return; } #endif @@ -716,7 +716,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca // if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT) if (x == 0 && SHORT(patch->width) == BASEVIDWIDTH && y == 0 && SHORT(patch->height) == BASEVIDHEIGHT) { - column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[0])); + column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[0])); if (!column->topdelta) { source = (const UINT8 *)(column) + 3; @@ -784,7 +784,7 @@ 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) + LONG(patch->columnofs[col>>FRACBITS])); + column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS])); while (column->topdelta != 0xff) { @@ -831,7 +831,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ //if (rendermode != render_soft && !con_startup) // Not this again if (rendermode == render_opengl) { - HWR_DrawCroppedPatch((GLPatch_t*)patch,x,y,pscale,scrn,sx,sy,w,h); + HWR_DrawCroppedPatch(patch,x,y,pscale,scrn,sx,sy,w,h); return; } #endif @@ -1007,7 +1007,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ continue; if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION) break; - column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[col>>FRACBITS])); + column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS])); while (column->topdelta != 0xff) { diff --git a/src/w_wad.c b/src/w_wad.c index e4a19f30e..f40f4eb4a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -836,11 +836,6 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) Z_Calloc(numlumps * sizeof (*wadfile->lumpcache), PU_STATIC, &wadfile->lumpcache); Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache); -#ifdef HWRENDER - // allocates GLPatch info structures and store them in a tree - wadfile->hwrcache = M_AATreeAlloc(AATREE_ZUSER); -#endif - // // add the wadfile // @@ -1676,13 +1671,7 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (!lumpcache[lump]) { size_t len = W_LumpLengthPwad(wad, lump); - void *ptr, *lumpdata; -#ifndef NO_PNG_LUMPS - void *srcdata = NULL; -#endif - - ptr = Z_Malloc(len, tag, &lumpcache[lump]); - lumpdata = Z_Malloc(len, tag, NULL); + void *ptr, *dest, *lumpdata = Z_Malloc(len, PU_STATIC, NULL); // read the lump in full W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); @@ -1692,14 +1681,25 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (R_IsLumpPNG((UINT8 *)lumpdata, len)) { size_t newlen; - srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); - ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); - M_Memcpy(ptr, srcdata, newlen); - Z_Free(srcdata); + void *converted = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); + ptr = Z_Malloc(newlen, PU_STATIC, NULL); + M_Memcpy(ptr, converted, newlen); + Z_Free(converted); + len = newlen; } else // just copy it into the patch cache #endif + { + ptr = Z_Malloc(len, PU_STATIC, NULL); M_Memcpy(ptr, lumpdata, len); + } + + Z_Free(lumpdata); + + dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]); + Patch_Create(ptr, len, dest); + + Z_Free(ptr); } else Z_ChangeTag(lumpcache[lump], tag); @@ -1714,45 +1714,22 @@ void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag) void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { -#ifdef HWRENDER - GLPatch_t *grPatch; -#endif + 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 W_CacheSoftwarePatchNumPwad(wad, lump, tag); - } + return (void *)patch; + #ifdef HWRENDER - - grPatch = HWR_GetCachedGLPatchPwad(wad, lump); - - if (grPatch->mipmap->data) - { - if (tag == PU_CACHE) - tag = PU_HWRCACHE; - Z_ChangeTag(grPatch->mipmap->data, tag); - } - else - { - patch_t *ptr = NULL; - - // Only load the patch if we haven't initialised the grPatch yet - if (grPatch->mipmap->width == 0) - ptr = W_CacheLumpNumPwad(grPatch->wadnum, grPatch->lumpnum, PU_STATIC); - - // Run HWR_MakePatch in all cases, to recalculate some things - HWR_MakePatch(ptr, grPatch, grPatch->mipmap, false); - Z_Free(ptr); - } - - // return GLPatch_t, which can be casted to (patch_t) with valid patch header info - return (void *)grPatch; + Patch_CreateGL(patch); + return (void *)patch; #endif } @@ -1767,7 +1744,7 @@ void W_UnlockCachedPatch(void *patch) // have different lifetimes from software's. #ifdef HWRENDER if (rendermode == render_opengl) - HWR_UnlockCachedPatch((GLPatch_t*)patch); + HWR_UnlockCachedPatch((GLPatch_t *)((patch_t *)patch)->hardware); else #endif Z_Unlock(patch); diff --git a/src/w_wad.h b/src/w_wad.h index fddc65529..ee3df9cf4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -102,10 +102,6 @@ virtlump_t* vres_Find(const virtres_t*, const char*); #define lumpcache_t void * -#ifdef HWRENDER -#include "m_aatree.h" -#endif - // Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further. typedef enum restype { @@ -123,9 +119,6 @@ typedef struct wadfile_s lumpinfo_t *lumpinfo; lumpcache_t *lumpcache; lumpcache_t *patchcache; -#ifdef HWRENDER - aatree_t *hwrcache; // patches are cached in renderer's native format -#endif UINT16 numlumps; // this wad's number of resources FILE *handle; UINT32 filesize; // for network diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 3f6c5e290..54526975e 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -107,6 +107,7 @@ static loadfunc_t hwdFuncTable[] = { {"ClearBuffer@12", &hwdriver.pfnClearBuffer}, {"SetTexture@4", &hwdriver.pfnSetTexture}, {"UpdateTexture@4", &hwdriver.pfnUpdateTexture}, + {"DeleteTexture@4", &hwdriver.pfnDeleteTexture}, {"ReadRect@24", &hwdriver.pfnReadRect}, {"GClipRect@20", &hwdriver.pfnGClipRect}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, @@ -139,6 +140,7 @@ static loadfunc_t hwdFuncTable[] = { {"ClearBuffer", &hwdriver.pfnClearBuffer}, {"SetTexture", &hwdriver.pfnSetTexture}, {"UpdateTexture", &hwdriver.pfnUpdateTexture}, + {"DeleteTexture", &hwdriver.pfnDeleteTexture}, {"ReadRect", &hwdriver.pfnReadRect}, {"GClipRect", &hwdriver.pfnGClipRect}, {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, diff --git a/src/y_inter.c b/src/y_inter.c index d857d60dc..4810ce7fa 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -158,7 +158,6 @@ typedef struct boolean usebuffer = false; static boolean useinterpic; -static boolean safetorender = true; static y_buffer_t *y_buffer; static INT32 intertic; @@ -175,7 +174,6 @@ static void Y_CalculateCompetitionWinners(void); static void Y_CalculateTimeRaceWinners(void); static void Y_CalculateMatchWinners(void); static void Y_UnloadData(void); -static void Y_CleanupData(void); // Stuff copy+pasted from st_stuff.c #define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n) @@ -322,19 +320,6 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; - // Lactozilla: Renderer switching - if (needpatchrecache) - { - Y_CleanupData(); - safetorender = false; - } - - if (!safetorender) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - - if (!safetorender) - goto dontdrawbg; - if (useinterpic) V_DrawScaledPatch(0, 0, 0, interpic); else if (!usetile) @@ -372,7 +357,6 @@ void Y_IntermissionDrawer(void) if (!LUA_HudEnabled(hud_intermissiontally)) goto skiptallydrawer; -dontdrawbg: if (intertype == int_coop) { INT32 bonusy; @@ -422,17 +406,14 @@ dontdrawbg: bonusy = 150; // Total - if (safetorender) - { - V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); - V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); - } + V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); + V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1; // Draw bonuses for (i = 3; i >= 0; --i) { - if (data.coop.bonuses[i].display && safetorender) + if (data.coop.bonuses[i].display) { V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]); V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points); @@ -661,8 +642,7 @@ dontdrawbg: char strtime[10]; // draw the header - if (safetorender) - V_DrawScaledPatch(112, 2, 0, data.match.result); + V_DrawScaledPatch(112, 2, 0, data.match.result); // draw the level name V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); @@ -1218,8 +1198,6 @@ void Y_StartIntermission(void) I_Error("endtic is dirty"); #endif - safetorender = true; - if (!multiplayer) { timer = 0; @@ -2067,7 +2045,6 @@ void Y_EndIntermission(void) } #define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL; -#define CLEANUP(x) x = NULL; // // Y_UnloadData @@ -2118,45 +2095,3 @@ static void Y_UnloadData(void) break; } } - -static void Y_CleanupData(void) -{ - // unload the background patches - CLEANUP(bgpatch); - CLEANUP(bgtile); - CLEANUP(interpic); - - switch (intertype) - { - case int_coop: - // unload the coop and single player patches - CLEANUP(data.coop.bonuspatches[3]); - CLEANUP(data.coop.bonuspatches[2]); - CLEANUP(data.coop.bonuspatches[1]); - CLEANUP(data.coop.bonuspatches[0]); - CLEANUP(data.coop.ptotal); - break; - case int_spec: - // unload the special stage patches - //CLEANUP(data.spec.cemerald); - //CLEANUP(data.spec.nowsuper); - CLEANUP(data.spec.bonuspatches[1]); - CLEANUP(data.spec.bonuspatches[0]); - CLEANUP(data.spec.pscore); - CLEANUP(data.spec.pcontinues); - break; - case int_match: - case int_race: - CLEANUP(data.match.result); - break; - case int_ctf: - CLEANUP(data.match.blueflag); - CLEANUP(data.match.redflag); - break; - default: - //without this default, - //int_none, int_tag, int_chaos, and int_classicrace - //are not handled - break; - } -} diff --git a/src/z_zone.c b/src/z_zone.c index 2387a1143..7a6dfe040 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -499,33 +499,6 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) // Utility functions // ----------------- -// for renderer switching -boolean needpatchflush = false; -boolean needpatchrecache = false; - -// flush all patches from memory -void Z_FlushCachedPatches(void) -{ - CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n"); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRMODELTEXTURE); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTag(PU_HWRCACHE_UNLOCKED); - Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); - Z_FreeTag(PU_HWRMODELTEXTURE_UNLOCKED); -} - -// happens before a renderer switch -void Z_PreparePatchFlush(void) -{ - CONS_Debug(DBG_RENDER, "Z_PreparePatchFlush()...\n"); -#ifdef ROTSPRITE - R_FreeAllRotSprite(); -#endif -} - // starting value of nextcleanup #define CLEANUPCOUNT 2000 diff --git a/src/z_zone.h b/src/z_zone.h index 5cbcc6655..c9dafc1ae 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -144,10 +144,4 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); char *Z_StrDup(const char *in); #define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed -// For renderer switching -extern boolean needpatchflush; -extern boolean needpatchrecache; -void Z_FlushCachedPatches(void); -void Z_PreparePatchFlush(void); - #endif