The two TArrays of type FTextureID skinIDs and surfaceskinIDs no longer have any null elements. These elements will have a textureid (FTextureID.texnum) of 0.

Re-worded error messages which were unprecise or unfitting before (model index below 0 was not acknowledged at all, or grouped together with a "too many models" message).

modelIDs are given a default value of -1.

Important: A MODELDEF's FrameIndex lines can no longer refer to model indices that are beyond the number of models of that MODELDEF entry. There is in fact a check to avoid going beyond the number of an actor's models which would abort program operation at startup, but it never caught any such occurances.

surfaceSkinIDs was two-dimensional and is now a one-dimensional TArray as well, elements are accessed via [Row + Column * NumRows], in this case surfaceIndex + modelIndex * MD3_MAX_SURFACES]
Used TArray.Alloc to make TArrays have the correct size depending on the number of models.

Also removed MAX_MODELS_PER_FRAME.
Edited skinSurfaceIDs access for one-dimensional TArray

Added MD3_MODELS_MIN
To ensure compatibility with mods, all model-related TArrays (four in total) have a minimum size of 4, defined by MD3_MODELS_MIN.
This commit is contained in:
Chernoskill 2021-02-09 14:48:43 +01:00 committed by Cherno
commit fa2058004b
6 changed files with 87 additions and 29 deletions

View file

@ -268,7 +268,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
}
}
for (int i = 0; i<MAX_MODELS_PER_FRAME; i++)
for (int i = 0; i < smf->modelsAmount; i++)
{
if (smf->modelIDs[i] != -1)
{
@ -317,8 +317,12 @@ void InitModels()
FSpriteModelFrame smf;
memset(&smf, 0, sizeof(smf));
smf.isVoxel = true;
smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
smf.modelsAmount = 1;
smf.modelframes.Alloc(1);
smf.modelframes[0] = -1;
smf.modelIDs.Alloc(1);
smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex;
smf.skinIDs.Alloc(1);
smf.skinIDs[0] = md->GetPaletteTexture();
smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale;
smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees;
@ -380,7 +384,6 @@ static void ParseModelDefLump(int Lump)
FSpriteModelFrame smf;
memset(&smf, 0, sizeof(smf));
smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1;
smf.xscale=smf.yscale=smf.zscale=1.f;
auto type = PClass::FindClass(sc.String);
@ -389,6 +392,47 @@ static void ParseModelDefLump(int Lump)
sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
}
smf.type = type;
FScanner::SavedPos scPos = sc.SavePos();
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("model"))
{
sc.MustGetNumber();
index = sc.Number;
if (index < 0)
{
sc.ScriptError("Model index must be 0 or greater in %s", type->TypeName.GetChars());
}
smf.modelsAmount = index + 1;
}
}
//Make sure modelsAmount is at least equal to MD3_MIN_MODELS(4) to ensure compatibility with old mods
if (smf.modelsAmount < MD3_MIN_MODELS)
{
smf.modelsAmount = MD3_MIN_MODELS;
}
//Allocate TArrays
smf.modelIDs.Alloc(smf.modelsAmount);
smf.skinIDs.Alloc(smf.modelsAmount);
smf.surfaceskinIDs.Alloc(smf.modelsAmount * MD3_MAX_SURFACES);
smf.modelframes.Alloc(smf.modelsAmount);
//Make sure all modelIDs are -1 by default
for (auto& modelID : smf.modelIDs)
{
modelID = -1;
}
//Make sure no TArray elements of type FTextureID are null. These elements will have a textureid (FTextureID.texnum) of 0.
for (auto& skinID : smf.skinIDs)
{
skinID = FTextureID(FNullTextureID());
}
for (auto& surfaceskinID : smf.surfaceskinIDs)
{
surfaceskinID = FTextureID(FNullTextureID());
}
sc.RestorePos(scPos);
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
@ -404,7 +448,11 @@ static void ParseModelDefLump(int Lump)
{
sc.MustGetNumber();
index = sc.Number;
if (index < 0 || index >= MAX_MODELS_PER_FRAME)
if (index < 0)
{
sc.ScriptError("Model index must be 0 or greater in %s", type->TypeName.GetChars());
}
else if (index >= smf.modelsAmount)
{
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
}
@ -529,7 +577,7 @@ static void ParseModelDefLump(int Lump)
{
sc.MustGetNumber();
index=sc.Number;
if (index<0 || index>=MAX_MODELS_PER_FRAME)
if (index<0 || index>= smf.modelsAmount)
{
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
}
@ -556,7 +604,7 @@ static void ParseModelDefLump(int Lump)
sc.MustGetNumber();
surface = sc.Number;
if (index<0 || index >= MAX_MODELS_PER_FRAME)
if (index<0 || index >= smf.modelsAmount)
{
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
}
@ -568,14 +616,15 @@ static void ParseModelDefLump(int Lump)
sc.MustGetString();
FixPathSeperator(sc.String);
int ssIndex = surface + index * MD3_MAX_SURFACES;
if (sc.Compare(""))
{
smf.surfaceskinIDs[index][surface] = FNullTextureID();
smf.surfaceskinIDs[ssIndex] = FNullTextureID();
}
else
{
smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String);
if (!smf.surfaceskinIDs[index][surface].isValid())
smf.surfaceskinIDs[ssIndex] = LoadSkin(path.GetChars(), sc.String);
if (!smf.surfaceskinIDs[ssIndex].isValid())
{
Printf("Surface Skin '%s' not found in '%s'\n",
sc.String, type->TypeName.GetChars());
@ -610,7 +659,7 @@ static void ParseModelDefLump(int Lump)
sc.MustGetNumber();
index=sc.Number;
if (index<0 || index>=MAX_MODELS_PER_FRAME)
if (index<0 || index>= smf.modelsAmount)
{
sc.ScriptError("Too many models in %s", type->TypeName.GetChars());
}