mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 08:52:00 +00:00
- model command migrated
This commit is contained in:
parent
542e1b2ba7
commit
8c854441bc
2 changed files with 245 additions and 418 deletions
|
@ -142,14 +142,6 @@ enum scripttoken_t
|
|||
T_SURFACE, T_VIEW,
|
||||
};
|
||||
|
||||
static int32_t lastmodelid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
|
||||
|
||||
static const char *skyfaces[6] =
|
||||
{
|
||||
"front face", "right face", "back face",
|
||||
"left face", "top face", "bottom face"
|
||||
};
|
||||
|
||||
static int32_t defsparser(scriptfile *script);
|
||||
|
||||
static void defsparser_include(const char *fn, scriptfile *script, FScriptPosition *pos)
|
||||
|
@ -433,416 +425,7 @@ static int32_t defsparser(scriptfile *script)
|
|||
|
||||
// NEW (ENCOURAGED) DEFINITION SYNTAX
|
||||
case T_MODEL:
|
||||
{
|
||||
FScanner::SavedPos modelend;
|
||||
FString modelfn;
|
||||
double scale=1.0, mzadd=0.0, myoffset=0.0;
|
||||
int32_t shadeoffs=0, pal=0, flags=0;
|
||||
uint8_t usedframebitmap[(1024+7)>>3];
|
||||
|
||||
int32_t model_ok = 1;
|
||||
|
||||
static const tokenlist modeltokens[] =
|
||||
{
|
||||
{ "scale", T_SCALE },
|
||||
{ "shade", T_SHADE },
|
||||
{ "zadd", T_ZADD },
|
||||
{ "yoffset", T_YOFFSET },
|
||||
{ "frame", T_FRAME },
|
||||
{ "anim", T_ANIM },
|
||||
{ "skin", T_SKIN },
|
||||
{ "detail", T_DETAIL },
|
||||
{ "glow", T_GLOW },
|
||||
{ "specular", T_SPECULAR },
|
||||
{ "normal", T_NORMAL },
|
||||
{ "hud", T_HUD },
|
||||
{ "flags", T_FLAGS },
|
||||
};
|
||||
|
||||
memset(usedframebitmap, 0, sizeof(usedframebitmap));
|
||||
|
||||
modelskin = lastmodelskin = 0;
|
||||
seenframe = 0;
|
||||
|
||||
if (scriptfile_getstring(script,&modelfn)) break;
|
||||
if (scriptfile_getbraces(script,&modelend)) break;
|
||||
|
||||
lastmodelid = md_loadmodel(modelfn);
|
||||
if (lastmodelid < 0)
|
||||
{
|
||||
Printf("Warning: Failed loading MD2/MD3 model \"%s\"\n", modelfn.GetChars());
|
||||
scriptfile_setposition(script, modelend);
|
||||
break;
|
||||
}
|
||||
while (!scriptfile_endofblock(script, modelend))
|
||||
{
|
||||
int32_t token = getatoken(script,modeltokens,countof(modeltokens));
|
||||
switch (token)
|
||||
{
|
||||
//case T_ERROR: Printf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break;
|
||||
case T_SCALE:
|
||||
scriptfile_getdouble(script,&scale); break;
|
||||
case T_SHADE:
|
||||
scriptfile_getnumber(script,&shadeoffs); break;
|
||||
case T_ZADD:
|
||||
scriptfile_getdouble(script,&mzadd); break;
|
||||
case T_YOFFSET:
|
||||
scriptfile_getdouble(script,&myoffset); break;
|
||||
case T_FLAGS:
|
||||
scriptfile_getnumber(script,&flags); break;
|
||||
case T_FRAME:
|
||||
{
|
||||
auto framepos = scriptfile_getposition(script);
|
||||
FScanner::SavedPos frameend;
|
||||
FString framename;
|
||||
char happy=1;
|
||||
int32_t tilex = 0, framei;
|
||||
int32_t ftilenume = -1, ltilenume = -1;
|
||||
double smoothduration = 0.1f;
|
||||
|
||||
static const tokenlist modelframetokens[] =
|
||||
{
|
||||
{ "pal", T_PAL },
|
||||
{ "frame", T_FRAME },
|
||||
{ "name", T_FRAME },
|
||||
{ "tile", T_TILE },
|
||||
{ "tile0", T_TILE0 },
|
||||
{ "tile1", T_TILE1 },
|
||||
{ "smoothduration", T_SMOOTHDURATION },
|
||||
};
|
||||
|
||||
if (scriptfile_getbraces(script,&frameend)) break;
|
||||
while (!scriptfile_endofblock(script, frameend))
|
||||
{
|
||||
switch (getatoken(script,modelframetokens,countof(modelframetokens)))
|
||||
{
|
||||
case T_PAL:
|
||||
scriptfile_getsymbol(script,&pal); break;
|
||||
case T_FRAME:
|
||||
scriptfile_getstring(script,&framename); break;
|
||||
case T_TILE:
|
||||
scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
|
||||
case T_TILE0:
|
||||
scriptfile_getsymbol(script,&ftilenume); break; //first tile number
|
||||
case T_TILE1:
|
||||
scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive)
|
||||
case T_SMOOTHDURATION:
|
||||
scriptfile_getdouble(script,&smoothduration); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_tile_range("model: frame", &ftilenume, <ilenume, script, pos))
|
||||
{
|
||||
model_ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastmodelid < 0)
|
||||
{
|
||||
framepos.Message(MSG_WARNING, "ignoring frame definition");
|
||||
break;
|
||||
}
|
||||
|
||||
if (smoothduration > 1.0)
|
||||
{
|
||||
framepos.Message(MSG_WARNING, "smoothduration out of range");
|
||||
smoothduration = 1.0;
|
||||
}
|
||||
for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
|
||||
{
|
||||
framei = md_defineframe(lastmodelid, framename, tilex, max(0,modelskin), smoothduration,pal);
|
||||
switch (framei)
|
||||
{
|
||||
case -1:
|
||||
happy = 0; break; // invalid model id!?
|
||||
case -2:
|
||||
framepos.Message(MSG_WARNING, "Invalid tile number");
|
||||
happy = 0;
|
||||
break;
|
||||
case -3:
|
||||
framepos.Message(MSG_WARNING, "%s: Invalid frame name", framename.GetChars());
|
||||
happy = 0;
|
||||
break;
|
||||
default:
|
||||
if (framei >= 0 && framei<1024)
|
||||
usedframebitmap[framei>>3] |= (1 << (framei&7));
|
||||
}
|
||||
model_ok &= happy;
|
||||
}
|
||||
seenframe = 1;
|
||||
}
|
||||
break;
|
||||
case T_ANIM:
|
||||
{
|
||||
auto animpos = scriptfile_getposition(script);
|
||||
FScanner::SavedPos animend;
|
||||
FString startframe, endframe;
|
||||
int happy=1;
|
||||
int32_t flags = 0;
|
||||
double dfps = 1.0;
|
||||
|
||||
static const tokenlist modelanimtokens[] =
|
||||
{
|
||||
{ "frame0", T_FRAME0 },
|
||||
{ "frame1", T_FRAME1 },
|
||||
{ "fps", T_FPS },
|
||||
{ "flags", T_FLAGS },
|
||||
};
|
||||
|
||||
if (scriptfile_getbraces(script,&animend)) break;
|
||||
while (!scriptfile_endofblock(script, animend))
|
||||
{
|
||||
switch (getatoken(script,modelanimtokens,countof(modelanimtokens)))
|
||||
{
|
||||
case T_FRAME0:
|
||||
scriptfile_getstring(script,&startframe); break;
|
||||
case T_FRAME1:
|
||||
scriptfile_getstring(script,&endframe); break;
|
||||
case T_FPS:
|
||||
scriptfile_getdouble(script,&dfps); break; //animation frame rate
|
||||
case T_FLAGS:
|
||||
scriptfile_getsymbol(script,&flags); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startframe.IsEmpty()) animpos.Message(MSG_ERROR, "missing 'start frame' for anim definition"), happy = 0;
|
||||
if (endframe.IsEmpty()) animpos.Message(MSG_ERROR, "missing 'end frame' for anim definition"), happy = 0;
|
||||
model_ok &= happy;
|
||||
if (!happy) break;
|
||||
|
||||
if (lastmodelid < 0)
|
||||
{
|
||||
Printf("Warning: Ignoring animation definition.\n");
|
||||
break;
|
||||
}
|
||||
switch (md_defineanimation(lastmodelid, startframe, endframe, (int32_t)(dfps*(65536.0*.001)), flags))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
break; // invalid model id!?
|
||||
case -2:
|
||||
pos.Message(MSG_ERROR, "Invalid starting frame name");
|
||||
model_ok = 0;
|
||||
break;
|
||||
case -3:
|
||||
pos.Message(MSG_ERROR, "Invalid ending frame name");
|
||||
model_ok = 0;
|
||||
break;
|
||||
case -4:
|
||||
pos.Message(MSG_ERROR, "Out of memory");
|
||||
model_ok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case T_SKIN: case T_DETAIL: case T_GLOW: case T_SPECULAR: case T_NORMAL:
|
||||
{
|
||||
auto skinpos = scriptfile_getposition(script);
|
||||
FScanner::SavedPos skinend;
|
||||
FString skinfn;
|
||||
int32_t palnum = 0, surfnum = 0;
|
||||
double param = 1.0, specpower = 1.0, specfactor = 1.0;
|
||||
int32_t flags = 0;
|
||||
|
||||
static const tokenlist modelskintokens[] =
|
||||
{
|
||||
{ "pal", T_PAL },
|
||||
{ "file", T_FILE },
|
||||
{ "surf", T_SURF },
|
||||
{ "surface", T_SURF },
|
||||
{ "intensity", T_PARAM },
|
||||
{ "scale", T_PARAM },
|
||||
{ "detailscale", T_PARAM },
|
||||
{ "specpower", T_SPECPOWER }, { "specularpower", T_SPECPOWER }, { "parallaxscale", T_SPECPOWER },
|
||||
{ "specfactor", T_SPECFACTOR }, { "specularfactor", T_SPECFACTOR }, { "parallaxbias", T_SPECFACTOR },
|
||||
{ "nocompress", T_NOCOMPRESS },
|
||||
{ "nodownsize", T_NODOWNSIZE },
|
||||
{ "forcefilter", T_FORCEFILTER },
|
||||
{ "artquality", T_ARTQUALITY },
|
||||
};
|
||||
|
||||
if (scriptfile_getbraces(script,&skinend)) break;
|
||||
while (!scriptfile_endofblock(script, skinend))
|
||||
{
|
||||
switch (getatoken(script,modelskintokens,countof(modelskintokens)))
|
||||
{
|
||||
case T_PAL:
|
||||
scriptfile_getsymbol(script,&palnum); break;
|
||||
case T_PARAM:
|
||||
scriptfile_getdouble(script,¶m); break;
|
||||
case T_SPECPOWER:
|
||||
scriptfile_getdouble(script,&specpower); break;
|
||||
case T_SPECFACTOR:
|
||||
scriptfile_getdouble(script,&specfactor); break;
|
||||
case T_FILE:
|
||||
scriptfile_getstring(script,&skinfn); break; //skin filename
|
||||
case T_SURF:
|
||||
scriptfile_getnumber(script,&surfnum); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skinfn.IsEmpty())
|
||||
{
|
||||
skinpos.Message(MSG_ERROR, "missing 'skin filename' for skin definition");
|
||||
model_ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (seenframe) { modelskin = ++lastmodelskin; }
|
||||
seenframe = 0;
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case T_DETAIL:
|
||||
palnum = DETAILPAL;
|
||||
param = 1.0f / param;
|
||||
break;
|
||||
case T_GLOW:
|
||||
palnum = GLOWPAL;
|
||||
break;
|
||||
case T_SPECULAR:
|
||||
palnum = SPECULARPAL;
|
||||
break;
|
||||
case T_NORMAL:
|
||||
palnum = NORMALPAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fileSystem.FileExists(skinfn))
|
||||
break;
|
||||
|
||||
switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum, param, specpower, specfactor, flags))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
break; // invalid model id!?
|
||||
case -2:
|
||||
skinpos.Message(MSG_ERROR, "Invalid skin filename");
|
||||
model_ok = 0;
|
||||
break;
|
||||
case -3:
|
||||
skinpos.Message(MSG_ERROR, "Invalid palette number");
|
||||
model_ok = 0;
|
||||
break;
|
||||
case -4:
|
||||
skinpos.Message(MSG_ERROR, "Out of memory");
|
||||
model_ok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case T_HUD:
|
||||
{
|
||||
auto hudpos = scriptfile_getposition(script);
|
||||
FScanner::SavedPos frameend;
|
||||
char happy=1;
|
||||
int32_t tilex = 0;
|
||||
int32_t ftilenume = -1, ltilenume = -1, flags = 0, fov = -1, angadd = 0;
|
||||
double xadd = 0.0, yadd = 0.0, zadd = 0.0;
|
||||
|
||||
static const tokenlist modelhudtokens[] =
|
||||
{
|
||||
{ "tile", T_TILE },
|
||||
{ "tile0", T_TILE0 },
|
||||
{ "tile1", T_TILE1 },
|
||||
{ "xadd", T_XADD },
|
||||
{ "yadd", T_YADD },
|
||||
{ "zadd", T_ZADD },
|
||||
{ "angadd", T_ANGADD },
|
||||
{ "fov", T_FOV },
|
||||
{ "hide", T_HIDE },
|
||||
{ "nobob", T_NOBOB },
|
||||
{ "flipped",T_FLIPPED},
|
||||
{ "nodepth",T_NODEPTH},
|
||||
};
|
||||
|
||||
if (scriptfile_getbraces(script,&frameend)) break;
|
||||
while (!scriptfile_endofblock(script, frameend))
|
||||
{
|
||||
switch (getatoken(script,modelhudtokens,countof(modelhudtokens)))
|
||||
{
|
||||
case T_TILE:
|
||||
scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break;
|
||||
case T_TILE0:
|
||||
scriptfile_getsymbol(script,&ftilenume); break; //first tile number
|
||||
case T_TILE1:
|
||||
scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive)
|
||||
case T_XADD:
|
||||
scriptfile_getdouble(script,&xadd); break;
|
||||
case T_YADD:
|
||||
scriptfile_getdouble(script,&yadd); break;
|
||||
case T_ZADD:
|
||||
scriptfile_getdouble(script,&zadd); break;
|
||||
case T_ANGADD:
|
||||
scriptfile_getsymbol(script,&angadd); break;
|
||||
case T_FOV:
|
||||
scriptfile_getsymbol(script,&fov); break;
|
||||
case T_HIDE:
|
||||
flags |= HUDFLAG_HIDE; break;
|
||||
case T_NOBOB:
|
||||
flags |= HUDFLAG_NOBOB; break;
|
||||
case T_FLIPPED:
|
||||
flags |= HUDFLAG_FLIPPED; break;
|
||||
case T_NODEPTH:
|
||||
flags |= HUDFLAG_NODEPTH; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_tile_range("hud", &ftilenume, <ilenume, script, hudpos))
|
||||
{
|
||||
model_ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastmodelid < 0)
|
||||
{
|
||||
hudpos.Message(MSG_WARNING, "Ignoring frame definition.");
|
||||
break;
|
||||
}
|
||||
for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++)
|
||||
{
|
||||
vec3f_t const add = { (float)xadd, (float)yadd, (float)zadd };
|
||||
switch (md_definehud(lastmodelid, tilex, add, angadd, flags, fov))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
happy = 0; break; // invalid model id!?
|
||||
case -2:
|
||||
hudpos.Message(MSG_ERROR, "Invalid tile number");
|
||||
happy = 0;
|
||||
break;
|
||||
case -3:
|
||||
hudpos.Message(MSG_ERROR, "Invalid frame name");
|
||||
happy = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
model_ok &= happy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!model_ok)
|
||||
{
|
||||
if (lastmodelid >= 0)
|
||||
{
|
||||
pos.Message(MSG_ERROR, "Removing model %d due to errors.", lastmodelid);
|
||||
md_undefinemodel(lastmodelid);
|
||||
nextmodelid--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd,(float)myoffset,flags);
|
||||
modelskin = lastmodelskin = 0;
|
||||
seenframe = 0;
|
||||
|
||||
}
|
||||
parseModel(*script, pos);
|
||||
break;
|
||||
case T_VOXEL:
|
||||
parseVoxel(*script, pos);
|
||||
|
|
|
@ -1745,3 +1745,247 @@ void parseUndefModelOf(FScanner& sc, FScriptPosition& pos)
|
|||
if (!ValidateTilenum("undefmodelof", tile, pos)) return;
|
||||
pos.Message(MSG_WARNING, "undefmodelof: currently non-functional.");
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static bool parseModelFrameBlock(FScanner& sc, FixedBitArray<1024>& usedframes)
|
||||
{
|
||||
FScanner::SavedPos blockend;
|
||||
FScriptPosition pos = sc;
|
||||
|
||||
FString framename;
|
||||
bool ok = true;
|
||||
int pal = -1;
|
||||
int starttile = -1, endtile = -1;
|
||||
double smoothduration = 0.1f;
|
||||
|
||||
if (sc.StartBraces(&blockend)) return false;
|
||||
while (!sc.FoundEndBrace(blockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("pal")) sc.GetNumber(pal, true);
|
||||
else if (sc.Compare({ "name", "frame" })) sc.GetString(framename);
|
||||
else if (sc.Compare("tile")) { sc.GetNumber(starttile, true); endtile = starttile; }
|
||||
else if (sc.Compare("tile0")) sc.GetNumber(starttile, true);
|
||||
else if (sc.Compare("tile1")) sc.GetNumber(endtile, true);
|
||||
else if (sc.Compare("smoothduration")) sc.GetFloat(smoothduration, true);
|
||||
}
|
||||
|
||||
if (!ValidateTileRange("model: frame", starttile, endtile, pos)) return false;
|
||||
|
||||
if (smoothduration > 1.0)
|
||||
{
|
||||
pos.Message(MSG_WARNING, "smoothduration out of range");
|
||||
smoothduration = 1.0;
|
||||
}
|
||||
for (int i = starttile; i <= endtile && ok; i++)
|
||||
{
|
||||
int res = md_defineframe(mdglobal.lastmodelid, framename, i, max(0, mdglobal.modelskin), smoothduration, pal);
|
||||
if (res < 0)
|
||||
{
|
||||
ok = false;
|
||||
if (res == -2) pos.Message(MSG_WARNING, "Invalid tile number %d", i);
|
||||
else if (res == -3) pos.Message(MSG_WARNING, "%s: Invalid frame name", framename.GetChars());
|
||||
}
|
||||
else if (res < 1024) usedframes.Set(res);
|
||||
}
|
||||
mdglobal.seenframe = 1;
|
||||
return ok;
|
||||
}
|
||||
|
||||
static bool parseModelAnimBlock(FScanner& sc)
|
||||
{
|
||||
FScanner::SavedPos blockend;
|
||||
FScriptPosition pos = sc;
|
||||
|
||||
FString startframe, endframe;
|
||||
int flags = 0;
|
||||
double fps = 1.0;
|
||||
|
||||
if (sc.StartBraces(&blockend)) return false;
|
||||
while (!sc.FoundEndBrace(blockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("frame0")) sc.GetString(startframe);
|
||||
else if (sc.Compare("frame1")) sc.GetString(endframe);
|
||||
else if (sc.Compare("fps")) sc.GetFloat(fps, true);
|
||||
else if (sc.Compare("flags")) sc.GetNumber(flags, true);
|
||||
}
|
||||
|
||||
if (startframe.IsEmpty())
|
||||
{
|
||||
pos.Message(MSG_ERROR, "missing start frame for anim definition");
|
||||
return false;
|
||||
}
|
||||
if (endframe.IsEmpty())
|
||||
{
|
||||
pos.Message(MSG_ERROR, "missing end frame for anim definition");
|
||||
return false;
|
||||
}
|
||||
|
||||
int res = md_defineanimation(mdglobal.lastmodelid, startframe, endframe, (int)(fps * (65536.0 * .001)), flags);
|
||||
if (res < 0)
|
||||
{
|
||||
if (res == -2) pos.Message(MSG_ERROR, "Invalid starting frame name %s", startframe.GetChars());
|
||||
else if (res == -3) pos.Message(MSG_ERROR, "Invalid ending frame name %s", endframe.GetChars());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseModelSkinBlock(FScanner& sc, int whichpal)
|
||||
{
|
||||
FScanner::SavedPos blockend;
|
||||
FScriptPosition pos = sc;
|
||||
|
||||
FString filename;
|
||||
int pal = 0, surface = 0;
|
||||
double param = 1.0, specpower = 1.0, specfactor = 1.0;
|
||||
int flags = 0;
|
||||
|
||||
if (sc.StartBraces(&blockend)) return false;
|
||||
while (!sc.FoundEndBrace(blockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("pal")) sc.GetNumber(pal, true);
|
||||
else if (sc.Compare("file")) sc.GetString(filename);
|
||||
else if (sc.Compare({ "surface", "surf" })) sc.GetNumber(surface, true);
|
||||
else if (sc.Compare({ "intensity", "scale", "detailscale" })) sc.GetFloat(param, true);
|
||||
else if (sc.Compare({ "specpower", "specularpower", "parallaxscale" })) sc.GetFloat(specpower, true);
|
||||
else if (sc.Compare({ "specfactor", "specularfactor", "parallaxbias" })) sc.GetFloat(specfactor, true);
|
||||
else if (sc.Compare("forcefilter")) { /* not suppoted yet*/ }
|
||||
}
|
||||
|
||||
|
||||
if (filename.IsEmpty())
|
||||
{
|
||||
pos.Message(MSG_ERROR, "missing 'skin filename' for skin definition");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mdglobal.seenframe) mdglobal.modelskin = ++mdglobal.lastmodelskin;
|
||||
mdglobal.seenframe = 0;
|
||||
|
||||
if (!fileSystem.FileExists(filename))
|
||||
{
|
||||
pos.Message(MSG_ERROR, "%s: file not found", filename.GetChars());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (whichpal == DETAILPAL) param = 1. / param;
|
||||
int res = md_defineskin(mdglobal.lastmodelid, filename, pal, max(0, mdglobal.modelskin), surface, param, specpower, specfactor, flags);
|
||||
if (res < 0)
|
||||
{
|
||||
if (res == -2) pos.Message(MSG_ERROR, "Invalid skin filename %s", filename.GetChars());
|
||||
else if (res == -3) pos.Message(MSG_ERROR, "Invalid palette number %d", pal);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parseModelHudBlock(FScanner& sc)
|
||||
{
|
||||
FScanner::SavedPos blockend;
|
||||
FScriptPosition pos = sc;
|
||||
|
||||
int starttile = -1, endtile = -1, flags = 0, fov = -1, angadd = 0;
|
||||
DVector3 add{};
|
||||
|
||||
if (sc.StartBraces(&blockend)) return false;
|
||||
while (!sc.FoundEndBrace(blockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("tile")) { sc.GetNumber(starttile, true); endtile = starttile; }
|
||||
else if (sc.Compare("tile0")) sc.GetNumber(starttile, true);
|
||||
else if (sc.Compare("tile1")) sc.GetNumber(endtile, true);
|
||||
else if (sc.Compare("xadd")) sc.GetFloat(add.X, true);
|
||||
else if (sc.Compare("yadd")) sc.GetFloat(add.Y, true);
|
||||
else if (sc.Compare("zadd")) sc.GetFloat(add.Z, true);
|
||||
else if (sc.Compare("angadd")) sc.GetNumber(angadd, true);
|
||||
else if (sc.Compare("fov")) sc.GetNumber(fov, true);
|
||||
else if (sc.Compare("hide")) flags |= HUDFLAG_HIDE;
|
||||
else if (sc.Compare("nobob")) flags |= HUDFLAG_NOBOB;
|
||||
else if (sc.Compare("flipped")) flags |= HUDFLAG_FLIPPED;
|
||||
else if (sc.Compare("nodepth")) flags |= HUDFLAG_NODEPTH;
|
||||
}
|
||||
|
||||
if (!ValidateTileRange("hud", starttile, endtile, pos)) return false;
|
||||
|
||||
for (int i = starttile; i <= endtile; i++)
|
||||
{
|
||||
vec3f_t addf = { (float)add.X, (float)add.Y, (float)add.Z };
|
||||
int res = md_definehud(mdglobal.lastmodelid, i, addf, angadd, flags, fov);
|
||||
if (res < 0)
|
||||
{
|
||||
if (res == -2) pos.Message(MSG_ERROR, "Invalid tile number %d", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void parseModel(FScanner& sc, FScriptPosition& pos)
|
||||
{
|
||||
FScanner::SavedPos blockend;
|
||||
|
||||
FString modelfn;
|
||||
double scale = 1.0, mzadd = 0.0, myoffset = 0.0;
|
||||
int32_t shadeoffs = 0, pal = 0, flags = 0;
|
||||
FixedBitArray<1024> usedframes;
|
||||
|
||||
usedframes.Zero();
|
||||
mdglobal.modelskin = mdglobal.lastmodelskin = 0;
|
||||
mdglobal.seenframe = 0;
|
||||
|
||||
if (!sc.GetString(modelfn)) return;
|
||||
|
||||
if (sc.StartBraces(&blockend)) return;
|
||||
|
||||
mdglobal.lastmodelid = md_loadmodel(modelfn);
|
||||
if (mdglobal.lastmodelid < 0)
|
||||
{
|
||||
pos.Message(MSG_WARNING, "Unable to load model file \"%s\"\n", modelfn.GetChars());
|
||||
sc.RestorePos(blockend);
|
||||
sc.CheckString("}");
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
while (!sc.FoundEndBrace(blockend))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("scale")) sc.GetFloat(scale, true);
|
||||
else if (sc.Compare("shade")) sc.GetNumber(shadeoffs, true);
|
||||
else if (sc.Compare("zadd")) sc.GetFloat(mzadd, true);
|
||||
else if (sc.Compare("yoffset")) sc.GetFloat(myoffset, true);
|
||||
else if (sc.Compare("frame")) ok &= parseModelFrameBlock(sc, usedframes);
|
||||
else if (sc.Compare("anim")) ok &= parseModelAnimBlock(sc);
|
||||
else if (sc.Compare("skin")) ok &= parseModelSkinBlock(sc, 0);
|
||||
else if (sc.Compare("detail")) ok &= parseModelSkinBlock(sc, DETAILPAL);
|
||||
else if (sc.Compare("glow")) ok &= parseModelSkinBlock(sc, GLOWPAL);
|
||||
else if (sc.Compare("specular")) ok &= parseModelSkinBlock(sc, SPECULARPAL);
|
||||
else if (sc.Compare("normal")) ok &= parseModelSkinBlock(sc, NORMALPAL);
|
||||
else if (sc.Compare("hud")) ok &= parseModelHudBlock(sc);
|
||||
else if (sc.Compare("flags")) sc.GetNumber(flags, true);
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
if (mdglobal.lastmodelid >= 0)
|
||||
{
|
||||
pos.Message(MSG_ERROR, "Removing model %d due to errors.", mdglobal.lastmodelid);
|
||||
md_undefinemodel(mdglobal.lastmodelid);
|
||||
nextmodelid--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
md_setmisc(mdglobal.lastmodelid, (float)scale, shadeoffs, (float)mzadd, (float)myoffset, flags);
|
||||
mdglobal.modelskin = mdglobal.lastmodelskin = 0;
|
||||
mdglobal.seenframe = 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue