- Added the current value of the string buffer to the state saved when

making a function call in ACS. Now you can print inside functions and
  also return values from them for the caller to plug directly into
  another string without having to save it to a temporary variable.


SVN r1492 (trunk)
This commit is contained in:
Randy Heit 2009-03-20 02:13:25 +00:00
parent 301a554a69
commit 5c5137747f
2 changed files with 25 additions and 18 deletions

View file

@ -1,4 +1,8 @@
March 19, 2009 March 19, 2009
- Added the current value of the string buffer to the state saved when
making a function call in ACS. Now you can print inside functions and
also return values from them for the caller to plug directly into
another string without having to save it to a temporary variable.
- Added an OutputVolume() call after the MusicVolumeChanged() call in - Added an OutputVolume() call after the MusicVolumeChanged() call in
MIDIStreamer::Play(). Since the state isn't playing yet when MIDIStreamer::Play(). Since the state isn't playing yet when
MusicVolumeChanged() is called, it doesn't do this itself. MusicVolumeChanged() is called, it doesn't do this itself.

View file

@ -101,11 +101,21 @@ FRandom pr_acs ("ACS");
struct CallReturn struct CallReturn
{ {
CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, FString &str)
: ReturnFunction(func),
ReturnModule(module),
ReturnLocals(locals),
ReturnAddress(pc),
bDiscardResult(discard),
StringBuilder(str)
{}
ScriptFunction *ReturnFunction; ScriptFunction *ReturnFunction;
FBehavior *ReturnModule; FBehavior *ReturnModule;
SDWORD *ReturnLocals; SDWORD *ReturnLocals;
int ReturnAddress; int ReturnAddress;
int bDiscardResult; int bDiscardResult;
FString StringBuilder;
}; };
static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module, static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
@ -3053,11 +3063,6 @@ int DLevelScript::RunScript ()
case PCD_CALL: case PCD_CALL:
case PCD_CALLDISCARD: case PCD_CALLDISCARD:
{ {
union
{
CallReturn *ret;
SDWORD *retsp;
};
int funcnum; int funcnum;
int i; int i;
ScriptFunction *func; ScriptFunction *func;
@ -3087,13 +3092,9 @@ int DLevelScript::RunScript ()
Stack[sp+i] = 0; Stack[sp+i] = 0;
} }
sp += i; sp += i;
retsp = &Stack[sp]; ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction,
ret->ReturnAddress = activeBehavior->PC2Ofs (pc); activeBehavior, mylocals, pcd == PCD_CALLDISCARD, work);
ret->ReturnFunction = activeFunction; sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int);
ret->ReturnModule = activeBehavior;
ret->ReturnLocals = mylocals;
ret->bDiscardResult = (pcd == PCD_CALLDISCARD);
sp += sizeof(CallReturn)/sizeof(int);
pc = module->Ofs2PC (func->Address); pc = module->Ofs2PC (func->Address);
activeFunction = func; activeFunction = func;
activeBehavior = module; activeBehavior = module;
@ -3108,7 +3109,7 @@ int DLevelScript::RunScript ()
union union
{ {
SDWORD *retsp; SDWORD *retsp;
CallReturn *retState; CallReturn *ret;
}; };
if (pcd == PCD_RETURNVAL) if (pcd == PCD_RETURNVAL)
@ -3122,15 +3123,17 @@ int DLevelScript::RunScript ()
sp -= sizeof(CallReturn)/sizeof(int); sp -= sizeof(CallReturn)/sizeof(int);
retsp = &Stack[sp]; retsp = &Stack[sp];
sp = locals - Stack; sp = locals - Stack;
pc = retState->ReturnModule->Ofs2PC (retState->ReturnAddress); pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress);
activeFunction = retState->ReturnFunction; activeFunction = ret->ReturnFunction;
activeBehavior = retState->ReturnModule; activeBehavior = ret->ReturnModule;
fmt = activeBehavior->GetFormat(); fmt = activeBehavior->GetFormat();
locals = retState->ReturnLocals; locals = ret->ReturnLocals;
if (!retState->bDiscardResult) if (!ret->bDiscardResult)
{ {
Stack[sp++] = value; Stack[sp++] = value;
} }
work = ret->StringBuilder;
ret->~CallReturn();
} }
break; break;