- adapted sky code for using texture IDs.

This commit is contained in:
Christoph Oelckers 2022-12-09 12:53:16 +01:00
parent 8dfbbc8220
commit e78fd90f67
12 changed files with 88 additions and 159 deletions

View file

@ -1118,71 +1118,6 @@ void parseEcho(FScanner& sc, FScriptPosition& pos)
//
//===========================================================================
void parseMultiPsky(FScanner& sc, FScriptPosition& pos)
{
// The maximum tile offset ever used in any tiled parallaxed multi-sky.
enum { PSKYOFF_MAX = 16 };
FScanner::SavedPos blockend;
SkyDefinition sky{};
bool crc;
sky.scale = 1.f;
sky.baselineofs = INT_MIN;
if (sc.CheckString("crc"))
{
if (!sc.GetNumber(sky.crc32, true)) return;
crc = true;
}
else
{
if (!sc.GetNumber(sky.tilenum, true)) return;
crc = false;
}
if (sc.StartBraces(&blockend)) return;
while (!sc.FoundEndBrace(blockend))
{
sc.MustGetString();
if (sc.Compare("horizfrac")) sc.GetNumber(true); // not used anymore
else if (sc.Compare("yoffset")) sc.GetNumber(sky.pmoffset, true);
else if (sc.Compare("baseline")) sc.GetNumber(sky.baselineofs, true);
else if (sc.Compare("lognumtiles")) sc.GetNumber(sky.lognumtiles, true);
else if (sc.Compare("yscale")) { int intscale; sc.GetNumber(intscale, true); sky.scale = intscale * (1.f / 65536.f); }
else if (sc.Compare({ "tile", "panel" }))
{
if (!sc.CheckString("}"))
{
int panel = 0, offset = 0;
sc.GetNumber(panel, true);
sc.GetNumber(offset, true);
if ((unsigned)panel < MAXPSKYTILES && (unsigned)offset <= PSKYOFF_MAX) sky.offsets[panel] = offset;
}
else
{
int panel = 0, offset;
while (!sc.CheckString("}"))
{
sc.GetNumber(offset, true);
if ((unsigned)panel < MAXPSKYTILES && (unsigned)offset <= PSKYOFF_MAX) sky.offsets[panel] = offset;
panel++;
}
}
}
}
if (sky.baselineofs == INT_MIN) sky.baselineofs = sky.pmoffset;
if (!crc && sky.tilenum != DEFAULTPSKY && (unsigned)sky.tilenum >= MAXUSERTILES) return;
if ((1 << sky.lognumtiles) > MAXPSKYTILES) return;
if (crc) addSkyCRC(sky, sky.crc32);
else addSky(sky, sky.tilenum);
}
//===========================================================================
//
//
//
//===========================================================================
void parseRffDefineId(FScanner& sc, FScriptPosition& pos)
{
FString resName;
@ -1974,7 +1909,7 @@ static const dispatch basetokens[] =
{ "globalflags", parseSkip<1> },
{ "copytile", parseCopyTile },
{ "globalgameflags", parseSkip<1> },
{ "multipsky", parseMultiPsky },
{ "multipsky", parseEmptyBlockWithParm },
{ "undefblendtablerange", parseSkip<2> },
{ "shadefactor", parseSkip<1> },
{ "newgamechoices", parseEmptyBlock },

View file

@ -37,61 +37,38 @@
#include "gamefuncs.h"
#include "tarray.h"
#include "texinfo.h"
#include "buildtiles.h"
#include "texturemanager.h"
static TArray<SkyDefinition> skies;
static SkyDefinition *FindSky(int tilenum)
static SkyDefinition *FindSky(FTextureID texid)
{
for (auto& sky : skies)
if (tilenum == sky.tilenum) return &sky;
if (texid == sky.texid) return &sky;
return nullptr;
}
static SkyDefinition *FindSkyCRC(int64_t crc)
void addSky(SkyDefinition& sky, FTextureID texid)
{
for (auto& sky : skies)
if (crc == sky.crc32) return &sky;
SkyDefinition* old = FindSky(texid);
return nullptr;
}
void addSky(SkyDefinition& sky, int tilenum)
{
SkyDefinition* old = FindSky(tilenum);
sky.tilenum = tilenum;
sky.crc32 = INT64_MAX;
sky.texid = texid;
if (sky.scale == 0) sky.scale = 1.f;
if (old) *old = sky;
else skies.Push(sky);
}
void addSkyCRC(SkyDefinition& sky, int64_t crc32)
{
SkyDefinition* old = FindSkyCRC(crc32);
sky.tilenum = -1;
sky.crc32 = crc32;
if (sky.scale == 0) sky.scale = 1.f;
if (old) *old = sky;
else skies.Push(sky);
}
SkyDefinition getSky(int tilenum)
SkyDefinition getSky(FTextureID texid)
{
SkyDefinition result;
auto sky = FindSky(tilenum);
auto sky = FindSky(texid);
if (sky) result = *sky;
else
{
// todo: handle CRC.
sky = FindSky(DEFAULTPSKY);
sky = FindSky(FNullTextureID());
if (sky)
result = *sky;
else
@ -99,33 +76,34 @@ SkyDefinition getSky(int tilenum)
result = {};
result.scale = 1.f;
}
int w = tileWidth(tilenum);
if (result.lognumtiles == 0 || w >= 256)
auto tex = TexMan.GetGameTexture(texid);
if (tex->isValid())
{
if (w < 512) result.lognumtiles = 2;
else if (w < 1024) result.lognumtiles = 1;
else result.lognumtiles = 0;
int w = (int)tex->GetDisplayWidth();
if (result.lognumtiles == 0 || w >= 256)
{
if (w < 512) result.lognumtiles = 2;
else if (w < 1024) result.lognumtiles = 1;
else result.lognumtiles = 0;
}
}
}
return result;
}
void defineSky(int tilenum, int lognumtiles, const int16_t *tileofs, int yoff, float yscale, int yoff2)
void defineSky(const char* tilename, int lognumtiles, const int16_t* tileofs, int yoff, float yscale, int yoff2)
{
FTextureID texid = FNullTextureID();
if (tilename)
{
texid = TexMan.CheckForTexture(tilename, ETextureType::Any);
if (!texid.isValid()) return;
}
SkyDefinition sky;
sky.baselineofs = yoff2 == 0x7fffffff ? yoff : yoff2;
sky.pmoffset = yoff;
sky.lognumtiles = lognumtiles;
sky.scale = yscale;
memset(sky.offsets, 0, sizeof(sky.offsets));
if (tileofs) memcpy(sky.offsets, tileofs, 2 << lognumtiles);
addSky(sky, tilenum);
}
void defineSky(const char* tilename, int lognumtiles, const int16_t* tileofs, int yoff, float yscale, int yoff2)
{
int tile = tileForName(tilename);
if (tile >= 0)
defineSky(tile, lognumtiles, tileofs, yoff, yscale, yoff2);
addSky(sky, texid);
}

