diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 0e225267e..bad37ccd6 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,9 @@ June 22, 2009 +- Changed the definition of SBarInfoCoordinate to use bitfields to pack its + members into 32 bits so that it can be stored in a plain old int without + any transformations. The transformation coord -> int -> coord was + destructive if the coordinate value was negative, causing the final + coordinate to be centered even if the original was not. - SBARINFO patch: Enable forcescaled with fullscreenoffsets. - Fixed: Since UDMF allows for fractional vertex coordinates, it is no longer safe for P_AlignPlane() to truncate coordinates when searching for the diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index bffd1830f..91afb8f8a 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -49,23 +49,21 @@ class FScanner; * This class is used to help prevent errors that may occur from adding or * subtracting from coordinates. * - * In order to provide the maximum flexibility, coordinates can be stored as an - * int with the 31st bit representing REL_CENTER. This class can handle this - * flag. + * In order to provide the maximum flexibility, coordinates are packed into + * an int with one bit reserved for relCenter. */ class SBarInfoCoordinate { public: - static const int REL_CENTER = 0x40000000; - SBarInfoCoordinate() {} SBarInfoCoordinate(int coord, bool relCenter); - SBarInfoCoordinate(int value); SBarInfoCoordinate &Add(int add); int Coordinate() const { return value; } bool RelCenter() const { return relCenter; } - int Value() const { return value | (relCenter ? REL_CENTER : 0); } + void Set(int coord, bool center) { value = coord; relCenter = center; } + void SetCoord(int coord) { value = coord; } + void SetRelCenter(bool center) { relCenter = center; } int operator* () const { return Coordinate(); } SBarInfoCoordinate operator+ (int add) const { return SBarInfoCoordinate(*this).Add(add); } @@ -76,8 +74,8 @@ class SBarInfoCoordinate void operator-= (int sub) { Add(-sub); } protected: - int value; - bool relCenter; + unsigned relCenter:1; + int value:31; }; struct SBarInfoCommand; //we need to be able to use this before it is defined. @@ -171,8 +169,7 @@ struct SBarInfo void ParseSBarInfo(int lump); void ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block); void ParseMugShotBlock(FScanner &sc, FMugShotState &state); - void getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int &y); //retrieves the next two arguments as x and y. - void getCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y); + void getCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y); //retrieves the next two arguments as x and y. int getSignedInteger(FScanner &sc); //returns a signed integer. int newImage(const char* patchname); void Init(); diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index 079052ff4..1a0527efa 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -96,15 +96,6 @@ SBarInfoCoordinate::SBarInfoCoordinate(int coord, bool relCenter) : { } -SBarInfoCoordinate::SBarInfoCoordinate(int value) -{ - relCenter = ((value & REL_CENTER) != 0); - if(value < 0) - this->value = (value | REL_CENTER); - else - this->value = (value & (~REL_CENTER)); -} - SBarInfoCoordinate &SBarInfoCoordinate::Add(int add) { value += add; @@ -765,7 +756,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a { drawingFont = cmd.font; } - DrawNumber(CPlayer->mo->InvSel->Amount, 3, cmd.special2, cmd.special3, xOffset, yOffset, alpha, block.fullScreenOffsets, cmd.translation, cmd.special4, false, !!(cmd.flags & DRAWSELECTEDINVENTORY_DRAWSHADOW)); + DrawNumber(CPlayer->mo->InvSel->Amount, 3, *(SBarInfoCoordinate*)&cmd.special2, *(SBarInfoCoordinate*)&cmd.special3, xOffset, yOffset, alpha, block.fullScreenOffsets, cmd.translation, cmd.special4, false, !!(cmd.flags & DRAWSELECTEDINVENTORY_DRAWSHADOW)); } } else if((cmd.flags & DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY)) @@ -794,7 +785,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a { drawingFont = cmd.font; } - DrawInventoryBar(cmd.special, cmd.value, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, alwaysshow, cmd.special2, cmd.special3, cmd.translation, artibox, noarrows, alwaysshowcounter, bgalpha); + DrawInventoryBar(cmd.special, cmd.value, cmd.x, cmd.y, xOffset, yOffset, alpha, block.fullScreenOffsets, alwaysshow, *(SBarInfoCoordinate*)&cmd.special2, *(SBarInfoCoordinate*)&cmd.special3, cmd.translation, artibox, noarrows, alwaysshowcounter, bgalpha); break; } case SBARINFO_DRAWBAR: @@ -1208,8 +1199,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a int tmpX = *x; int tmpY = *y; screen->VirtualToRealCoordsInt(tmpX, tmpY, w, h, 320, 200, true); - x = tmpX; - y = tmpY; + x.SetCoord(tmpX); + y.SetCoord(tmpY); } } else diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index 6dd1a81a5..d0b455141 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -765,12 +765,12 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken(','); } this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); - cmd.special2 = *(cmd.x + 30); - cmd.special3 = *(cmd.y + 24); + *(SBarInfoCoordinate*)&cmd.special2 = cmd.x + 30; + *(SBarInfoCoordinate*)&cmd.special3 = cmd.y + 24; cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { - this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); + this->getCoordinates(sc, block.fullScreenOffsets, *(SBarInfoCoordinate*)&cmd.special2, *(SBarInfoCoordinate*)&cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); @@ -847,12 +847,12 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken(','); this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); - cmd.special2 = *(cmd.x + 26); - cmd.special3 = *(cmd.y + 22); + *(SBarInfoCoordinate*)&cmd.special2 = cmd.x + 26; + *(SBarInfoCoordinate*)&cmd.special3 = cmd.y + 22; cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { - this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); + this->getCoordinates(sc, block.fullScreenOffsets, *(SBarInfoCoordinate*)&cmd.special2, *(SBarInfoCoordinate*)&cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); @@ -1346,11 +1346,11 @@ void SBarInfo::ParseMugShotBlock(FScanner &sc, FMugShotState &state) } } -void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int &y) +void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y) { bool negative = false; bool relCenter = false; - int *coords[2] = {&x, &y}; + SBarInfoCoordinate *coords[2] = {&x, &y}; for(int i = 0;i < 2;i++) { negative = false; @@ -1361,7 +1361,7 @@ void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int // [-]INT center negative = sc.CheckToken('-'); sc.MustGetToken(TK_IntConst); - *coords[i] = negative ? -sc.Number : sc.Number; + coords[i]->Set(negative ? -sc.Number : sc.Number, false); if(sc.CheckToken('+')) { sc.MustGetToken(TK_Identifier); @@ -1371,24 +1371,12 @@ void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int } if(fullScreenOffsets) { - if(relCenter) - *coords[i] |= SBarInfoCoordinate::REL_CENTER; - else - *coords[i] &= ~SBarInfoCoordinate::REL_CENTER; + coords[i]->SetRelCenter(relCenter); } } if(!fullScreenOffsets) - y = (negative ? -sc.Number : sc.Number) - (200 - this->height); -} - -void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y) -{ - int tmpX = *x; - int tmpY = *y; - getCoordinates(sc, fullScreenOffsets, tmpX, tmpY); - x = tmpX; - y = tmpY; + y.SetCoord((negative ? -sc.Number : sc.Number) - (200 - this->height)); } int SBarInfo::getSignedInteger(FScanner &sc) @@ -1497,8 +1485,8 @@ SBarInfoCommand::SBarInfoCommand() //sets the default values for more predicable special3 = 0; special4 = 0; flags = 0; - x = 0; - y = 0; + x.Set(0, 0); + y.Set(0, 0); value = 0; image_index = 0; sprite_index.SetInvalid();