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;