View file

@ -1,29 +1,25 @@
#pragma once
#include <stdint.h>
#include "textureid.h"
enum
{
DEFAULTPSKY = -1,
MAXPSKYTILES = 16,
};
struct SkyDefinition
{
int64_t crc32; // CRC32 of the master tile
int tilenum;
FTextureID texid;
int baselineofs;
float scale;
int lognumtiles;
int16_t offsets[MAXPSKYTILES];
int pmoffset; // offset for Polymost, should go away.
};
void addSky(SkyDefinition& sky, int tilenum);
void addSkyCRC(SkyDefinition& sky, int64_t crc32);
void addSky(SkyDefinition& sky, FTextureID texid);
void SetSkyOverride(float scale, int bits);
SkyDefinition getSky(int tilenum);
void defineSky(int tilenum, int lognumtiles, const int16_t *tileofs, int yoff = 0, float yscale = 1.f, int yoff2 = 0x7fffffff);
SkyDefinition getSky(FTextureID texid);
//void defineSky(FTextureID texid, int lognumtiles, const int16_t *tileofs, int yoff = 0, float yscale = 1.f, int yoff2 = 0x7fffffff);
void defineSky(const char* tilename, int lognumtiles, const int16_t* tileofs, int yoff = 0, float yscale = 1.f, int yoff2 = 0x7fffffff);

View file

