From 5c5137747f25e177e0872db67ffc019b19973397 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 20 Mar 2009 02:13:25 +0000 Subject: [PATCH] - 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) --- docs/rh-log.txt | 4 ++++ src/p_acs.cpp | 39 +++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index ab2a8c1665..393ae6ace7 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,8 @@ 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 MIDIStreamer::Play(). Since the state isn't playing yet when MusicVolumeChanged() is called, it doesn't do this itself. diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 612190a391..d616be1b1e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -101,11 +101,21 @@ FRandom pr_acs ("ACS"); 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; FBehavior *ReturnModule; SDWORD *ReturnLocals; int ReturnAddress; int bDiscardResult; + FString StringBuilder; }; 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_CALLDISCARD: { - union - { - CallReturn *ret; - SDWORD *retsp; - }; int funcnum; int i; ScriptFunction *func; @@ -3087,13 +3092,9 @@ int DLevelScript::RunScript () Stack[sp+i] = 0; } sp += i; - retsp = &Stack[sp]; - ret->ReturnAddress = activeBehavior->PC2Ofs (pc); - ret->ReturnFunction = activeFunction; - ret->ReturnModule = activeBehavior; - ret->ReturnLocals = mylocals; - ret->bDiscardResult = (pcd == PCD_CALLDISCARD); - sp += sizeof(CallReturn)/sizeof(int); + ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction, + activeBehavior, mylocals, pcd == PCD_CALLDISCARD, work); + sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int); pc = module->Ofs2PC (func->Address); activeFunction = func; activeBehavior = module; @@ -3108,7 +3109,7 @@ int DLevelScript::RunScript () union { SDWORD *retsp; - CallReturn *retState; + CallReturn *ret; }; if (pcd == PCD_RETURNVAL) @@ -3122,15 +3123,17 @@ int DLevelScript::RunScript () sp -= sizeof(CallReturn)/sizeof(int); retsp = &Stack[sp]; sp = locals - Stack; - pc = retState->ReturnModule->Ofs2PC (retState->ReturnAddress); - activeFunction = retState->ReturnFunction; - activeBehavior = retState->ReturnModule; + pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress); + activeFunction = ret->ReturnFunction; + activeBehavior = ret->ReturnModule; fmt = activeBehavior->GetFormat(); - locals = retState->ReturnLocals; - if (!retState->bDiscardResult) + locals = ret->ReturnLocals; + if (!ret->bDiscardResult) { Stack[sp++] = value; } + work = ret->StringBuilder; + ret->~CallReturn(); } break;