mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-09 01:01:07 +00:00
Sythesize extension fields for mods that don't define them. This allows scale+colormod to be used, even for classic.
This commit is contained in:
parent
2735d0f960
commit
343ee56c1d
1 changed files with 86 additions and 11 deletions
|
@ -1136,6 +1136,8 @@ void PR_ClearProgs(qcvm_t *vm)
|
|||
if (qcvm->knownstrings)
|
||||
Z_Free ((void *)qcvm->knownstrings);
|
||||
free(qcvm->edicts); // ericw -- sv.edicts switched to use malloc()
|
||||
if (qcvm->fielddefs != (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_fielddefs))
|
||||
free(qcvm->fielddefs);
|
||||
free(qcvm->progs); // spike -- pr_progs switched to use malloc (so menuqc doesn't end up stuck on the early hunk nor wiped on every map change)
|
||||
memset(qcvm, 0, sizeof(*qcvm));
|
||||
|
||||
|
@ -1143,6 +1145,88 @@ void PR_ClearProgs(qcvm_t *vm)
|
|||
PR_SwitchQCVM(oldvm);
|
||||
}
|
||||
|
||||
//makes sure extension fields are actually registered so they can be used for mappers without qc changes. eg so scale can be used.
|
||||
static void PR_MergeEngineFieldDefs (void)
|
||||
{
|
||||
struct {
|
||||
const char *fname;
|
||||
etype_t type;
|
||||
int newidx;
|
||||
} extrafields[] =
|
||||
{ //table of engine fields to add. we'll be using ED_FindFieldOffset for these later.
|
||||
//this is useful for fields that should be defined for mappers which are not defined by the mod.
|
||||
//future note: mutators will need to edit the mutator's globaldefs table too. remember to handle vectors and their 3 globals too.
|
||||
{"alpha", ev_float}, //just because we can (though its already handled in a weird hacky way)
|
||||
{"scale", ev_float}, //hurrah for being able to rescale entities.
|
||||
{"emiteffectnum", ev_float}, //constantly emitting particles, even without moving.
|
||||
{"traileffectnum", ev_float}, //custom effect for trails
|
||||
//{"glow_size", ev_float}, //deprecated particle trail rubbish
|
||||
//{"glow_color", ev_float}, //deprecated particle trail rubbish
|
||||
{"tag_entity", ev_float}, //for setattachment to not bug out when omitted.
|
||||
{"tag_index", ev_float}, //for setattachment to not bug out when omitted.
|
||||
{"modelflags", ev_float}, //deprecated rubbish to fill the high 8 bits of effects.
|
||||
//{"vw_index", ev_float}, //modelindex2
|
||||
//{"pflags", ev_float}, //for rtlights
|
||||
//{"drawflags", ev_float}, //hexen2 compat
|
||||
//{"abslight", ev_float}, //hexen2 compat
|
||||
{"colormod", ev_vector}, //lighting tints
|
||||
//{"glowmod", ev_vector}, //fullbright tints
|
||||
//{"fatness", ev_float}, //bloated rendering...
|
||||
//{"gravitydir", ev_vector}, //says which direction gravity should act for this ent...
|
||||
|
||||
};
|
||||
int maxofs = qcvm->progs->entityfields;
|
||||
int maxdefs = qcvm->progs->numfielddefs;
|
||||
unsigned int j, a;
|
||||
|
||||
//figure out where stuff goes
|
||||
for (j = 0; j < countof(extrafields); j++)
|
||||
{
|
||||
extrafields[j].newidx = ED_FindFieldOffset(extrafields[j].fname);
|
||||
if (extrafields[j].newidx < 0)
|
||||
{
|
||||
extrafields[j].newidx = maxofs;
|
||||
maxdefs++;
|
||||
if (extrafields[j].type == ev_vector)
|
||||
maxdefs+=3;
|
||||
maxofs+=type_size[extrafields[j].type];
|
||||
}
|
||||
}
|
||||
|
||||
if (maxdefs != qcvm->progs->numfielddefs)
|
||||
{ //we now know how many entries we need to add...
|
||||
ddef_t *olddefs = qcvm->fielddefs;
|
||||
qcvm->fielddefs = malloc(maxdefs * sizeof(*qcvm->fielddefs));
|
||||
memcpy(qcvm->fielddefs, olddefs, qcvm->progs->numfielddefs*sizeof(*qcvm->fielddefs));
|
||||
if (olddefs != (ddef_t *)((byte *)qcvm->progs + qcvm->progs->ofs_fielddefs))
|
||||
free(olddefs);
|
||||
|
||||
//allocate the extra defs
|
||||
for (j = 0; j < countof(extrafields); j++)
|
||||
{
|
||||
if (extrafields[j].newidx >= qcvm->progs->entityfields && extrafields[j].newidx < maxofs)
|
||||
{ //looks like its new. make sure ED_FindField can find it.
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].ofs = extrafields[j].newidx;
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].type = extrafields[j].type;
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].s_name = ED_NewString(extrafields[j].fname);
|
||||
qcvm->progs->numfielddefs++;
|
||||
|
||||
if (extrafields[j].type == ev_vector)
|
||||
{ //vectors are weird and annoying.
|
||||
for (a = 0; a < 3; a++)
|
||||
{
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].ofs = extrafields[j].newidx+a;
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].type = ev_float;
|
||||
qcvm->fielddefs[qcvm->progs->numfielddefs].s_name = ED_NewString(va("%s_%c", extrafields[j].fname, 'x'+a));
|
||||
qcvm->progs->numfielddefs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
qcvm->progs->entityfields = maxofs;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PR_LoadProgs
|
||||
|
@ -1151,7 +1235,6 @@ PR_LoadProgs
|
|||
qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcrc, builtin_t *builtins, size_t numbuiltins)
|
||||
{
|
||||
int i;
|
||||
unsigned int u;
|
||||
|
||||
PR_ClearProgs(qcvm); //just in case.
|
||||
|
||||
|
@ -1259,9 +1342,6 @@ qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcr
|
|||
qcvm->globaldefs[i].s_name = LittleLong (qcvm->globaldefs[i].s_name);
|
||||
}
|
||||
|
||||
for (u = 0; u < sizeof(qcvm->extfields)/sizeof(int); u++)
|
||||
((int*)&qcvm->extfields)[u] = -1;
|
||||
|
||||
for (i = 0; i < qcvm->progs->numfielddefs; i++)
|
||||
{
|
||||
qcvm->fielddefs[i].type = LittleShort (qcvm->fielddefs[i].type);
|
||||
|
@ -1278,6 +1358,7 @@ qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcr
|
|||
qcvm->numbuiltins = numbuiltins;
|
||||
|
||||
//spike: detect extended fields from progs
|
||||
PR_MergeEngineFieldDefs();
|
||||
#define QCEXTFIELD(n,t) qcvm->extfields.n = ED_FindFieldOffset(#n);
|
||||
QCEXTFIELDS_ALL
|
||||
QCEXTFIELDS_GAME
|
||||
|
@ -1286,13 +1367,7 @@ qboolean PR_LoadProgs (const char *filename, qboolean fatal, unsigned int needcr
|
|||
QCEXTFIELDS_SS
|
||||
#undef QCEXTFIELD
|
||||
|
||||
i = qcvm->progs->entityfields;
|
||||
if (qcvm->extfields.emiteffectnum < 0)
|
||||
qcvm->extfields.emiteffectnum = i++;
|
||||
if (qcvm->extfields.traileffectnum < 0)
|
||||
qcvm->extfields.traileffectnum = i++;
|
||||
|
||||
qcvm->edict_size = i * 4 + sizeof(edict_t) - sizeof(entvars_t);
|
||||
qcvm->edict_size = qcvm->progs->entityfields * 4 + sizeof(edict_t) - sizeof(entvars_t);
|
||||
// round off to next highest whole word address (esp for Alpha)
|
||||
// this ensures that pointers in the engine data area are always
|
||||
// properly aligned
|
||||
|
|
Loading…
Reference in a new issue