@ -34,8 +34,8 @@
#include "buildtiles.h"
CVAR(Bool,gl_noskyboxes, false, 0)
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t* tilemap, int remap);
FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum);
FGameTexture* GetSkyTexture(FTextureID texid, int lognumtiles, const int16_t* tilemap, int remap);
FGameTexture* SkyboxReplacement(FTextureID texid, int palnum);
//==========================================================================
//
@ -45,25 +45,25 @@ FGameTexture* SkyboxReplacement(FTextureID picnum, int palnum);
void initSkyInfo(HWDrawInfo *di, HWSkyInfo* sky, sectortype* sector, int plane)
{
int picnum = plane == legacyTileNum(plane_ceiling ? sector->ceilingtexture : sector->floortexture);
auto tex = tileGetTexture(picnum);
//tileUpdatePicnum(&picnum); // for now we can make do without this.
FTextureID otexid = plane == plane_ceiling ? sector->ceilingtexture : sector->floortexture;
auto tex = TexMan.GetGameTexture(otexid, true);
auto texid = tex->GetID(); // after animation
int palette = plane == plane_ceiling ? sector->ceilingpal : sector->floorpal;
FGameTexture* skytex = SkyboxReplacement(tex->GetID(), palette);
FGameTexture* skytex = SkyboxReplacement(texid, palette);
int realskybits = 0;
// todo: check for skybox replacement.
SkyDefinition skydef;
if (!skytex)
{
int remap = TRANSLATION(Translation_Remap + curbasepal, palette);
skydef = getSky(picnum);
int tw = tileWidth(picnum);
skydef = getSky(texid);
int tw = (int)tex->GetDisplayWidth();
skytex = GetSkyTexture(picnum, skydef.lognumtiles, skydef.offsets, remap);
skytex = GetSkyTexture(texid, skydef.lognumtiles, skydef.offsets, remap);
realskybits = skydef.lognumtiles;
if (skytex) skydef.lognumtiles = 0;
else skytex = tileGetTexture(picnum);
else skytex = tex;
}
else
{

View file

@ -42,7 +42,7 @@
#include "buildtiles.h"
#include "texinfo.h"
FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t *tilemap, int remap)
FGameTexture* GetSkyTexture(FTextureID baseid, int lognumtiles, const int16_t *tilemap, int remap)
{
FString synthname;
@ -54,26 +54,31 @@ FGameTexture* GetSkyTexture(int basetile, int lognumtiles, const int16_t *tilema
}
int numtiles = 1 << lognumtiles;
synthname.Format("Sky%04x%02x", basetile, remap);
synthname.Format("Sky%04x%02x", baseid.GetIndex(), remap);
for(int i = 0; i < numtiles; i++)
{
synthname += 'A' + tilemap[i];
};
auto tex = TexMan.FindGameTexture(synthname);
if (tex) return tex;
auto basetex = TexMan.GetGameTexture(baseid);
auto scalex = basetex->GetScaleX();
auto scaley = basetex->GetScaleY();
TArray<TexPartBuild> build(numtiles, true);
int tilewidth = tileWidth(basetile);
int tilewidth = basetex->GetTexelWidth();
for(int i = 0; i < numtiles; i++)
{
auto texture = tileGetTexture(basetile + tilemap[i]);
// Todo - allow named textures for the single patches
auto texture = TexMan.GameByIndex(baseid.GetIndex() + tilemap[i]);
if (!texture || !texture->isValid() || texture->GetTexture() == 0) return nullptr;
build[i].TexImage = static_cast<FImageTexture*>(texture->GetTexture());
build[i].OriginX = tilewidth * i;
build[i].Translation = GPalette.GetTranslation(GetTranslationType(remap), GetTranslationIndex(remap));
}
auto tt = MakeGameTexture(new FImageTexture(new FMultiPatchTexture(tilewidth*numtiles, tileHeight(basetile), build, false, false)), synthname, ETextureType::Override);
tt->SetUpscaleFlag(tileGetTexture(basetile)->GetUpscaleFlag(), true);
auto tt = MakeGameTexture(new FImageTexture(new FMultiPatchTexture(tilewidth*numtiles, basetex->GetTexelHeight(), build, false, false)), synthname, ETextureType::Override);
tt->SetScale(scalex, scaley);
tt->SetUpscaleFlag(basetex->GetUpscaleFlag(), true);
TexMan.AddGameTexture(tt, true);
return tt;
}

View file

@ -252,7 +252,7 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur
tpskyoff[i] = LittleShort(tpskyoff[i]);
}
defineSky(DEFAULTPSKY, mapHeader.pskybits, tpskyoff);
defineSky(nullptr, mapHeader.pskybits, tpskyoff);
for (unsigned i = 0; i < sector.Size(); i++)
{

View file

@ -226,7 +226,6 @@ static void genspriteremaps(void)
//---------------------------------------------------------------------------
//
// Define sky layouts.
// This one's easy - the other games are a total mess
//
//---------------------------------------------------------------------------
@ -240,39 +239,39 @@ static void setupbackdrop()
static const int16_t defoff4[8] = { 4, 5, 6, 7, 0, 1, 2, 3 };
static const int16_t defoff7[8] = { 7, 0, 1, 2, 3, 4, 5, 6 };
defineSky(DEFAULTPSKY, 3, nullptr);
defineSky(nullptr, 3, nullptr);
defineSky("CLOUDYOCEAN", 3, nullptr);
defineSky("MOONSKY12", 3, moonoff);
defineSky("BIGORBIT1", 3, orbitoff);
defineSky("LA", 3, laoff);
if (isWorldTour())
{
defineSky(5284, 3, defoff);
defineSky(5412, 3, defoff, 80);
defineSky(5420, 3, defoff, 80);
defineSky(5450, 3, defoff7, 80);
defineSky(5540, 3, defoff, 80);
defineSky(5548, 3, defoff, 80);
defineSky(5556, 3, defoff1, 80);
defineSky(5720, 3, defoff4, 80);
defineSky(5814, 3, defoff, 80);
defineSky("SPACESKY", 3, defoff);
defineSky("PARISSKY", 3, defoff, 80);
defineSky("LONDONSKY", 3, defoff, 80);
defineSky("MOSCOWSKY", 3, defoff7, 80);
defineSky("DESERTSKY", 3, defoff, 80);
defineSky("AMSTERDAMSKY", 3, defoff, 80);
defineSky("HOLLYWOODSKY", 3, defoff1, 80);
defineSky("FRISCOSKY", 3, defoff4, 80);
defineSky("ROMESKY", 3, defoff, 80);
}
if (isNam())
{
defineSky(212, 3, nullptr, 0, 1, 140);
defineSky(225, 3, nullptr, 0, 1, 140);
defineSky("NAMSKY1", 3, nullptr, 0, 1, 140);
defineSky("NAMSKY2", 3, nullptr, 0, 1, 140);
}
if (isWW2GI() && (g_gameType & GAMEFLAG_ADDON))
{
defineSky(1086, 3, nullptr, 0, 1, 140);
defineSky("PLATOONSKY", 3, nullptr, 0, 1, 140);
}
// this sky isn't actually placed wrong - it's just so poorly designed that it needs to be shifted down to hide its shortcomings as good as possible.
if (isDuke() && (g_gameType & GAMEFLAG_DUKEDC))
{
defineSky(3708, 3, nullptr, 0, 1, -40);
defineSky("DUKEDCSKY", 3, nullptr, 0, 1, -40);
}
}

