From 0869497ecb1aaba6565c3a11bb4775efab35ea72 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 6 Dec 2022 18:30:57 +0100 Subject: [PATCH] - rewrote the tile pixel cache to work on texture IDs instead of tile IDs. This allows using the related checking features with other textures as well. --- source/common/textures/image.h | 1 - source/core/defparser.cpp | 21 ++++++ source/core/gamefuncs.cpp | 13 ++-- source/core/textures/buildtiles.cpp | 102 ++++++++++++++++++++++----- source/core/textures/buildtiles.h | 72 +------------------ source/games/blood/src/fire.cpp | 3 +- source/games/blood/src/gameutil.cpp | 33 +++++---- source/games/blood/src/tile.cpp | 2 - source/games/blood/src/view.cpp | 27 +------ source/games/duke/src/bowling.cpp | 34 +++++---- source/games/exhumed/src/2d.cpp | 25 +++---- source/games/exhumed/src/exhumed.cpp | 10 +-- source/games/exhumed/src/menu.cpp | 7 +- source/games/exhumed/src/player.cpp | 2 +- source/games/exhumed/src/ramses.cpp | 14 ++-- 15 files changed, 179 insertions(+), 187 deletions(-) diff --git a/source/common/textures/image.h b/source/common/textures/image.h index 0924fe97e..54f6cf585 100644 --- a/source/common/textures/image.h +++ b/source/common/textures/image.h @@ -86,7 +86,6 @@ public: // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. TArray GetPalettedPixels(int conversion); - // Unlile for paletted images there is no variant here that returns a persistent bitmap, because all users have to process the returned image into another format. FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr); diff --git a/source/core/defparser.cpp b/source/core/defparser.cpp index 262fc1176..e46e4c9f2 100644 --- a/source/core/defparser.cpp +++ b/source/core/defparser.cpp @@ -123,6 +123,22 @@ bool ValidateTilenum(const char* cmd, int tile, FScriptPosition pos) // //=========================================================================== +struct TileImport +{ + FString fn; + int tile = -1; + int alphacut = 128, flags = 0; + int haveextra = 0; + int xoffset = INT_MAX, yoffset = INT_MAX; + int istexture = 0, extra = INT_MAX; + int64_t crc32 = INT64_MAX; + int sizex = INT_MAX, sizey; + // Blood extensions + int surface = INT_MAX, vox = INT_MAX, shade = INT_MAX; + +}; + + void processTileImport(const char* cmd, FScriptPosition& pos, TileImport& imp) { if (!ValidateTilenum(cmd, imp.tile, pos)) @@ -167,6 +183,11 @@ void processTileImport(const char* cmd, FScriptPosition& pos, TileImport& imp) // //=========================================================================== +struct SetAnim +{ + int tile1, tile2, speed, type; +}; + void processSetAnim(const char* cmd, FScriptPosition& pos, SetAnim& imp) { if (!ValidateTilenum(cmd, imp.tile1, pos) || diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 7b6fe4055..ff1076a03 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -577,10 +577,11 @@ double intersectWallSprite(DCoreActor* actor, const DVector3& start, const DVect if (checktex) { - int tilenum = actor->spr.picnum; - tileUpdatePicnum(&tilenum); + auto tiletexid = actor->spr.spritetexture(); + auto tiletex = TexMan.GetGameTexture(tiletexid, true); + auto pixels = GetRawPixels(tiletex->GetID()); - if (tileLoad(tilenum)) + if (pixels && tiletex->GetScaleX() == 1 && tiletex->GetScaleY() == 1) // does not work with scaled textures. { double zfactor = 1. - (position - result.Z) / height; @@ -589,10 +590,10 @@ double intersectWallSprite(DCoreActor* actor, const DVector3& start, const DVect if (actor->spr.cstat & CSTAT_SPRITE_XFLIP) factor2 = 1 - factor2; if (actor->spr.cstat & CSTAT_SPRITE_YFLIP) zfactor = 1 - zfactor; - int xtex = int(factor2 * tileWidth(tilenum)); - int ytex = int(zfactor * tileHeight(tilenum)); + int xtex = int(factor2 * tiletex->GetTexelWidth()); + int ytex = int(zfactor * tiletex->GetTexelHeight()); - auto texel = (tilePtr(tilenum) + tileHeight(tilenum) * xtex + ytex); + auto texel = (pixels + tiletex->GetTexelHeight() * xtex + ytex); if (*texel == TRANSPARENT_INDEX) return -1; } diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 2c5e641fd..9e219a8d0 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -110,6 +110,92 @@ TArray FTileTexture::CreatePalettedPixels(int conversion) return buffer; } +//========================================================================== +// +// raw pixel cache. This is for accessing pixel data in the game code, +// not for rendering. +// +//========================================================================== + +struct RawCacheNode +{ + TArray data; + uint64_t lastUseTime; + + RawCacheNode() = default; + RawCacheNode(RawCacheNode& other) = default; + RawCacheNode& operator=(RawCacheNode& other) = default; + + RawCacheNode(RawCacheNode&& other) noexcept + { + data = std::move(other.data); + lastUseTime = other.lastUseTime; + } + + RawCacheNode& operator=(RawCacheNode&& other) noexcept + { + data = std::move(other.data); + lastUseTime = other.lastUseTime; + return *this; + } +}; + +//========================================================================== +// +// +// +//========================================================================== +static TMap CacheNodes; + +const uint8_t* GetRawPixels(FTextureID texid) +{ + if (!texid.isValid()) return nullptr; + auto gtex = TexMan.GetGameTexture(texid); + auto tex = dynamic_cast(gtex->GetTexture()); + + if (!tex || !tex->GetImage()) return nullptr; + auto img = tex->GetImage(); + auto timg = dynamic_cast(img); + if (!timg || !timg->GetRawData()) + { + auto cache = CacheNodes.CheckKey(texid.GetIndex()); + if (cache) + { + cache->lastUseTime = I_nsTime(); + return cache->data.Data(); + } + RawCacheNode newnode; + newnode.data = img->GetPalettedPixels(0); + newnode.lastUseTime = I_nsTime(); + auto retval =newnode.data.Data(); + CacheNodes.Insert(texid.GetIndex(), std::move(newnode)); + return retval; + } + else + { + return timg->GetRawData(); + } +} + +//========================================================================== +// +//To use this the texture must have been made writable during texture init. +// +//========================================================================== + +uint8_t* GetWritablePixels(FTextureID texid) +{ + if (!texid.isValid()) return nullptr; + auto gtex = TexMan.GetGameTexture(texid); + auto tex = dynamic_cast(gtex->GetTexture()); + + if (!tex || !tex->GetImage()) return nullptr; + auto timg = dynamic_cast(tex->GetImage()); + if (!timg) return nullptr; + gtex->CleanHardwareData(); // we can safely assume that this only gets called when the texture is about to be changed. + return timg->GetRawData(); +} + //========================================================================== // // @@ -245,22 +331,6 @@ int CountTiles (const char *fn, const uint8_t *RawData) return tileend >= tilestart ? tileend - tilestart + 1 : 0; } -//=========================================================================== -// -// InvalidateTile -// -//=========================================================================== - -void BuildTiles::InvalidateTile(int num) -{ - if ((unsigned) num < MAXTILES) - { - auto tex = tiledata[num].texture; - tex->CleanHardwareData(); - tiledata[num].rawCache.data.Clear(); - } -} - //=========================================================================== // // MakeCanvas diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index bfa7dd9bf..8daebe67f 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -7,9 +7,6 @@ #include "intvec.h" #include "name.h" -// picanm[].sf: -// |bit(1<<7) -// |animtype|animtype|texhitscan|nofullbright|speed|speed|speed|speed| enum AnimFlags { PICANM_ANIMTYPE_NONE = 0, @@ -75,12 +72,6 @@ struct picanm_t }; picanm_t tileConvertAnimFormat(int32_t const picanmdisk, int* lo, int* to); -struct rottile_t -{ - int16_t newtile; - int16_t owner; -}; - class FTileTexture : public FImageSource { public: @@ -262,12 +253,6 @@ struct BuildArtFile // //========================================================================== -struct RawCacheNode -{ - TArray data; - uint64_t lastUseTime; -}; - struct TileOffs { int xsize, ysize, xoffs, yoffs; @@ -276,7 +261,6 @@ struct TileOffs struct TileDesc { FGameTexture* texture; // the currently active tile - RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time. picanm_t picanm; // animation descriptor ReplacementType replacement; float alphaThreshold; @@ -302,7 +286,6 @@ struct BuildTiles TDeletingArray ArtFiles; TileDesc tiledata[MAXTILES]; TArray addedArt; - TArray maptilesadded; TMap nametoindex; TMap textotile; bool locked; // if this is true, no more tile modifications are allowed. @@ -375,7 +358,6 @@ struct BuildTiles FGameTexture* ValidateCustomTile(int tilenum, ReplacementType type); uint8_t* tileMakeWritable(int num); uint8_t* tileCreate(int tilenum, int width, int height); - void InvalidateTile(int num); void MakeCanvas(int tilenum, int width, int height); }; @@ -384,40 +366,8 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu void tileCopy(int tile, int tempsource, int temppal, int xoffset, int yoffset, int flags); void tileSetDummy(int tile, int width, int height); void tileDelete(int tile); -bool tileLoad(int tileNum); -void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int tilenum2, int sx2, int sy2); extern BuildTiles TileFiles; -inline bool tileCheck(int num) -{ - auto tex = TileFiles.tiledata[num].texture; - return tex && tex->GetTexelWidth() > 0 && tex->GetTexelHeight() > 0; -} - -inline const uint8_t* tilePtr(int num) -{ - if (TileFiles.tiledata[num].rawCache.data.Size() == 0) - { - auto tex = TileFiles.tiledata[num].texture; - if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return nullptr; - TileFiles.tiledata[num].rawCache.data = tex->GetTexture()->Get8BitPixels(false); - } - TileFiles.tiledata[num].rawCache.lastUseTime = I_nsTime(); - return TileFiles.tiledata[num].rawCache.data.Data(); -} - -inline bool tileLoad(int tileNum) -{ - return !!tilePtr(tileNum); -} - -inline uint8_t* tileData(int num) -{ - auto tex = dynamic_cast(TileFiles.tiledata[num].texture->GetTexture()); - if (!tex) return nullptr; - auto p = dynamic_cast(tex->GetImage()); - return p ? p->GetRawData() : nullptr; -} // Some hacks to allow accessing the no longer existing arrays as if they still were arrays to avoid changing hundreds of lines of code. struct PicAnm @@ -491,25 +441,9 @@ inline int legacyTileNum(FTextureID tex) void tileUpdateAnimations(); -struct TileImport -{ - FString fn; - int tile = -1; - int alphacut = 128, flags = 0; - int haveextra = 0; - int xoffset = INT_MAX, yoffset = INT_MAX; - int istexture = 0, extra = INT_MAX; - int64_t crc32 = INT64_MAX; - int sizex = INT_MAX, sizey; - // Blood extensions - int surface = INT_MAX, vox = INT_MAX, shade = INT_MAX; - -}; - -struct SetAnim -{ - int tile1, tile2, speed, type; -}; +const uint8_t* GetRawPixels(FTextureID texid); +uint8_t* GetWritablePixels(FTextureID texid); +void InvalidateTexture(FTextureID num); class FGameTexture; bool PickTexture(FGameTexture* tex, int paletteid, TexturePick& pick, bool wantindexed = false); diff --git a/source/games/blood/src/fire.cpp b/source/games/blood/src/fire.cpp index f66e8be1a..0b864c4df 100644 --- a/source/games/blood/src/fire.cpp +++ b/source/games/blood/src/fire.cpp @@ -75,7 +75,7 @@ void DoFireFrame(void) memcpy(FrameBuffer + 16896 + i * 128, SeedBuffer[nRand], 128); } CellularFrame(FrameBuffer, 128, 132); - auto pData = tileData(2342); + auto pData = GetWritablePixels(tileGetTextureID(2342)); uint8_t* pSource = FrameBuffer; int x = fireSize; do @@ -129,7 +129,6 @@ void FireProcess(void) { DoFireFrame(); lastUpdate = clock; - TileFiles.InvalidateTile(2342); } } } diff --git a/source/games/blood/src/gameutil.cpp b/source/games/blood/src/gameutil.cpp index 017183c87..33e8f353d 100644 --- a/source/games/blood/src/gameutil.cpp +++ b/source/games/blood/src/gameutil.cpp @@ -272,37 +272,40 @@ int VectorScan(DBloodActor* actor, double nOffset, double nZOffset, const DVecto if ((other->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != 0) return SS_SPRITE; - int nPicnum = other->spr.picnum; - if (tileWidth(nPicnum) == 0 || tileHeight(nPicnum) == 0) + auto nTex = other->spr.spritetexture(); + auto pTex = TexMan.GetGameTexture(nTex); + int twidth = pTex->GetTexelWidth(); + int theight = pTex->GetTexelHeight(); + if (twidth == 0 || theight == 0 || pTex->GetScaleX() != 1 || pTex->GetScaleY() != 1) // pixel checking does not work with scaled textures (at least not with this code...) return SS_SPRITE; - double height = (tileHeight(nPicnum) * other->spr.scale.Y); + double height = (theight * other->spr.scale.Y); double otherZ = other->spr.pos.Z; if (other->spr.cstat & CSTAT_SPRITE_YCENTER) otherZ += height / 2; - int nTopOfs = tileTopOffset(nPicnum); + int nTopOfs = pTex->GetTexelTopOffset(); if (nTopOfs) otherZ -= (nTopOfs * other->spr.scale.Y); assert(height > 0); - double height2 = (otherZ - gHitInfo.hitpos.Z) * tileHeight(nPicnum) / height; + double height2 = (otherZ - gHitInfo.hitpos.Z) * theight / height; if (!(other->spr.cstat & CSTAT_SPRITE_YFLIP)) - height2 = tileHeight(nPicnum) - height2; + height2 = theight - height2; - if (height2 >= 0 && height2 < tileHeight(nPicnum)) + if (height2 >= 0 && height2 < theight) { - double width = (tileWidth(nPicnum) * other->spr.scale.X) * 0.75; // should actually be 0.8 to match the renderer! + double width = (twidth * other->spr.scale.X) * 0.75; // should actually be 0.8 to match the renderer! double check1 = ((pos.Y - other->spr.pos.Y) * vel.X - (pos.X - other->spr.pos.X) * vel.Y) / vel.XY().Length(); assert(width > 0); - double width2 = check1 * tileWidth(nPicnum) / width; - int nLeftOfs = tileLeftOffset(nPicnum); - width2 += nLeftOfs + tileWidth(nPicnum) / 2; - if (width2 >= 0 && width2 < tileWidth(nPicnum)) + double width2 = check1 * twidth / width; + int nLeftOfs = pTex->GetTexelLeftOffset(); + width2 += nLeftOfs + twidth / 2; + if (width2 >= 0 && width2 < twidth) { - auto pData = tilePtr(nPicnum); - if (pData[int(width2) * tileHeight(nPicnum) + int(height2)] != TRANSPARENT_INDEX) + auto pData = GetRawPixels(nTex); + if (pData[int(width2) * theight + int(height2)] != TRANSPARENT_INDEX) return SS_SPRITE; } } @@ -359,7 +362,7 @@ int VectorScan(DBloodActor* actor, double nOffset, double nZOffset, const DVecto int nHOffset = int(pWall->xpan_ + ((fHOffset * pWall->xrepeat) * 8) / nLength) % nSizX; nnOfs %= nSizY; - auto pData = tilePtr(pWall->overpicnum); + auto pData = GetRawPixels(pWall->overtexture()); int nPixel = nHOffset * nSizY + nnOfs; if (pData[nPixel] == TRANSPARENT_INDEX) diff --git a/source/games/blood/src/tile.cpp b/source/games/blood/src/tile.cpp index bb5dbf29d..a661022ad 100644 --- a/source/games/blood/src/tile.cpp +++ b/source/games/blood/src/tile.cpp @@ -93,8 +93,6 @@ void GameInterface::SetupSpecialTextures() { // set up all special tiles here, before we fully hook up with the texture manager. tileDelete(504); - TileFiles.tileCreate(4077, kLensSize, kLensSize); - TileFiles.tileCreate(4079, 128, 128); TileFiles.tileMakeWritable(2342); TileFiles.lock(); // from this point on the tile<->texture associations may not change anymore. mirrortile = tileGetTextureID(504); diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index b8c565b54..b9d843c6b 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -130,9 +130,6 @@ void viewDrawAimedPlayerName(PLAYER* pPlayer) } } -static TArray lensdata; -int* lensTable; - extern DAngle random_angles[16][3]; //--------------------------------------------------------------------------- @@ -145,19 +142,6 @@ void viewInit(void) { Printf("Initializing status bar\n"); - lensdata = fileSystem.LoadFile("lens.dat"); - assert(lensdata.Size() == kLensSize * kLensSize * sizeof(int)); - - lensTable = (int*)lensdata.Data(); -#if WORDS_BIGENDIAN - for (int i = 0; i < kLensSize * kLensSize; i++) - { - lensTable[i] = LittleLong(lensTable[i]); - } -#endif - uint8_t* data = tileData(4077); - memset(data, TRANSPARENT_INDEX, kLensSize * kLensSize); - for (int i = 0; i < 16; i++) { random_angles[i][0] = RandomAngle(); @@ -254,15 +238,8 @@ void viewSetErrorMessage(const char* pMessage) void DoLensEffect(void) { - // To investigate whether this can be implemented as a shader effect. - auto d = tileData(4077); - assert(d != NULL); - auto s = tilePtr(4079); - assert(s != NULL); - for (int i = 0; i < kLensSize * kLensSize; i++, d++) - if (lensTable[i] >= 0) - *d = s[lensTable[i]]; - TileFiles.InvalidateTile(4077); + // the lens effect depends on the software renderer and easy availability of the pixel data. + // If this ever gets redone for hardware rendering it needs very different handling on the GPU side. } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/bowling.cpp b/source/games/duke/src/bowling.cpp index bb6e2c822..327023692 100644 --- a/source/games/duke/src/bowling.cpp +++ b/source/games/duke/src/bowling.cpp @@ -31,6 +31,7 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms #include "names_r.h" #include "dukeactor.h" #include "buildtiles.h" +#include "texturemanager.h" BEGIN_DUKE_NS @@ -39,17 +40,15 @@ BEGIN_DUKE_NS // //========================================================================== -void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int tilenum2, int sx2, int sy2) +void tileCopySection(FTextureID tilenum1, int sx1, int sy1, int xsiz, int ysiz, uint8_t* p2, int xsiz2, int ysiz2, int sx2, int sy2) { - int xsiz1 = tileWidth(tilenum1); - int ysiz1 = tileHeight(tilenum1); - int xsiz2 = tileWidth(tilenum2); - int ysiz2 = tileHeight(tilenum2); - if (xsiz1 > 0 && ysiz1 > 0 && xsiz2 > 0 && ysiz2 > 0) + auto tex = TexMan.GetGameTexture(tilenum1); + int xsiz1 = tex->GetTexelWidth(); + int ysiz1 = tex->GetTexelHeight(); + if (xsiz1 > 0 && ysiz1 > 0) { - auto p1 = tilePtr(tilenum1); - auto p2 = tileData(tilenum2); - if (p2 == nullptr) return; // Error: Destination is not writable. + auto p1 = GetRawPixels(tilenum1); + if (!p1) return; int x1 = sx1; int x2 = sx2; @@ -81,17 +80,22 @@ void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int til void updatepindisplay(int tag, int pins) { + if (tag < 1 || tag > 4) return; + + static const char* lanepics[] = { "BOWLINGLANE1", "BOWLINGLANE2", "BOWLINGLANE3", "BOWLINGLANE4" }; + auto texidbg = TexMan.CheckForTexture("LANEPICBG", ETextureType::Any); + auto texidlite = TexMan.CheckForTexture("LANEPICS", ETextureType::Any); + auto texidwork = TexMan.CheckForTexture(lanepics[tag-1], ETextureType::Any); static const uint8_t pinx[] = { 64, 56, 72, 48, 64, 80, 40, 56, 72, 88 }; static const uint8_t piny[] = { 48, 40, 40, 32, 32, 32, 24, 24, 24, 24 }; - if (tag < 1 || tag > 4) return; - tag += RTILE_BOWLINGLANE1 - 1; - if (tileData(tag)) + auto pixels = GetWritablePixels(texidwork); + if (pixels) { - tileCopySection(RTILE_LANEPICBG, 0, 0, 128, 64, tag, 0, 0); + auto tex = TexMan.GetGameTexture(texidwork); + tileCopySection(texidbg, 0, 0, 128, 64, pixels, tex->GetTexelWidth(), tex->GetTexelHeight(), 0, 0); for (int i = 0; i < 10; i++) if (pins & (1 << i)) - tileCopySection(RTILE_LANEPICS, 0, 0, 8, 8, tag, pinx[i] - 4, piny[i] - 10); - TileFiles.InvalidateTile(tag); + tileCopySection(texidlite, 0, 0, 8, 8, pixels, tex->GetTexelWidth(), tex->GetTexelHeight(), pinx[i] - 4, piny[i] - 10); } } diff --git a/source/games/exhumed/src/2d.cpp b/source/games/exhumed/src/2d.cpp index b53943277..4a0efb73a 100644 --- a/source/games/exhumed/src/2d.cpp +++ b/source/games/exhumed/src/2d.cpp @@ -112,10 +112,10 @@ void menu_DoPlasma() if (!PlasmaBuffer) { - auto pixels = tileData(kTile4092); + auto pixels = GetWritablePixels(tileGetTextureID(kTile4092)); memset(pixels, 96, kPlasmaWidth * kPlasmaHeight); - PlasmaBuffer = tileData(kTile4093); + PlasmaBuffer = GetWritablePixels(tileGetTextureID(kTile4093)); memset(PlasmaBuffer, 96, kPlasmaWidth * kPlasmaHeight); @@ -139,9 +139,9 @@ void menu_DoPlasma() } } - uint8_t* plasmapix = tileData(nPlasmaTile); + uint8_t* plasmapix = GetWritablePixels(tileGetTextureID(nPlasmaTile)); uint8_t* r_ebx = plasmapix + 81; - const uint8_t* r_edx = tileData(nPlasmaTile ^ 1) + 81; // flip between value of 4092 and 4093 with xor + const uint8_t* r_edx = GetWritablePixels(tileGetTextureID(nPlasmaTile ^ 1)) + 81; // flip between value of 4092 and 4093 with xor for (int x = 0; x < kPlasmaWidth - 2; x++) { @@ -231,7 +231,7 @@ void menu_DoPlasma() r_ebx += 2; } - auto logopix = tilePtr(nLogoTile); + auto logopix = GetRawPixels(tileGetTextureID(nLogoTile)); for (int j = 0; j < 5; j++) { @@ -292,8 +292,6 @@ void menu_DoPlasma() v28[nSmokeOffset] = 175; } - TileFiles.InvalidateTile(nPlasmaTile); - // flip between tile 4092 and 4093 if (nPlasmaTile == kTile4092) { nPlasmaTile = kTile4093; @@ -439,7 +437,7 @@ static int DoStatic(int a, int b) { auto tex = dynamic_cast(tileGetTexture(kTileLoboLaptop)->GetTexture()->GetImage()); if (tex) tex->Reload(); - auto pixels = tileData(kTileLoboLaptop); + auto pixels = GetWritablePixels(tileGetTextureID(kTileLoboLaptop)); int y = 160 - a / 2; int left = 81 - b / 2; @@ -449,8 +447,6 @@ static int DoStatic(int a, int b) auto pTile = (pixels + (200 * y)) + left; - TileFiles.InvalidateTile(kTileLoboLaptop); - for(;y < bottom; y++) { uint8_t* pixel = pTile; @@ -466,10 +462,11 @@ static int DoStatic(int a, int b) static int UndoStatic() { - auto tex = dynamic_cast(tileGetTexture(kTileLoboLaptop)->GetTexture()->GetImage()); - if (tex) tex->Reload(); - TileFiles.InvalidateTile(kTileLoboLaptop); - return tileGetTexture(kTileLoboLaptop)->GetID().GetIndex(); + auto tex = dynamic_cast(tileGetTexture(kTileLoboLaptop)->GetTexture()->GetImage()); + if (tex) tex->Reload(); + auto texid = tileGetTextureID(kTileLoboLaptop); + GetWritablePixels(texid); + return texid.GetIndex(); } DEFINE_ACTION_FUNCTION_NATIVE(DLastLevelCinema, DoStatic, DoStatic) diff --git a/source/games/exhumed/src/exhumed.cpp b/source/games/exhumed/src/exhumed.cpp index 92d341cf9..a5de0c1ae 100644 --- a/source/games/exhumed/src/exhumed.cpp +++ b/source/games/exhumed/src/exhumed.cpp @@ -236,7 +236,7 @@ void DrawClock() { int ebp = 49; - auto pixels = tileData(kTile3603); + auto pixels = GetWritablePixels(tileGetTextureID(kTile3603)); memset(pixels, TRANSPARENT_INDEX, 4096); @@ -630,16 +630,14 @@ void CopyTileToBitmap(int nSrcTile, int nDestTile, int xPos, int yPos) { int nOffs = tileHeight(nDestTile) * xPos; - auto pixels = tileData(nDestTile); + auto pixels = GetWritablePixels(tileGetTextureID(nDestTile)); uint8_t *pDest = pixels + nOffs + yPos; uint8_t *pDestB = pDest; - tileLoad(nSrcTile); - int destYSize = tileHeight(nDestTile); int srcYSize = tileHeight(nSrcTile); - const uint8_t *pSrc = tilePtr(nSrcTile); + const uint8_t *pSrc = GetRawPixels(tileGetTextureID(nSrcTile)); for (int x = 0; x < tileWidth(nSrcTile); x++) { @@ -659,8 +657,6 @@ void CopyTileToBitmap(int nSrcTile, int nDestTile, int xPos, int yPos) // reset pDestB pDestB = pDest; } - - TileFiles.InvalidateTile(nDestTile); } //--------------------------------------------------------------------------- diff --git a/source/games/exhumed/src/menu.cpp b/source/games/exhumed/src/menu.cpp index b3b9e05e0..6b5fc5b76 100644 --- a/source/games/exhumed/src/menu.cpp +++ b/source/games/exhumed/src/menu.cpp @@ -93,8 +93,8 @@ void DoEnergyTile() { nButtonColor += nButtonColor < 0 ? 8 : 0; - auto energy1 = tileData(kEnergy1); - auto energy2 = tileData(kEnergy2); + auto energy1 = GetWritablePixels(tileGetTextureID(kEnergy1)); + auto energy2 = GetWritablePixels(tileGetTextureID(kEnergy2)); uint8_t* ptr1 = energy1 + 1984; uint8_t* ptr2 = energy1 + 2048; @@ -117,8 +117,6 @@ void DoEnergyTile() } } - TileFiles.InvalidateTile(kEnergy1); - if (nSmokeSparks) { uint8_t* c = &energytile[67]; // skip a line @@ -245,7 +243,6 @@ void DoEnergyTile() energytile[val] = 175; word_9AB5B = 1; } - TileFiles.InvalidateTile(kEnergy2); } } diff --git a/source/games/exhumed/src/player.cpp b/source/games/exhumed/src/player.cpp index 804e2069b..3def7f18f 100644 --- a/source/games/exhumed/src/player.cpp +++ b/source/games/exhumed/src/player.cpp @@ -224,7 +224,7 @@ void InitPlayerInventory(int nPlayer) PlayerList[nPlayer].nPlayerScore = 0; - auto pixels = tilePtr(kTile3571 + nPlayer); + auto pixels = GetRawPixels(tileGetTextureID(kTile3571 + nPlayer)); PlayerList[nPlayer].nPlayerColor = pixels[tileWidth(nPlayer + kTile3571) * tileHeight(nPlayer + kTile3571) / 2]; } diff --git a/source/games/exhumed/src/ramses.cpp b/source/games/exhumed/src/ramses.cpp index 0b1c36967..4ef381373 100644 --- a/source/games/exhumed/src/ramses.cpp +++ b/source/games/exhumed/src/ramses.cpp @@ -68,8 +68,6 @@ void InitSpiritHead() nSpiritScale = pSpiritSpr->spr.scale; - tileLoad(kTileRamsesNormal); // Ramses Normal Head - ExhumedSpriteIterator it; while (auto act = it.Next()) { @@ -79,8 +77,8 @@ void InitSpiritHead() } } - auto pTile = tilePtr(kTileRamsesNormal); // Ramses Normal Head - auto pGold = tilePtr(kTileRamsesGold); + auto pTile = GetRawPixels(tileGetTextureID(kTileRamsesNormal)); // Ramses Normal Head + auto pGold = GetRawPixels(tileGetTextureID(kTileRamsesGold)); for (int x = 0; x < 97; x++) { for (int y = 0; y < 106; y++) @@ -121,14 +119,13 @@ void InitSpiritHead() nHeadStage = 0; // work tile is twice as big as the normal head size - Worktile = tileData(kTileRamsesWorkTile); + Worktile = GetWritablePixels(tileGetTextureID(kTileRamsesWorkTile)); pSpiritSpr->spr.cstat &= ~CSTAT_SPRITE_INVISIBLE; nHeadTimeStart = PlayClock; memset(Worktile, TRANSPARENT_INDEX, WorktileSize); - TileFiles.InvalidateTile(kTileRamsesWorkTile); nPixelsToShow = 0; @@ -176,7 +173,7 @@ void DimSector(sectortype* pSector) void CopyHeadToWorkTile(int nTile) { - const uint8_t* pSrc = tilePtr(nTile); + const uint8_t* pSrc = GetRawPixels(tileGetTextureID(nTile)); uint8_t *pDest = &Worktile[212 * 49 + 53]; for (unsigned i = 0; i < kSpiritY; i++) @@ -200,7 +197,6 @@ void DoSpiritHead() auto pSpiritSpr = pSpiritSprite; sPlayerInput[0].actions |= SB_CENTERVIEW; - TileFiles.InvalidateTile(kTileRamsesWorkTile); switch (nHeadStage) { @@ -263,7 +259,7 @@ void DoSpiritHead() if (nMouthTile != 0) { int srctile = nMouthTile + 598; - auto src = tilePtr(srctile); + auto src = GetRawPixels(tileGetTextureID(srctile)); int sizx = tileWidth(srctile); int sizy = tileHeight(srctile); int workptr = 212 * (97 - sizx / 2) + 159 - sizy;