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;