View file

@ -935,3 +935,19 @@ x(BOSS5STAYPUT, 5311)
x(SERIOUSSAM, 5846)
x(VIEWSCR, 7) // hijacks CYCLER
// WT skies
x(SPACESKY, 5284)
x(PARISSKY, 5412)
x(LONDONSKY, 5420)
x(MOSCOWSKY, 5450)
x(DESERTSKY, 5540)
x(AMSTERDAMSKY, 5548)
x(HOLLYWOODSKY, 5556)
x(FRISCOSKY, 5720)
x(ROMESKY, 5814)
x(DUKEDCSKY, 3708)
x(NAMSKY1, 212)
x(NAMSKY2, 225)
x(PLATOONSKY, 1086)

View file

@ -583,7 +583,7 @@ void GameInterface::app_init()
nTotalPlayers += nNetPlayerCount;
}
defineSky(DEFAULTPSKY, 2, nullptr, 256, 1.f);
defineSky(nullptr, 2, nullptr, 256, 1.f);
InitFX();
seq_LoadSequences();

View file

@ -293,7 +293,7 @@ void GameInterface::app_init()
//Connect();
SortBreakInfo();
defineSky(DEFAULTPSKY, 1, nullptr);
defineSky(nullptr, 1, nullptr);
memset(Track, 0, sizeof(Track));
memset(Player, 0, sizeof(Player));

View file

@ -1159,7 +1159,7 @@ void GameInterface::SerializeGameState(FSerializer& arc)
int SavePlayClock = PlayClock;
InitTimingVars();
PlayClock = SavePlayClock;
defineSky(DEFAULTPSKY, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
defineSky(nullptr, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
InitNetVars();
screenpeek = myconnectindex;

View file

@ -1872,7 +1872,7 @@ void SpriteSetup(void)
pskybits_override = actor->spr.lotag;
if (SP_TAG4(actor) > 2048)
parallaxyscale_override = SP_TAG4(actor);
defineSky(DEFAULTPSKY, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
defineSky(nullptr, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
KillActor(actor);
break;
}