- Changed parameter storage for states to use a separate member variable

instead of forcing it into misc1/misc2. Although this increases the EXE's
  size by 30k it has several advantages:
  * State parameters are no longer limited to 65535 for all states combined.
  * State parameters can be used with long durations.
  * Some special handling in the weapon state set functions can be removed.


SVN r364 (trunk)
This commit is contained in:
Christoph Oelckers 2006-10-29 11:01:00 +00:00
parent b178bb2612
commit 88ca8e630c
5 changed files with 64 additions and 104 deletions

View file

@ -1,3 +1,11 @@
October 28, 2006 (Changes by Graf Zahl)
- Changed parameter storage for states to use a separate member variable
instead of forcing it into misc1/misc2. Although this increases the EXE's
size by 30k it has several advantages:
* State parameters are no longer limited to 65535 for all states combined.
* State parameters can be used with long durations.
* Some special handling in the weapon state set functions can be removed.
October 26, 2006 October 26, 2006
- Removed A_JumpSet and merged its functionality with A_Jump by turning - Removed A_JumpSet and merged its functionality with A_Jump by turning
A_Jump into a varargs function. A_Jump into a varargs function.

View file

@ -78,7 +78,6 @@
#include "doomdef.h" #include "doomdef.h"
#include "name.h" #include "name.h"
const BYTE SF_STATEPARAM = 0x20;
const BYTE SF_FULLBRIGHT = 0x40; const BYTE SF_FULLBRIGHT = 0x40;
const BYTE SF_BIGTIC = 0x80; const BYTE SF_BIGTIC = 0x80;
@ -105,10 +104,11 @@ struct FState
BYTE Frame; BYTE Frame;
actionf_p Action; actionf_p Action;
FState *NextState; FState *NextState;
int ParameterIndex;
inline int GetFrame() const inline int GetFrame() const
{ {
return Frame & ~(SF_FULLBRIGHT|SF_BIGTIC|SF_STATEPARAM); return Frame & ~(SF_FULLBRIGHT|SF_BIGTIC);
} }
inline int GetFullbright() const inline int GetFullbright() const
{ {
@ -138,17 +138,6 @@ struct FState
{ {
return Misc2; return Misc2;
} }
inline int GetMisc1_2() const
{
return ((*(DWORD *)&Tics) >> 8) & 0xFFFF;
}
inline void SetMisc1_2 (WORD val)
{
DWORD x = *(DWORD *)&Tics;
x &= 0xFF0000FF;
x |= (DWORD)val << 8;
*(DWORD *)&Tics = x;
}
inline FState *GetNextState() const inline FState *GetNextState() const
{ {
return NextState; return NextState;

View file

@ -91,33 +91,15 @@ void P_SetPsprite (player_t *player, int position, FState *state)
else else
psp->tics = state->GetTics(); // could be 0 psp->tics = state->GetTics(); // could be 0
if (!(state->Frame & SF_STATEPARAM)) if (state->GetMisc1())
{ { // Set coordinates.
if (state->GetMisc1()) psp->sx = state->GetMisc1()<<FRACBITS;
{ // Set coordinates.
psp->sx = state->GetMisc1()<<FRACBITS;
}
if (state->GetMisc2())
{
psp->sy = state->GetMisc2()<<FRACBITS;
}
} }
else // for parameterized action functions this must be done differently! if (state->GetMisc2())
{ {
unsigned int index = state->GetMisc1_2(); psp->sy = state->GetMisc2()<<FRACBITS;
}
if (index > 0 && index < StateParameters.Size() - 2)
{
if (StateParameters[index])
{ // Set coordinates.
psp->sx = (fixed_t)StateParameters[index] << FRACBITS;
}
if (StateParameters[index+1])
{
psp->sy = (fixed_t)StateParameters[index+1] << FRACBITS;
}
}
}
if (state->GetAction()) if (state->GetAction())
{ {
// The parameterized action functions need access to the current state and // The parameterized action functions need access to the current state and
@ -163,31 +145,13 @@ void P_SetPspriteNF (player_t *player, int position, FState *state)
psp->state = state; psp->state = state;
psp->tics = state->GetTics(); // could be 0 psp->tics = state->GetTics(); // could be 0
if (!(state->Frame & SF_STATEPARAM)) if (state->GetMisc1())
{ { // Set coordinates.
if (state->GetMisc1()) psp->sx = state->GetMisc1()<<FRACBITS;
{ // Set coordinates.
psp->sx = state->GetMisc1()<<FRACBITS;
}
if (state->GetMisc2())
{
psp->sy = state->GetMisc2()<<FRACBITS;
}
} }
else // for parameterized action functions this must be done differently! if (state->GetMisc2())
{ {
unsigned int index = state->GetMisc1_2(); psp->sy = state->GetMisc2()<<FRACBITS;
if (index > 0 && index < StateParameters.Size()-2)
{
if (StateParameters[index])
{ // Set coordinates.
psp->sx = (fixed_t)StateParameters[index] << FRACBITS;
}
if (StateParameters[index+1])
{
psp->sy = (fixed_t)StateParameters[index+1] << FRACBITS;
}
}
} }
state = psp->state->GetNextState(); state = psp->state->GetNextState();
} while (!psp->tics); // An initial state of 0 could cycle through. } while (!psp->tics); // An initial state of 0 could cycle through.

View file

@ -1300,21 +1300,10 @@ int PrepareStateParameters(FState * state, int numparams)
int paramindex=StateParameters.Size(); int paramindex=StateParameters.Size();
int i, v; int i, v;
if (state->Frame&SF_BIGTIC)
{
SC_ScriptError("You cannot use a parameterized code pointer with a state duration larger than 254!");
}
v=state->Misc1;
StateParameters.Push(v);
v=state->Misc2;
StateParameters.Push(v);
v=0; v=0;
for(i=0;i<numparams;i++) StateParameters.Push(v); for(i=0;i<numparams;i++) StateParameters.Push(v);
state->SetMisc1_2(paramindex); state->ParameterIndex = paramindex+1;
state->Frame|=SF_STATEPARAM; return paramindex;
return paramindex+2; // return the index of the first actual state parameter
} }
//========================================================================== //==========================================================================
@ -1452,13 +1441,30 @@ static void RetargetStates (intptr_t count, const char *target, const PClass *cl
} }
} }
//==========================================================================
//
// Reads a state label that may contain '.'s.
// processes a state block
//
//==========================================================================
static void ParseStateString(char * statestring)
{
SC_MustGetString();
strncpy (statestring, sc_String, 255);
while (SC_CheckString ("."))
{
SC_MustGetString ();
strcat (statestring, ".");
strcat (statestring, sc_String);
}
}
//========================================================================== //==========================================================================
// //
// ProcessStates // ProcessStates
// processes a state block // processes a state block
// //
//========================================================================== //==========================================================================
static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
{ {
char statestring[256]; char statestring[256];
@ -1472,20 +1478,15 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
statestring[255] = 0; statestring[255] = 0;
ChkBraceOpn(); ChkBraceOpn();
SC_SetEscape(false); // disable escape sequences in the state parser
while (!TestBraceCls() && !sc_End) while (!TestBraceCls() && !sc_End)
{ {
memset(&state,0,sizeof(state)); memset(&state,0,sizeof(state));
SC_MustGetString(); ParseStateString(statestring);
if (SC_Compare("GOTO")) if (!stricmp(statestring, "GOTO"))
{ {
do_goto: SC_MustGetString(); do_goto:
strncpy (statestring, sc_String, 255); ParseStateString(statestring);
if (SC_CheckString ("."))
{
SC_MustGetString ();
strcat (statestring, ".");
strcat (statestring, sc_String);
}
if (SC_CheckString ("+")) if (SC_CheckString ("+"))
{ {
SC_MustGetNumber (); SC_MustGetNumber ();
@ -1506,7 +1507,7 @@ do_goto: SC_MustGetString();
SC_ScriptError("GOTO before first state"); SC_ScriptError("GOTO before first state");
} }
} }
else if (SC_Compare("STOP")) else if (!stricmp(statestring, "STOP"))
{ {
do_stop: do_stop:
if (laststate!=NULL) if (laststate!=NULL)
@ -1523,7 +1524,7 @@ do_stop:
continue; continue;
} }
} }
else if (SC_Compare("WAIT") || SC_Compare("FAIL")) else if (!stricmp(statestring, "WAIT") || !stricmp(statestring, "FAIL"))
{ {
if (!laststate) if (!laststate)
{ {
@ -1532,7 +1533,7 @@ do_stop:
} }
laststate->NextState=(FState*)-2; laststate->NextState=(FState*)-2;
} }
else if (SC_Compare("LOOP")) else if (!stricmp(statestring, "LOOP"))
{ {
if (!laststate) if (!laststate)
{ {
@ -1545,11 +1546,7 @@ do_stop:
{ {
char * statestrp; char * statestrp;
strncpy(statestring, sc_String, 255); SC_MustGetString();
SC_SetEscape(false);
SC_MustGetString(); // this can read the frame string so escape characters have to be disabled
SC_SetEscape(true);
if (SC_Compare (":")) if (SC_Compare (":"))
{ {
laststate = NULL; laststate = NULL;
@ -1560,16 +1557,16 @@ do_stop:
if (stp) *stp=(FState *) (count+1); if (stp) *stp=(FState *) (count+1);
else else
SC_ScriptError("Unknown state label %s", statestring); SC_ScriptError("Unknown state label %s", statestring);
SC_MustGetString ();
if (SC_Compare ("Goto")) ParseStateString(statestring);
if (!stricmp(statestring, "GOTO"))
{ {
goto do_goto; goto do_goto;
} }
else if (SC_Compare("Stop")) else if (!stricmp(statestring, "STOP"))
{ {
goto do_stop; goto do_stop;
} }
strncpy(statestring, sc_String, 255);
SC_MustGetString (); SC_MustGetString ();
} while (SC_Compare (":")); } while (SC_Compare (":"));
// continue; // continue;
@ -1584,9 +1581,8 @@ do_stop:
memcpy(state.sprite.name, statestring, 4); memcpy(state.sprite.name, statestring, 4);
state.Misc1=state.Misc2=0; state.Misc1=state.Misc2=0;
SC_SetEscape(false); state.ParameterIndex=0;
SC_MustGetString(); // This reads the frame string so escape characters have to be disabled SC_MustGetString();
SC_SetEscape(true);
strncpy(statestring, sc_String + 1, 255); strncpy(statestring, sc_String + 1, 255);
statestrp = statestring; statestrp = statestring;
state.Frame=(*sc_String&223)-'A'; state.Frame=(*sc_String&223)-'A';
@ -1716,7 +1712,9 @@ do_stop:
case 'm': // Actor name case 'm': // Actor name
case 'T': case 'T':
case 't': // String case 't': // String
SC_SetEscape(true);
SC_MustGetString(); SC_MustGetString();
SC_SetEscape(false);
v = (int)(sc_String[0] ? FName(sc_String) : NAME_None); v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
break; break;
@ -1825,7 +1823,7 @@ endofstate:
frame=0; frame=0;
} }
state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC|SF_STATEPARAM))|frame; state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame;
StateArray.Push(state); StateArray.Push(state);
count++; count++;
} }
@ -1837,6 +1835,7 @@ endofstate:
{ {
SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars()); SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars());
} }
SC_SetEscape(true); // re-enable escape sequences
return count; return count;
} }

View file

@ -156,12 +156,12 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState * State)
//========================================================================== //==========================================================================
int CheckIndex(int paramsize, FState ** pcallstate) int CheckIndex(int paramsize, FState ** pcallstate)
{ {
if (!(CallingState->Frame&SF_STATEPARAM)) return -1; if (CallingState->ParameterIndex == 0) return -1;
unsigned int index = CallingState->GetMisc1_2(); unsigned int index = (unsigned int) CallingState->ParameterIndex-1;
if (index > StateParameters.Size()-paramsize-2) return -1; if (index > StateParameters.Size()-paramsize) return -1;
if (pcallstate) *pcallstate=CallingState; if (pcallstate) *pcallstate=CallingState;
return index+2; // skip the misc parameters return index;
} }