From 94ffa6d5ae84f813c1da5ac9a13b1f276f4e0663 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 24 Feb 2007 17:56:43 +0000 Subject: [PATCH] - Added << operators for FString that function exactly like +=, except they are left-associative, so you can use them like you would with an ostream and append to a string in a single expression without any overhead from allocating temporary strings as would happen if you used the + operator. In other words, instead of this: string += "Some string " + "that is assembled" + " in parts"; You can do this and be more efficient while still being just as readable: string << "Some string " << "that is assembled" << " in parts"; - Changed PCD_PRINTBIND to include the command in its output if it isn't bound. - Fixed: ACS_ExecuteWithResultValue could not be used inside a script because DLevelScript::RunScript() was not reentrant, thanks to having a global stack. The stack should be local to each instance of RunScript. - Fixed: rt_draw4cols() could get stuck in rare situations where it thinks it should be drawing something but doesn't. Since long-term I plan to just replace all the masked drawing the variants of maskwallscan, I'm not going to try and find the real cause and fix it there. Instead, it just detects the situation and bails out when it finds it. SVN r492 (trunk) --- docs/rh-log.txt | 20 ++++++++++++++++++++ src/p_acs.cpp | 14 ++++++-------- src/r_drawt.cpp | 9 +++++++++ src/zstring.h | 5 +++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5b584a5a4..88c8a7c83 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,23 @@ +February 24, 2007 +- Added << operators for FString that function exactly like +=, except they + are left-associative, so you can use them like you would with an ostream + and append to a string in a single expression without any overhead from + allocating temporary strings as would happen if you used the + operator. + In other words, instead of this: + string += "Some string " + "that is assembled" + " in parts"; + You can do this and be more efficient while still being just as readable: + string << "Some string " << "that is assembled" << " in parts"; +- Changed PCD_PRINTBIND to include the command in its output if it isn't + bound. +- Fixed: ACS_ExecuteWithResultValue could not be used inside a script because + DLevelScript::RunScript() was not reentrant, thanks to having a global stack. + The stack should be local to each instance of RunScript. +- Fixed: rt_draw4cols() could get stuck in rare situations where it thinks it + should be drawing something but doesn't. Since long-term I plan to just + replace all the masked drawing the variants of maskwallscan, I'm not going + to try and find the real cause and fix it there. Instead, it just detects + the situation and bails out when it finds it. + February 24, 2007 (Changes by Graf Zahl) - Fixed: In the Doom2 cast finale it was impossible to toggle the console. - Added APROP_Friendly actor property for ACS. diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 63b911278..2bf1506fb 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3,7 +3,7 @@ ** General BEHAVIOR management and ACS execution environment ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2007 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -102,8 +102,6 @@ struct CallReturn int bDiscardResult; }; -static SDWORD Stack[STACK_SIZE]; - static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module, bool lineSide, int arg0, int arg1, int arg2, int always, bool delay); @@ -2308,12 +2306,12 @@ int DLevelScript::RunScript () break; } - int *pc = this->pc; + SDWORD Stack[STACK_SIZE]; int sp = 0; + int *pc = this->pc; ACSFormat fmt = activeBehavior->GetFormat(); int runaway = 0; // used to prevent infinite loops int pcd; - //char workreal[4096], *const work = workreal+2, *workwhere = work; FString work; const char *lookup; int optstart = -1; @@ -3769,11 +3767,11 @@ int DLevelScript::RunScript () C_GetKeysForCommand ((char *)lookup, &key1, &key2); if (key2) - work = work + KeyNames[key1] + " or " + KeyNames[key2]; + work << KeyNames[key1] << " or " << KeyNames[key2]; else if (key1) - work += KeyNames[key1]; + work << KeyNames[key1]; else - work += "???"; + work << "??? (" << (char *)lookup << ')'; } --sp; break; diff --git a/src/r_drawt.cpp b/src/r_drawt.cpp index 89b9b967d..d63fcf831 100644 --- a/src/r_drawt.cpp +++ b/src/r_drawt.cpp @@ -861,6 +861,7 @@ void rt_draw4cols (int sx) // aBc if (bad != 0 || maxtop > minbot) { + int drawcount = 0; for (x = 0; x < 4; ++x) { if (!(bad & 1)) @@ -869,15 +870,23 @@ void rt_draw4cols (int sx) { hcolfunc_post1 (x, sx+x, horizspan[x][0], horizspan[x][1]); horizspan[x] += 2; + drawcount++; } else if (minnexttop > horizspan[x][0]) { hcolfunc_post1 (x, sx+x, horizspan[x][0], minnexttop-1); horizspan[x][0] = minnexttop; + drawcount++; } } bad >>= 1; } + // Drawcount *should* always be non-zero. The reality is that some situations + // can make this not true. Unfortunately, I'm not sure what those situations are. + if (drawcount == 0) + { + return; + } continue; } diff --git a/src/zstring.h b/src/zstring.h index ffb1f4ae3..ed51a73b5 100644 --- a/src/zstring.h +++ b/src/zstring.h @@ -121,6 +121,11 @@ public: FString &operator += (const FName &name) { return *this += name.GetChars(); } FString &AppendCStrPart (const char *tail, size_t tailLen); + FString &operator << (const FString &tail) { return *this += tail; } + FString &operator << (const char *tail) { return *this += tail; } + FString &operator << (char tail) { return *this += tail; } + FString &operator << (const FName &name) { return *this += name.GetChars(); } + FString Left (size_t numChars) const; FString Right (size_t numChars) const; FString Mid (size_t pos, size_t numChars) const;