diff --git a/source/core/defparser.cpp b/source/core/defparser.cpp index 9b9e5bca4..262fc1176 100644 --- a/source/core/defparser.cpp +++ b/source/core/defparser.cpp @@ -83,6 +83,109 @@ void parseIncludeDefault(FScanner& sc, FScriptPosition& pos) performInclude(&sc, G_DefaultDefFile(), &pos); } +//=========================================================================== +// +// Helpers for tile parsing +// +//=========================================================================== + +bool ValidateTileRange(const char* cmd, int& begin, int& end, FScriptPosition pos, bool allowswap = true) +{ + if (end < begin) + { + pos.Message(MSG_WARNING, "%s: tile range [%d..%d] is backwards. Indices were swapped.", cmd, begin, end); + std::swap(begin, end); + } + + if ((unsigned)begin >= MAXUSERTILES || (unsigned)end >= MAXUSERTILES) + { + pos.Message(MSG_ERROR, "%s: Invalid tile range [%d..%d]", cmd, begin, end); + return false; + } + + return true; +} + +bool ValidateTilenum(const char* cmd, int tile, FScriptPosition pos) +{ + if ((unsigned)tile >= MAXUSERTILES) + { + pos.Message(MSG_ERROR, "%s: Invalid tile number %d", cmd, tile); + return false; + } + + return true; +} + +//=========================================================================== +// +// Internal worker for tileImportTexture +// +//=========================================================================== + +void processTileImport(const char* cmd, FScriptPosition& pos, TileImport& imp) +{ + if (!ValidateTilenum(cmd, imp.tile, pos)) + return; + + if (imp.crc32 != INT64_MAX && int(imp.crc32) != tileGetCRC32(imp.tile)) + return; + + if (imp.sizex != INT_MAX && tileWidth(imp.tile) != imp.sizex && tileHeight(imp.tile) != imp.sizey) + return; + + imp.alphacut = clamp(imp.alphacut, 0, 255); + + gi->SetTileProps(imp.tile, imp.surface, imp.vox, imp.shade); + + if (imp.fn.IsNotEmpty() && tileImportFromTexture(imp.fn, imp.tile, imp.alphacut, imp.istexture) < 0) return; + + TileFiles.tiledata[imp.tile].picanm.sf |= imp.flags; + // This is not quite the same as originally, for two reasons: + // 1: Since these are texture properties now, there's no need to clear them. + // 2: The original code assumed that an imported texture cannot have an offset. But this can import Doom patches and PNGs with grAb, so the situation is very different. + if (imp.xoffset == INT_MAX) imp.xoffset = tileLeftOffset(imp.tile); + else imp.xoffset = clamp(imp.xoffset, -128, 127); + if (imp.yoffset == INT_MAX) imp.yoffset = tileTopOffset(imp.tile); + else imp.yoffset = clamp(imp.yoffset, -128, 127); + + auto tex = tileGetTexture(imp.tile); + if (tex) + { + tex->SetOffsets(imp.xoffset, imp.yoffset); + if (imp.flags & PICANM_NOFULLBRIGHT_BIT) + { + tex->SetDisableBrightmap(); + } + } + if (imp.extra != INT_MAX) TileFiles.tiledata[imp.tile].picanm.extra = imp.extra; +} + +//=========================================================================== +// +// Internal worker for tileSetAnim +// +//=========================================================================== + +void processSetAnim(const char* cmd, FScriptPosition& pos, SetAnim& imp) +{ + if (!ValidateTilenum(cmd, imp.tile1, pos) || + !ValidateTilenum(cmd, imp.tile2, pos)) + return; + + if (imp.type < 0 || imp.type > 3) + { + pos.Message(MSG_ERROR, "%s: animation type must be 0-3, got %d", cmd, imp.type); + return; + } + + int count = imp.tile2 - imp.tile1; + if (imp.type == (PICANM_ANIMTYPE_BACK >> PICANM_ANIMTYPE_SHIFT) && imp.tile1 > imp.tile2) + count = -count; + + TileFiles.setAnim(imp.tile1, imp.type, imp.speed, count); +} + //=========================================================================== // // diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 773fec5e3..9b978c047 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -964,6 +964,7 @@ static void InitTextures() gi->LoadGameTextures(); // loads game-side data that must be present before processing the .def files. LoadDefinitions(); InitFont(); // InitFonts may only be called once all texture data has been initialized. + gi->SetupSpecialTextures(); // For installing dynamic or deleted textures in the texture manager. This must be done after parsing .def and before setting the aliases. TileFiles.SetAliases(); lookups.postLoadTables(); @@ -972,7 +973,6 @@ static void InitTextures() SetupFontSubstitution(); V_LoadTranslations(); // loading the translations must be delayed until the palettes have been fully set up. UpdateUpscaleMask(); - TileFiles.SetBackup(); } //========================================================================== diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index b22f74524..76786550f 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -72,6 +72,7 @@ struct GameInterface virtual bool GenerateSavePic() { return false; } virtual void app_init() = 0; virtual void LoadGameTextures() {} + virtual void SetupSpecialTextures() {} virtual void loadPalette(); virtual void clearlocalinputstate() {} virtual void UpdateScreenSize() {} diff --git a/source/core/mainloop.cpp b/source/core/mainloop.cpp index 419a2e20b..f511f4e5f 100644 --- a/source/core/mainloop.cpp +++ b/source/core/mainloop.cpp @@ -347,7 +347,6 @@ static void GameTicker() { default: case GS_STARTUP: - artClearMapArt(); gi->Startup(); break; diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index e49dc2cbd..bf3b7ad2a 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -533,8 +533,6 @@ void loadMap(const char* filename, int flags, DVector3* pos, int16_t* ang, secto } - artSetupMapArt(filename); - //Must be last. fixSectors(); *cursect = validSectorIndex(cursectnum) ? §or[cursectnum] : nullptr; diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index ddfc7e288..a1be4bbb5 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -142,7 +142,6 @@ void BuildTiles::Init() for (auto& tile : tiledata) { tile.texture = Placeholder; - tile.backup = Placeholder; tile.picanm = {}; tile.RotTile = { -1,-1 }; tile.replacement = ReplacementType::Art; @@ -157,12 +156,11 @@ void BuildTiles::Init() // //========================================================================== -void BuildTiles::AddTile(int tilenum, FGameTexture* tex, bool permap) +void BuildTiles::AddTile(int tilenum, FGameTexture* tex) { if (!tex->GetID().isValid()) TexMan.AddGameTexture(tex); tiledata[tilenum].texture = tex; - if (!permap) tiledata[tilenum].backup = tex; } //=========================================================================== @@ -207,7 +205,7 @@ void BuildTiles::AddTiles (int firsttile, TArray& RawData, const char * auto tex = GetTileTexture(texname, RawData, uint32_t(tiledata - tiles), width, height); AddTile(i, tex); int leftoffset, topoffset; - this->tiledata[i].picanmbackup = this->tiledata[i].picanm = tileConvertAnimFormat(anm, &leftoffset, &topoffset); + this->tiledata[i].picanm = tileConvertAnimFormat(anm, &leftoffset, &topoffset); tex->SetOffsets(leftoffset, topoffset); tiledata += size; @@ -372,9 +370,9 @@ void BuildTiles::SetAliases() FGameTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type) { + if (locked) I_FatalError("Modifying tiles after startup is not allowed."); if (tilenum < 0 || tilenum >= MAXTILES) return nullptr; auto &td = tiledata[tilenum]; - if (td.texture != td.backup) return nullptr; // no mucking around with map tiles. auto tile = td.texture; auto reptype = td.replacement; if (reptype == type) return tile; // already created @@ -391,11 +389,10 @@ FGameTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type) else if (type == ReplacementType::Restorable) { // This is for modifying an existing tile. - // It only gets used for the crosshair and a few specific effects: + // It only gets used for a few specific effects: // A) the fire in Blood. // B) the pin display in Redneck Rampage's bowling lanes. // C) Exhumed's menu plus one special effect tile. - // All of these effects should probably be redone without actual texture hacking... if (tile->GetTexelWidth() == 0 || tile->GetTexelHeight() == 0) return nullptr; // The base must have a size for this to work. // todo: invalidate hardware textures for tile. replacement = new FImageTexture(new FRestorableTile(tile->GetTexture()->GetImage())); @@ -437,6 +434,27 @@ int32_t BuildTiles::artLoadFiles(const char* filename) return 0; } +//========================================================================== +// +// Retrieves the pixel store for a modifiable tile +// Modifiable tiles must be declared on startup. +// +//========================================================================== + +uint8_t* BuildTiles::tileGet(int tilenum) +{ + if (tilenum < 0 || tilenum >= MAXTILES) return nullptr; + auto& td = tiledata[tilenum]; + auto tile = td.texture; + auto reptype = td.replacement; + if (reptype == ReplacementType::Writable || reptype == ReplacementType::Restorable) + { + auto wtex = static_cast(tile->GetTexture()->GetImage()); + if (wtex) return wtex->GetRawData(); + } + return nullptr; +} + //========================================================================== // // Creates a tile for displaying custom content @@ -537,7 +555,7 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu // create a new game texture here - we want to give it a different name! tex = MakeGameTexture(tex->GetTexture(), FStringf("#%05d", tilenum), ETextureType::Override); TexMan.AddGameTexture(tex); - TileFiles.tiledata[tilenum].backup = TileFiles.tiledata[tilenum].texture = tex; + TileFiles.tiledata[tilenum].texture = tex; if (istexture) tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0); return 0; @@ -597,73 +615,6 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags picanm->sf = (picanm->sf & ~PICANM_MISC_MASK) | (sourceanm->sf & PICANM_MISC_MASK) | flags; } -//========================================================================== -// -// Clear map specific ART -// -//========================================================================== -static FString currentMapArt; - -void artClearMapArt(void) -{ - for (auto& td : TileFiles.tiledata) - { - td.texture = td.backup; - td.picanm = td.picanmbackup; - } - currentMapArt = ""; -} - -//========================================================================== -// -// Load map specficied ART -// -//========================================================================== - -void artSetupMapArt(const char* filename) -{ - FString lcfilename = StripExtension(filename); - lcfilename.MakeLower(); - - if (currentMapArt.CompareNoCase(lcfilename) == 0) return; - artClearMapArt(); - currentMapArt = lcfilename; - - - // Re-get from the texture manager if this map's tiles have already been created. - if (TileFiles.maptilesadded.Find(lcfilename) < TileFiles.maptilesadded.Size()) - { - for (int i = 0; i < MAXTILES; i++) - { - FStringf name("maptile_%s_%05d", lcfilename.GetChars(), i); - auto texid = TexMan.CheckForTexture(name, ETextureType::Any); - if (texid.isValid()) - { - TileFiles.tiledata[i].texture = TexMan.GetGameTexture(texid); - } - } - return; - } - - TileFiles.maptilesadded.Push(lcfilename); - - - FStringf firstname("%s_00.art", lcfilename.GetChars()); - auto fr = fileSystem.OpenFileReader(firstname); - if (!fr.isOpen()) return; - for (auto& td : TileFiles.tiledata) - { - td.picanmbackup = td.picanm; - } - - - for (int i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++) - { - FStringf fullname("%s_%02d.art", lcfilename.GetChars(), i); - TileFiles.LoadArtFile(fullname, filename); - } -} - //========================================================================== // // @@ -672,7 +623,7 @@ void artSetupMapArt(const char* filename) void tileDelete(int tile) { - TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.GameByIndex(0); + TileFiles.tiledata[tile].texture = TexMan.GameByIndex(0); TileFiles.tiledata[tile].replacement = ReplacementType::Art; // whatever this was, now it isn't anymore. (SW tries to nuke camera textures with this, :( ) tiletovox[tile] = -1; // clear the link but don't clear the voxel. It may be in use for another tile. modelManager.UndefineTile(tile); @@ -749,8 +700,7 @@ int BuildTiles::tileCreateRotated(int tileNum) auto dtex = MakeGameTexture(new FImageTexture(new FLooseTile(dbuffer, tex->GetTexelHeight(), tex->GetTexelWidth())), "", ETextureType::Override); int index = findUnusedTile(); - bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup; - TileFiles.AddTile(index, dtex, mapart); + TileFiles.AddTile(index, dtex); return index; } @@ -846,30 +796,6 @@ int tileAnimateOfs(int tilenum, int randomize) return 0; } -//========================================================================== -// -// Check if two tiles are the same -// -//========================================================================== - -bool tileEqualTo(int me, int other) -{ - auto tile = tileGetTexture(me); - auto tile2 = tileGetTexture(other); - int tilew1 = tile->GetTexelWidth(); - int tileh1 = tile->GetTexelHeight(); - int tilew2 = tile2->GetTexelWidth(); - int tileh2 = tile2->GetTexelHeight(); - if (tilew1 == tilew2 && tileh1 == tileh2) - { - auto p1 = tileRawData(me); - auto p2 = tileRawData(other); - if (p1 && p2 && !memcmp(p1, p2, tilew1 * tileh2)) - return true; - } - return false; -} - //=========================================================================== // // Picks a texture for rendering for a given tilenum/palette combination @@ -909,136 +835,5 @@ FCanvasTexture* tileGetCanvas(int tilenum) return canvas; } - - -//=========================================================================== -// -// Parsing stuff for tile data comes below. -// -//=========================================================================== - -//=========================================================================== -// -// Helpers for tile parsing -// -//=========================================================================== - -bool ValidateTileRange(const char* cmd, int &begin, int& end, FScriptPosition pos, bool allowswap) -{ - if (end < begin) - { - pos.Message(MSG_WARNING, "%s: tile range [%d..%d] is backwards. Indices were swapped.", cmd, begin, end); - std::swap(begin, end); - } - - if ((unsigned)begin >= MAXUSERTILES || (unsigned)end >= MAXUSERTILES) - { - pos.Message(MSG_ERROR, "%s: Invalid tile range [%d..%d]", cmd, begin, end); - return false; - } - - return true; -} - -bool ValidateTilenum(const char* cmd, int tile, FScriptPosition pos) -{ - if ((unsigned)tile >= MAXUSERTILES) - { - pos.Message(MSG_ERROR, "%s: Invalid tile number %d", cmd, tile); - return false; - } - - return true; -} - -//=========================================================================== -// -// Internal worker for tileImportTexture -// -//=========================================================================== - -void processTileImport(const char *cmd, FScriptPosition& pos, TileImport& imp) -{ - if (!ValidateTilenum(cmd, imp.tile, pos)) - return; - - if (imp.crc32 != INT64_MAX && int(imp.crc32) != tileGetCRC32(imp.tile)) - return; - - if (imp.sizex != INT_MAX && tileWidth(imp.tile) != imp.sizex && tileHeight(imp.tile) != imp.sizey) - return; - - imp.alphacut = clamp(imp.alphacut, 0, 255); - - gi->SetTileProps(imp.tile, imp.surface, imp.vox, imp.shade); - - if (imp.fn.IsNotEmpty() && tileImportFromTexture(imp.fn, imp.tile, imp.alphacut, imp.istexture) < 0) return; - - TileFiles.tiledata[imp.tile].picanm.sf |= imp.flags; - // This is not quite the same as originally, for two reasons: - // 1: Since these are texture properties now, there's no need to clear them. - // 2: The original code assumed that an imported texture cannot have an offset. But this can import Doom patches and PNGs with grAb, so the situation is very different. - if (imp.xoffset == INT_MAX) imp.xoffset = tileLeftOffset(imp.tile); - else imp.xoffset = clamp(imp.xoffset, -128, 127); - if (imp.yoffset == INT_MAX) imp.yoffset = tileTopOffset(imp.tile); - else imp.yoffset = clamp(imp.yoffset, -128, 127); - - auto tex = tileGetTexture(imp.tile); - if (tex) - { - tex->SetOffsets(imp.xoffset, imp.yoffset); - if (imp.flags & PICANM_NOFULLBRIGHT_BIT) - { - tex->SetDisableBrightmap(); - } - } - if (imp.extra != INT_MAX) TileFiles.tiledata[imp.tile].picanm.extra = imp.extra; -} - -//=========================================================================== -// -// Internal worker for tileSetAnim -// -//=========================================================================== - -void processSetAnim(const char* cmd, FScriptPosition& pos, SetAnim& imp) -{ - if (!ValidateTilenum(cmd, imp.tile1, pos) || - !ValidateTilenum(cmd, imp.tile2, pos)) - return; - - if (imp.type < 0 || imp.type > 3) - { - pos.Message(MSG_ERROR, "%s: animation type must be 0-3, got %d", cmd, imp.type); - return; - } - - int count = imp.tile2 - imp.tile1; - if (imp.type == (PICANM_ANIMTYPE_BACK >> PICANM_ANIMTYPE_SHIFT) && imp.tile1 > imp.tile2) - count = -count; - - TileFiles.setAnim(imp.tile1, imp.type, imp.speed, count); -} - PicAnm picanm; -#if 0 // this only gets in if unavoidable. It'd be preferable if the script side can solely operate on texture names. -#include "vm.h" - -static int GetTexture(int tile, int anim) -{ - if (tile < 0 || tile >= MAXTILES) return 0; - auto tex = tileGetTexture(tile, anim); - return tex ? tex->GetID().GetIndex() : 0; -} - -DEFINE_ACTION_FUNCTION_NATIVE(_TileFiles, GetTexture, GetTexture) -{ - PARAM_PROLOGUE; - PARAM_INT(tile); - PARAM_BOOL(animate); - ACTION_RETURN_INT(GetTexture(tile, animate)); -} -#endif - - diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index 84e4842da..e73b0ddb8 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -276,10 +276,8 @@ struct TileOffs struct TileDesc { FGameTexture* texture; // the currently active tile - FGameTexture* backup; // original backup for map tiles RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time. picanm_t picanm; // animation descriptor - picanm_t picanmbackup; // animation descriptor backup when using map tiles rottile_t RotTile;// = { -1,-1 }; ReplacementType replacement; float alphaThreshold; @@ -308,12 +306,18 @@ struct BuildTiles TArray maptilesadded; TMap cameratextures; TMap nametoindex; + bool locked; // if this is true, no more tile modifications are allowed. void addName(const char* name, int index) { nametoindex.Insert(name, index); } + void lock() + { + locked = true; + } + int tileForName(const char* name) { FName nm(name, true); @@ -332,22 +336,13 @@ struct BuildTiles CloseAll(); } - void SetBackup() - { - for (auto& td : tiledata) - { - td.backup = td.texture; - td.picanmbackup = td.picanm; - } - } - void CloseAll(); - void AddTile(int tilenum, FGameTexture* tex, bool permap = false); + void AddTile(int tilenum, FGameTexture* tex); void AddTiles(int firsttile, TArray& store, const char* mapname); - void AddFile(BuildArtFile* bfd, bool permap) + void AddFile(BuildArtFile* bfd) { ArtFiles.Push(bfd); } @@ -374,6 +369,7 @@ struct BuildTiles int32_t artLoadFiles(const char* filename); uint8_t* tileMakeWritable(int num); uint8_t* tileCreate(int tilenum, int width, int height); + uint8_t* tileGet(int tilenum); int findUnusedTile(void); int tileCreateRotated(int owner); void InvalidateTile(int num); @@ -386,8 +382,6 @@ void tileCopy(int tile, int tempsource, int temppal, int xoffset, int yoffset, i void tileSetDummy(int tile, int width, int height); void tileDelete(int tile); bool tileLoad(int tileNum); -void artClearMapArt(void); -void artSetupMapArt(const char* filename); void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int tilenum2, int sx2, int sy2); extern BuildTiles TileFiles; @@ -422,14 +416,6 @@ inline uint8_t* tileData(int num) return p ? p->GetRawData() : nullptr; } -inline const uint8_t* tileRawData(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 { @@ -498,13 +484,8 @@ inline FGameTexture* tileGetTexture(int tile, bool animate = false) return TileFiles.tiledata[tile].texture; } -bool tileEqualTo(int me, int other); void tileUpdateAnimations(); -bool ValidateTileRange(const char* cmd, int& begin, int& end, FScriptPosition pos, bool allowswap = true); -bool ValidateTilenum(const char* cmd, int tile, FScriptPosition pos); - - struct TileImport { FString fn; @@ -520,14 +501,11 @@ struct TileImport }; -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); class FGameTexture; bool PickTexture(FGameTexture* tex, int paletteid, TexturePick& pick, bool wantindexed = false); FCanvasTexture* tileGetCanvas(int tilenum); diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index 81a156ffb..c5c9643a9 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -4889,14 +4889,6 @@ void MoveDude(DBloodActor* actor) playerCorrectInertia(pPlayer, oldpos); switch (nLink) { - case kMarkerLowStack: - if (pPlayer && pPlayer->nPlayer == gViewIndex) - gotpic.Set(actor->sector()->floorpicnum); - break; - case kMarkerUpStack: - if (pPlayer && pPlayer->nPlayer == gViewIndex) - gotpic.Set(actor->sector()->ceilingpicnum); - break; case kMarkerLowWater: case kMarkerLowGoo: actor->xspr.medium = kMediumNormal; diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index 594f7ba10..23bf7a935 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -143,6 +143,7 @@ struct GameInterface : public ::GameInterface void EnterPortal(DCoreActor* viewer, int type) override; void LeavePortal(DCoreActor* viewer, int type) override; void LoadGameTextures() override; + void SetupSpecialTextures() override; int GetCurrentSkill() override; bool IsQAVInterpTypeValid(const FString& type) override; void AddQAVInterpProps(const int res_id, const FString& interptype, const bool loopable, const TMap>&& ignoredata) override; diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 1d8df2475..18f1d88b4 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -267,9 +267,9 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur pSector->setzfrommap(LittleLong(load.ceilingz), LittleLong(load.floorz)); pSector->ceilingstat = ESectorFlags::FromInt(LittleShort(load.ceilingstat)); pSector->floorstat = ESectorFlags::FromInt(LittleShort(load.floorstat)); - pSector->ceilingpicnum = LittleShort(load.ceilingpicnum); + pSector->ceilingpicnum = LittleShort(load.ceilingpic); pSector->ceilingheinum = LittleShort(load.ceilingheinum); - pSector->floorpicnum = LittleShort(load.floorpicnum); + pSector->floorpicnum = LittleShort(load.floorpic); pSector->floorheinum = LittleShort(load.floorheinum); pSector->type = LittleShort(load.type); pSector->hitag = LittleShort(load.hitag); diff --git a/source/games/blood/src/fire.cpp b/source/games/blood/src/fire.cpp index 96dfb7a7f..4183e095b 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 = TileFiles.tileMakeWritable(2342); + auto pData = TileFiles.tileGet(2342); uint8_t* pSource = FrameBuffer; int x = fireSize; do diff --git a/source/games/blood/src/mapstructs.h b/source/games/blood/src/mapstructs.h index 6adaeebe3..d0b8bcdea 100644 --- a/source/games/blood/src/mapstructs.h +++ b/source/games/blood/src/mapstructs.h @@ -27,10 +27,10 @@ struct sectortypedisk int16_t wallptr, wallnum; int32_t ceilingz, floorz; uint16_t ceilingstat, floorstat; - int16_t ceilingpicnum, ceilingheinum; + int16_t ceilingpic, ceilingheinum; int8_t ceilingshade; uint8_t ceilingpal, ceilingxpanning, ceilingypanning; - int16_t floorpicnum, floorheinum; + int16_t floorpic, floorheinum; int8_t floorshade; uint8_t floorpal, floorxpanning, floorypanning; uint8_t visibility, fogpal; diff --git a/source/games/blood/src/mirrors.cpp b/source/games/blood/src/mirrors.cpp index 83733955d..be9ecea73 100644 --- a/source/games/blood/src/mirrors.cpp +++ b/source/games/blood/src/mirrors.cpp @@ -47,10 +47,6 @@ void InitMirrors(void) tileDelete(504); portalClear(); - for (int i = 0; i < 16; i++) - { - tileDelete(4080 + i); - } for (int i = (int)wall.Size() - 1; i >= 0; i--) { auto pWalli = &wall[i]; @@ -131,7 +127,6 @@ void InitMirrors(void) mirror[mirrorcnt].diff = link2->spr.pos - link->spr.pos; mirror[mirrorcnt].mynum = i; mirror[mirrorcnt].link = j; - secti->floorpicnum = 4080 + mirrorcnt; secti->portalflags = PORTAL_SECTOR_FLOOR; secti->portalnum = portalAdd(PORTAL_SECTOR_FLOOR, j, mirror[mirrorcnt].diff); mirrorcnt++; @@ -139,7 +134,6 @@ void InitMirrors(void) mirror[mirrorcnt].diff = link->spr.pos - link2->spr.pos; mirror[mirrorcnt].mynum = j; mirror[mirrorcnt].link = i; - sectj->ceilingpicnum = 4080 + mirrorcnt; sectj->portalflags = PORTAL_SECTOR_CEILING; sectj->portalnum = portalAdd(PORTAL_SECTOR_CEILING, i, mirror[mirrorcnt].diff); mirrorcnt++; diff --git a/source/games/blood/src/tile.cpp b/source/games/blood/src/tile.cpp index b1043727e..a98fd9382 100644 --- a/source/games/blood/src/tile.cpp +++ b/source/games/blood/src/tile.cpp @@ -34,14 +34,19 @@ BEGIN_BLD_NS int nTileFiles = 0; -int tileStart[256]; -int tileEnd[256]; -int hTileFile[256]; - uint8_t surfType[kMaxTiles]; int8_t tileShade[kMaxTiles]; short voxelIndex[kMaxTiles]; +struct TextureProps +{ + uint8_t surfType; + int8_t tileShade; + int16_t voxelIndex; +}; + +TArray tprops; + #define x(a, b) registerName(#a, b); static void SetTileNames() { @@ -92,6 +97,16 @@ void GameInterface::LoadGameTextures() SetTileNames(); } +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. +} + //--------------------------------------------------------------------------- // // diff --git a/source/games/blood/src/view.cpp b/source/games/blood/src/view.cpp index 3fb5958c4..58c91c5ba 100644 --- a/source/games/blood/src/view.cpp +++ b/source/games/blood/src/view.cpp @@ -155,7 +155,7 @@ void viewInit(void) lensTable[i] = LittleLong(lensTable[i]); } #endif - uint8_t* data = TileFiles.tileCreate(4077, kLensSize, kLensSize); + uint8_t* data = TileFiles.tileGet(4077); memset(data, TRANSPARENT_INDEX, kLensSize * kLensSize); for (int i = 0; i < 16; i++) @@ -544,10 +544,6 @@ void renderCrystalBall() } PLAYER* pOther = &gPlayer[i]; //othercameraclock = PlayClock + MulScale(4, (int)gInterpolate, 16);; - if (!tileData(4079)) - { - TileFiles.tileCreate(4079, 128, 128); - } //renderSetTarget(4079, 128, 128); renderSetAspect(65536, 78643); int vd8 = pOther->actor->spr.x; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index 31e6f71d9..0edffbf80 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -1203,8 +1203,6 @@ void exitlevel(MapRecord* nextlevel) // MP scoreboard ShowScoreboard(playerswhenstarted, [=](bool) { - // Clear potentially loaded per-map ART only after the bonus screens. - artClearMapArt(); gameaction = ga_level; ud.eog = false; if (endofgame) @@ -1227,8 +1225,6 @@ void exitlevel(MapRecord* nextlevel) // SP cutscene + summary ShowIntermission(currentLevel, nextlevel, &info, [=](bool) { - // Clear potentially loaded per-map ART only after the bonus screens. - artClearMapArt(); ud.eog = false; gameaction = endofgame? ga_startup : ga_nextlevel; });