diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 47c641c18..9e762e1ae 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,17 @@ -May 3, 2009 (Changes by Graf Zahl) +May 8, 2009 +- Added transference of a select few flags from PowerProtection to its owner. +- Added actor type parameters to A_PodPain() and A_MakePod(). +- The savegame path is now passed through NicePath(), since it's user- + specifiable. +- Added save_dir cvar. When non-empty, it controls where savegames go. +- SBARINFO update: + * Added the ability to center things with fullscreenoffsets enabled. Due + to some limitations the syntax is [-] [+ center]. + * Fixed: the translucent flag on drawinventorybar didn't work quite right. + * Fixed: Extremely minor inaccuracy in the Doom SBarInfo code. The + fullscreen inventory bar wasn't scaled correctly. + +May 3, 2009 (Changes by Graf Zahl) - fixed: The CHECKSWITCHRANGE line flag was ignored for one sided lines. - Added more compatibility settings, submitted by Gez. diff --git a/src/g_game.cpp b/src/g_game.cpp index 8e7032499..4bc0918c2 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -104,6 +104,7 @@ CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH); CVAR (Bool, chasedemo, false, 0); CVAR (Bool, storesavepic, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, longsavemessages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (String, save_dir, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG); gameaction_t gameaction; gamestate_t gamestate = GS_STARTUP; @@ -1760,32 +1761,28 @@ void G_SaveGame (const char *filename, const char *description) FString G_BuildSaveName (const char *prefix, int slot) { FString name; - const char *leader; + FString leader; const char *slash = ""; - if (NULL != (leader = Args->CheckValue ("-savedir"))) + leader = Args->CheckValue ("-savedir"); + if (leader.IsEmpty()) { - size_t len = strlen (leader); - if (leader[len-1] != '\\' && leader[len-1] != '/') +#ifndef unix + if (Args->CheckParm ("-cdrom")) { - slash = "/"; + leader = CDROM_DIR "/"; + } + else +#endif + { + leader = save_dir; } } -#ifndef unix - else if (Args->CheckParm ("-cdrom")) + size_t len = leader.Len(); + if (leader[0] != '\0' && leader[len-1] != '\\' && leader[len-1] != '/') { - leader = CDROM_DIR "/"; + slash = "/"; } - else - { - leader = progdir; - } -#else - else - { - leader = ""; - } -#endif if (slot < 0) { name.Format ("%s%s%s", leader, slash, prefix); @@ -1797,10 +1794,10 @@ FString G_BuildSaveName (const char *prefix, int slot) #ifdef unix if (leader[0] == 0) { - name = GetUserFile (name); + return GetUserFile (name); } #endif - return name; + return NicePath(name); } CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/src/g_heretic/a_hereticmisc.cpp b/src/g_heretic/a_hereticmisc.cpp index 85c75ca34..2f76a566a 100644 --- a/src/g_heretic/a_hereticmisc.cpp +++ b/src/g_heretic/a_hereticmisc.cpp @@ -40,8 +40,11 @@ static FRandom pr_volcimpact ("VolcBallImpact"); // //---------------------------------------------------------------------------- -DEFINE_ACTION_FUNCTION(AActor, A_PodPain) +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PodPain) { + ACTION_PARAM_START(1); + ACTION_PARAM_CLASS(gootype, 0); + int count; int chance; AActor *goo; @@ -53,7 +56,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PodPain) } for (count = chance > 240 ? 2 : 1; count; count--) { - goo = Spawn("PodGoo", self->x, self->y, self->z + 48*FRACUNIT, ALLOW_REPLACE); + goo = Spawn(gootype, self->x, self->y, self->z + 48*FRACUNIT, ALLOW_REPLACE); goo->target = self; goo->momx = pr_podpain.Random2() << 9; goo->momy = pr_podpain.Random2() << 9; @@ -88,8 +91,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_RemovePod) #define MAX_GEN_PODS 16 -DEFINE_ACTION_FUNCTION(AActor, A_MakePod) +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MakePod) { + ACTION_PARAM_START(1); + ACTION_PARAM_CLASS(podtype, 0); + AActor *mo; fixed_t x; fixed_t y; @@ -102,7 +108,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MakePod) x = self->x; y = self->y; z = self->z; - mo = Spawn("Pod", x, y, ONFLOORZ, ALLOW_REPLACE); + mo = Spawn(podtype, x, y, ONFLOORZ, ALLOW_REPLACE); if (!P_CheckPosition (mo, x, y)) { // Didn't fit mo->Destroy (); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 1529206cc..692ad2faf 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -552,10 +552,13 @@ IMPLEMENT_CLASS (APowerInvisibility) void APowerInvisibility::CommonInit() { - Owner->flags |= MF_SHADOW; - // transfer seeker missile blocking (but only if the owner does not already have this flag - if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK; - else flags5 &= ~MF5_CANTSEEK; + if (Owner != NULL) + { + Owner->flags |= MF_SHADOW; + // transfer seeker missile blocking (but only if the owner does not already have this flag + if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK; + else flags5 &= ~MF5_CANTSEEK; + } } //=========================================================================== @@ -1522,7 +1525,10 @@ void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bo // Quarter damage powerup ------------------------------------------------------ -IMPLEMENT_CLASS( APowerProtection) +IMPLEMENT_CLASS(APowerProtection) + +#define PROTECTION_FLAGS3 (MF3_NORADIUSDMG | MF3_DONTMORPH | MF3_DONTSQUASH | MF3_DONTBLAST | MF3_NOTELEOTHER) +#define PROTECTION_FLAGS5 (MF5_NOPAIN | MF5_DONTRIP) //=========================================================================== // @@ -1532,8 +1538,19 @@ IMPLEMENT_CLASS( APowerProtection) void APowerProtection::InitEffect( ) { - // Use sound channel 5 to avoid interference with other actions. - if (Owner != NULL) S_Sound(Owner, 5, SeeSound, 1.0f, ATTN_NONE); + if (Owner != NULL) + { + S_Sound(Owner, CHAN_AUTO, SeeSound, 1.0f, ATTN_NONE); + + // Transfer various protection flags if owner does not already have them. + // If the owner already has the flag, clear it from the powerup. + // If the powerup still has a flag set, add it to the owner. + flags3 &= ~(Owner->flags3 & PROTECTION_FLAGS3); + Owner->flags3 |= flags3 & PROTECTION_FLAGS3; + + flags5 &= ~(Owner->flags5 & PROTECTION_FLAGS5); + Owner->flags5 |= flags5 & PROTECTION_FLAGS5; + } } //=========================================================================== @@ -1544,8 +1561,12 @@ void APowerProtection::InitEffect( ) void APowerProtection::EndEffect( ) { - // Use sound channel 5 to avoid interference with other actions. - if (Owner != NULL) S_Sound(Owner, 5, DeathSound, 1.0f, ATTN_NONE); + if (Owner != NULL) + { + S_Sound(Owner, CHAN_AUTO, DeathSound, 1.0f, ATTN_NONE); + Owner->flags3 &= ~(flags3 & PROTECTION_FLAGS3); + Owner->flags5 &= ~(flags5 & PROTECTION_FLAGS5); + } } //=========================================================================== @@ -1559,27 +1580,30 @@ void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage static const fixed_t def = FRACUNIT/4; if (passive && damage > 0) { - const fixed_t * pdf = NULL; - DmgFactors * df = GetClass()->ActorInfo->DamageFactors; + const fixed_t *pdf = NULL; + DmgFactors *df = GetClass()->ActorInfo->DamageFactors; if (df != NULL && df->CountUsed() != 0) { pdf = df->CheckKey(damageType); - if (pdf== NULL && damageType != NAME_None) pdf = df->CheckKey(NAME_None); + if (pdf == NULL && damageType != NAME_None) pdf = df->CheckKey(NAME_None); } else pdf = &def; if (pdf != NULL) { damage = newdamage = FixedMul(damage, *pdf); - if (Owner != NULL && *pdf < FRACUNIT) S_Sound(Owner, 5, ActiveSound, 1.0f, ATTN_NONE); + if (Owner != NULL && *pdf < FRACUNIT) S_Sound(Owner, CHAN_AUTO, ActiveSound, 1.0f, ATTN_NONE); } } - if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive); + if (Inventory != NULL) + { + Inventory->ModifyDamage(damage, damageType, newdamage, passive); + } } // Drain rune ------------------------------------------------------- -IMPLEMENT_CLASS( APowerDrain) +IMPLEMENT_CLASS(APowerDrain) //=========================================================================== // @@ -1615,7 +1639,7 @@ void APowerDrain::EndEffect( ) // Regeneration rune ------------------------------------------------------- -IMPLEMENT_CLASS( APowerRegeneration) +IMPLEMENT_CLASS(APowerRegeneration) //=========================================================================== // @@ -1650,7 +1674,7 @@ void APowerRegeneration::EndEffect( ) // High jump rune ------------------------------------------------------- -IMPLEMENT_CLASS( APowerHighJump) +IMPLEMENT_CLASS(APowerHighJump) //=========================================================================== // @@ -1685,7 +1709,7 @@ void APowerHighJump::EndEffect( ) // Morph powerup ------------------------------------------------------ -IMPLEMENT_CLASS( APowerMorph) +IMPLEMENT_CLASS(APowerMorph) //=========================================================================== // diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index 539d6a7b5..b0d687dca 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -45,6 +45,41 @@ class FBarTexture; 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. + */ +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); } + + int operator* () const { return Coordinate(); } + SBarInfoCoordinate operator+ (int add) const { return SBarInfoCoordinate(*this).Add(add); } + SBarInfoCoordinate operator+ (const SBarInfoCoordinate &other) const { return SBarInfoCoordinate(*this).Add(other.Coordinate()); } + SBarInfoCoordinate operator- (int sub) const { return SBarInfoCoordinate(*this).Add(-sub); } + SBarInfoCoordinate operator- (const SBarInfoCoordinate &other) const { return SBarInfoCoordinate(*this).Add(-other.Coordinate()); } + void operator+= (int add) { Add(add); } + void operator-= (int sub) { Add(-sub); } + + protected: + int value; + bool relCenter; +}; + struct SBarInfoCommand; //we need to be able to use this before it is defined. struct MugShotState; @@ -103,8 +138,8 @@ struct SBarInfoCommand int special3; int special4; int flags; - int x; - int y; + SBarInfoCoordinate x; + SBarInfoCoordinate y; int value; int image_index; FTextureID sprite_index; @@ -136,7 +171,8 @@ struct SBarInfo void ParseSBarInfo(int lump); void ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block); void ParseMugShotBlock(FScanner &sc, FMugShotState &state); - void getCoordinates(FScanner &sc, SBarInfoCommand &cmd, bool fullScreenOffsets); //retrieves the next two arguments as x and y. + 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); int getSignedInteger(FScanner &sc); //returns a signed integer. int newImage(const char* patchname); void Init(); @@ -144,14 +180,14 @@ struct SBarInfo SBarInfo(); SBarInfo(int lumpnum); ~SBarInfo(); - static void Load(); + + static void Load(); }; #define SCRIPT_CUSTOM 0 #define SCRIPT_DEFAULT 1 extern SBarInfo *SBarInfoScript[2]; - // Enums used between the parser and the display enum //gametype flags { @@ -359,14 +395,14 @@ public: void SetMugShotState(const char* stateName, bool waitTillDone=false, bool reset=false); private: void doCommands(SBarInfoBlock &block, int xOffset=0, int yOffset=0, int alpha=FRACUNIT); - void DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool translate=false, bool dim=false, int offsetflags=0); - void DrawString(const char* str, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false); - void DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool fillzeros=false, bool drawshadow=false); - void DrawFace(const char *defaultFace, int accuracy, int stateflags, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets); + void DrawGraphic(FTexture* texture, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool translate=false, bool dim=false, int offsetflags=0); + void DrawString(const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false); + void DrawNumber(int num, int len, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool fillzeros=false, bool drawshadow=false); + void DrawFace(const char *defaultFace, int accuracy, int stateflags, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets); int updateState(bool xdth, bool animatedgodmode); - void DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow, - int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter, int bgalpha); - void DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize, + void DrawInventoryBar(int type, int num, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow, + SBarInfoCoordinate counterx, SBarInfoCoordinate countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter, int bgalpha); + void DrawGem(FTexture* chain, FTexture* gem, int value, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize, bool wiggle, bool translate); FRemapTable* getTranslation(); diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index aac681b8e..3eebc16ab 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -79,6 +79,40 @@ enum imgINVRTGEM2, }; +#define ADJUST_RELCENTER(x, y, outX, outY) \ + if(x.RelCenter()) \ + outX = *x + SCREENWIDTH/(hud_scale ? CleanXfac*2 : 2); \ + else \ + outX = *x; \ + if(y.RelCenter()) \ + outY = *y + SCREENHEIGHT/(hud_scale ? CleanYfac*2 : 2); \ + else \ + outY = *y; + +//////////////////////////////////////////////////////////////////////////////// + +SBarInfoCoordinate::SBarInfoCoordinate(int coord, bool relCenter) : + value(coord), relCenter(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; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// + //Used for shading FBarShader::FBarShader(bool vertical, bool reverse) //make an alpha map { @@ -914,8 +948,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a if(!block.fullScreenOffsets) { // Calc real screen coordinates for bar - x = (cmd.x + ST_X + xOffset) << FRACBITS; - y = (cmd.y + ST_Y + yOffset) << FRACBITS; + x = *(cmd.x + ST_X + xOffset) << FRACBITS; + y = *(cmd.y + ST_Y + yOffset) << FRACBITS; w = fg->GetScaledWidth() << FRACBITS; h = fg->GetScaledHeight() << FRACBITS; if (Scaled) @@ -929,10 +963,13 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } else { - x = cmd.x + xOffset; - y = cmd.y + yOffset; + ADJUST_RELCENTER(cmd.x,cmd.y,x,y) + + x += xOffset; + y += yOffset; w = fg->GetScaledWidth(); h = fg->GetScaledHeight(); + if(vid_fps && x < 0 && y >= 0) y += 10; } @@ -951,15 +988,26 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } else { - screen->Clear(x, y, x + w, y + h, GPalette.BlackIndex, 0); + int clx = x; + int cly = y; + int clw = x + w; + int clh = y + h; + if(block.fullScreenOffsets) + { + clx = x < 0 ? SCREENWIDTH + x : x; + cly = y < 0 ? SCREENHEIGHT + y : y; + clw = clx+w > SCREENWIDTH ? SCREENWIDTH-clx : clx+w; + clh = cly+h > SCREENHEIGHT ? SCREENHEIGHT-cly : cly+h; + } + screen->Clear(clx, cly, clw, clh, GPalette.BlackIndex, 0); } } if(!block.fullScreenOffsets) { // Calc clipping rect for background - cx = (cmd.x + ST_X + cmd.special3 + xOffset) << FRACBITS; - cy = (cmd.y + ST_Y + cmd.special3 + yOffset) << FRACBITS; + cx = *(cmd.x + ST_X + cmd.special3 + xOffset) << FRACBITS; + cy = *(cmd.y + ST_Y + cmd.special3 + yOffset) << FRACBITS; cw = (fg->GetScaledWidth() - fg->GetScaledLeftOffset() - cmd.special3 * 2) << FRACBITS; ch = (fg->GetScaledHeight() - fg->GetScaledTopOffset() - cmd.special3 * 2) << FRACBITS; if (Scaled) @@ -973,8 +1021,10 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } else { - cx = cmd.x + cmd.special3 + xOffset; - cy = cmd.y + cmd.special3 + yOffset; + ADJUST_RELCENTER(cmd.x,cmd.y,cx,cy) + + cx += cmd.special3 + xOffset; + cy += cmd.special3 + yOffset; cw = fg->GetScaledWidth() - fg->GetScaledLeftOffset() - cmd.special3 * 2; ch = fg->GetScaledHeight() - fg->GetScaledTopOffset() - cmd.special3 * 2; if(vid_fps && x < 0 && y >= 0) @@ -1128,8 +1178,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a }; bool vertical = !!(cmd.flags & DRAWSHADER_VERTICAL); bool reverse = !!(cmd.flags & DRAWSHADER_REVERSE); - int x = cmd.x + xOffset; - int y = cmd.y + yOffset; + SBarInfoCoordinate x = cmd.x + xOffset; + SBarInfoCoordinate y = cmd.y + yOffset; int w = cmd.special; int h = cmd.special2; if(!block.fullScreenOffsets) @@ -1137,16 +1187,22 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a x += ST_X; y += ST_Y; if(Scaled) - screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true); + { + int tmpX = *x; + int tmpY = *y; + screen->VirtualToRealCoordsInt(tmpX, tmpY, w, h, 320, 200, true); + x = tmpX; + y = tmpY; + } } else { - if(vid_fps && x < 0 && y >= 0) + if(vid_fps && *x < 0 && *y >= 0) y += 10; } if(!block.fullScreenOffsets) { - screen->DrawTexture (shaders[(vertical << 1) + reverse], x, y, + screen->DrawTexture (shaders[(vertical << 1) + reverse], *x, *y, DTA_DestWidth, w, DTA_DestHeight, h, DTA_Alpha, alpha, @@ -1156,7 +1212,10 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } else { - screen->DrawTexture (shaders[(vertical << 1) + reverse], x, y, + int rx, ry; + ADJUST_RELCENTER(x,y,rx,ry) + + screen->DrawTexture (shaders[(vertical << 1) + reverse], rx, ry, DTA_DestWidth, w, DTA_DestHeight, h, DTA_Alpha, alpha, @@ -1392,7 +1451,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a } //draws an image with the specified flags -void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, +void DSBarInfo::DrawGraphic(FTexture* texture, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool translate, bool dim, int offsetflags) //flags { if (texture == NULL) @@ -1410,18 +1469,16 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yO if(!fullScreenOffsets) { // I'll handle the conversion from fixed to int myself for more control - fixed_t fx = (x + ST_X) << FRACBITS; - fixed_t fy = (y + ST_Y) << FRACBITS; + fixed_t fx = (x + ST_X).Coordinate() << FRACBITS; + fixed_t fy = (y + ST_Y).Coordinate() << FRACBITS; fixed_t fw = texture->GetScaledWidth() << FRACBITS; fixed_t fh = texture->GetScaledHeight() << FRACBITS; if(Scaled) screen->VirtualToRealCoords(fx, fy, fw, fh, 320, 200, true); - x = fx >> FRACBITS; - y = fy >> FRACBITS; // Round to nearest w = (fw + (FRACUNIT>>1)) >> FRACBITS; h = (fh + (FRACUNIT>>1)) >> FRACBITS; - screen->DrawTexture(texture, x, y, + screen->DrawTexture(texture, (fx >> FRACBITS), (fy >> FRACBITS), DTA_DestWidth, w, DTA_DestHeight, h, DTA_Translation, translate ? getTranslation() : 0, @@ -1432,11 +1489,14 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yO } else { + int rx, ry; + ADJUST_RELCENTER(x,y,rx,ry) + w = texture->GetScaledWidth(); h = texture->GetScaledHeight(); - if(vid_fps && x < 0 && y >= 0) - y += 10; - screen->DrawTexture(texture, x, y, + if(vid_fps && rx < 0 && ry >= 0) + ry += 10; + screen->DrawTexture(texture, rx, ry, DTA_DestWidth, w, DTA_DestHeight, h, DTA_Translation, translate ? getTranslation() : 0, @@ -1448,9 +1508,15 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yO } } -void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool drawshadow) +void DSBarInfo::DrawString(const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool drawshadow) { x += spacing; + int ax = *x; + int ay = *y; + if(fullScreenOffsets) + { + ADJUST_RELCENTER(x,y,ax,ay) + } while(*str != '\0') { if(*str == ' ') @@ -1474,8 +1540,8 @@ void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffs x += (character->LeftOffset+1); //ignore x offsets since we adapt to character size int rx, ry, rw, rh; - rx = x + xOffset; - ry = y + yOffset; + rx = ax + xOffset; + ry = ay + yOffset; rw = character->GetScaledWidth(); rh = character->GetScaledHeight(); if(!fullScreenOffsets) @@ -1487,8 +1553,8 @@ void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffs } else { - if(vid_fps && x < 0 && y >= 0) - y += 10; + if(vid_fps && ax < 0 && ay >= 0) + ry += 10; } if(drawshadow) { @@ -1533,15 +1599,15 @@ void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffs TAG_DONE); } if(script->spacingCharacter == '\0') - x += width + spacing - (character->LeftOffset+1); + ax += width + spacing - (character->LeftOffset+1); else //width gets changed at the call to GetChar() - x += drawingFont->GetCharWidth((int) script->spacingCharacter) + spacing; + ax += drawingFont->GetCharWidth((int) script->spacingCharacter) + spacing; str++; } } //draws the specified number up to len digits -void DSBarInfo::DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool fillzeros, bool drawshadow) +void DSBarInfo::DrawNumber(int num, int len, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing, bool fillzeros, bool drawshadow) { FString value; int maxval = (int) ceil(pow(10., len))-1; @@ -1570,7 +1636,7 @@ void DSBarInfo::DrawNumber(int num, int len, int x, int y, int xOffset, int yOff } //draws the mug shot -void DSBarInfo::DrawFace(const char *defaultFace, int accuracy, int stateflags, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets) +void DSBarInfo::DrawFace(const char *defaultFace, int accuracy, int stateflags, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets) { FTexture *face = MugShot.GetFace(CPlayer, defaultFace, accuracy, stateflags); if (face != NULL) @@ -1579,8 +1645,8 @@ void DSBarInfo::DrawFace(const char *defaultFace, int accuracy, int stateflags, } } -void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow, - int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter, int bgalpha) +void DSBarInfo::DrawInventoryBar(int type, int num, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, bool alwaysshow, + SBarInfoCoordinate counterx, SBarInfoCoordinate countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter, int bgalpha) { //yes, there is some Copy & Paste here too AInventory *item; int i; @@ -1592,59 +1658,60 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, i { for(item = CPlayer->mo->InvFirst, i = 0; item != NULL && i < num; item = item->NextInv(), ++i) { + SBarInfoCoordinate rx = x + i*spacing; if(drawArtiboxes) { - DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*spacing, y, xOffset, yOffset, bgalpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgARTIBOX], rx, y, xOffset, yOffset, bgalpha, fullScreenOffsets); } if(type != GAME_Strife) //Strife draws the cursor before the icons - DrawGraphic(TexMan(item->Icon), x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets, false, item->Amount <= 0); + DrawGraphic(TexMan(item->Icon), rx, y, xOffset, yOffset, alpha, fullScreenOffsets, false, item->Amount <= 0); if(item == CPlayer->mo->InvSel) { if(type == GAME_Heretic) { - DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y+29, xOffset, yOffset, alpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgSELECTBOX], rx, y+29, xOffset, yOffset, alpha, fullScreenOffsets); } else if(type == GAME_Hexen) { - DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y-1, xOffset, yOffset, alpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgSELECTBOX], rx, y-1, xOffset, yOffset, alpha, fullScreenOffsets); } else if(type == GAME_Strife) { - DrawGraphic(Images[invBarOffset + imgCURSOR], x+i*spacing-6, y-2, xOffset, yOffset, alpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgCURSOR], rx-6, y-2, xOffset, yOffset, alpha, fullScreenOffsets); } else { - DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgSELECTBOX], rx, y, xOffset, yOffset, alpha, fullScreenOffsets); } } if(type == GAME_Strife) - DrawGraphic(TexMan(item->Icon), x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets, false, item->Amount <= 0); + DrawGraphic(TexMan(item->Icon), rx, y, xOffset, yOffset, alpha, fullScreenOffsets, false, item->Amount <= 0); if(alwaysshowcounter || item->Amount != 1) { - DrawNumber(item->Amount, 3, counterx+i*spacing, countery, xOffset, yOffset, alpha, fullScreenOffsets, translation); + DrawNumber(item->Amount, 3, counterx + (i*spacing), countery, xOffset, yOffset, alpha, fullScreenOffsets, translation); } } for (; i < num && drawArtiboxes; ++i) { - DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*spacing, y, xOffset, yOffset, alpha, fullScreenOffsets); + DrawGraphic(Images[invBarOffset + imgARTIBOX], x + (i*spacing), y, xOffset, yOffset, bgalpha, fullScreenOffsets); } // Is there something to the left? if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst) { DrawGraphic(Images[!(gametic & 4) ? - invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], (type != GAME_Strife) ? x-12 : x-14, y, xOffset, yOffset, alpha, fullScreenOffsets); + invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x + ((type != GAME_Strife) ? -12 : -14), y, xOffset, yOffset, alpha, fullScreenOffsets); } // Is there something to the right? if (!noArrows && item != NULL) { DrawGraphic(Images[!(gametic & 4) ? - invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], (type != GAME_Strife) ? x+num*31+2 : x+num*35-4, y, xOffset, yOffset, alpha, fullScreenOffsets); + invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x + ((type != GAME_Strife) ? num*31+2 : num*35-4), y, xOffset, yOffset, alpha, fullScreenOffsets); } } } //draws heretic/hexen style life gems -void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize, +void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, int padleft, int padright, int chainsize, bool wiggle, bool translate) { if(chain == NULL) diff --git a/src/g_shared/sbarinfo_parser.cpp b/src/g_shared/sbarinfo_parser.cpp index e9e1f2187..7d59297f9 100644 --- a/src/g_shared/sbarinfo_parser.cpp +++ b/src/g_shared/sbarinfo_parser.cpp @@ -525,7 +525,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) cmd.sprite_index.SetInvalid(); } sc.MustGetToken(','); - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); @@ -658,7 +658,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) if(!sc.CheckToken('|')) sc.MustGetToken(','); } - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { bool needsComma = false; @@ -717,7 +717,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken(','); } - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSELECTEDINVENTORY: @@ -762,19 +762,13 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) if(!sc.CheckToken('|')) sc.MustGetToken(','); } - this->getCoordinates(sc, cmd, block.fullScreenOffsets); - cmd.special2 = cmd.x + 30; - cmd.special3 = cmd.y + 24; + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); + cmd.special2 = *(cmd.x + 30); + cmd.special3 = *(cmd.y + 24); cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { - int x = cmd.x; - int y = cmd.y; - this->getCoordinates(sc, cmd, block.fullScreenOffsets); - cmd.special2 = cmd.x; - cmd.special3 = cmd.y; - cmd.x = x; - cmd.y = y; + this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); @@ -850,17 +844,13 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.ScriptError("Unknown font '%s'.", sc.String); sc.MustGetToken(','); - this->getCoordinates(sc, cmd, block.fullScreenOffsets); - cmd.special2 = cmd.x + 26; - cmd.special3 = cmd.y + 22; + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); + cmd.special2 = *(cmd.x + 26); + cmd.special3 = *(cmd.y + 22); cmd.translation = CR_GOLD; if(sc.CheckToken(',')) //more font information { - sc.MustGetToken(TK_IntConst); - cmd.special2 = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - cmd.special3 = sc.Number - (200 - this->height); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.special2, cmd.special3); if(sc.CheckToken(',')) { sc.MustGetToken(TK_Identifier); @@ -973,7 +963,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) if(!sc.CheckToken('|')) sc.MustGetToken(','); } - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) //border { sc.MustGetToken(TK_IntConst); @@ -1013,7 +1003,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.ScriptError("Chain size must be a positive number."); cmd.special4 = sc.Number; sc.MustGetToken(','); - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSHADER: @@ -1042,7 +1032,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) cmd.flags |= DRAWSHADER_REVERSE; sc.MustGetToken(','); } - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); sc.MustGetToken(';'); break; case SBARINFO_DRAWSTRING: @@ -1057,7 +1047,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) sc.MustGetToken(TK_StringConst); cmd.setString(sc, sc.String, 0, -1, false); sc.MustGetToken(','); - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) //spacing { sc.MustGetToken(TK_IntConst); @@ -1092,7 +1082,7 @@ void SBarInfo::ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block) cmd.special = sc.Number; } sc.MustGetToken(','); - this->getCoordinates(sc, cmd, block.fullScreenOffsets); + this->getCoordinates(sc, block.fullScreenOffsets, cmd.x, cmd.y); if(sc.CheckToken(',')) { //key offset @@ -1352,19 +1342,49 @@ void SBarInfo::ParseMugShotBlock(FScanner &sc, FMugShotState &state) } } -void SBarInfo::getCoordinates(FScanner &sc, SBarInfoCommand &cmd, bool fullScreenOffsets) +void SBarInfo::getCoordinates(FScanner &sc, bool fullScreenOffsets, int &x, int &y) { bool negative = false; - negative = sc.CheckToken('-'); - sc.MustGetToken(TK_IntConst); - cmd.x = negative ? -sc.Number : sc.Number; - sc.MustGetToken(','); - negative = sc.CheckToken('-'); - sc.MustGetToken(TK_IntConst); + bool relCenter = false; + int *coords[2] = {&x, &y}; + for(int i = 0;i < 2;i++) + { + negative = false; + relCenter = false; + if(i > 0) + sc.MustGetToken(','); + + // [-]INT center + negative = sc.CheckToken('-'); + sc.MustGetToken(TK_IntConst); + *coords[i] = negative ? -sc.Number : sc.Number; + if(sc.CheckToken('+')) + { + sc.MustGetToken(TK_Identifier); + if(!sc.Compare("center")) + sc.ScriptError("Expected 'center' but got '%s' instead.", sc.String); + relCenter = true; + } + if(fullScreenOffsets) + { + if(relCenter) + *coords[i] |= SBarInfoCoordinate::REL_CENTER; + else + *coords[i] &= ~SBarInfoCoordinate::REL_CENTER; + } + } + if(!fullScreenOffsets) - cmd.y = (negative ? -sc.Number : sc.Number) - (200 - this->height); - else - cmd.y = negative ? -sc.Number : sc.Number; + 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; } int SBarInfo::getSignedInteger(FScanner &sc) diff --git a/wadsrc/static/actors/heretic/hereticmisc.txt b/wadsrc/static/actors/heretic/hereticmisc.txt index b03e57a17..01d0ac771 100644 --- a/wadsrc/static/actors/heretic/hereticmisc.txt +++ b/wadsrc/static/actors/heretic/hereticmisc.txt @@ -15,7 +15,7 @@ ACTOR Pod 2035 +NOBLOCKMONST +DONTGIB +OLDRADIUSDMG DeathSound "world/podexplode" - action native A_PodPain (); + action native A_PodPain (class podtype = "PodGoo"); action native A_RemovePod (); States @@ -69,7 +69,7 @@ ACTOR PodGenerator 43 +NOSECTOR +DONTSPLASH - action native A_MakePod (); + action native A_MakePod (class podtype = "Pod"); States { diff --git a/wadsrc/static/sbarinfo/doom.txt b/wadsrc/static/sbarinfo/doom.txt index f2f3ca9fb..0e49eae84 100644 --- a/wadsrc/static/sbarinfo/doom.txt +++ b/wadsrc/static/sbarinfo/doom.txt @@ -120,7 +120,7 @@ statusbar inventory // Standard bar overlay (ZDoom Addition) drawinventorybar Doom, 7, INDEXFONT, 50, 170; } -statusbar inventoryfullscreen // ZDoom HUD overlay. +statusbar inventoryfullscreen, fullscreenoffsets // ZDoom HUD overlay. { - drawinventorybar Doom, translucent, 7, INDEXFONT, 50, 170; + drawinventorybar Doom, translucent, 7, INDEXFONT, -106+center, -31; }