From 340db9160b9cb521c7bb9cc1b03009e7c405c043 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 18 Jul 2012 22:30:10 +0000 Subject: [PATCH 001/101] - Draw 1 pixel of border at the edges of the status bar to prevent imprecision HOMs (only top and bottom for non-widescreen for now). - The completeborder command is handled at the base statusbar now since it can do so more efficiently. SVN r3771 (trunk) --- src/g_shared/sbar.h | 1 + src/g_shared/sbarinfo.cpp | 9 ++----- src/g_shared/shared_sbar.cpp | 47 ++++++++++++++++++++++++------------ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index be5ebddd5..22a99709d 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -343,6 +343,7 @@ public: bool Scaled; bool Centering; bool FixedOrigin; + bool CompleteBorder; fixed_t CrosshairSize; fixed_t Displacement; diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 6a1f6fd98..99158f568 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -978,6 +978,8 @@ public: } invBarOffset = script->Images.Size(); Images.Init(&patchnames[0], patchnames.Size()); + + CompleteBorder = script->completeBorder; } ~DSBarInfo () @@ -991,13 +993,6 @@ public: int hud = STBAR_NORMAL; if(state == HUD_StatusBar) { - if(script->completeBorder) //Fill the statusbar with the border before we draw. - { - FTexture *b = TexMan[gameinfo.border->b]; - V_DrawBorder(viewwindowx, viewwindowy + viewheight + b->GetHeight(), viewwindowx + viewwidth, SCREENHEIGHT); - if(screenblocks == 10) - screen->FlatFill(viewwindowx, viewwindowy + viewheight, viewwindowx + viewwidth, viewwindowy + viewheight + b->GetHeight(), b, true); - } if(script->automapbar && automapactive) { hud = STBAR_AUTOMAP; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index ee4e98890..57a0d9106 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -216,6 +216,7 @@ void ST_Clear() DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) { + CompleteBorder = false; Centering = false; FixedOrigin = false; CrosshairSize = FRACUNIT; @@ -1037,27 +1038,43 @@ void DBaseStatusBar::RefreshBackground () const { int x, x2, y, ratio; - if (SCREENWIDTH > 320) + ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT); + x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2); + y = x == ST_X && x > 0 ? ST_Y : ::ST_Y; + + if(!CompleteBorder) { - ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT); - x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2); - if (x > 0) + V_DrawBorder (x+1, y, SCREENWIDTH, y+1); + V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT); + } + else + { + x = SCREENWIDTH; + } + + if (x > 0) + { + if(!CompleteBorder) { - y = x == ST_X ? ST_Y : ::ST_Y; x2 = !(ratio & 3) || !Scaled ? ST_X+HorizontalResolution : SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2); - V_DrawBorder (0, y, x, SCREENHEIGHT); - V_DrawBorder (x2, y, SCREENWIDTH, SCREENHEIGHT); + } + else + { + x2 = SCREENWIDTH; + } - if (setblocks >= 10) - { - const gameborder_t *border = gameinfo.border; - FTexture *p; + V_DrawBorder (0, y, x+1, SCREENHEIGHT); + V_DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT); - p = TexMan[border->b]; - screen->FlatFill(0, y, x, y + p->GetHeight(), p, true); - screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true); - } + if (setblocks >= 10) + { + const gameborder_t *border = gameinfo.border; + FTexture *p; + + p = TexMan[border->b]; + screen->FlatFill(0, y, x, y + p->GetHeight(), p, true); + screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true); } } } From ffc4398aa7e8536f0ba73600490bb3ce4c12ac42 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 01:34:29 +0000 Subject: [PATCH 002/101] - Added a 90 degree offset to all voxels, since Build's compass directions start at north rather than east. SVN r3774 (trunk) --- src/g_shared/a_morph.cpp | 12 ++++++------ src/r_data/voxels.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index a027afcc5..862baa30b 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -47,12 +47,12 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i } if (p->morphTics) { // Player is already a beast - if ((p->mo->GetClass() == spawntype) - && (p->mo->PlayerFlags & PPF_CANSUPERMORPH) - && (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE)) - && (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL)) - { // Make a super chicken - p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); + if ((p->mo->GetClass() == spawntype) + && (p->mo->PlayerFlags & PPF_CANSUPERMORPH) + && (p->morphTics < (((duration) ? duration : MORPHTICS) - TICRATE)) + && (p->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true) == NULL)) + { // Make a super chicken + p->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); } return false; } diff --git a/src/r_data/voxels.cpp b/src/r_data/voxels.cpp index 50705c5cc..eca4c89c4 100644 --- a/src/r_data/voxels.cpp +++ b/src/r_data/voxels.cpp @@ -71,7 +71,7 @@ TDeletingArray VoxelDefs; struct VoxelOptions { VoxelOptions() - : DroppedSpin(0), PlacedSpin(0), Scale(FRACUNIT), AngleOffset(0) + : DroppedSpin(0), PlacedSpin(0), Scale(FRACUNIT), AngleOffset(ANGLE_90) {} int DroppedSpin; @@ -332,7 +332,7 @@ FVoxelDef *R_LoadVoxelDef(int lumpnum, int spin) voxdef->Voxel = vox; voxdef->Scale = FRACUNIT; voxdef->DroppedSpin = voxdef->PlacedSpin = spin; - voxdef->AngleOffset = 0; + voxdef->AngleOffset = ANGLE_90; Voxels.Push(vox); VoxelDefs.Push(voxdef); @@ -508,7 +508,7 @@ static void VOX_ReadOptions(FScanner &sc, VoxelOptions &opts) { sc.TokenMustBe(TK_FloatConst); } - opts.AngleOffset = angle_t(sc.Float * ANGLE_180 / 180.0); + opts.AngleOffset = ANGLE_90 + angle_t(sc.Float * ANGLE_180 / 180.0); } else { From f96f665e6399fbb14618accbea8befef536f7e53 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 01:51:02 +0000 Subject: [PATCH 003/101] - Fixed: R_ExtendSpriteFrames() would change spr.spriteframes even when it wasn't moving them around. SVN r3775 (trunk) --- src/r_data/sprites.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 853299228..012abb2f6 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -423,6 +423,10 @@ static void R_ExtendSpriteFrames(spritedef_t &spr, int frame) // at all, so we can tack the new frames directly on to the end // of the SpriteFrames array. newstart = SpriteFrames.Reserve(frame - spr.numframes); + if (spr.numframes == 0) + { + spr.spriteframes = WORD(newstart); + } } else { // We need to allocate space for all the sprite's frames and copy @@ -439,7 +443,6 @@ static void R_ExtendSpriteFrames(spritedef_t &spr, int frame) // Initialize all new frames to 0. memset(&SpriteFrames[newstart], 0, sizeof(spriteframe_t)*(frame - spr.numframes)); spr.numframes = frame; - spr.spriteframes = newstart; } //========================================================================== From 6760a3bfe98ec659639668e6859874908f6ff8bf Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 02:32:04 +0000 Subject: [PATCH 004/101] - Fixed: hud_scale is supposed use strictly integral scaling factors. SVN r3776 (trunk) --- src/g_shared/sbarinfo.cpp | 49 +++++++------------- src/g_shared/sbarinfo.h | 2 + src/g_shared/shared_sbar.cpp | 1 - src/v_video.cpp | 87 ++++++++++++++++++++---------------- src/v_video.h | 1 + 5 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 99158f568..1640899a2 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -149,6 +149,8 @@ class SBarInfoCommand virtual void Reset() {} virtual void Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged) {} + SBarInfo *GetScript() { return script; } + protected: void GetCoordinates(FScanner &sc, bool fullScreenOffsets, SBarInfoCoordinate &x, SBarInfoCoordinate &y) { @@ -798,6 +800,8 @@ void SBarInfo::Init() spacingAlignment = ALIGN_CENTER; resW = 320; resH = 200; + cleanX = -1; + cleanY = -1; for(unsigned int i = 0;i < NUMHUDS;i++) huds[i] = new SBarInfoMainBlock(this); @@ -987,9 +991,18 @@ public: Images.Uninit(); } + void ScreenSizeChanged() + { + V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY); + } + void Draw (EHudState state) { DBaseStatusBar::Draw(state); + if (script->cleanX <= 0) + { // Calculate cleanX and cleanY + ScreenSizeChanged(); + } int hud = STBAR_NORMAL; if(state == HUD_StatusBar) { @@ -1245,8 +1258,8 @@ public: { double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX; - double xScale = !hud_scale ? 1.0 : (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW; - double yScale = !hud_scale ? 1.0 : (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENHEIGHT/(double) script->resH; + double xScale = !hud_scale ? 1 : script->cleanX; + double yScale = !hud_scale ? 1 : script->cleanY; adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale); @@ -1278,34 +1291,6 @@ public: rcy = cy == 0 ? 0 : ry+(((double) cy/FRACUNIT)*yScale); rcr = cr == 0 ? INT_MAX : rx+w-(((double) cr/FRACUNIT)*xScale); rcb = cb == 0 ? INT_MAX : ry+h-(((double) cb/FRACUNIT)*yScale); - - // Fix the clipping for fullscreenoffsets. - /*if(ry < 0) - { - if(rcy != 0) - rcy = hud_scale ? SCREENHEIGHT + (int) (rcy*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcy; - if(rcb != INT_MAX) - rcb = hud_scale ? SCREENHEIGHT + (int) (rcb*CleanYfac*200.0/script->resH) : SCREENHEIGHT + rcb; - } - else if(hud_scale) - { - rcy *= (int) (CleanYfac*200.0/script->resH); - if(rcb != INT_MAX) - rcb *= (int) (CleanYfac*200.0/script->resH); - } - if(rx < 0) - { - if(rcx != 0) - rcx = hud_scale ? SCREENWIDTH + (int) (rcx*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcx; - if(rcr != INT_MAX) - rcr = hud_scale ? SCREENWIDTH + (int) (rcr*CleanXfac*320.0/script->resW) : SCREENWIDTH + rcr; - } - else if(hud_scale) - { - rcx *= (int) (CleanXfac*320.0/script->resW); - if(rcr != INT_MAX) - rcr *= (int) (CleanXfac*320.0/script->resW); - }*/ } if(clearDontDraw) @@ -1365,8 +1350,8 @@ public: { if(hud_scale) { - xScale = (double) CleanXfac*320.0/(double) script->resW;//(double) SCREENWIDTH/(double) script->resW; - yScale = (double) CleanYfac*200.0/(double) script->resH;//(double) SCREENWIDTH/(double) script->resW; + xScale = script->cleanX; + yScale = script->cleanY; } adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale); } diff --git a/src/g_shared/sbarinfo.h b/src/g_shared/sbarinfo.h index d2d81f1f7..1b92b1d80 100644 --- a/src/g_shared/sbarinfo.h +++ b/src/g_shared/sbarinfo.h @@ -108,6 +108,8 @@ struct SBarInfo FMugShot MugShot; int resW; int resH; + int cleanX; + int cleanY; int GetGameType() { return gameType; } void ParseSBarInfo(int lump); diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 57a0d9106..f7054fe22 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -70,7 +70,6 @@ EXTERN_CVAR (Bool, am_showitems) EXTERN_CVAR (Bool, am_showtime) EXTERN_CVAR (Bool, am_showtotaltime) EXTERN_CVAR (Bool, noisedebug) -EXTERN_CVAR (Bool, hud_scale) EXTERN_CVAR (Int, con_scaletext) DBaseStatusBar *StatusBar; diff --git a/src/v_video.cpp b/src/v_video.cpp index 310ca5b2e..ad850f6f4 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1324,10 +1324,7 @@ CCMD(clean) bool V_DoModeSetup (int width, int height, int bits) { DFrameBuffer *buff = I_SetMode (width, height, screen); - int ratio; - int cwidth; - int cheight; - int cx1, cy1, cx2, cy2; + int cx1, cx2; if (buff == NULL) { @@ -1342,41 +1339,7 @@ bool V_DoModeSetup (int width, int height, int bits) // if D3DFB is being used for the display. FFont::StaticPreloadFonts(); - ratio = CheckRatio (width, height); - if (ratio & 4) - { - cwidth = width; - cheight = height * BaseRatioSizes[ratio][3] / 48; - } - else - { - cwidth = width * BaseRatioSizes[ratio][3] / 48; - cheight = height; - } - // Use whichever pair of cwidth/cheight or width/height that produces less difference - // between CleanXfac and CleanYfac. - cx1 = MAX(cwidth / 320, 1); - cy1 = MAX(cheight / 200, 1); - cx2 = MAX(width / 320, 1); - cy2 = MAX(height / 200, 1); - if (abs(cx1 - cy1) <= abs(cx2 - cy2)) - { // e.g. 640x360 looks better with this. - CleanXfac = cx1; - CleanYfac = cy1; - } - else - { // e.g. 720x480 looks better with this. - CleanXfac = cx2; - CleanYfac = cy2; - } - - if (CleanXfac > 1 && CleanYfac > 1 && CleanXfac != CleanYfac) - { - if (CleanXfac < CleanYfac) - CleanYfac = CleanXfac; - else - CleanXfac = CleanYfac; - } + V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2); CleanWidth = width / CleanXfac; CleanHeight = height / CleanYfac; @@ -1426,6 +1389,52 @@ bool V_DoModeSetup (int width, int height, int bits) return true; } +void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2) +{ + int ratio; + int cwidth; + int cheight; + int cx1, cy1, cx2, cy2; + + ratio = CheckRatio(realwidth, realheight); + if (ratio & 4) + { + cwidth = realwidth; + cheight = realheight * BaseRatioSizes[ratio][3] / 48; + } + else + { + cwidth = realwidth * BaseRatioSizes[ratio][3] / 48; + cheight = realheight; + } + // Use whichever pair of cwidth/cheight or width/height that produces less difference + // between CleanXfac and CleanYfac. + cx1 = MAX(cwidth / designwidth, 1); + cy1 = MAX(cheight / designheight, 1); + cx2 = MAX(realwidth / designwidth, 1); + cy2 = MAX(realheight / designheight, 1); + if (abs(cx1 - cy1) <= abs(cx2 - cy2)) + { // e.g. 640x360 looks better with this. + *cleanx = cx1; + *cleany = cy1; + } + else + { // e.g. 720x480 looks better with this. + *cleanx = cx2; + *cleany = cy2; + } + + if (*cleanx > 1 && *cleany > 1 && *cleanx != *cleany) + { + if (*cleanx < *cleany) + *cleany = *cleanx; + else + *cleanx = *cleany; + } + if (_cx1 != NULL) *_cx1 = cx1; + if (_cx2 != NULL) *_cx2 = cx2; +} + bool IVideo::SetResolution (int width, int height, int bits) { int oldwidth, oldheight; diff --git a/src/v_video.h b/src/v_video.h index 6aee6d203..f6a1caeba 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -46,6 +46,7 @@ extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1; extern int DisplayWidth, DisplayHeight, DisplayBits; bool V_DoModeSetup (int width, int height, int bits); +void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *cx1=NULL, int *cx2=NULL); class FTexture; From 23c950ba98ee7ad5d28b00aa47a905a1ec8f2b19 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 02:33:08 +0000 Subject: [PATCH 005/101] - Fix typo: MF6_SEEINVISIBLE is in flags6, not flags. SVN r3777 (trunk) --- src/p_enemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 01e8aafac..3494792e6 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1670,7 +1670,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) // [RC] Well, let's let special monsters with this flag active be able to see // the player then, eh? - if(!(actor->flags & MF6_SEEINVISIBLE)) + if(!(actor->flags6 & MF6_SEEINVISIBLE)) { if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) || player->mo->flags3 & MF3_GHOST) From 5c7e04c539bcb08660a980ebaa775ae9b9d5189b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 02:40:34 +0000 Subject: [PATCH 006/101] - Fixed typo: Midtextures with world panning replaced rw_midtexturemid with the rowoffset instead of adding them together. SVN r3778 (trunk) --- src/r_segs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 41632d240..a40a2ce35 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1965,7 +1965,7 @@ void R_NewWall (bool needlights) } if (midtexture->bWorldPanning) { - rw_midtexturemid = MulScale16(rowoffset, yrepeat); + rw_midtexturemid += MulScale16(rowoffset, yrepeat); } else { From d2843c199e1d5c1513649e733172df9b4e9534da Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 02:58:52 +0000 Subject: [PATCH 007/101] - Fixed: Pain flashes were not inheritable. SVN r3779 (trunk) --- src/info.cpp | 26 ++++++++++++++++++++++++++ src/info.h | 1 + src/v_blend.cpp | 9 +-------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/info.cpp b/src/info.cpp index a1dd4723e..69476d290 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -329,6 +329,32 @@ void FActorInfo::SetPainFlash(FName type, PalEntry color) // //========================================================================== +bool FActorInfo::GetPainFlash(FName type, PalEntry *color) const +{ + const FActorInfo *info = this; + + while (info != NULL) + { + if (info->PainFlashes != NULL) + { + PalEntry *flash = info->PainFlashes->CheckKey(type); + if (flash != NULL) + { + *color = *flash; + return true; + } + } + // Try parent class + info = info->Class->ParentClass->ActorInfo; + } + return false; +} + +//========================================================================== +// +// +//========================================================================== + void FActorInfo::SetColorSet(int index, const FPlayerColorSet *set) { if (set != NULL) diff --git a/src/info.h b/src/info.h index b6da1ccd8..c2962512d 100644 --- a/src/info.h +++ b/src/info.h @@ -224,6 +224,7 @@ struct FActorInfo void SetDamageFactor(FName type, fixed_t factor); void SetPainChance(FName type, int chance); void SetPainFlash(FName type, PalEntry color); + bool GetPainFlash(FName type, PalEntry *color) const; void SetColorSet(int index, const FPlayerColorSet *set); FState *FindState (int numnames, FName *names, bool exact=false) const; diff --git a/src/v_blend.cpp b/src/v_blend.cpp index 1ec7837a0..0faa501ce 100644 --- a/src/v_blend.cpp +++ b/src/v_blend.cpp @@ -120,15 +120,8 @@ void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend); } - PainFlashList * pfl = CPlayer->mo->GetClass()->ActorInfo->PainFlashes; PalEntry painFlash = CPlayer->mo->DamageFade; - - if (pfl) - { - PalEntry * color = pfl->CheckKey(CPlayer->mo->DamageTypeReceived); - - if (color) painFlash = *color; - } + CPlayer->mo->GetClass()->ActorInfo->GetPainFlash(CPlayer->mo->DamageTypeReceived, &painFlash); if (painFlash.a != 0) { From 37dffe210f3ae355d9699146885e288dc022bda7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 03:04:59 +0000 Subject: [PATCH 008/101] - Fixed: player_t::settings_controller was not serialized. SVN r3780 (trunk) --- src/p_user.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_user.cpp b/src/p_user.cpp index e5fd9d7bb..6b853e8b8 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2699,6 +2699,14 @@ void player_t::Serialize (FArchive &arc) { cheats &= ~(1 << 17); // make sure old CF_REGENERATION bit is cleared } + if (SaveVersion >= 3780) + { + arc << settings_controller; + } + else + { + settings_controller = (this - players == Net_Arbitrator); + } if (isbot) { From 12ef53a2ffc2e115b2c8eebbc7ede2b2c9f0a0b1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jul 2012 03:46:36 +0000 Subject: [PATCH 009/101] - snd_midipatchset and fluid_patchset are now processed through NicePath() for variable substitution. In addition, on Windows, if they contain no path separator, they will automatically have $PROGDIR prepended to them. SVN r3781 (trunk) --- src/sound/fmodsound.cpp | 16 +++++++++++++++- src/sound/music_fluidsynth_mididevice.cpp | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 21ba53b5b..b01754324 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1598,6 +1598,7 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla FMOD::Sound *stream; FMOD_RESULT result; bool url; + FString patches; InitCreateSoundExInfo(&exinfo); mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM; @@ -1614,7 +1615,20 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla exinfo.fileoffset = offset; if ((*snd_midipatchset)[0] != '\0') { - exinfo.dlsname = snd_midipatchset; +#ifdef _WIN32 + // If the path does not contain any path separators, automatically + // prepend $PROGDIR to the path. + if (strcspn(snd_midipatchset, ":/\\") == strlen(snd_midipatchset)) + { + patches << "$PROGDIR/" << snd_midipatchset; + patches = NicePath(patches); + } + else +#endif + { + patches = NicePath(snd_midipatchset); + } + exinfo.dlsname = patches; } url = (offset == 0 && length == 0 && strstr(filename_or_data, "://") > filename_or_data); diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index d50e236b7..7914aa256 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -42,6 +42,7 @@ #include "m_swap.h" #include "w_wad.h" #include "v_text.h" +#include "cmdlib.h" // MACROS ------------------------------------------------------------------ @@ -471,7 +472,21 @@ int FluidSynthMIDIDevice::LoadPatchSets(const char *patches) count = 0; while (tok != NULL) { - if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, tok, count == 0)) + FString path; +#ifdef _WIN32 + // If the path does not contain any path separators, automatically + // prepend $PROGDIR to the path. + if (strcspn(tok, ":/\\") == strlen(tok)) + { + path << "$PROGDIR/" << tok; + path = NicePath(path); + } + else +#endif + { + path = NicePath(tok); + } + if (FLUID_FAILED != fluid_synth_sfload(FluidSynth, path, count == 0)) { DPrintf("Loaded patch set %s.\n", tok); count++; From c53a4f3ae18ec5ff09e4d227f5532a6b612c7665 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 22 Jul 2012 03:06:51 +0000 Subject: [PATCH 010/101] - Fixed: 1 pixel border was drawn when there was no status bar. SVN r3782 (trunk) --- src/g_shared/shared_sbar.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index f7054fe22..28741ed47 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1043,8 +1043,11 @@ void DBaseStatusBar::RefreshBackground () const if(!CompleteBorder) { - V_DrawBorder (x+1, y, SCREENWIDTH, y+1); - V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT); + if(y < SCREENHEIGHT) + { + V_DrawBorder (x+1, y, SCREENWIDTH, y+1); + V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT); + } } else { From 6bb6df483af2877d13bf0b6e5f07869778f86bc2 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jul 2012 03:20:34 +0000 Subject: [PATCH 011/101] - Fixed: DSBarInfo::ScreenSizeChanged() must call its supermethod. SVN r3783 (trunk) --- src/g_shared/sbarinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 1640899a2..7e0667062 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -993,6 +993,7 @@ public: void ScreenSizeChanged() { + Super::ScreenSizeChanged(); V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY); } From 22cc0544af343e7a873b2288df28ac8eac01fb97 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jul 2012 04:30:07 +0000 Subject: [PATCH 012/101] - Fixed: FStateDefinitions::FinishStates() must ResolveGotoLabels before resolving labelled gotos. Otherwise, something like this fails: Goto State1 State1: Goto State2 State2: because when "Goto State1" is processed, State1 is still pointing at the string "State2" rather than State2's state, so the goto will end up pointing at a string (which will soon be freed from memory) instead of at an actual state. SVN r3784 (trunk) --- src/p_states.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/p_states.cpp b/src/p_states.cpp index 739249189..aeff2f5b6 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -884,7 +884,6 @@ int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults) { FState *realstates = new FState[count]; int i; - int currange; memcpy(realstates, &StateArray[0], count*sizeof(FState)); actor->OwnedStates = realstates; @@ -892,12 +891,15 @@ int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults) // adjust the state pointers // In the case new states are added these must be adjusted, too! - FixStatePointers (actor, StateLabels); + FixStatePointers(actor, StateLabels); - for(i = currange = 0; i < count; i++) + // Fix state pointers that are gotos + ResolveGotoLabels(actor, defaults, StateLabels); + + for (i = 0; i < count; i++) { // resolve labels and jumps - switch(realstates[i].DefineFlags) + switch (realstates[i].DefineFlags) { case SDF_STOP: // stop realstates[i].NextState = NULL; @@ -916,14 +918,16 @@ int FStateDefinitions::FinishStates (FActorInfo *actor, AActor *defaults) break; case SDF_LABEL: - realstates[i].NextState = ResolveGotoLabel (defaults, actor->Class, (char *)realstates[i].NextState); + realstates[i].NextState = ResolveGotoLabel(defaults, actor->Class, (char *)realstates[i].NextState); break; } } } - - // Fix state pointers that are gotos - ResolveGotoLabels (actor, defaults, StateLabels); + else + { + // Fix state pointers that are gotos + ResolveGotoLabels(actor, defaults, StateLabels); + } return count; } From 2b0cc30f7c76afea04933f904d7c8e0195dd4942 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 26 Jul 2012 04:47:29 +0000 Subject: [PATCH 013/101] - Fixed: The label offset has no business being involved in the positioning of the options menu cursor. Also put the cursor towards the bottom of tall small fonts. SVN r3785 (trunk) --- src/menu/optionmenu.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 4c5b2ef62..6302ffa5b 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -58,8 +58,6 @@ void M_DrawConText (int color, int x, int y, const char *str) { - int len = (int)strlen(str); - screen->DrawText (ConFont, color, x, y, str, DTA_CellX, 8 * CleanXfac_1, DTA_CellY, 8 * CleanYfac_1, @@ -440,7 +438,7 @@ void DOptionMenu::Drawer () { if (((DMenu::MenuTime%8) < 6) || DMenu::CurrentMenu != this) { - M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y-CleanYfac_1+OptionSettings.mLabelOffset, "\xd"); + M_DrawConText(OptionSettings.mFontColorSelection, cur_indent + 3 * CleanXfac_1, y+fontheight-9*CleanYfac_1, "\xd"); } } } From 10f128197777cdfa6a833b896141c93f1988142a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 26 Jul 2012 05:27:37 +0000 Subject: [PATCH 014/101] - Remove LabelOffset from menus entirely and just compute things so that the console font and small font, when mixed on the same line, align at their baselines. SVN r3786 (trunk) --- src/menu/menu.h | 1 - src/menu/menudef.cpp | 2 +- src/menu/messagebox.cpp | 2 +- src/menu/optionmenu.cpp | 6 ++---- src/menu/optionmenuitems.h | 21 +++++++++++---------- src/p_conversation.cpp | 5 +---- 6 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/menu/menu.h b/src/menu/menu.h index a8ec2989b..4ab3d2e10 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -139,7 +139,6 @@ struct FOptionMenuSettings EColorRange mFontColorHighlight; EColorRange mFontColorSelection; int mLinespacing; - int mLabelOffset; }; struct FOptionMenuDescriptor : public FMenuDescriptor diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 349f08bf3..98b1dc34b 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -605,7 +605,7 @@ static void ParseOptionSettings(FScanner &sc) else if (sc.Compare("LabelOffset")) { sc.MustGetNumber(); - OptionSettings.mLabelOffset = sc.Number; + // ignored } else { diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index e415f57c8..a97dc7bba 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -214,7 +214,7 @@ void DMessageBoxMenu::Drawer () { screen->DrawText(ConFont, OptionSettings.mFontColorSelection, (150 - 160) * CleanXfac + screen->GetWidth() / 2, - (y + (fontheight + 1) * messageSelection - 100) * CleanYfac + screen->GetHeight() / 2, + (y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen->GetHeight() / 2, "\xd", DTA_CellX, 8 * CleanXfac, DTA_CellY, 8 * CleanYfac, diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 6302ffa5b..08489fe23 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -398,8 +398,6 @@ void DOptionMenu::Drawer () } } mDesc->mDrawTop = y; - //int labelofs = OptionSettings.mLabelOffset * CleanXfac_1; - //int cursorspace = 14 * CleanXfac_1; int fontheight = OptionSettings.mLinespacing * CleanYfac_1; y *= CleanYfac_1; @@ -449,11 +447,11 @@ void DOptionMenu::Drawer () if (CanScrollUp) { - M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop + OptionSettings.mLabelOffset, "\x1a"); + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, ytop, "\x1a"); } if (CanScrollDown) { - M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1 + OptionSettings.mLabelOffset, "\x1b"); + M_DrawConText(CR_ORANGE, 3 * CleanXfac_1, y - 8*CleanYfac_1, "\x1b"); } Super::Drawer(); } diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 461af0478..d57e13d05 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -407,11 +407,11 @@ public: C_NameKeys (description, Key1, Key2); if (description[0]) { - M_DrawConText(CR_WHITE, indent + CURSORSPACE, y-1+OptionSettings.mLabelOffset, description); + M_DrawConText(CR_WHITE, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, description); } else { - screen->DrawText(SmallFont, CR_BLACK, indent + CURSORSPACE, y + OptionSettings.mLabelOffset, "---", + screen->DrawText(SmallFont, CR_BLACK, indent + CURSORSPACE, y + (OptionSettings.mLinespacing-8)*CleanYfac_1, "---", DTA_CleanNoMove_1, true, TAG_DONE); } return indent; @@ -569,12 +569,13 @@ public: // //============================================================================= - void DrawSlider (int x, int y, double min, double max, double cur,int fracdigits, int indent) + void DrawSlider (int x, int y, double min, double max, double cur, int fracdigits, int indent) { char textbuf[16]; double range; int maxlen = 0; int right = x + (12*8 + 4) * CleanXfac_1; + int cy = y + (OptionSettings.mLinespacing-8)*CleanYfac_1; range = max - min; double ccur = clamp(cur, min, max) - min; @@ -589,14 +590,14 @@ public: if (!mSliderShort) { - M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), y, "\x13"); + M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x12"); + M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 78) / range)) * CleanXfac_1), cy, "\x13"); } else { // On 320x200 we need a shorter slider - M_DrawConText(CR_WHITE, x, y, "\x10\x11\x11\x11\x11\x11\x12"); - M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), y, "\x13"); + M_DrawConText(CR_WHITE, x, cy, "\x10\x11\x11\x11\x11\x11\x12"); + M_DrawConText(CR_ORANGE, x + int((5 + ((ccur * 38) / range)) * CleanXfac_1), cy, "\x13"); right -= 5*8*CleanXfac_1; } @@ -613,7 +614,7 @@ public: { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); mDrawX = indent + CURSORSPACE; - DrawSlider (mDrawX, y + OptionSettings.mLabelOffset, mMin, mMax, GetValue(), mShowValue, indent); + DrawSlider (mDrawX, y, mMin, mMax, GetValue(), mShowValue, indent); return indent; } @@ -777,8 +778,8 @@ public: if (mCVar != NULL) { int box_x = indent + CURSORSPACE; - int box_y = y + OptionSettings.mLabelOffset * CleanYfac_1 / 2; - screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + (SmallFont->GetHeight() - 1) * CleanYfac_1, + int box_y = y + CleanYfac_1; + screen->Clear (box_x, box_y, box_x + 32*CleanXfac_1, box_y + OptionSettings.mLinespacing*CleanYfac_1, -1, (uint32)*mCVar | 0xff000000); } return indent; diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 3ecd4f5f7..380b72de4 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -926,7 +926,6 @@ public: const char *speakerName; int x, y, linesize; int width, fontheight; - int labelofs; player_t *cp = &players[consoleplayer]; @@ -1015,8 +1014,6 @@ public: } y = mYpos; - labelofs = OptionSettings.mLabelOffset; - y -= labelofs; fontheight = OptionSettings.mLinespacing; int response = 0; @@ -1041,7 +1038,7 @@ public: int color = ((DMenu::MenuTime%8) < 4) || DMenu::CurrentMenu != this ? CR_RED:CR_GREY; x = (50 + 3 - 160) * CleanXfac + screen->GetWidth() / 2; - int yy = (y-1+labelofs - 100) * CleanYfac + screen->GetHeight() / 2; + int yy = (y + fontheight/2 - 5 - 100) * CleanYfac + screen->GetHeight() / 2; screen->DrawText (ConFont, color, x, yy, "\xd", DTA_CellX, 8 * CleanXfac, DTA_CellY, 8 * CleanYfac, From d9931431261071e2808c18da0eecb3f61f5d14f3 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 26 Jul 2012 05:36:43 +0000 Subject: [PATCH 015/101] - Remove LabelOffset from menudef.txt. SVN r3787 (trunk) --- wadsrc/static/menudef.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index c555818c4..1b8432462 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -313,11 +313,9 @@ OptionMenuSettings { // These can be overridden if a different menu fonts requires it. Linespacing 8 - LabelOffset 0 IfGame(Heretic, Hexen) { Linespacing 9 - LabelOffset 2 } } From 6bd8fafbad50a52102ff0f8f8c5e39dbe644c485 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 27 Jul 2012 01:44:55 +0000 Subject: [PATCH 016/101] - Fixed: The float bob offsetting in R_ProjectSprite was using r_TicFrac as a millisecond count rather than as a fraction of a tic. SVN r3788 (trunk) --- src/r_things.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index bdfd9f95e..80d0a75bc 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -517,7 +517,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // [RH] Make floatbobbing a renderer-only effect. if (thing->flags2 & MF2_FLOATBOB) { - fz += finesine[(Scale(thing->FloatBobPhase + level.maptime, FINEANGLES, 64) + r_TicFrac * ((FINEANGLES/64) / 1000)) & FINEMASK] * 8; + fz += finesine[MulScale22(((thing->FloatBobPhase + level.maptime) << FRACBITS) + r_TicFrac, FINEANGLES) & FINEMASK] * 8; } // transform the origin point From eea532ce48f27cc5f7ed11aa6aaba6a75a8fe0f1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 27 Jul 2012 01:53:21 +0000 Subject: [PATCH 017/101] - Move the float bob offset calculation into a separate function. SVN r3789 (trunk) --- src/actor.h | 16 ++++++++++++---- src/r_things.cpp | 8 +------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/actor.h b/src/actor.h index 9c4fd9ff7..13ddf91fa 100644 --- a/src/actor.h +++ b/src/actor.h @@ -30,9 +30,7 @@ #include "dthinker.h" -// States are tied to finite states are -// tied to animation frames. -// Needs precompiled tables/data structures. +// States are tied to finite states are tied to animation frames. #include "info.h" #include "doomdef.h" @@ -40,6 +38,7 @@ #include "r_data/renderstyle.h" #include "s_sound.h" #include "memarena.h" +#include "g_level.h" struct subsector_t; // @@ -715,7 +714,16 @@ public: // What species am I? virtual FName GetSpecies(); - + + fixed_t GetBobOffset(fixed_t ticfrac=0) const + { + if (!(flags2 & MF2_FLOATBOB)) + { + return 0; + } + return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8; + } + // Enter the crash state void Crash(); diff --git a/src/r_things.cpp b/src/r_things.cpp index 80d0a75bc..459ebdbce 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -512,13 +512,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // [RH] Interpolate the sprite's position to make it look smooth fx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX); fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY); - fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ); - - // [RH] Make floatbobbing a renderer-only effect. - if (thing->flags2 & MF2_FLOATBOB) - { - fz += finesine[MulScale22(((thing->FloatBobPhase + level.maptime) << FRACBITS) + r_TicFrac, FINEANGLES) & FINEMASK] * 8; - } + fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac); // transform the origin point tr_x = fx - viewx; From 97372c9c05187e100c250d5a5f7ee5c3fcc6d418 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 27 Jul 2012 02:01:36 +0000 Subject: [PATCH 018/101] - Changed A_SpawnItem and A_SpawnItemEx to take the caller's floatbob into account when calculating the spawned actor's z. SVN r3790 (trunk) --- src/thingdef/thingdef_codeptr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 14361d597..5d0ecb938 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1806,7 +1806,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem) AActor * mo = Spawn( missile, self->x + FixedMul(distance, finecosine[self->angle>>ANGLETOFINESHIFT]), self->y + FixedMul(distance, finesine[self->angle>>ANGLETOFINESHIFT]), - self->z - self->floorclip + zheight, ALLOW_REPLACE); + self->z - self->floorclip + self->GetBobOffset() + zheight, ALLOW_REPLACE); int flags = (transfer_translation? SIXF_TRANSFERTRANSLATION:0) + (useammo? SIXF_SETMASTER:0); bool res = InitSpawnedItem(self, mo, flags); @@ -1875,7 +1875,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx) xvel = newxvel; } - AActor * mo = Spawn(missile, x, y, self->z - self->floorclip + zofs, ALLOW_REPLACE); + AActor * mo = Spawn(missile, x, y, self->z - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE); bool res = InitSpawnedItem(self, mo, flags); ACTION_SET_RESULT(res); // for an inventory item's use state if (mo) From 56aeb85eee8e142facafdc984be82b87a2f05db7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 27 Jul 2012 02:35:00 +0000 Subject: [PATCH 019/101] - Fixed: menu_endgame showed no text during a netgame, nor did it block you from ending a netgame. SVN r3791 (trunk) --- src/menu/messagebox.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index a97dc7bba..e7b6abcef 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -466,19 +466,7 @@ IMPLEMENT_CLASS(DEndGameMenu) DEndGameMenu::DEndGameMenu(bool playsound) { - int messageindex = gametic % gameinfo.quitmessages.Size(); - FString EndString = gameinfo.quitmessages[messageindex]; - - if (netgame) - { - EndString = GStrings("NETEND"); - return; - } - - EndString = GStrings("ENDGAME"); - - - Init(NULL, EndString, 0, playsound); + Init(NULL, GStrings(netgame ? "NETEND" : "ENDGAME"), 0, playsound); } //============================================================================= @@ -492,7 +480,10 @@ void DEndGameMenu::HandleResult(bool res) if (res) { M_ClearMenus (); - D_StartTitle (); + if (!netgame) + { + D_StartTitle (); + } } else { From 9c0b0dc774694c419df9d83196c6e7bde43a8643 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 30 Jul 2012 00:05:24 +0000 Subject: [PATCH 020/101] - Add the bob offset to the missiles spawned by P_SpawnMissile(), P_SpawnMissileAngle(), P_SpawnMissileAngleSpeed(), A_MissileAttack, A_ComboAttack, A_BasicAttack, A_CustomMissile, A_CustomComboAttack, A_ThrowGrenade, A_SpawnDebris, and A_Burst. - Add the bob offset to the value returned by GetActorZ. SVN r3795 (trunk) --- src/p_acs.cpp | 4 +++ src/p_mobj.cpp | 6 ++--- src/thingdef/thingdef_codeptr.cpp | 44 +++++++++++++++---------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index ebe473019..a5f046d76 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6346,6 +6346,10 @@ scriptwait: { AActor *actor = SingleActorFromTID(STACK(1), activator); STACK(1) = actor == NULL ? 0 : (&actor->x)[pcd - PCD_GETACTORX]; + if (pcd == PCD_GETACTORZ) + { + pcd += actor->GetBobOffset(); + } } break; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index da023800d..666cb2612 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5291,7 +5291,7 @@ static fixed_t GetDefaultSpeed(const PClass *type) AActor *P_SpawnMissile (AActor *source, AActor *dest, const PClass *type, AActor *owner) { - return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT, + return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT + source->GetBobOffset(), source, dest, type, true, owner); } @@ -5413,7 +5413,7 @@ AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const AActor *P_SpawnMissileAngle (AActor *source, const PClass *type, angle_t angle, fixed_t velz) { - return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, + return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(), type, angle, velz, GetDefaultSpeed (type)); } @@ -5456,7 +5456,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type, angle_t angle, fixed_t velz, fixed_t speed) { - return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT, + return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(), type, angle, velz, speed); } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 5d0ecb938..14e4c3377 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -321,9 +321,9 @@ static void DoAttack (AActor *self, bool domelee, bool domissile, else if (domissile && MissileType != NULL) { // This seemingly senseless code is needed for proper aiming. - self->z+=MissileHeight-32*FRACUNIT; - AActor * missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, MissileType, false); - self->z-=MissileHeight-32*FRACUNIT; + self->z += MissileHeight + self->GetBobOffset() - 32*FRACUNIT; + AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, MissileType, false); + self->z -= MissileHeight + self->GetBobOffset() - 32*FRACUNIT; if (missile) { @@ -880,32 +880,32 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile) angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT; fixed_t x = Spawnofs_XY * finecosine[ang]; fixed_t y = Spawnofs_XY * finesine[ang]; - fixed_t z = SpawnHeight - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0); + fixed_t z = SpawnHeight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0); switch (aimmode) { case 0: default: // same adjustment as above (in all 3 directions this time) - for better aiming! - self->x+=x; - self->y+=y; - self->z+=z; + self->x += x; + self->y += y; + self->z += z; missile = P_SpawnMissileXYZ(self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false); - self->x-=x; - self->y-=y; - self->z-=z; + self->x -= x; + self->y -= y; + self->z -= z; break; case 1: - missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z+SpawnHeight, self, self->target, ti, false); + missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + SpawnHeight, self, self->target, ti, false); break; case 2: - self->x+=x; - self->y+=y; - missile = P_SpawnMissileAngleZSpeed(self, self->z+SpawnHeight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false); - self->x-=x; - self->y-=y; + self->x += x; + self->y += y; + missile = P_SpawnMissileAngleZSpeed(self, self->z + self->GetBobOffset() + SpawnHeight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false); + self->x -= x; + self->y -= y; flags |= CMF_ABSOLUTEPITCH; @@ -1120,9 +1120,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack) else if (ti) { // This seemingly senseless code is needed for proper aiming. - self->z+=SpawnHeight-32*FRACUNIT; - AActor * missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false); - self->z-=SpawnHeight-32*FRACUNIT; + self->z += SpawnHeight + self->GetBobOffset() - 32*FRACUNIT; + AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false); + self->z -= SpawnHeight + self->GetBobOffset() - 32*FRACUNIT; if (missile) { @@ -1920,7 +1920,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade) AActor * bo; bo = Spawn(missile, self->x, self->y, - self->z - self->floorclip + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0), + self->z - self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0), ALLOW_REPLACE); if (bo) { @@ -2263,7 +2263,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris) { mo = Spawn(debris, self->x+((pr_spawndebris()-128)<<12), self->y+((pr_spawndebris()-128)<<12), - self->z+(pr_spawndebris()*self->height/256), ALLOW_REPLACE); + self->z+(pr_spawndebris()*self->height/256+self->GetBobOffset()), ALLOW_REPLACE); if (mo && transfer_translation) { mo->Translation = self->Translation; @@ -2570,7 +2570,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst) mo = Spawn(chunk, self->x + (((pr_burst()-128)*self->radius)>>7), self->y + (((pr_burst()-128)*self->radius)>>7), - self->z + (pr_burst()*self->height/255), ALLOW_REPLACE); + self->z + (pr_burst()*self->height/255 + self->GetBobOffset()), ALLOW_REPLACE); if (mo) { From 0aee56be158a839da3ca907e7f11f28ebdbe58e5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 30 Jul 2012 00:50:19 +0000 Subject: [PATCH 021/101] - Fixed typo in r3795's change to GetActorZ and a potential null pointer dereference. SVN r3796 (trunk) --- src/p_acs.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index a5f046d76..8ab158d48 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6345,10 +6345,17 @@ scriptwait: case PCD_GETACTORZ: { AActor *actor = SingleActorFromTID(STACK(1), activator); - STACK(1) = actor == NULL ? 0 : (&actor->x)[pcd - PCD_GETACTORX]; - if (pcd == PCD_GETACTORZ) + if (actor == NULL) { - pcd += actor->GetBobOffset(); + STACK(1) = 0; + } + else if (pcd == PCD_GETACTORZ) + { + STACK(1) = actor->z + actor->GetBobOffset(); + } + else + { + STACK(1) = (&actor->x)[pcd - PCD_GETACTORX]; } } break; From 67f64081d0fc3e6ff14a2882f2f18aaa0598212d Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 30 Jul 2012 09:31:04 +0000 Subject: [PATCH 022/101] - Changed unix config directory from ~/.zdoom to ~/.config/zdoom to comply with Ubuntu Software Centre guidelines. SVN r3797 (trunk) --- src/m_misc.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/p_glnodes.cpp | 2 +- src/version.h | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 08149ad96..32783236e 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -340,9 +340,41 @@ FString GetUserFile (const char *file) struct stat info; path = NicePath("~/" GAME_DIR "/"); + if (stat (path, &info) == -1) { - if (mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + struct stat extrainfo; + + // Sanity check for ~/.config + FString configPath = NicePath("~/.config/"); + if (stat (configPath, &extrainfo) == -1) + { + if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + { + I_FatalError ("Failed to create ~/.config directory:\n%s", strerror(errno)); + } + } + else if (!S_ISDIR(extrainfo.st_mode)) + { + I_FatalError ("~/.config must be a directory"); + } + + // This can be removed after a release or two + // Transfer the old zdoom directory to the new location + bool moved = false; + FString oldpath = NicePath("~/.zdoom/"); + if (stat (oldpath, &extrainfo) != -1) + { + if (rename(oldpath, path) == -1) + { + I_Error ("Failed to move old zdoom directory (%s) to new location (%s).", + oldpath.GetChars(), path.GetChars()); + } + else + moved = true; + } + + if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) { I_FatalError ("Failed to create %s directory:\n%s", path.GetChars(), strerror (errno)); @@ -682,7 +714,7 @@ void M_ScreenShot (const char *filename) if (dirlen == 0) { #ifdef unix - autoname = "~/.zdoom/screenshots/"; + autoname = "~/" GAME_DIR "/screenshots/"; #elif defined(__APPLE__) char cpath[PATH_MAX]; FSRef folder; diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 95c078eb8..ee32df4b0 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1088,7 +1088,7 @@ static FString GetCachePath() path += "/zdoom/cache"; #else // Don't use GAME_DIR and such so that ZDoom and its child ports can share the node cache. - path = NicePath("~/.zdoom/cache"); + path = NicePath("~/.config/zdoom/cache"); #endif return path; } diff --git a/src/version.h b/src/version.h index 00fa5371e..b8d15d1b0 100644 --- a/src/version.h +++ b/src/version.h @@ -116,7 +116,7 @@ static inline const char *MakeSaveSig() #define BUGS_FORUM_URL "http://forum.zdoom.org/index.php?c=3" #ifdef unix -#define GAME_DIR ".zdoom" +#define GAME_DIR ".config/zdoom" #elif defined(__APPLE__) #define GAME_DIR GAMENAME #else From 8c465df44e49204c393f36107175d4e5cf3e57de Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 1 Aug 2012 03:12:43 +0000 Subject: [PATCH 023/101] - Added ACS function IsTIDUsed(tid): It returns whether any actors using the given TID exist. This is more efficient than ThingCount(tid, T_NONE), because it only needs to check for one actor with the TID and not all of them. It also makes no distinction between dead things and live things like ThingCount does. - Added ACS function UniqueTID(tid, limit): It returns a new TID that is not currently used by any actors. It has two modes of operation. If tid is non-zero, then it checks TIDs one-by-one starting at the given tid until if finds a free one. If tid is zero, then it returns a completely random TID. If limit is non-zero, then it will only check that many times for a free TID, so it might not find a free one. If no free TID is found, 0 is returned. If limit is zero, then the search is effectively unlimited. SVN r3798 (trunk) --- src/actor.h | 4 +++ src/p_acs.cpp | 10 ++++++ src/p_mobj.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/actor.h b/src/actor.h index 13ddf91fa..a0fd4578e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -976,6 +976,7 @@ private: static FSharedStringArena mStringPropertyData; friend class FActorIterator; + friend bool P_IsTIDUsed(int tid); sector_t *LinkToWorldForMapThing (); @@ -1070,6 +1071,9 @@ public: } }; +bool P_IsTIDUsed(int tid); +int P_FindUniqueTID(int start_tid, int limit); + inline AActor *Spawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) { return AActor::StaticSpawn (type, x, y, z, allowreplacement); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 8ab158d48..fe2001411 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3363,6 +3363,8 @@ enum EACSFunctions ACSF_ACS_NamedLockedExecuteDoor, ACSF_ACS_NamedExecuteWithResult, ACSF_ACS_NamedExecuteAlways, + ACSF_UniqueTID, + ACSF_IsTIDUsed, // ZDaemon ACSF_GetTeamScore = 19620, @@ -3879,6 +3881,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) } break; + case ACSF_UniqueTID: + return P_FindUniqueTID(argCount > 0 ? args[0] : 0, argCount > 1 ? args[1] : 0); + break; + + case ACSF_IsTIDUsed: + return P_IsTIDUsed(args[0]); + break; + default: break; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 666cb2612..938c976f3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -37,6 +37,7 @@ #include "doomstat.h" #include "v_video.h" #include "c_cvars.h" +#include "c_dispatch.h" #include "b_bot.h" //Added by MC: #include "stats.h" #include "a_hexenglobal.h" @@ -107,6 +108,7 @@ static FRandom pr_missiledamage ("MissileDamage"); FRandom pr_slam ("SkullSlam"); static FRandom pr_multiclasschoice ("MultiClassChoice"); static FRandom pr_rockettrail("RocketTrail"); +static FRandom pr_uniquetid("UniqueTID"); // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -2612,10 +2614,7 @@ AActor *AActor::TIDHash[128]; void AActor::ClearTIDHashes () { - int i; - - for (i = 0; i < 128; i++) - TIDHash[i] = NULL; + memset(TIDHash, NULL, sizeof(TIDHash)); } // @@ -2666,6 +2665,92 @@ void AActor::RemoveFromHash () tid = 0; } +//========================================================================== +// +// P_IsTIDUsed +// +// Returns true if there is at least one actor with the specified TID +// (dead or alive). +// +//========================================================================== + +bool P_IsTIDUsed(int tid) +{ + AActor *probe = AActor::TIDHash[tid & 127]; + while (probe != NULL) + { + if (probe->tid == tid) + { + return true; + } + probe = probe->inext; + } + return false; +} + +//========================================================================== +// +// P_FindUniqueTID +// +// Returns an unused TID. If start_tid is 0, then a random TID will be +// chosen. Otherwise, it will perform a linear search starting from +// start_tid. If limit is non-0, then it will not check more than +// number of TIDs. Returns 0 if no suitable TID was found. +// +//========================================================================== + +int P_FindUniqueTID(int start_tid, int limit) +{ + int tid; + + if (start_tid != 0) + { // Do a linear search. + limit = start_tid + limit - 1; + if (limit < start_tid) + { // If it overflowed, clamp to INT_MAX + limit = INT_MAX; + } + for (tid = start_tid; tid <= limit; ++tid) + { + if (tid != 0 && !P_IsTIDUsed(tid)) + { + return tid; + } + } + // Nothing free found. + return 0; + } + // Do a random search. To try and be a bit more performant, this + // actually does several linear searches. In the case of *very* + // dense TID usage, this could potentially perform worse than doing + // a complete linear scan starting at 1. However, you would need + // to use an absolutely ridiculous number of actors before this + // becomes a real concern. + if (limit == 0) + { + limit = INT_MAX; + } + for (int i = 0; i < limit; i += 5) + { + // Use a positive starting TID. + tid = pr_uniquetid.GenRand32() & INT_MAX; + tid = P_FindUniqueTID(tid == 0 ? 1 : tid, 5); + if (tid != 0) + { + return tid; + } + } + // Nothing free found. + return 0; +} + +CCMD(utid) +{ + Printf("%d\n", + P_FindUniqueTID(argv.argc() > 1 ? atoi(argv[1]) : 0, + argv.argc() > 2 ? atoi(argv[2]) : 0)); +} + //========================================================================== // // AActor :: GetMissileDamage From a05169748866d8bc0f43ee44e393157c06f02239 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 2 Aug 2012 03:44:13 +0000 Subject: [PATCH 024/101] - Since ZDoom hasn't actually run on Windows 95 in some time, and nobody has complained, remove the IsDebuggerPresent thunk. SVN r3800 (trunk) --- src/win32/wrappers.asm | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 src/win32/wrappers.asm diff --git a/src/win32/wrappers.asm b/src/win32/wrappers.asm deleted file mode 100644 index 6754ff12b..000000000 --- a/src/win32/wrappers.asm +++ /dev/null @@ -1,39 +0,0 @@ -; The Visual C++ CRT unconditionally links to IsDebuggerPresent. -; This function is not available under Windows 95, so here is a -; lowlevel replacement for it. - -extern __imp__GetModuleHandleA@4 -extern __imp__GetProcAddress@8 - - SECTION .data - -global __imp__IsDebuggerPresent@0 -__imp__IsDebuggerPresent@0: - dd IsDebuggerPresent_Check - - SECTION .rdata - -StrKERNEL32: - db "KERNEL32",0 - -StrIsDebuggerPresent: - db "IsDebuggerPresent",0 - - SECTION .text - -IsDebuggerPresent_No: - xor eax,eax - ret - -IsDebuggerPresent_Check: - push StrKERNEL32 - call [__imp__GetModuleHandleA@4] - push StrIsDebuggerPresent - push eax - call [__imp__GetProcAddress@8] - test eax,eax - jne near .itis - mov eax,IsDebuggerPresent_No -.itis: - mov [__imp__IsDebuggerPresent@0],eax - jmp eax From 4cdf524e6ccacbf2fbb261351c18a8712c288c40 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 2 Aug 2012 03:44:48 +0000 Subject: [PATCH 025/101] - Remove wrappers.asm from the project file too. SVN r3801 (trunk) --- zdoom.vcproj | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/zdoom.vcproj b/zdoom.vcproj index aa00d21b3..5ec9fc34f 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2028,46 +2028,6 @@ RelativePath=".\src\win32\win32video.cpp" > - - - - - - - - - - - - - - Date: Thu, 2 Aug 2012 04:00:40 +0000 Subject: [PATCH 026/101] - Change the text when riched20.dll cannot be loaded, and also display it with MessageBox, since it's far too early to be used with I_FatalError. (But since this should always be available on every Windows version after 95, this should be a non-issue.) - Make unknown OS versions default to Windows 2000 instead of Windows 95. SVN r3802 (trunk) --- src/win32/i_main.cpp | 12 ++++++------ src/win32/i_system.cpp | 4 ++-- src/win32/win32video.cpp | 4 ---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 4079fcae7..a11233e29 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1224,14 +1224,14 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n InitCommonControls (); // Load some needed controls and be pretty under XP + // We need to load riched20.dll so that we can create the control. if (NULL == LoadLibrary ("riched20.dll")) { - // Technically, it isn't really Internet Explorer that is needed, but this - // is an example of a specific program that will provide riched20.dll. - // But considering how much extra stuff needs to be installed to make Windows 95 - // useable with pretty much any recent software, the chances are high that - // the user already has riched20.dll installed. - I_FatalError ("Sorry, you need to install Internet Explorer 3 or higher to play ZDoom on Windows 95."); + // This should only happen on basic Windows 95 installations, but since we + // don't support Windows 95, we have no obligation to provide assistance in + // getting it installed. + MessageBoxA(NULL, "Could not load riched20.dll", "ZDoom Error", MB_OK | MB_ICONSTOP); + exit(0); } #if !defined(__GNUC__) && defined(_DEBUG) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index ae2e86d32..e28ce07a7 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -607,8 +607,8 @@ void I_DetectOS(void) if (OSPlatform == os_unknown) { - Printf ("(Assuming Windows 95)\n"); - OSPlatform = os_Win95; + Printf ("(Assuming Windows 2000)\n"); + OSPlatform = os_Win2k; } } diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index d82744ef7..adc68af23 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -389,10 +389,6 @@ void Win32Video::DumpAdapters() { *p = '\0'; } - // Get monitor info from GDI for more details. Windows 95 apparently does not have - // the GetMonitorInfo function. I will leave this like this for now instead of using - // GetProcAddress to see if it's still worth worrying about Windows 95 support. - // (e.g. Will anybody complain that they can't run ZDoom anymore?) HMONITOR hm = D3D->GetAdapterMonitor(i); MONITORINFOEX mi; mi.cbSize = sizeof(mi); From 26f9540d3c7d9ec2c769ef5d7e26f7cf56d0e753 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Aug 2012 01:42:49 +0000 Subject: [PATCH 027/101] - Fixed: I missed a nuance of the MIDI spec when writing MIDIStreamer::CreateSMF(): Running status is supposed to be canceled by sysex events and meta events. This confused FMOD when the resulting song used used running status right after these events. SVN r3803 (trunk) --- src/sound/music_midistream.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 30d8ba6f6..08edc2961 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -1130,7 +1130,7 @@ void MIDIStreamer::Precache() void MIDIStreamer::CreateSMF(TArray &file, int looplimit) { DWORD delay = 0; - BYTE running_status = 0; + BYTE running_status = 255; // Always create songs aimed at GM devices. CheckCaps(MOD_MIDIPORT); @@ -1163,6 +1163,7 @@ void MIDIStreamer::CreateSMF(TArray &file, int looplimit) file.Push(BYTE(tempo >> 16)); file.Push(BYTE(tempo >> 8)); file.Push(BYTE(tempo)); + running_status = 255; } else if (MEVT_EVENTTYPE(event[2]) == MEVT_LONGMSG) { @@ -1176,6 +1177,7 @@ void MIDIStreamer::CreateSMF(TArray &file, int looplimit) file.Push(MIDI_SYSEX); WriteVarLen(file, len); memcpy(&file[file.Reserve(len - 1)], bytes, len); + running_status = 255; } } else if (MEVT_EVENTTYPE(event[2]) == 0) From 6e81216bbd18a476fdd2b7498741b8b7e0990c7c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Aug 2012 02:14:32 +0000 Subject: [PATCH 028/101] - Fixed: The softsynths did not reset the tempo to its initial value when restarting a song. SVN r3804 (trunk) --- src/sound/music_midistream.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 08edc2961..ba0077903 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -944,7 +944,13 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) if (Restarting) { Restarting = false; - events = WriteStopNotes(events); // Stop all notes in case any were left hanging. + // Reset the tempo to the inital value. + events[0] = 0; // dwDeltaTime + events[1] = 0; // dwStreamID + events[2] = (MEVT_TEMPO << 24) | InitialTempo; // dwEvent + events += 3; + // Stop all notes in case any were left hanging. + events = WriteStopNotes(events); DoRestart(); } events = MakeEvents(events, max_event_p, max_time); From 0d631a9075af6e6861e9d0baf579b26db97ca2a7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Aug 2012 02:42:16 +0000 Subject: [PATCH 029/101] - Fixed: The nextmap and nextsecret ccmds should be disabled in network games. SVN r3805 (trunk) --- src/c_cmds.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 56a9bcf36..9c7b781d2 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -949,9 +949,16 @@ CCMD(thaw) //----------------------------------------------------------------------------- CCMD(nextmap) { - char * next=NULL; + if (netgame) + { + Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextmap" + TEXTCOLOR_NORMAL" is for single-player only.\n"); + return; + } + char *next = NULL; - if (*level.nextmap) next = level.nextmap; + if (*level.nextmap) + next = level.nextmap; if (next != NULL && strncmp(next, "enDSeQ", 6)) { @@ -970,9 +977,16 @@ CCMD(nextmap) //----------------------------------------------------------------------------- CCMD(nextsecret) { - char * next=NULL; + if (netgame) + { + Printf ("Use "TEXTCOLOR_BOLD"changemap"TEXTCOLOR_NORMAL" instead. "TEXTCOLOR_BOLD"Nextsecret" + TEXTCOLOR_NORMAL" is for single-player only.\n"); + return; + } + char *next = NULL; - if (*level.secretmap) next = level.secretmap; + if (*level.secretmap) + next = level.secretmap; if (next != NULL && strncmp(next, "enDSeQ", 6)) { From 4ac8f5eae4803438ef467c8b40da768ae7d7a595 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 4 Aug 2012 03:01:17 +0000 Subject: [PATCH 030/101] - Fixed: FMultiPatchTexture::CopyTrueColorPixels() set up the alpha values backwards for blend mode BLEND_OVERLAY. SVN r3806 (trunk) --- src/textures/multipatchtexture.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 1a884472a..5d5f61062 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -608,10 +608,11 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota } else { - info.blendcolor[3] = b.a * FRACUNIT / 255; - info.blendcolor[0] = b.r * (FRACUNIT-info.blendcolor[3]); - info.blendcolor[1] = b.g * (FRACUNIT-info.blendcolor[3]); - info.blendcolor[2] = b.b * (FRACUNIT-info.blendcolor[3]); + fixed_t blendalpha = b.a * FRACUNIT / 255; + info.blendcolor[0] = b.r * blendalpha; + info.blendcolor[1] = b.g * blendalpha; + info.blendcolor[2] = b.b * blendalpha; + info.blendcolor[3] = FRACUNIT - blendalpha; info.blend = BLEND_OVERLAY; } } From cb413c600eb0d8a6a7129b126092bc550d403f5b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 6 Aug 2012 09:49:15 +0000 Subject: [PATCH 031/101] - Fixed: Memory error when loading BMF palettes. - Fixed: When locating WhiteIndex and BlackIndex in the palette index 0 was skipped. - Fixed: When filling an area black for vid_fps or pillarbox/letterbox use GPalette.BlackIndex instead of assuming palette index 0 is black. SVN r3807 (trunk) --- src/v_draw.cpp | 8 ++++---- src/v_font.cpp | 4 ++-- src/v_palette.cpp | 4 ++-- src/v_video.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index f399e4e53..87b4e0842 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -837,10 +837,10 @@ void DCanvas::FillBorder (FTexture *img) } else { - Clear (0, 0, Width, bordtop, 0, 0); // Top - Clear (0, bordtop, bordleft, Height - bordbottom, 0, 0); // Left - Clear (Width - bordright, bordtop, Width, Height - bordbottom, 0, 0); // Right - Clear (0, Height - bordbottom, Width, Height, 0, 0); // Bottom + Clear (0, 0, Width, bordtop, GPalette.BlackIndex, 0); // Top + Clear (0, bordtop, bordleft, Height - bordbottom, GPalette.BlackIndex, 0); // Left + Clear (Width - bordright, bordtop, Width, Height - bordbottom, GPalette.BlackIndex, 0); // Right + Clear (0, Height - bordbottom, Width, Height, GPalette.BlackIndex, 0); // Bottom } } diff --git a/src/v_font.cpp b/src/v_font.cpp index b7d5392cd..e95613f7b 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1304,7 +1304,7 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY identity[0] = 0; palette += 3; // Skip the transparent color - for (i = 1; i <= ActiveColors; ++i, palette += 3) + for (i = 1; i < ActiveColors; ++i, palette += 3) { int r = palette[0]; int g = palette[1]; @@ -1331,7 +1331,7 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY { diver = 1.0 / 255.0; } - for (i = 1; i <= ActiveColors; ++i) + for (i = 1; i < ActiveColors; ++i) { luminosity[i] = (luminosity[i] - minlum) * diver; } diff --git a/src/v_palette.cpp b/src/v_palette.cpp index fa8ed4615..92182311b 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -159,8 +159,8 @@ void FPalette::SetPalette (const BYTE *colors) // Find white and black from the original palette so that they can be // used to make an educated guess of the translucency % for a BOOM // translucency map. - WhiteIndex = BestColor ((DWORD *)BaseColors, 255, 255, 255); - BlackIndex = BestColor ((DWORD *)BaseColors, 0, 0, 0); + WhiteIndex = BestColor ((DWORD *)BaseColors, 255, 255, 255, 0, 255); + BlackIndex = BestColor ((DWORD *)BaseColors, 0, 0, 0, 0, 255); } // In ZDoom's new texture system, color 0 is used as the transparent color. diff --git a/src/v_video.cpp b/src/v_video.cpp index ad850f6f4..e6145cc95 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -859,7 +859,7 @@ void DFrameBuffer::DrawRateStuff () chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2u ms (%3u fps)", howlong, LastCount); rate_x = Width - chars * 8; - Clear (rate_x, 0, Width, 8, 0, 0); + Clear (rate_x, 0, Width, 8, GPalette.BlackIndex, 0); DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0], TAG_DONE); DWORD thisSec = ms/1000; From 70d8daa34144d0eb8d96bc688654642ae190e88f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 6 Aug 2012 10:25:51 +0000 Subject: [PATCH 032/101] - Merged some ECWolf's font code changes. In particular support for retranslating the fonts should the palette change at run time. (This required storing what lump the font was generated from for FON1. This information is stored in FFont since ECWolf also uses the information to allow FONTDEF fonts to be overriden with single lump fonts consistently, but I didn't merge that part as it might break something.) SVN r3808 (trunk) --- src/v_font.cpp | 327 +++++++++++++++++++++++++++++++++++++------------ src/v_font.h | 9 +- 2 files changed, 254 insertions(+), 82 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index e95613f7b..8fb0a2400 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -124,16 +124,26 @@ public: FSingleLumpFont (const char *fontname, int lump); protected: - void CheckFON1Chars (int lump, const BYTE *data, double *luminosity); + void CheckFON1Chars (double *luminosity); void BuildTranslations2 (); void FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette, bool rescale, PalEntry *out_palette); + void LoadTranslations (); void LoadFON1 (int lump, const BYTE *data); void LoadFON2 (int lump, const BYTE *data); void LoadBMF (int lump, const BYTE *data); void CreateFontFromPic (FTextureID picnum); static int STACK_ARGS BMFCompare(const void *a, const void *b); + + enum + { + FONT1, + FONT2, + BMFFONT + } FontType; + BYTE PaletteData[768]; + bool RescalePalette; }; class FSinglePicFont : public FFont @@ -153,16 +163,22 @@ protected: class FSpecialFont : public FFont { public: - FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate); + FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump); + + void LoadTranslations(); + +protected: + bool notranslate[256]; }; // This is a font character that loads a texture and recolors it. class FFontChar1 : public FTexture { public: - FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap); + FFontChar1 (FTexture *sourcelump); const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); + void SetSourceRemap(const BYTE *sourceremap); void Unload (); ~FFontChar1 (); @@ -178,11 +194,12 @@ protected: class FFontChar2 : public FTexture { public: - FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0); + FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); + void SetSourceRemap(const BYTE *sourceremap); void Unload (); protected: @@ -322,18 +339,17 @@ FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font) // //========================================================================== -FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start) +FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump) { int i; FTextureID lump; char buffer[12]; FTexture **charlumps; - BYTE usedcolors[256], identity[256]; - double *luminosity; int maxyoffs; bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false; bool stcfn121 = false; + Lump = fdlump; Chars = new CharData[count]; charlumps = new FTexture *[count]; PatchRemap = new BYTE[256]; @@ -341,7 +357,6 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; - memset (usedcolors, 0, 256); Name = copystring (name); Next = FirstFont; FirstFont = this; @@ -392,18 +407,12 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { FontHeight = height; } - RecordTextureColors (pic, usedcolors); } } - } - ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); - - for (i = 0; i < count; i++) - { if (charlumps[i] != NULL) { - Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap); + Chars[i].Pic = new FFontChar1 (charlumps[i]); Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); } else @@ -424,9 +433,8 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, FixXMoves(); - BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); + LoadTranslations(); - delete[] luminosity; delete[] charlumps; } @@ -803,6 +811,42 @@ int FFont::GetCharWidth (int code) const return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove; } +//========================================================================== +// +// FFont :: LoadTranslations +// +//========================================================================== + +void FFont::LoadTranslations() +{ + unsigned int count = LastChar - FirstChar + 1; + BYTE usedcolors[256], identity[256]; + double *luminosity; + + memset (usedcolors, 0, 256); + for (unsigned int i = 0; i < count; i++) + { + FFontChar1 *pic = static_cast(Chars[i].Pic); + if(pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + RecordTextureColors (pic, usedcolors); + } + } + + ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); + + for (unsigned int i = 0; i < count; i++) + { + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + } + + BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); + + delete[] luminosity; +} + //========================================================================== // // FFont :: Preload @@ -854,8 +898,9 @@ void FFont::StaticPreloadFonts() // //========================================================================== -FFont::FFont () +FFont::FFont (int lump) { + Lump = lump; Chars = NULL; PatchRemap = NULL; Name = NULL; @@ -869,7 +914,7 @@ FFont::FFont () // //========================================================================== -FSingleLumpFont::FSingleLumpFont (const char *name, int lump) +FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) { assert(lump >= 0); @@ -927,6 +972,51 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) ActiveColors = 0; } +//========================================================================== +// +// FSingleLumpFont :: LoadTranslations +// +//========================================================================== + +void FSingleLumpFont::LoadTranslations() +{ + double luminosity[256]; + BYTE identity[256]; + PalEntry local_palette[256]; + bool useidentity = true; + bool usepalette = false; + const void* ranges; + unsigned int count = LastChar - FirstChar + 1; + + switch(FontType) + { + case FONT1: + useidentity = false; + ranges = &TranslationParms[1][0]; + CheckFON1Chars (luminosity); + break; + + case BMFFONT: + case FONT2: + usepalette = true; + FixupPalette (identity, luminosity, PaletteData, RescalePalette, local_palette); + + ranges = &TranslationParms[0][0]; + break; + + default: + break; + } + + for(unsigned int i = 0;i < count;++i) + { + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + } + + BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL); +} + //========================================================================== // // FSingleLumpFont :: LoadFON1 @@ -937,7 +1027,6 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) { - double luminosity[256]; int w, h; Chars = new CharData[256]; @@ -945,6 +1034,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) w = data[4] + data[5]*256; h = data[6] + data[7]*256; + FontType = FONT1; FontHeight = h; SpaceWidth = w; FirstChar = 0; @@ -952,8 +1042,10 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) GlobalKerning = 0; PatchRemap = new BYTE[256]; - CheckFON1Chars (lump, data, luminosity); - BuildTranslations (luminosity, NULL, &TranslationParms[1][0], ActiveColors, NULL); + for(unsigned int i = 0;i < 256;++i) + Chars[i].Pic = NULL; + + LoadTranslations(); } //========================================================================== @@ -969,17 +1061,17 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) { int count, i, totalwidth; int *widths2; - BYTE identity[256]; - double luminosity[256]; - PalEntry local_palette[256]; WORD *widths; const BYTE *palette; const BYTE *data_p; + FontType = FONT2; FontHeight = data[4] + data[5]*256; FirstChar = data[6]; LastChar = data[7]; ActiveColors = data[10]; + PatchRemap = NULL; + RescalePalette = data[9] == 0; count = LastChar - FirstChar + 1; Chars = new CharData[count]; @@ -1029,7 +1121,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) SpaceWidth = totalwidth * 2 / (3 * count); } - FixupPalette (identity, luminosity, palette, data[9] == 0, local_palette); + memcpy(PaletteData, palette, 768); data_p = palette + (ActiveColors+1)*3; @@ -1043,7 +1135,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) } else { - Chars[i].Pic = new FFontChar2 (lump, NULL, int(data_p - data), widths2[i], FontHeight); + Chars[i].Pic = new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight); do { SBYTE code = *data_p++; @@ -1066,7 +1158,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) } } - BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette); + LoadTranslations(); delete[] widths2; } @@ -1087,15 +1179,14 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) int i, chari; BYTE raw_palette[256*3]; PalEntry sort_palette[256]; - PalEntry local_palette[256]; - double luminosity[256]; - BYTE identity[256]; + FontType = BMFFONT; FontHeight = data[5]; GlobalKerning = (SBYTE)data[8]; ActiveColors = data[16]; SpaceWidth = -1; nwidth = -1; + RescalePalette = true; infolen = data[17 + ActiveColors*3]; chardata = data + 18 + ActiveColors*3 + infolen; @@ -1160,7 +1251,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) PatchRemap[sort_palette[i].a] = i; } - FixupPalette(identity, luminosity, raw_palette, true, local_palette); + memcpy(PaletteData, raw_palette, 768); // Now scan through the characters again, creating glyphs for each one. for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2]) @@ -1180,7 +1271,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) { // Empty character: skip it. continue; } - Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data), + Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, int(chardata + chari + 6 - data), chardata[chari+1], // width chardata[chari+2], // height -(SBYTE)chardata[chari+3], // x offset @@ -1202,7 +1293,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) } FixXMoves(); - BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette); + LoadTranslations(); } //========================================================================== @@ -1232,8 +1323,11 @@ int STACK_ARGS FSingleLumpFont::BMFCompare(const void *a, const void *b) // //========================================================================== -void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *luminosity) +void FSingleLumpFont::CheckFON1Chars (double *luminosity) { + FMemLump memLump = Wads.ReadLump(Lump); + const BYTE* data = (const BYTE*) memLump.GetMem(); + BYTE used[256], reverse[256]; const BYTE *data_p; int i, j; @@ -1245,8 +1339,11 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino { int destSize = SpaceWidth * FontHeight; - Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight); - Chars[i].XMove = SpaceWidth; + if(!Chars[i].Pic) + { + Chars[i].Pic = new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight); + Chars[i].XMove = SpaceWidth; + } // Advance to next char's data and count the used colors. do @@ -1347,7 +1444,8 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY // //========================================================================== -FSinglePicFont::FSinglePicFont(const char *picname) +FSinglePicFont::FSinglePicFont(const char *picname) : + FFont(-1) // Since lump is only needed for priority information we don't need to worry about this here. { FTextureID picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Any); @@ -1413,8 +1511,8 @@ int FSinglePicFont::GetCharWidth (int code) const // //========================================================================== -FFontChar1::FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap) -: SourceRemap (sourceremap) +FFontChar1::FFontChar1 (FTexture *sourcelump) +: SourceRemap (NULL) { UseType = FTexture::TEX_FontChar; BaseTexture = sourcelump; @@ -1453,9 +1551,16 @@ void FFontChar1::MakeTexture () Pixels = new BYTE[Width*Height]; const BYTE *pix = BaseTexture->GetPixels(); - for (int x = 0; x < Width*Height; ++x) + if (!SourceRemap) { - Pixels[x] = SourceRemap[pix[x]]; + memcpy(Pixels, pix, Width*Height); + } + else + { + for (int x = 0; x < Width*Height; ++x) + { + Pixels[x] = SourceRemap[pix[x]]; + } } } @@ -1476,6 +1581,18 @@ const BYTE *FFontChar1::GetColumn (unsigned int column, const Span **spans_out) return Pixels + column*Height; } +//========================================================================== +// +// FFontChar1 :: SetSourceRemap +// +//========================================================================== + +void FFontChar1::SetSourceRemap(const BYTE *sourceremap) +{ + Unload(); + SourceRemap = sourceremap; +} + //========================================================================== // // FFontChar1 :: Unload @@ -1510,8 +1627,8 @@ FFontChar1::~FFontChar1 () // //========================================================================== -FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap) +FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) +: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(NULL) { UseType = TEX_FontChar; Width = width; @@ -1594,6 +1711,18 @@ const BYTE *FFontChar2::GetColumn (unsigned int column, const Span **spans_out) return Pixels + column*Height; } +//========================================================================== +// +// FFontChar2 :: SetSourceRemap +// +//========================================================================== + +void FFontChar2::SetSourceRemap(const BYTE *sourceremap) +{ + Unload(); + SourceRemap = sourceremap; +} + //========================================================================== // // FFontChar2 :: MakeTexture @@ -1730,16 +1859,15 @@ void FFontChar2::MakeTexture () // //========================================================================== -FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate) +FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump) : FFont(lump) { int i, j; FTexture **charlumps; - BYTE usedcolors[256], identity[256]; - double *luminosity; int maxyoffs; - int TotalColors; FTexture *pic; - + + memcpy(this->notranslate, notranslate, 256*sizeof(bool)); + Name = copystring(name); Chars = new CharData[count]; charlumps = new FTexture*[count]; @@ -1748,7 +1876,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; - memset (usedcolors, 0, 256); Next = FirstFont; FirstFont = this; @@ -1771,7 +1898,58 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l { FontHeight = height; } + } + if (charlumps[i] != NULL) + { + Chars[i].Pic = new FFontChar1 (charlumps[i]); + Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); + } + else + { + Chars[i].Pic = NULL; + Chars[i].XMove = INT_MIN; + } + } + + // Special fonts normally don't have all characters so be careful here! + if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) + { + SpaceWidth = (Chars['N' - first].XMove + 1) / 2; + } + else + { + SpaceWidth = 4; + } + + FixXMoves(); + + LoadTranslations(); + + delete[] charlumps; +} + +//========================================================================== +// +// FSpecialFont :: LoadTranslations +// +//========================================================================== + +void FSpecialFont::LoadTranslations() +{ + int count = LastChar - FirstChar + 1; + BYTE usedcolors[256], identity[256]; + double *luminosity; + int TotalColors; + int i, j; + + memset (usedcolors, 0, 256); + for (i = 0; i < count; i++) + { + FFontChar1 *pic = static_cast(Chars[i].Pic); + if(pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture RecordTextureColors (pic, usedcolors); } } @@ -1802,30 +1980,10 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l for (i = 0; i < count; i++) { - if (charlumps[i] != NULL) - { - Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap); - Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); - } - else - { - Chars[i].Pic = NULL; - Chars[i].XMove = INT_MIN; - } + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); } - // Special fonts normally don't have all characters so be careful here! - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) - { - SpaceWidth = (Chars['N' - first].XMove + 1) / 2; - } - else - { - SpaceWidth = 4; - } - - FixXMoves(); - BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL); // add the untranslated colors to the Ranges tables @@ -1845,7 +2003,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l ActiveColors = TotalColors; delete[] luminosity; - delete[] charlumps; } //========================================================================== @@ -1994,7 +2151,7 @@ void V_InitCustomFonts() } if (format == 1) { - FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start); + FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump); fnt->SetCursor(cursor); } else if (format == 2) @@ -2017,7 +2174,7 @@ void V_InitCustomFonts() } if (count > 0) { - FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate); + FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump); fnt->SetCursor(cursor); } } @@ -2396,19 +2553,19 @@ void V_InitFonts() } else if (Wads.CheckNumForName ("FONTA_S") >= 0) { - SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1); + SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1); SmallFont->SetCursor('['); } else { - SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART); + SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } } if (!(SmallFont2 = FFont::FindFont("SmallFont2"))) // Only used by Strife { if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0) { - SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART); + SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } else { @@ -2427,7 +2584,7 @@ void V_InitFonts() } else { - BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1); + BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1); } } if (!(ConFont = FFont::FindFont("ConsoleFont"))) @@ -2455,4 +2612,14 @@ void V_ClearFonts() } FFont::FirstFont = NULL; SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL; -} \ No newline at end of file +} + +void V_RetranslateFonts() +{ + FFont *font = FFont::FirstFont; + while(font) + { + font->LoadTranslations(); + font = font->Next; + } +} diff --git a/src/v_font.h b/src/v_font.h index 27cf50b2c..0b510612d 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -76,15 +76,17 @@ extern int NumTextColors; class FFont { public: - FFont (const char *fontname, const char *nametemplate, int first, int count, int base); + FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump); virtual ~FFont (); virtual FTexture *GetChar (int code, int *const width) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range) const; + int GetLump() const { return Lump; } int GetSpaceWidth () const { return SpaceWidth; } int GetHeight () const { return FontHeight; } int GetDefaultKerning () const { return GlobalKerning; } + virtual void LoadTranslations(); void Preload() const; static FFont *FindFont (const char *fontname); @@ -99,7 +101,7 @@ public: void SetCursor(char c) { Cursor = c; } protected: - FFont (); + FFont (int lump); void BuildTranslations (const double *luminosity, const BYTE *identity, const void *ranges, int total_colors, const PalEntry *palette); @@ -122,6 +124,7 @@ protected: TArray Ranges; BYTE *PatchRemap; + int Lump; char *Name; FFont *Next; @@ -129,6 +132,7 @@ protected: friend struct FontsDeleter; friend void V_ClearFonts(); + friend void V_RetranslateFonts(); friend FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font); }; @@ -143,5 +147,6 @@ PalEntry V_LogColorFromColorRange (EColorRange range); EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor); FFont *V_GetFont(const char *); void V_InitFontColors(); +void V_RetranslateFonts(); #endif //__V_FONT_H__ From 1b05969d44500b607e428f48c840fc96180cb72c Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 6 Aug 2012 10:28:55 +0000 Subject: [PATCH 033/101] - Fixed: FString would truncate a string if Insert was called on a string which has a reference count greater than 1. SVN r3809 (trunk) --- src/zstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zstring.cpp b/src/zstring.cpp index d126d607b..7cc594b14 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -773,7 +773,7 @@ void FString::Insert (size_t index, const char *instr, size_t instrlen) AllocBuffer (mylen + instrlen); StrCopy (Chars, old->Chars(), index); StrCopy (Chars + index, instr, instrlen); - StrCopy (Chars + index + instrlen, Chars + index, mylen - index + 1); + StrCopy (Chars + index + instrlen, old->Chars() + index, mylen - index + 1); old->Release(); } } From 6af0744f75f8423e29f5733c2a819e6733e4b28b Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 6 Aug 2012 20:59:52 +0000 Subject: [PATCH 034/101] - Removed unused variable in v_font.cpp. SVN r3810 (trunk) --- src/v_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 8fb0a2400..3ef631c5c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1861,7 +1861,7 @@ void FFontChar2::MakeTexture () FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump) : FFont(lump) { - int i, j; + int i; FTexture **charlumps; int maxyoffs; FTexture *pic; From 5f4889d99e2e075397179c30b2f6fb4ec9606977 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 7 Aug 2012 08:11:56 +0000 Subject: [PATCH 035/101] - Backported SPACEWIDTH for fontdefs from ECWolf. SVN r3811 (trunk) --- src/v_font.cpp | 19 ++++++++++++++++--- src/v_font.h | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 3ef631c5c..176b5097d 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -339,7 +339,7 @@ FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font) // //========================================================================== -FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump) +FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump, int spacewidth) { int i; FTextureID lump; @@ -422,7 +422,11 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, } } - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) + if (spacewidth != -1) + { + SpaceWidth = spacewidth; + } + else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } @@ -2056,6 +2060,7 @@ void V_InitCustomFonts() int start; int first; int count; + int spacewidth; char cursor = '_'; while ((llump = Wads.FindLump ("FONTDEFS", &lastlump)) != -1) @@ -2070,6 +2075,7 @@ void V_InitCustomFonts() start = 33; first = 33; count = 223; + spacewidth = -1; sc.MustGetStringName ("{"); while (!sc.CheckString ("}")) @@ -2108,6 +2114,13 @@ void V_InitCustomFonts() sc.MustGetString(); cursor = sc.String[0]; } + else if (sc.Compare ("SPACEWIDTH")) + { + if (format == 2) goto wrong; + sc.MustGetNumber(); + spacewidth = sc.Number; + format = 1; + } else if (sc.Compare ("NOTRANSLATION")) { if (format == 1) goto wrong; @@ -2151,7 +2164,7 @@ void V_InitCustomFonts() } if (format == 1) { - FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump); + FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump, spacewidth); fnt->SetCursor(cursor); } else if (format == 2) diff --git a/src/v_font.h b/src/v_font.h index 0b510612d..13dca6e2c 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -76,7 +76,7 @@ extern int NumTextColors; class FFont { public: - FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump); + FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1); virtual ~FFont (); virtual FTexture *GetChar (int code, int *const width) const; From cb296a66606aaefd87b77bd089eba527d88569a1 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 7 Aug 2012 20:09:07 +0000 Subject: [PATCH 036/101] - Fixed: Valgrind error when copying the FON2 palettes. SVN r3812 (trunk) --- src/v_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 176b5097d..c1923e4ac 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1125,7 +1125,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) SpaceWidth = totalwidth * 2 / (3 * count); } - memcpy(PaletteData, palette, 768); + memcpy(PaletteData, palette, (ActiveColors+1)*3); data_p = palette + (ActiveColors+1)*3; From e2a018227f3392dbcfe47e8e22c30258316f23fe Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 9 Aug 2012 04:31:31 +0000 Subject: [PATCH 037/101] - Added additive blending for floors and ceilings. SVN r3813 (trunk) --- src/r_bsp.cpp | 4 +- src/r_draw.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ src/r_draw.h | 6 ++ src/r_plane.cpp | 38 ++++++++---- 4 files changed, 185 insertions(+), 13 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 689977911..c7f6d8497 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1185,7 +1185,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::floor), floorlightlevel + r_actualextralight, // killough 3/16/98 frontsector->GetAlpha(sector_t::floor), - !!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE), + !!(fakeFloor->flags && FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), @@ -1250,7 +1250,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::ceiling), ceilinglightlevel + r_actualextralight, // killough 4/11/98 frontsector->GetAlpha(sector_t::ceiling), - !!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE), + !!(fakeFloor->flags && FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), diff --git a/src/r_draw.cpp b/src/r_draw.cpp index cc9bc9b26..60a0e46e4 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -79,6 +79,8 @@ void (*R_DrawSpan)(void); void (*R_DrawSpanMasked)(void); void (*R_DrawSpanTranslucent)(void); void (*R_DrawSpanMaskedTranslucent)(void); +void (*R_DrawSpanAddClamp)(void); +void (*R_DrawSpanMaskedAddClamp)(void); void (STACK_ARGS *rt_map4cols)(int,int,int); // @@ -1324,6 +1326,152 @@ void R_DrawSpanMaskedTranslucentP_C (void) } } +void R_DrawSpanAddClampP_C (void) +{ + dsfixed_t xfrac; + dsfixed_t yfrac; + dsfixed_t xstep; + dsfixed_t ystep; + BYTE* dest; + const BYTE* source = ds_source; + const BYTE* colormap = ds_colormap; + int count; + int spot; + DWORD *fg2rgb = dc_srcblend; + DWORD *bg2rgb = dc_destblend; + + xfrac = ds_xfrac; + yfrac = ds_yfrac; + + dest = ylookup[ds_y] + ds_x1 + dc_destorg; + + count = ds_x2 - ds_x1 + 1; + + xstep = ds_xstep; + ystep = ds_ystep; + + if (ds_xbits == 6 && ds_ybits == 6) + { + // 64x64 is the most common case by far, so special case it. + do + { + spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); + DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest++ = RGB32k[0][0][a & (a>>15)]; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } + else + { + BYTE yshift = 32 - ds_ybits; + BYTE xshift = yshift - ds_xbits; + int xmask = ((1 << ds_xbits) - 1) << ds_ybits; + do + { + spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest++ = RGB32k[0][0][a & (a>>15)]; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } +} + +void R_DrawSpanMaskedAddClampP_C (void) +{ + dsfixed_t xfrac; + dsfixed_t yfrac; + dsfixed_t xstep; + dsfixed_t ystep; + BYTE* dest; + const BYTE* source = ds_source; + const BYTE* colormap = ds_colormap; + int count; + int spot; + DWORD *fg2rgb = dc_srcblend; + DWORD *bg2rgb = dc_destblend; + + xfrac = ds_xfrac; + yfrac = ds_yfrac; + + dest = ylookup[ds_y] + ds_x1 + dc_destorg; + + count = ds_x2 - ds_x1 + 1; + + xstep = ds_xstep; + ystep = ds_ystep; + + if (ds_xbits == 6 && ds_ybits == 6) + { + // 64x64 is the most common case by far, so special case it. + do + { + BYTE texdata; + + spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); + texdata = source[spot]; + if (texdata != 0) + { + DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest = RGB32k[0][0][a & (a>>15)]; + } + dest++; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } + else + { + BYTE yshift = 32 - ds_ybits; + BYTE xshift = yshift - ds_xbits; + int xmask = ((1 << ds_xbits) - 1) << ds_ybits; + do + { + BYTE texdata; + + spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + texdata = source[spot]; + if (texdata != 0) + { + DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest = RGB32k[0][0][a & (a>>15)]; + } + dest++; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } +} + // [RH] Just fill a span with a color void R_FillSpan (void) { @@ -2040,6 +2188,8 @@ void R_InitColumnDrawers () #endif R_DrawSpanTranslucent = R_DrawSpanTranslucentP_C; R_DrawSpanMaskedTranslucent = R_DrawSpanMaskedTranslucentP_C; + R_DrawSpanAddClamp = R_DrawSpanAddClampP_C; + R_DrawSpanMaskedAddClamp = R_DrawSpanMaskedAddClampP_C; } // [RH] Choose column drawers in a single place diff --git a/src/r_draw.h b/src/r_draw.h index ace6bde0b..c8a7f2d47 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -106,6 +106,12 @@ extern void (*R_DrawSpanTranslucent)(void); // Span drawing for masked, translucent textures. extern void (*R_DrawSpanMaskedTranslucent)(void); +// Span drawing for translucent, additive textures. +extern void (*R_DrawSpanAddClamp)(void); + +// Span drawing for masked, translucent, additive textures. +extern void (*R_DrawSpanMaskedAddClamp)(void); + // [RH] Span blit into an interleaved intermediate buffer extern void (*R_DrawColumnHoriz)(void); void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *spans); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 0652121f7..0e8237cb6 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -596,7 +596,6 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl else sky = 0; // not skyflatnum so it can't be a sky skybox = NULL; alpha = FRACUNIT; - additive = false; } // New visplane algorithm uses hash table -- killough @@ -1047,7 +1046,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = pl->viewy; viewangle = pl->viewangle; MirrorFlags = pl->MirrorFlags; - R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, false, true); + R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); } } } @@ -1528,16 +1527,24 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske else plane_shade = true; - // Additive not supported yet because the drawer function doesn't look like it can handle it. if (spanfunc != R_FillSpan) { if (masked) { - if (alpha < OPAQUE) + if (alpha < OPAQUE || additive) { - spanfunc = R_DrawSpanMaskedTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + if (!additive) + { + spanfunc = R_DrawSpanMaskedTranslucent; + dc_srcblend = Col2RGB8[alpha>>10]; + dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + } + else + { + spanfunc = R_DrawSpanMaskedAddClamp; + dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; + dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + } } else { @@ -1546,11 +1553,20 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske } else { - if (alpha < OPAQUE) + if (alpha < OPAQUE || additive) { - spanfunc = R_DrawSpanTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + if (!additive) + { + spanfunc = R_DrawSpanTranslucent; + dc_srcblend = Col2RGB8[alpha>>10]; + dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + } + else + { + spanfunc = R_DrawSpanAddClamp; + dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; + dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + } } else { From ebc4e5b4e1b71273baacafa8c9f6b4fd17be164a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 10 Aug 2012 02:17:16 +0000 Subject: [PATCH 038/101] - Fixed: P_TouchSpecialThing() considered all pickup items to be 32 units tall for the sake of touching, even if they were taller. SVN r3814 (trunk) --- src/p_interaction.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 70009f4ee..3ad2770e9 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -86,7 +86,9 @@ void P_TouchSpecialThing (AActor *special, AActor *toucher) { fixed_t delta = special->z - toucher->z; - if (delta > toucher->height || delta < -32*FRACUNIT) + // The pickup is at or above the toucher's feet OR + // The pickup is below the toucher. + if (delta > toucher->height || delta < MIN(-32*FRACUNIT, -special->height)) { // out of reach return; } From 5c702e66e2dae61be06bb788a5a496fcf29d1e06 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 10 Aug 2012 02:49:41 +0000 Subject: [PATCH 039/101] - Player icons that are taller than the small font will now expand the vertical size of the player bars on the scoreboard. - Fixed: Having +showscores down during the intermission would draw both the regular intermission scoreboard plus the HUD scoreboard. - Fixed: hu_scores used the player icon's unscaled width when calculating sizes. SVN r3815 (trunk) --- src/ct_chat.cpp | 4 +++- src/hu_scores.cpp | 37 ++++++++++++++++++++++++------------- src/hu_stuff.h | 2 +- src/wi_stuff.cpp | 20 +++++++++++--------- 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index d05e44a67..d99acda42 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -273,7 +273,9 @@ void CT_Drawer (void) if (players[consoleplayer].camera != NULL && (Button_ShowScores.bDown || - players[consoleplayer].camera->health <= 0)) + players[consoleplayer].camera->health <= 0) && + // Don't draw during intermission, since it has its own scoreboard in wi_stuff.cpp. + gamestate != GS_INTERMISSION) { HU_DrawScores (&players[consoleplayer]); } diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 1d881bd3d..9af0c0c05 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -60,7 +60,7 @@ static void HU_DoDrawScores (player_t *, player_t *[MAXPLAYERS]); static void HU_DrawTimeRemaining (int y); -static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int); +static void HU_DrawPlayer (player_t *, bool, int, int, int, int, int, int, int, int); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -178,10 +178,11 @@ void HU_DrawScores (player_t *player) // //========================================================================== -void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth) +void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheight) { maxnamewidth = SmallFont->StringWidth("Name"); maxscorewidth = 0; + maxiconheight = 0; for (int i = 0; i < MAXPLAYERS; i++) { @@ -195,11 +196,18 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth) if (players[i].mo->ScoreIcon.isValid()) { FTexture *pic = TexMan[players[i].mo->ScoreIcon]; - width = pic->GetWidth() - pic->GetScaledLeftOffset() + 2; + width = pic->GetScaledWidth() - pic->GetScaledLeftOffset() + 2; if (width > maxscorewidth) { maxscorewidth = width; } + // The icon's top offset does not count toward its height, because + // zdoom.pk3's standard Hexen class icons are designed that way. + int height = pic->GetScaledHeight() - pic->GetScaledTopOffset(); + if (height > maxiconheight) + { + maxiconheight = height; + } } } } @@ -214,11 +222,11 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth) static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYERS]) { int color; - int height = SmallFont->GetHeight() * CleanYfac; + int height, lineheight; unsigned int i; - int maxnamewidth, maxscorewidth; + int maxnamewidth, maxscorewidth, maxiconheight; int numTeams = 0; - int x, y, bottom; + int x, y, ypadding, bottom; int col2, col3, col4; if (deathmatch) @@ -233,7 +241,10 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER color = sb_cooperative_headingcolor; } - HU_GetPlayerWidths(maxnamewidth, maxscorewidth); + HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight); + height = SmallFont->GetHeight() * CleanYfac; + lineheight = MAX(height, maxiconheight * CleanYfac); + ypadding = (lineheight - height + 1) / 2; bottom = gamestate != GS_INTERMISSION ? ST_Y : SCREENHEIGHT; y = MAX(48*CleanYfac, (bottom - MAXPLAYERS * (height + CleanYfac + 1)) / 2); @@ -320,8 +331,8 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER { if (playeringame[sortedplayers[i] - players]) { - HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, height); - y += height + CleanYfac; + HU_DrawPlayer (sortedplayers[i], player==sortedplayers[i], x, col2, col3, col4, maxnamewidth, y, ypadding, lineheight); + y += lineheight + CleanYfac; } } } @@ -365,7 +376,7 @@ static void HU_DrawTimeRemaining (int y) // //========================================================================== -static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int height) +static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, int col3, int col4, int maxnamewidth, int y, int ypadding, int height) { int color; char str[80]; @@ -386,7 +397,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, HU_DrawColorBar(col1, y, height, (int)(player - players)); mysnprintf (str, countof(str), "%d", deathmatch ? player->fragcount : player->killcount); - screen->DrawText (SmallFont, color, col2, y, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str, + screen->DrawText (SmallFont, color, col2, y + ypadding, player->playerstate == PST_DEAD && !deathmatch ? "DEAD" : str, DTA_CleanNoMove, true, TAG_DONE); if (player->mo->ScoreIcon.isValid()) @@ -397,13 +408,13 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, TAG_DONE); } - screen->DrawText (SmallFont, color, col4, y, player->userinfo.netname, + screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE); if (teamplay && Teams[player->userinfo.team].GetLogo ().IsNotEmpty ()) { FTexture *pic = TexMan[Teams[player->userinfo.team].GetLogo ().GetChars ()]; - screen->DrawTexture (pic, col1 - (pic->GetWidth() + 2) * CleanXfac, y, + screen->DrawTexture (pic, col1 - (pic->GetScaledWidth() + 2) * CleanXfac, y, DTA_CleanNoMove, true, TAG_DONE); } } diff --git a/src/hu_stuff.h b/src/hu_stuff.h index ce7266c75..c8e76fee0 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -46,7 +46,7 @@ extern int chatmodeon; // [RH] Draw deathmatch scores void HU_DrawScores (player_t *me); -void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth); +void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheight); void HU_DrawColorBar(int x, int y, int height, int playernum); int HU_GetRowColor(player_t *player, bool hightlight); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 1b81aeb00..6e841518f 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1588,8 +1588,8 @@ void WI_updateNetgameStats () void WI_drawNetgameStats () { - int i, x, y, height; - int maxnamewidth, maxscorewidth; + int i, x, y, ypadding, height, lineheight; + int maxnamewidth, maxscorewidth, maxiconheight; int pwidth = IntermissionFont->GetCharWidth('%'); int icon_x, name_x, kills_x, bonus_x, secret_x; int bonus_len, secret_len; @@ -1602,8 +1602,10 @@ void WI_drawNetgameStats () y = WI_drawLF(); - HU_GetPlayerWidths(maxnamewidth, maxscorewidth); + HU_GetPlayerWidths(maxnamewidth, maxscorewidth, maxiconheight); height = SmallFont->GetHeight() * CleanYfac; + lineheight = MAX(height, maxiconheight * CleanYfac); + ypadding = (lineheight - height + 1) / 2; y += 16*CleanYfac; bonus_label = (gameinfo.gametype & GAME_Raven) ? "BONUS" : "ITEMS"; @@ -1642,27 +1644,27 @@ void WI_drawNetgameStats () continue; player = &players[i]; - HU_DrawColorBar(x, y, height, i); + HU_DrawColorBar(x, y, lineheight, i); color = (EColorRange)HU_GetRowColor(player, i == consoleplayer); if (player->mo->ScoreIcon.isValid()) { FTexture *pic = TexMan[player->mo->ScoreIcon]; screen->DrawTexture(pic, icon_x, y, DTA_CleanNoMove, true, TAG_DONE); } - screen->DrawText(SmallFont, color, name_x, y, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE); - WI_drawPercent(SmallFont, kills_x, y, cnt_kills[i], wbs->maxkills, false, color); + screen->DrawText(SmallFont, color, name_x, y + ypadding, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE); + WI_drawPercent(SmallFont, kills_x, y + ypadding, cnt_kills[i], wbs->maxkills, false, color); missed_kills -= cnt_kills[i]; if (ng_state >= 4) { - WI_drawPercent(SmallFont, bonus_x, y, cnt_items[i], wbs->maxitems, false, color); + WI_drawPercent(SmallFont, bonus_x, y + ypadding, cnt_items[i], wbs->maxitems, false, color); missed_items -= cnt_items[i]; if (ng_state >= 6) { - WI_drawPercent(SmallFont, secret_x, y, cnt_secret[i], wbs->maxsecret, false, color); + WI_drawPercent(SmallFont, secret_x, y + ypadding, cnt_secret[i], wbs->maxsecret, false, color); missed_secrets -= cnt_secret[i]; } } - y += height + CleanYfac; + y += lineheight + CleanYfac; } // Draw "MISSED" line From 718d3f8d43f2d575e4d25f828755f19e9bfa03b7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 10 Aug 2012 02:56:09 +0000 Subject: [PATCH 040/101] - Changed vid_tft's default to true. How many people still run 1280x1024 on a CRT these days? - Fixed: M_InitVideoModesMenu() needs to call vid_tft's callback. SVN r3816 (trunk) --- src/menu/videomenu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 3e8f18ea8..8a6e6720d 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -99,7 +99,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE) } } -CUSTOM_CVAR (Bool, vid_tft, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { FOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) @@ -316,6 +316,7 @@ void M_InitVideoModesMenu () size_t currval = 0; M_RefreshModesList(); + vid_tft.Callback(); for (unsigned int i = 1; i <= 32 && currval < countof(BitTranslate); i++) { From 3ddac32b4f35678b0c48c73f5461cbd920e7ad2b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 10 Aug 2012 03:49:50 +0000 Subject: [PATCH 041/101] - Because setting a DSP unit inactive completely ceases all processing on it, including timing, sounds queued up while the Channel Group Target Unit is inactive will all play at the same time once the unit is made active. To avoid this, it is now only deactivated when the gamestate is GS_LEVEL. Otherwise, it just gets muted. Fixes http://forum.zdoom.org/viewtopic.php?f=2&t=33592 "Strife voices overlap" SVN r3818 (trunk) --- src/s_sound.cpp | 6 ++++-- src/sound/fmodsound.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/sound/fmodsound.h | 3 ++- src/sound/i_sound.cpp | 2 +- src/sound/i_sound.h | 8 +++++++- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 6c548f400..9749d635c 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1764,7 +1764,7 @@ void S_SetSoundPaused (int state) S_ResumeSound(true); if (GSnd != NULL) { - GSnd->SetInactive(false); + GSnd->SetInactive(SoundRenderer::INACTIVE_Active); } if (!netgame #ifdef _DEBUG @@ -1783,7 +1783,9 @@ void S_SetSoundPaused (int state) S_PauseSound(false, true); if (GSnd != NULL) { - GSnd->SetInactive(true); + GSnd->SetInactive(gamestate == GS_LEVEL ? + SoundRenderer::INACTIVE_Complete : + SoundRenderer::INACTIVE_Mute); } if (!netgame #ifdef _DEBUG diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index b01754324..5abb67e76 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -672,6 +672,7 @@ bool FMODSoundRenderer::Init() PrevEnvironment = DefaultEnvironments[0]; DSPClock.AsOne = 0; ChannelGroupTargetUnit = NULL; + ChannelGroupTargetUnitOutput = NULL; SfxReverbHooked = false; SfxReverbPlaceholder = NULL; OutputPlugin = 0; @@ -1155,6 +1156,15 @@ bool FMODSoundRenderer::Init() { ChannelGroupTargetUnit = NULL; } + else + { + FMOD::DSP *dontcare; + result = ChannelGroupTargetUnit->getOutput(0, &dontcare, &ChannelGroupTargetUnitOutput); + if (result != FMOD_OK) + { + ChannelGroupTargetUnitOutput = NULL; + } + } } } @@ -2123,11 +2133,33 @@ void FMODSoundRenderer::SetSfxPaused(bool paused, int slot) // //========================================================================== -void FMODSoundRenderer::SetInactive(bool inactive) +void FMODSoundRenderer::SetInactive(SoundRenderer::EInactiveState inactive) { + float mix; + bool active; + + if (inactive == INACTIVE_Active) + { + mix = 1; + active = true; + } + else if (inactive == INACTIVE_Complete) + { + mix = 1; + active = false; + } + else // inactive == INACTIVE_Mute + { + mix = 0; + active = true; + } + if (ChannelGroupTargetUnitOutput != NULL) + { + ChannelGroupTargetUnitOutput->setMix(mix); + } if (ChannelGroupTargetUnit != NULL) { - ChannelGroupTargetUnit->setActive(!inactive); + ChannelGroupTargetUnit->setActive(active); } } diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index e00b2ed27..99d627e5f 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -49,7 +49,7 @@ public: void SetSfxPaused (bool paused, int slot); // Pauses or resumes *every* channel, including environmental reverb. - void SetInactive (bool inactive); + void SetInactive (EInactiveState inactive); // Updates the position of a sound channel. void UpdateSoundParams3D (SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel); @@ -107,6 +107,7 @@ private: FMOD::ChannelGroup *MusicGroup; FMOD::DSP *WaterLP, *WaterReverb; FMOD::DSPConnection *SfxConnection; + FMOD::DSPConnection *ChannelGroupTargetUnitOutput; FMOD::DSP *ChannelGroupTargetUnit; FMOD::DSP *SfxReverbPlaceholder; bool SfxReverbHooked; diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index 27c00e93f..0fe68a25c 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -199,7 +199,7 @@ public: } // Pauses or resumes *every* channel, including environmental reverb. - void SetInactive(bool inactive) + void SetInactive(SoundRenderer::EInactiveState inactive) { } diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 660e47166..c905678ad 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -126,7 +126,13 @@ public: virtual void SetSfxPaused (bool paused, int slot) = 0; // Pauses or resumes *every* channel, including environmental reverb. - virtual void SetInactive(bool inactive) = 0; + enum EInactiveState + { + INACTIVE_Active, // sound is active + INACTIVE_Complete, // sound is completely paused + INACTIVE_Mute // sound is only muted + }; + virtual void SetInactive(EInactiveState inactive) = 0; // Updates the volume, separation, and pitch of a sound channel. virtual void UpdateSoundParams3D (SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel) = 0; From 2a9a1fb2406f57f884e95e51eb0f8accc00abf30 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 03:23:35 +0000 Subject: [PATCH 042/101] - Fixed: All 3D floors were additive due to a typo. SVN r3819 (trunk) --- src/r_bsp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index c7f6d8497..163b0e296 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1185,7 +1185,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::floor), floorlightlevel + r_actualextralight, // killough 3/16/98 frontsector->GetAlpha(sector_t::floor), - !!(fakeFloor->flags && FF_ADDITIVETRANS), + !!(fakeFloor->flags & FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), @@ -1250,7 +1250,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::ceiling), ceilinglightlevel + r_actualextralight, // killough 4/11/98 frontsector->GetAlpha(sector_t::ceiling), - !!(fakeFloor->flags && FF_ADDITIVETRANS), + !!(fakeFloor->flags & FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), From 27f6d431ca650b933eae0441e4728e9fbe4942b6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 03:36:49 +0000 Subject: [PATCH 043/101] - Trying to replace an actor that does not exist is now a warning rather than an error. SVN r3820 (trunk) --- src/thingdef/thingdef.cpp | 8 +++++--- src/thingdef/thingdef.h | 2 +- src/thingdef/thingdef_parse.cpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index aba84b265..a609b5e93 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -180,7 +180,7 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare // //========================================================================== -void SetReplacement(FActorInfo *info, FName replaceName) +void SetReplacement(FScanner &sc, FActorInfo *info, FName replaceName) { // Check for "replaces" if (replaceName != NAME_None) @@ -190,11 +190,13 @@ void SetReplacement(FActorInfo *info, FName replaceName) if (replacee == NULL) { - I_Error ("Replaced type '%s' not found in %s", replaceName.GetChars(), info->Class->TypeName.GetChars()); + sc.ScriptMessage("Replaced type '%s' not found for %s", replaceName.GetChars(), info->Class->TypeName.GetChars()); + return; } else if (replacee->ActorInfo == NULL) { - I_Error ("Replaced type '%s' is not an actor in %s", replaceName.GetChars(), info->Class->TypeName.GetChars()); + sc.ScriptMessage("Replaced type '%s' for %s is not an actor", replaceName.GetChars(), info->Class->TypeName.GetChars()); + return; } if (replacee != NULL) { diff --git a/src/thingdef/thingdef.h b/src/thingdef/thingdef.h index a7de7285d..e8d0f0a55 100644 --- a/src/thingdef/thingdef.h +++ b/src/thingdef/thingdef.h @@ -199,7 +199,7 @@ PSymbolActionFunction *FindGlobalActionFunction(const char *name); //========================================================================== FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName parentName, bool native); -void SetReplacement(FActorInfo *info, FName replaceName); +void SetReplacement(FScanner &sc, FActorInfo *info, FName replaceName); void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod); void FinishActor(const FScriptPosition &sc, FActorInfo *info, Baggage &bag); diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index a15c18e16..11c000102 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -1108,7 +1108,7 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag) info->DoomEdNum = DoomEdNum > 0? DoomEdNum : -1; info->Class->Meta.SetMetaString (ACMETA_Lump, Wads.GetLumpFullPath(sc.LumpNum)); - SetReplacement(info, replaceName); + SetReplacement(sc, info, replaceName); ResetBaggage (bag, info->Class->ParentClass); bag->Info = info; From 73552f0365a70d46984e43f84d014fa755a59755 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 22:24:15 +0000 Subject: [PATCH 044/101] - Added HUD message visibility flags, which are ORed into the type field: * HUDMSG_NOTWITH3DVIEW : This message does not appear when the 3D view is active. * HUDMSG_NOTWITHFULLMAP : This message does not appear when the fullscreen automap is active. * HUDMSG_NOTWITHOVERLAYMAP : This message does not appear when the overlay automap is active. These flags may be combined, so for example: HUDMSG_NOTWITHFULLMAP | HUDMSG_NOTWITHOVERLAYMAP would prevent the message from appearing if any form of automap is active. - Added HUD message layers, which are ORed into the type field: * HUDMSG_LAYER_OVERHUD : This is the default and standard behavior. The message appear on top of most HUD elements. This definition is just included for completeness' sake; you don't need to explicitly use it. * HUDMSG_LAYER_UNDERHUD : The message appears underneath other HUD elements, such as the status bar. * HUDMSG_LAYER_OVERMAP : The message appears on top of the fullscreen automap. At the moment, this layer is functionally equivalent to using the flags HUDMSG_NOTWITH3DVIEW | HUDMSG_NOTWITHOVERLAYMAP. However, if Blzut3 decides to implement support for drawing the automap permanently on a second screen, messages on this layer will move to that screen with the automap and be permanently visible as long as the map is visible on that other screen. These are not flags, so for example HUDMSG_LAYER_UNDERHUD | HUDMSG_LAYER_OVERHUD is not valid. SVN r3821 (trunk) --- src/d_main.cpp | 8 +- src/g_shared/hudmessages.cpp | 17 ++- src/g_shared/sbar.h | 34 +++++- src/g_shared/shared_sbar.cpp | 229 ++++++++++++++++++++--------------- src/p_acs.cpp | 23 +++- 5 files changed, 199 insertions(+), 112 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index a9e02edff..40c724496 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -804,17 +804,21 @@ void D_Display () if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10) { + StatusBar->DrawBottomStuff (HUD_None); if (DrawFSHUD || automapactive) DrawHUD(); StatusBar->DrawTopStuff (HUD_None); } else if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10) { - StatusBar->Draw (DrawFSHUD ? HUD_Fullscreen : HUD_None); - StatusBar->DrawTopStuff (DrawFSHUD ? HUD_Fullscreen : HUD_None); + EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None; + StatusBar->DrawBottomStuff (state); + StatusBar->Draw (state); + StatusBar->DrawTopStuff (state); } else { + StatusBar->DrawBottomStuff (HUD_StatusBar); StatusBar->Draw (HUD_StatusBar); StatusBar->DrawTopStuff (HUD_StatusBar); } diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 22e12ead1..7216f6f30 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -140,6 +140,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h State = 0; SourceText = copystring (text); Font = font; + VisibilityFlags = 0; ResetText (SourceText); } @@ -184,6 +185,14 @@ void DHUDMessage::Serialize (FArchive &arc) Lines = NULL; ResetText (SourceText); } + if (SaveVersion < 3821) + { + VisibilityFlags = 0; + } + else + { + arc << VisibilityFlags; + } } //============================================================================ @@ -262,7 +271,7 @@ bool DHUDMessage::Tick () // //============================================================================ -void DHUDMessage::Draw (int bottom) +void DHUDMessage::Draw (int bottom, int visibility) { int xscale, yscale; int x, y; @@ -271,6 +280,12 @@ void DHUDMessage::Draw (int bottom) bool clean = false; int hudheight; + // If any of the visibility flags match, do NOT draw this message. + if (VisibilityFlags & visibility) + { + return; + } + DrawSetup (); int screen_width = SCREENWIDTH; diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 22a99709d..893287022 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -66,13 +66,18 @@ public: virtual void Serialize (FArchive &arc); - void Draw (int bottom); + void Draw (int bottom, int visibility); virtual void ResetText (const char *text); virtual void DrawSetup (); virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight); virtual bool Tick (); // Returns true to indicate time for removal virtual void ScreenSizeChanged (); + void SetVisibility(int vis) + { + VisibilityFlags = vis; + } + protected: FBrokenLines *Lines; int Width, Height, NumLines; @@ -81,6 +86,7 @@ protected: int HoldTics; int Tics; int State; + int VisibilityFlags; int HUDWidth, HUDHeight; EColorRange TextColor; FFont *Font; @@ -95,6 +101,14 @@ private: friend class DBaseStatusBar; }; +// HUD message visibility flags +enum +{ + HUDMSG_NotWith3DView = 1, + HUDMSG_NotWithFullMap = 2, + HUDMSG_NotWithOverlayMap = 4, +}; + // HUD Message; appear instantly, then fade out type ------------------------ class DHUDMessageFadeOut : public DHUDMessage @@ -242,6 +256,16 @@ int FindMugShotStateIndex(FName state); class FTexture; class AAmmo; +enum +{ + HUDMSGLayer_OverHUD, + HUDMSGLayer_UnderHUD, + HUDMSGLayer_OverMap, + + NUM_HUDMSGLAYERS, + HUDMSGLayer_Default = HUDMSGLayer_OverHUD, +}; + class DBaseStatusBar : public DObject { DECLARE_CLASS (DBaseStatusBar, DObject) @@ -281,11 +305,10 @@ public: void SetScaled (bool scale, bool force=false); - void AttachMessage (DHUDMessage *msg, uint32 id=0); + void AttachMessage (DHUDMessage *msg, uint32 id=0, int layer=HUDMSGLayer_Default); DHUDMessage *DetachMessage (DHUDMessage *msg); DHUDMessage *DetachMessage (uint32 id); void DetachAllMessages (); - bool CheckMessage (DHUDMessage *msg); void ShowPlayerName (); fixed_t GetDisplacement () { return Displacement; } int GetPlayer (); @@ -296,6 +319,7 @@ public: virtual void Tick (); virtual void Draw (EHudState state); + void DrawBottomStuff (EHudState state); void DrawTopStuff (EHudState state); virtual void FlashItem (const PClass *itemtype); virtual void AttachToPlayer (player_t *player); @@ -364,10 +388,10 @@ public: private: DBaseStatusBar() {} bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const; - void DrawMessages (int bottom); + void DrawMessages (int layer, int bottom); void DrawConsistancy () const; - TObjPtr Messages; + TObjPtr Messages[NUM_HUDMSGLAYERS]; bool ShowLog; }; diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 28741ed47..7f55fe0d0 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -220,7 +220,7 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) FixedOrigin = false; CrosshairSize = FRACUNIT; RelTop = reltop; - Messages = NULL; + memset(Messages, 0, sizeof(Messages)); Displacement = 0; CPlayer = NULL; ShowLog = false; @@ -238,16 +238,17 @@ DBaseStatusBar::DBaseStatusBar (int reltop, int hres, int vres) void DBaseStatusBar::Destroy () { - DHUDMessage *msg; - - msg = Messages; - while (msg) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = msg->Next; - msg->Destroy(); - msg = next; + DHUDMessage *msg = Messages[i]; + while (msg) + { + DHUDMessage *next = msg->Next; + msg->Destroy(); + msg = next; + } + Messages[i] = NULL; } - Messages = NULL; Super::Destroy(); } @@ -339,32 +340,35 @@ void DBaseStatusBar::MultiplayerChanged () void DBaseStatusBar::Tick () { - DHUDMessage *msg = Messages; - DHUDMessage **prev = &Messages; - - while (msg) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = msg->Next; + DHUDMessage *msg = Messages[i]; + DHUDMessage **prev = &Messages[i]; - if (msg->Tick ()) + while (msg) { - *prev = next; - msg->Destroy(); - } - else - { - prev = &msg->Next; - } - msg = next; - } + DHUDMessage *next = msg->Next; - // If the crosshair has been enlarged, shrink it. - if (CrosshairSize > FRACUNIT) - { - CrosshairSize -= XHAIRSHRINKSIZE; - if (CrosshairSize < FRACUNIT) + if (msg->Tick ()) + { + *prev = next; + msg->Destroy(); + } + else + { + prev = &msg->Next; + } + msg = next; + } + + // If the crosshair has been enlarged, shrink it. + if (CrosshairSize > FRACUNIT) { - CrosshairSize = FRACUNIT; + CrosshairSize -= XHAIRSHRINKSIZE; + if (CrosshairSize < FRACUNIT) + { + CrosshairSize = FRACUNIT; + } } } } @@ -375,7 +379,7 @@ void DBaseStatusBar::Tick () // //--------------------------------------------------------------------------- -void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) +void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id, int layer) { DHUDMessage *old = NULL; DHUDMessage **prev; @@ -387,7 +391,7 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) old->Destroy(); } - prev = &Messages; + prev = &Messages[layer]; // The ID serves as a priority, where lower numbers appear in front of // higher numbers. (i.e. The list is sorted in descending order, since @@ -412,48 +416,56 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id) DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg) { - DHUDMessage *probe = Messages; - DHUDMessage **prev = &Messages; + for (int i = 0; i < countof(Messages); ++i) + { + DHUDMessage *probe = Messages[i]; + DHUDMessage **prev = &Messages[i]; - while (probe && probe != msg) - { - prev = &probe->Next; - probe = probe->Next; - } - if (probe != NULL) - { - *prev = probe->Next; - probe->Next = NULL; - // Redraw the status bar in case it was covered - if (screen != NULL) + while (probe && probe != msg) { - SB_state = screen->GetPageCount(); + prev = &probe->Next; + probe = probe->Next; + } + if (probe != NULL) + { + *prev = probe->Next; + probe->Next = NULL; + // Redraw the status bar in case it was covered + if (screen != NULL) + { + SB_state = screen->GetPageCount(); + } + return probe; } } - return probe; + return NULL; } DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id) { - DHUDMessage *probe = Messages; - DHUDMessage **prev = &Messages; + for (int i = 0; i < countof(Messages); ++i) + { + DHUDMessage *probe = Messages[i]; + DHUDMessage **prev = &Messages[i]; - while (probe && probe->SBarID != id) - { - prev = &probe->Next; - probe = probe->Next; - } - if (probe != NULL) - { - *prev = probe->Next; - probe->Next = NULL; - // Redraw the status bar in case it was covered - if (screen != NULL) + while (probe && probe->SBarID != id) { - SB_state = screen->GetPageCount(); + prev = &probe->Next; + probe = probe->Next; + } + if (probe != NULL) + { + *prev = probe->Next; + probe->Next = NULL; + // Redraw the status bar in case it was covered + if (screen != NULL) + { + SB_state = screen->GetPageCount(); + } + return probe; } } - return probe; + return NULL; } //--------------------------------------------------------------------------- @@ -464,31 +476,18 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id) void DBaseStatusBar::DetachAllMessages () { - DHUDMessage *probe = Messages; - - Messages = NULL; - while (probe != NULL) + for (int i = 0; i < countof(Messages); ++i) { - DHUDMessage *next = probe->Next; - probe->Destroy(); - probe = next; - } -} + DHUDMessage *probe = Messages[i]; -//--------------------------------------------------------------------------- -// -// PROC CheckMessage -// -//--------------------------------------------------------------------------- - -bool DBaseStatusBar::CheckMessage (DHUDMessage *msg) -{ - DHUDMessage *probe = Messages; - while (probe && probe != msg) - { - probe = probe->Next; + Messages[i] = NULL; + while (probe != NULL) + { + DHUDMessage *next = probe->Next; + probe->Destroy(); + probe = next; + } } - return (probe == msg); } //--------------------------------------------------------------------------- @@ -1191,13 +1190,23 @@ void DBaseStatusBar::FlashCrosshair () // //--------------------------------------------------------------------------- -void DBaseStatusBar::DrawMessages (int bottom) +void DBaseStatusBar::DrawMessages (int layer, int bottom) { - DHUDMessage *msg = Messages; + DHUDMessage *msg = Messages[layer]; + int visibility = 0; + + if (viewactive) + { + visibility |= HUDMSG_NotWith3DView; + } + if (automapactive) + { + visibility |= viewactive ? HUDMSG_NotWithOverlayMap : HUDMSG_NotWithFullMap; + } while (msg) { DHUDMessage *next = msg->Next; - msg->Draw (bottom); + msg->Draw (bottom, visibility); msg = next; } } @@ -1445,6 +1454,17 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b { } +//--------------------------------------------------------------------------- +// +// DrawBottomStuff +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::DrawBottomStuff (EHudState state) +{ + DrawMessages (HUDMSGLayer_UnderHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); +} + //--------------------------------------------------------------------------- // // DrawTopStuff @@ -1462,16 +1482,11 @@ void DBaseStatusBar::DrawTopStuff (EHudState state) } DrawPowerups (); - - if (state == HUD_StatusBar) + if (automapactive && !viewactive) { - DrawMessages (::ST_Y); + DrawMessages (HUDMSGLayer_OverMap, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); } - else - { - DrawMessages (SCREENHEIGHT); - } - + DrawMessages (HUDMSGLayer_OverHUD, (state == HUD_StatusBar) ? ::ST_Y : SCREENHEIGHT); DrawConsistancy (); if (ShowLog && MustDrawLog(state)) DrawLog (); @@ -1597,7 +1612,18 @@ void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon) void DBaseStatusBar::Serialize (FArchive &arc) { - arc << Messages; + if (SaveVersion < 3821) + { + memset(Messages, 0, sizeof(Messages)); + arc << Messages[HUDMSGLayer_Default]; + } + else + { + for (int i = 0; i < countof(Messages); ++i) + { + arc << Messages[i]; + } + } } void DBaseStatusBar::ScreenSizeChanged () @@ -1605,11 +1631,14 @@ void DBaseStatusBar::ScreenSizeChanged () st_scale.Callback (); SB_state = screen->GetPageCount (); - DHUDMessage *message = Messages; - while (message != NULL) + for (int i = 0; i < countof(Messages); ++i) { - message->ScreenSizeChanged (); - message = message->Next; + DHUDMessage *message = Messages[i]; + while (message != NULL) + { + message->ScreenSizeChanged (); + message = message->Next; + } } } diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fe2001411..36c086179 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -86,10 +86,23 @@ FRandom pr_acs ("ACS"); #define STACK_SIZE 4096 #define CLAMPCOLOR(c) (EColorRange)((unsigned)(c) >= NUM_TEXT_COLORS ? CR_UNTRANSLATED : (c)) -#define HUDMSG_LOG (0x80000000) -#define HUDMSG_COLORSTRING (0x40000000) #define LANGREGIONMASK MAKE_ID(0,0,0xff,0xff) +// HUD message flags +#define HUDMSG_LOG (0x80000000) +#define HUDMSG_COLORSTRING (0x40000000) +#define HUDMSG_ADDBLEND (0x20000000) + +// HUD message layers; these are not flags +#define HUDMSG_LAYER_SHIFT 12 +#define HUDMSG_LAYER_MASK (0x0000F000) +// See HUDMSGLayer enumerations in sbar.h + +// HUD message visibility flags +#define HUDMSG_VISIBILITY_SHIFT 16 +#define HUDMSG_VISIBILITY_MASK (0x00070000) +// See HUDMSG visibility enumerations in sbar.h + // Flags for ReplaceTextures #define NOT_BOTTOM 1 #define NOT_MIDDLE 2 @@ -5681,7 +5694,7 @@ scriptwait: color = CLAMPCOLOR(Stack[optstart-4]); } - switch (type & 0xFFFF) + switch (type & 0xFF) { default: // normal msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime); @@ -5707,7 +5720,9 @@ scriptwait: } break; } - StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0); + msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); + StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0, + (type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT); if (type & HUDMSG_LOG) { static const char bar[] = TEXTCOLOR_ORANGE "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36" From 4056f0191a9e8420cb33f68e713a38b211b37c94 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 22:54:01 +0000 Subject: [PATCH 045/101] - Safely handle unknown HUD message layers. SVN r3823 (trunk) --- src/g_shared/shared_sbar.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 7f55fe0d0..d2636d337 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -391,6 +391,12 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id, int layer) old->Destroy(); } + // Merge unknown layers into the default layer. + if ((size_t)layer >= countof(Messages)) + { + layer = HUDMSGLayer_Default; + } + prev = &Messages[layer]; // The ID serves as a priority, where lower numbers appear in front of From c9b480e0ec74908b5cca602f67dd44d166787da0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 23:14:31 +0000 Subject: [PATCH 046/101] - Added lowlevel support for custom alphas for HUD messages. - Added HUDMSG_ADDBLEND to draw HUD messages with additive blending. SVN r3824 (trunk) --- src/g_shared/hudmessages.cpp | 31 +++++++++++++++++++++++++++++++ src/g_shared/sbar.h | 10 ++++++++++ src/p_acs.cpp | 4 ++++ 3 files changed, 45 insertions(+) diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index 7216f6f30..76eaedcec 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -141,6 +141,8 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h SourceText = copystring (text); Font = font; VisibilityFlags = 0; + Style = STYLE_Translucent; + Alpha = FRACUNIT; ResetText (SourceText); } @@ -193,6 +195,15 @@ void DHUDMessage::Serialize (FArchive &arc) { arc << VisibilityFlags; } + if (SaveVersion < 3824) + { + Style = STYLE_Translucent; + Alpha = FRACUNIT; + } + else + { + arc << Style << Alpha; + } } //============================================================================ @@ -410,6 +421,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) { screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, + DTA_Alpha, Alpha, + DTA_RenderStyle, Style, TAG_DONE); } else @@ -417,6 +430,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, + DTA_Alpha, Alpha, + DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); } @@ -426,6 +441,8 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_Alpha, Alpha, + DTA_RenderStyle, Style, TAG_DONE); } } @@ -497,6 +514,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh else { fixed_t trans = -(Tics - FadeOutTics) * FRACUNIT / FadeOutTics; + trans = FixedMul(trans, Alpha); if (hudheight == 0) { if (con_scaletext <= 1) @@ -504,6 +522,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, DTA_Alpha, trans, + DTA_RenderStyle, Style, TAG_DONE); } else @@ -512,6 +531,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, DTA_Alpha, trans, + DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); } @@ -522,6 +542,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans, + DTA_RenderStyle, Style, TAG_DONE); } BorderNeedRefresh = screen->GetPageCount (); @@ -590,6 +611,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu if (State == 0) { fixed_t trans = Tics * FRACUNIT / FadeInTics; + trans = FixedMul(trans, Alpha); if (hudheight == 0) { if (con_scaletext <= 1) @@ -597,6 +619,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, DTA_Alpha, trans, + DTA_RenderStyle, Style, TAG_DONE); } else @@ -605,6 +628,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu DTA_VirtualWidth, SCREENWIDTH/2, DTA_VirtualHeight, SCREENHEIGHT/2, DTA_Alpha, trans, + DTA_RenderStyle, Style, DTA_KeepRatio, true, TAG_DONE); } @@ -615,6 +639,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans, + DTA_RenderStyle, Style, TAG_DONE); } BorderNeedRefresh = screen->GetPageCount (); @@ -768,6 +793,8 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_CleanNoMove, clean, DTA_TextLen, LineVisible, + DTA_Alpha, Alpha, + DTA_RenderStyle, Style, TAG_DONE); } else @@ -777,6 +804,8 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in DTA_VirtualHeight, SCREENHEIGHT/2, DTA_KeepRatio, true, DTA_TextLen, LineVisible, + DTA_Alpha, Alpha, + DTA_RenderStyle, Style, TAG_DONE); } } @@ -785,7 +814,9 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in screen->DrawText (Font, TextColor, x, y, Lines[linenum].Text, DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, + DTA_Alpha, Alpha, DTA_TextLen, LineVisible, + DTA_RenderStyle, Style, TAG_DONE); } } diff --git a/src/g_shared/sbar.h b/src/g_shared/sbar.h index 893287022..df3daf597 100644 --- a/src/g_shared/sbar.h +++ b/src/g_shared/sbar.h @@ -77,6 +77,14 @@ public: { VisibilityFlags = vis; } + void SetRenderStyle(ERenderStyle style) + { + Style = style; + } + void SetAlpha(fixed_t alpha) + { + Alpha = alpha; + } protected: FBrokenLines *Lines; @@ -90,6 +98,8 @@ protected: int HUDWidth, HUDHeight; EColorRange TextColor; FFont *Font; + FRenderStyle Style; + fixed_t Alpha; DHUDMessage () : SourceText(NULL) {} diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 36c086179..50570618f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5721,6 +5721,10 @@ scriptwait: break; } msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); + if (type & HUDMSG_ADDBLEND) + { + msg->SetRenderStyle(STYLE_Add); + } StatusBar->AttachMessage (msg, id ? 0xff000000|id : 0, (type & HUDMSG_LAYER_MASK) >> HUDMSG_LAYER_SHIFT); if (type & HUDMSG_LOG) From 26c17dc697ebf79b4875478b1be824c295eb9762 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Aug 2012 23:24:41 +0000 Subject: [PATCH 047/101] - Added ACS support for setting HUD messages alpha levels. This is an additional optional parameter added to the end of the HudMessage command's existing parameter lists. So for HUDMSG_PLAIN, it comes after the hold time. For HUDMSG_FADEOUT and HUDMSG_TYPEONE, it comes after the fade time. And for HUDMSG_FADEINOUT, it comes after the out time. - Alpha is a fixed point number between 0.0 and 1.0. - Example: Without alpha (unchanged from before): HudMessage(s:"Some text", HUDMSG_PLAIN, 0, CR_UNTRANSLATED, 0.5, 0.5, 3.0); With alpha (alpha is added to the end): HudMessage(s:"Some text", HUDMSG_PLAIN, 0, CR_UNTRANSLATED, 0.5, 0.5, 3.0, 0.5 /* this is the alpha */); SVN r3825 (trunk) --- src/p_acs.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 50570618f..4bd7df6a9 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5683,6 +5683,7 @@ scriptwait: float x = FIXED2FLOAT(Stack[optstart-3]); float y = FIXED2FLOAT(Stack[optstart-2]); float holdTime = FIXED2FLOAT(Stack[optstart-1]); + fixed_t alpha; DHUDMessage *msg; if (type & HUDMSG_COLORSTRING) @@ -5697,11 +5698,13 @@ scriptwait: switch (type & 0xFF) { default: // normal + alpha = (optstart < sp) ? Stack[optstart] : FRACUNIT; msg = new DHUDMessage (activefont, work, x, y, hudwidth, hudheight, color, holdTime); break; case 1: // fade out { float fadeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; + alpha = (optstart < sp-1) ? Stack[optstart+1] : FRACUNIT; msg = new DHUDMessageFadeOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); } break; @@ -5709,6 +5712,7 @@ scriptwait: { float typeTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.05f; float fadeTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; + alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; msg = new DHUDMessageTypeOnFadeOut (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); } break; @@ -5716,11 +5720,13 @@ scriptwait: { float inTime = (optstart < sp) ? FIXED2FLOAT(Stack[optstart]) : 0.5f; float outTime = (optstart < sp-1) ? FIXED2FLOAT(Stack[optstart+1]) : 0.5f; + alpha = (optstart < sp-2) ? Stack[optstart+2] : FRACUNIT; msg = new DHUDMessageFadeInOut (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); } break; } msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); + msg->SetAlpha(alpha); if (type & HUDMSG_ADDBLEND) { msg->SetRenderStyle(STYLE_Add); From 86ef939f820bc9e62957601387220b44c99e360e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Aug 2012 02:25:59 +0000 Subject: [PATCH 048/101] - Fixed: The new HUD message layers were not declared for the garbage collector. SVN r3826 (trunk) --- src/g_shared/shared_sbar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index d2636d337..4ca4a519c 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -61,7 +61,9 @@ #define POWERUPICONSIZE 32 IMPLEMENT_POINTY_CLASS(DBaseStatusBar) - DECLARE_POINTER(Messages) + DECLARE_POINTER(Messages[0]) + DECLARE_POINTER(Messages[1]) + DECLARE_POINTER(Messages[2]) END_POINTERS EXTERN_CVAR (Bool, am_showmonsters) From 7a8ccaad97f06628f360201ef591828f049e815f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Aug 2012 02:50:29 +0000 Subject: [PATCH 049/101] - Clear the shootable flag in P_ExplodeMissile(). SVN r3827 (trunk) --- src/p_mobj.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 938c976f3..f26f0978a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1159,6 +1159,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) } mo->velx = mo->vely = mo->velz = 0; mo->effects = 0; // [RH] + mo->flags &= ~MF_SHOOTABLE; FState *nextstate=NULL; From 166b4dbb75b5b638d1eb829be64d5dee6a375b7d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Aug 2012 03:00:03 +0000 Subject: [PATCH 050/101] - Since the string builder stuff takes care of recursive print calls now, the PCD_CALLs don't need to save it as part of the state when calling functions. SVN r3828 (trunk) --- src/p_acs.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4bd7df6a9..4b253efb8 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -112,13 +112,12 @@ FRandom pr_acs ("ACS"); struct CallReturn { - CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard, FString &str) + CallReturn(int pc, ScriptFunction *func, FBehavior *module, SDWORD *locals, bool discard) : ReturnFunction(func), ReturnModule(module), ReturnLocals(locals), ReturnAddress(pc), - bDiscardResult(discard), - StringBuilder(str) + bDiscardResult(discard) {} ScriptFunction *ReturnFunction; @@ -126,7 +125,6 @@ struct CallReturn SDWORD *ReturnLocals; int ReturnAddress; int bDiscardResult; - FString StringBuilder; }; static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module, @@ -170,8 +168,8 @@ TArray ACS_StringsOnTheFly, ACS_StringBuilderStack; -#define STRINGBUILDER_START(Builder) if (*Builder.GetChars() || ACS_StringBuilderStack.Size()) { ACS_StringBuilderStack.Push(Builder); Builder = ""; } -#define STRINGBUILDER_FINISH(Builder) if (!ACS_StringBuilderStack.Pop(Builder)) Builder = ""; +#define STRINGBUILDER_START(Builder) if (Builder.IsNotEmpty() || ACS_StringBuilderStack.Size()) { ACS_StringBuilderStack.Push(Builder); Builder = ""; } +#define STRINGBUILDER_FINISH(Builder) if (!ACS_StringBuilderStack.Pop(Builder)) { Builder = ""; } //============================================================================ // @@ -4323,7 +4321,7 @@ int DLevelScript::RunScript () } sp += i; ::new(&Stack[sp]) CallReturn(activeBehavior->PC2Ofs(pc), activeFunction, - activeBehavior, mylocals, pcd == PCD_CALLDISCARD, work); + activeBehavior, mylocals, pcd == PCD_CALLDISCARD); sp += (sizeof(CallReturn) + sizeof(int) - 1) / sizeof(int); pc = module->Ofs2PC (func->Address); activeFunction = func; @@ -4362,7 +4360,6 @@ int DLevelScript::RunScript () { Stack[sp++] = value; } - work = ret->StringBuilder; ret->~CallReturn(); } break; @@ -7570,6 +7567,3 @@ void DACSThinker::DumpScriptStatus () script = script->next; } } - -#undef STRINGBUILDER_START -#undef STRINGBUILDER_FINISH From 100391507e7e2b4a6c9b66877062ae873110655e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Aug 2012 03:24:59 +0000 Subject: [PATCH 051/101] - Added two new PlayerPawn properties: * GruntSpeed: The minimum speed a player must be falling at the time of landing to play *grunt. * FallingScreamSpeed: When a player is falling within this range of speeds, they will play *falling. SVN r3829 (trunk) --- src/d_player.h | 2 ++ src/p_mobj.cpp | 2 +- src/p_user.cpp | 14 ++++++++++++-- src/thingdef/thingdef_properties.cpp | 20 ++++++++++++++++++++ wadsrc/static/actors/shared/player.txt | 2 ++ 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d8fb75eae..e5307fd28 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -130,6 +130,8 @@ public: // [GRB] Player class properties fixed_t JumpZ; + fixed_t GruntSpeed; + fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed; fixed_t ViewHeight; fixed_t ForwardMove1, ForwardMove2; fixed_t SideMove1, SideMove2; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f26f0978a..f0788bb31 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2476,7 +2476,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) { grunted = false; // Why should this number vary by gravity? - if (mo->velz < (fixed_t)(800.f /*level.gravity * mo->Sector->gravity*/ * -983.04f) && mo->health > 0) + if (mo->health > 0 && mo->velz < -mo->player->mo->GruntSpeed) { S_Sound (mo, CHAN_VOICE, "*grunt", 1, ATTN_NORM); grunted = true; diff --git a/src/p_user.cpp b/src/p_user.cpp index 6b853e8b8..f3cab9236 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -463,6 +463,16 @@ void APlayerPawn::Serialize (FArchive &arc) << DamageFade << PlayerFlags << FlechetteType; + if (SaveVersion < 3829) + { + GruntSpeed = 12*FRACUNIT; + FallingScreamMinSpeed = 35*FRACUNIT; + FallingScreamMaxSpeed = 40*FRACUNIT; + } + else + { + arc << GruntSpeed << FallingScreamMinSpeed << FallingScreamMaxSpeed; + } } //=========================================================================== @@ -2383,8 +2393,8 @@ void P_PlayerThink (player_t *player) P_PlayerInSpecialSector (player); } P_PlayerOnSpecialFlat (player, P_GetThingFloorType (player->mo)); - if (player->mo->velz <= -35*FRACUNIT && - player->mo->velz >= -40*FRACUNIT && !player->morphTics && + if (player->mo->velz <= -player->mo->FallingScreamMinSpeed && + player->mo->velz >= -player->mo->FallingScreamMaxSpeed && !player->morphTics && player->mo->waterlevel == 0) { int id = S_FindSkinnedSound (player->mo, "*falling"); diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index eb11972f1..f5dc0d91f 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -2237,6 +2237,26 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, jumpz, F, PlayerPawn) defaults->JumpZ = z; } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, GruntSpeed, F, PlayerPawn) +{ + PROP_FIXED_PARM(z, 0); + defaults->GruntSpeed = z; +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, FallingScreamSpeed, FF, PlayerPawn) +{ + PROP_FIXED_PARM(minz, 0); + PROP_FIXED_PARM(maxz, 0); + defaults->FallingScreamMinSpeed = minz; + defaults->FallingScreamMaxSpeed = maxz; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/shared/player.txt b/wadsrc/static/actors/shared/player.txt index 3edb7aa40..05fb998c3 100644 --- a/wadsrc/static/actors/shared/player.txt +++ b/wadsrc/static/actors/shared/player.txt @@ -21,6 +21,8 @@ Actor PlayerPawn : Actor native +NOBLOCKMONST Player.AttackZOffset 8 Player.JumpZ 8 + Player.GruntSpeed 12 + Player.FallingScreamSpeed 35,40 Player.ViewHeight 41 Player.ForwardMove 1,1 Player.SideMove 1,1 From 25641251484987b205dbe2cfc1511be1440165cc Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 22 Aug 2012 04:16:58 +0000 Subject: [PATCH 052/101] - Fixed: Crash when trying to swap fragglescript special when specials 272 and 270 aren't in the translation array. SVN r3830 (trunk) --- src/fragglescript/t_load.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 850d61769..d9b4f2d04 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -342,7 +342,7 @@ void T_LoadScripts(MapData *map) // the default translator is being used. // Custom translators will not be patched. if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && level.info->Translator.IsEmpty() && - level.maptype == MAPTYPE_DOOM && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute) + level.maptype == MAPTYPE_DOOM && SimpleLineTranslations.Size() > 272 && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute) { FLineTrans t = SimpleLineTranslations[270]; SimpleLineTranslations[270] = SimpleLineTranslations[272]; From adf9bd2e1a76213e470a030b197fbb65608beba2 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Wed, 22 Aug 2012 04:23:51 +0000 Subject: [PATCH 053/101] - Fixed: screenshot_dir overrided -shotdir. SVN r3831 (trunk) --- src/m_misc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 32783236e..f552d4880 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -734,7 +734,6 @@ void M_ScreenShot (const char *filename) } else if (dirlen > 0) { - autoname = screenshot_dir; if (autoname[dirlen-1] != '/' && autoname[dirlen-1] != '\\') { autoname += '/'; From a505352da343a3c1145d20da5ec43bc841d4b2b3 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 21:31:48 +0000 Subject: [PATCH 054/101] - Added noclip2 cheat. This is similar to noclip, except it also adds nogravity and the ability to fly through 3D floors. SVN r3832 (trunk) --- src/actor.h | 2 ++ src/c_cmds.cpp | 9 +++++++++ src/d_player.h | 9 +++++++++ src/d_protocol.h | 3 ++- src/m_cheat.cpp | 14 ++++++++++++++ src/p_map.cpp | 10 +++++++--- src/p_mobj.cpp | 9 +++++++-- src/p_user.cpp | 26 +++++++++++++++++++++----- wadsrc/static/language.enu | 1 + 9 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/actor.h b/src/actor.h index a0fd4578e..751e3579e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -712,6 +712,8 @@ public: // Do I hate the other actor? bool IsHostile (AActor *other); + inline bool IsNoClip2() const; + // What species am I? virtual FName GetSpecies(); diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 9c7b781d2..b1f3a1561 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -175,6 +175,15 @@ CCMD (noclip) Net_WriteByte (CHT_NOCLIP); } +CCMD (noclip2) +{ + if (CheckCheatmode()) + return; + + Net_WriteByte (DEM_GENERICCHEAT); + Net_WriteByte (CHT_NOCLIP2); +} + CCMD (powerup) { if (CheckCheatmode ()) diff --git a/src/d_player.h b/src/d_player.h index e5307fd28..67f03db44 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -208,6 +208,7 @@ typedef enum CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die CF_WEAPONRELOADOK = 1 << 28, // [XA] Okay to reload this weapon. CF_WEAPONZOOMOK = 1 << 29, // [XA] Okay to use weapon zoom function. + CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip } cheat_t; #define WPIECE1 1 @@ -439,6 +440,14 @@ inline void AActor::SetFriendPlayer(player_t *player) } } +inline bool AActor::IsNoClip2() const +{ + if (player != NULL && player->mo == this) + { + return (player->cheats & CF_NOCLIP2) != 0; + } + return false; +} #define CROUCHSPEED (FRACUNIT/12) diff --git a/src/d_protocol.h b/src/d_protocol.h index b3d72a4ca..028ad1606 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -218,7 +218,8 @@ enum ECheatCommand CHT_GIMMIEI, CHT_GIMMIEJ, CHT_GIMMIEZ, - CHT_BUDDHA + CHT_BUDDHA, + CHT_NOCLIP2 }; void StartChunk (int id, BYTE **stream); diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 2d836327d..d639ec514 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -106,6 +106,20 @@ void cht_DoCheat (player_t *player, int cheat) msg = GStrings("STSTR_NCOFF"); break; + case CHT_NOCLIP2: + player->cheats ^= CF_NOCLIP2; + if (player->cheats & CF_NOCLIP2) + { + player->cheats |= CF_NOCLIP; + msg = GStrings("STSTR_NC2ON"); + } + else + { + player->cheats &= ~CF_NOCLIP; + msg = GStrings("STSTR_NCOFF"); + } + break; + case CHT_NOVELOCITY: player->cheats ^= CF_NOVELOCITY; if (player->cheats & CF_NOVELOCITY) diff --git a/src/p_map.cpp b/src/p_map.cpp index 632607da2..5b54be076 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -501,7 +501,11 @@ int P_GetFriction (const AActor *mo, int *frictionfactor) const msecnode_t *m; const sector_t *sec; - if (mo->flags2 & MF2_FLY && mo->flags & MF_NOGRAVITY) + if (mo->IsNoClip2()) + { + // The default values are fine for noclip2 mode + } + else if (mo->flags2 & MF2_FLY && mo->flags & MF_NOGRAVITY) { friction = FRICTION_FLY; } @@ -1298,7 +1302,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, b #ifdef _3DFLOORS //Check 3D floors - if(newsec->e->XFloor.ffloors.Size()) + if (!thing->IsNoClip2() && newsec->e->XFloor.ffloors.Size()) { F3DFloor* rover; fixed_t delta1; @@ -1605,7 +1609,7 @@ void P_FakeZMovement (AActor *mo) mo->z += mo->FloatSpeed; } } - if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz)) + if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz) && !mo->IsNoClip2()) { mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f0788bb31..4ccd669f7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1985,7 +1985,9 @@ explode: } if (mo->z > mo->floorz && !(mo->flags2 & MF2_ONMOBJ) && - (!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) && !mo->waterlevel) + !mo->IsNoClip2() && + (!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) && + !mo->waterlevel) { // [RH] Friction when falling is available for larger aircontrols if (player != NULL && level.airfriction != FRACUNIT) { @@ -2228,7 +2230,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } if (mo->player && (mo->flags & MF_NOGRAVITY) && (mo->z > mo->floorz)) { - mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8; + if (!mo->IsNoClip2()) + { + mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8; + } mo->velz = FixedMul (mo->velz, FRICTION_FLY); } if (mo->waterlevel && !(mo->flags & MF_NOGRAVITY)) diff --git a/src/p_user.cpp b/src/p_user.cpp index f3cab9236..b8dfd339c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1625,7 +1625,11 @@ void P_CalcHeight (player_t *player) // it causes bobbing jerkiness when the player moves from ice to non-ice, // and vice-versa. - if ((player->mo->flags & MF_NOGRAVITY) && !onground) + if (player->cheats & CF_NOCLIP2) + { + player->bob = 0; + } + else if ((player->mo->flags & MF_NOGRAVITY) && !onground) { player->bob = FRACUNIT / 2; } @@ -1750,7 +1754,7 @@ void P_MovePlayer (player_t *player) mo->angle += cmd->ucmd.yaw << 16; } - onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF); + onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); // killough 10/98: // @@ -2131,7 +2135,11 @@ void P_PlayerThink (player_t *player) player->inventorytics--; } // No-clip cheat - if (player->cheats & CF_NOCLIP || (player->mo->GetDefault()->flags & MF_NOCLIP)) + if ((player->cheats & (CF_NOCLIP | CF_NOCLIP2)) == CF_NOCLIP2) + { // No noclip2 without noclip + player->cheats &= ~CF_NOCLIP2; + } + if (player->cheats & (CF_NOCLIP | CF_NOCLIP2) || (player->mo->GetDefault()->flags & MF_NOCLIP)) { player->mo->flags |= MF_NOCLIP; } @@ -2139,6 +2147,14 @@ void P_PlayerThink (player_t *player) { player->mo->flags &= ~MF_NOCLIP; } + if (player->cheats & CF_NOCLIP2) + { + player->mo->flags |= MF_NOGRAVITY; + } + else if (!(player->mo->flags2 & MF2_FLY) && !(player->mo->GetDefault()->flags & MF_NOGRAVITY)) + { + player->mo->flags &= ~MF_NOGRAVITY; + } cmd = &player->cmd; // Make unmodified copies for ACS's GetPlayerInput. @@ -2359,7 +2375,7 @@ void P_PlayerThink (player_t *player) { cmd->ucmd.upmove = ksgn (cmd->ucmd.upmove) * 0x300; } - if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY)) + if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2)) { player->mo->velz = cmd->ucmd.upmove << 9; if (player->mo->waterlevel < 2 && !(player->mo->flags & MF_NOGRAVITY)) @@ -2477,7 +2493,7 @@ void P_PlayerThink (player_t *player) { if (player->mo->waterlevel < 3 || (player->mo->flags2 & MF2_INVULNERABLE) || - (player->cheats & CF_GODMODE)) + (player->cheats & (CF_GODMODE | CF_NOCLIP2))) { player->mo->ResetAirSupply (); } diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 2f9f7509e..ceecfd1c0 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -280,6 +280,7 @@ STSTR_KFAADDED = "Very Happy Ammo Added"; STSTR_FAADDED = "Ammo (no keys) Added"; STSTR_NCON = "No Clipping Mode ON"; STSTR_NCOFF = "No Clipping Mode OFF"; +STSTR_NC2ON = "No Clipping Mode 2 ON"; STSTR_BEHOLD = "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp"; STSTR_BEHOLDX = "Power-up Toggled"; STSTR_CHOPPERS = "... doesn't suck - GM"; From d5d4584008a5a7134ddc43a42554fa79c184886b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 21:35:47 +0000 Subject: [PATCH 055/101] - Ignore the Skulltag-based SERVERSIDEONLY flag in actor definitions. SVN r3833 (trunk) --- src/thingdef/thingdef_data.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index fe94a2fcc..573970db3 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -276,6 +276,7 @@ static FFlagDef ActorFlags[]= DEFINE_DUMMY_FLAG(NONETID), // netcode-based DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN), // netcode-based DEFINE_DUMMY_FLAG(CLIENTSIDEONLY), // netcode-based + DEFINE_DUMMY_FLAG(SERVERSIDEONLY), // netcode-based DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless }; From bc30b1a8060f2743f529956b12f14b6e27a9083e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 21:53:44 +0000 Subject: [PATCH 056/101] - Exported the scoreboard text to LANGUAGE. SVN r3834 (trunk) --- src/hu_scores.cpp | 15 ++++++++++----- src/wi_stuff.cpp | 30 +++++++++++++++++------------- wadsrc/static/language.enu | 10 ++++++++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 9af0c0c05..55d657b7c 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -47,6 +47,7 @@ #include "v_palette.h" #include "d_player.h" #include "hu_stuff.h" +#include "gstrings.h" // MACROS ------------------------------------------------------------------ @@ -310,18 +311,22 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER y += (BigFont->GetHeight() + 8) * CleanYfac; } - col2 = (SmallFont->StringWidth("Color") + 8) * CleanXfac; - col3 = col2 + (SmallFont->StringWidth("Frags") + 8) * CleanXfac; + const char *text_color = GStrings("SCORE_COLOR"), + *text_frags = GStrings(deathmatch ? "SCORE_FRAGS" : "SCORE_KILLS"), + *text_name = GStrings("SCORE_NAME"); + + col2 = (SmallFont->StringWidth(text_color) + 8) * CleanXfac; + col3 = col2 + (SmallFont->StringWidth(text_frags) + 8) * CleanXfac; col4 = col3 + maxscorewidth * CleanXfac; x = (SCREENWIDTH >> 1) - ((maxnamewidth * CleanXfac + col4) >> 1); - screen->DrawText (SmallFont, color, x, y, "Color", + screen->DrawText (SmallFont, color, x, y, text_color, DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText (SmallFont, color, x + col2, y, deathmatch ? "Frags" : "Kills", + screen->DrawText (SmallFont, color, x + col2, y, text_frags, DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText (SmallFont, color, x + col4, y, "Name", + screen->DrawText (SmallFont, color, x + col4, y, text_name, DTA_CleanNoMove, true, TAG_DONE); y += height + 6 * CleanYfac; diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 6e841518f..41981c45f 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1595,7 +1595,7 @@ void WI_drawNetgameStats () int bonus_len, secret_len; int missed_kills, missed_items, missed_secrets; EColorRange color; - const char *bonus_label; + const char *text_bonus, *text_color, *text_secret, *text_kills; // draw animated background WI_drawBackground(); @@ -1608,12 +1608,16 @@ void WI_drawNetgameStats () ypadding = (lineheight - height + 1) / 2; y += 16*CleanYfac; - bonus_label = (gameinfo.gametype & GAME_Raven) ? "BONUS" : "ITEMS"; - icon_x = (SmallFont->StringWidth("COLOR") + 8) * CleanXfac; + text_bonus = GStrings((gameinfo.gametype & GAME_Raven) ? "SCORE_BONUS" : "SCORE_ITEMS"); + text_color = GStrings("SCORE_COLOR"); + text_secret = GStrings("SCORE_SECRET"); + text_kills = GStrings("SCORE_KILLS"); + + icon_x = (SmallFont->StringWidth(text_color) + 8) * CleanXfac; name_x = icon_x + maxscorewidth * CleanXfac; - kills_x = name_x + (maxnamewidth + SmallFont->StringWidth("XXXXX") + 8) * CleanXfac; - bonus_x = kills_x + ((bonus_len = SmallFont->StringWidth(bonus_label)) + 8) * CleanXfac; - secret_x = bonus_x + ((secret_len = SmallFont->StringWidth("SECRET")) + 8) * CleanXfac; + kills_x = name_x + (maxnamewidth + MAX(SmallFont->StringWidth("XXXXX"), SmallFont->StringWidth(text_kills)) + 8) * CleanXfac; + bonus_x = kills_x + ((bonus_len = SmallFont->StringWidth(text_bonus)) + 8) * CleanXfac; + secret_x = bonus_x + ((secret_len = SmallFont->StringWidth(text_secret)) + 8) * CleanXfac; x = (SCREENWIDTH - secret_x) >> 1; icon_x += x; @@ -1624,11 +1628,11 @@ void WI_drawNetgameStats () color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED; - screen->DrawText(SmallFont, color, x, y, "COLOR", DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText(SmallFont, color, name_x, y, "NAME", DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText(SmallFont, color, kills_x - SmallFont->StringWidth("KILLS")*CleanXfac, y, "KILLS", DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText(SmallFont, color, bonus_x - bonus_len*CleanXfac, y, bonus_label, DTA_CleanNoMove, true, TAG_DONE); - screen->DrawText(SmallFont, color, secret_x - secret_len*CleanXfac, y, "SECRET", DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, x, y, text_color, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_NAME"), DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, kills_x - SmallFont->StringWidth(text_kills)*CleanXfac, y, text_kills, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, bonus_x - bonus_len*CleanXfac, y, text_bonus, DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, secret_x - secret_len*CleanXfac, y, text_secret, DTA_CleanNoMove, true, TAG_DONE); y += height + 6 * CleanYfac; missed_kills = wbs->maxkills; @@ -1669,7 +1673,7 @@ void WI_drawNetgameStats () // Draw "MISSED" line y += 5 * CleanYfac; - screen->DrawText(SmallFont, CR_DARKGRAY, name_x, y, "MISSED", DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, CR_DARKGRAY, name_x, y, GStrings("SCORE_MISSED"), DTA_CleanNoMove, true, TAG_DONE); WI_drawPercent(SmallFont, kills_x, y, missed_kills, wbs->maxkills, false, CR_DARKGRAY); if (ng_state >= 4) { @@ -1683,7 +1687,7 @@ void WI_drawNetgameStats () // Draw "TOTAL" line y += height + 5 * CleanYfac; color = (gameinfo.gametype & GAME_Raven) ? CR_GREEN : CR_UNTRANSLATED; - screen->DrawText(SmallFont, color, name_x, y, "TOTAL", DTA_CleanNoMove, true, TAG_DONE); + screen->DrawText(SmallFont, color, name_x, y, GStrings("SCORE_TOTAL"), DTA_CleanNoMove, true, TAG_DONE); WI_drawNum(SmallFont, kills_x, y, wbs->maxkills, 0, false, color); if (ng_state >= 4) { diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index ceecfd1c0..7564ff85b 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -793,6 +793,16 @@ STARTUP3 = ""; STARTUP4 = ""; STARTUP5 = ""; +// Scoreboard text +SCORE_ITEMS = "ITEMS"; +SCORE_BONUS = "BONUS"; +SCORE_COLOR = "COLOR"; +SCORE_SECRET = "SECRET"; +SCORE_NAME = "NAME"; +SCORE_KILLS = "KILLS"; +SCORE_FRAGS = "FRAGS"; +SCORE_MISSED = "MISSED"; +SCORE_TOTAL = "TOTAL"; // Item tags: Doom weapons TAG_FIST = "Brass Knuckles"; From 8a021c4b4bc3db73443fcdaf95160ad3a0900fa0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 22:09:17 +0000 Subject: [PATCH 057/101] - Added PLAYERINFO_FOV and PLAYERINFO_DESIREDFOV for use with GetPlayerInfo. PLAYERINFO_FOV is the player's current FOV, and PLAYERINFO_DESIREDFOV is the FOV that was set with the fov console command. SVN r3835 (trunk) --- src/p_acs.cpp | 5 ++++- src/p_acs.h | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4b253efb8..fdba35118 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6934,7 +6934,8 @@ scriptwait: } else { - userinfo_t *userinfo = &players[STACK(2)].userinfo; + player_t *pl = &players[STACK(2)]; + userinfo_t *userinfo = &pl->userinfo; switch (STACK(1)) { case PLAYERINFO_TEAM: STACK(2) = userinfo->team; break; @@ -6945,6 +6946,8 @@ scriptwait: case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->MoveBob; break; case PLAYERINFO_STILLBOB: STACK(2) = userinfo->StillBob; break; case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->PlayerClass; break; + case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break; + case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break; default: STACK(2) = 0; break; } } diff --git a/src/p_acs.h b/src/p_acs.h index 7a432815b..df2abdf84 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -664,7 +664,9 @@ public: PLAYERINFO_NEVERSWITCH, PLAYERINFO_MOVEBOB, PLAYERINFO_STILLBOB, - PLAYERINFO_PLAYERCLASS + PLAYERINFO_PLAYERCLASS, + PLAYERINFO_FOV, + PLAYERINFO_DESIREDFOV, }; enum EScriptState From 9d82c7fa0e378eccb9f1e407a52a4beeb1b63983 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 22:36:06 +0000 Subject: [PATCH 058/101] - Added PrecacheSounds mapinfo option. This takes a list of sounds to preload when the level is loaded. SVN r3837 (trunk) --- src/d_main.cpp | 8 ++++---- src/g_level.h | 4 +++- src/g_mapinfo.cpp | 22 +++++++++++++++++++++- src/s_sound.cpp | 8 +++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 40c724496..c428059e6 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2209,15 +2209,15 @@ void D_DoomMain (void) // [RH] Load sound environments S_ParseReverbDef (); + // [RH] Parse any SNDINFO lumps + Printf ("S_InitData: Load sound definitions.\n"); + S_InitData (); + // [RH] Parse through all loaded mapinfo lumps Printf ("G_ParseMapInfo: Load map definitions.\n"); G_ParseMapInfo (iwad_info->MapInfo); ReadStatistics(); - // [RH] Parse any SNDINFO lumps - Printf ("S_InitData: Load sound definitions.\n"); - S_InitData (); - Printf ("Texman.Init: Init texture manager.\n"); TexMan.Init(); C_InitConback(); diff --git a/src/g_level.h b/src/g_level.h index bc30b5603..c246e5b7e 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -36,8 +36,8 @@ #include "doomtype.h" #include "doomdef.h" -//#include "autosegs.h" #include "sc_man.h" +#include "s_sound.h" struct level_info_t; struct cluster_info_t; @@ -327,6 +327,8 @@ struct level_info_t TArray specialactions; + TArray PrecacheSounds; + level_info_t() { Reset(); diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 38440c8f0..1d229267e 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -269,6 +269,7 @@ void level_info_t::Reset() teamdamage = 0.f; specialactions.Clear(); DefaultEnvironment = 0; + PrecacheSounds.Clear(); } @@ -1029,7 +1030,7 @@ DEFINE_MAP_OPTION(specialaction, true) sa->Action = P_FindLineSpecial(parse.sc.String, &min_arg, &max_arg); if (sa->Action == 0 || min_arg < 0) { - parse.sc.ScriptError("Unknown specialaction '%s'"); + parse.sc.ScriptError("Unknown specialaction '%s'", parse.sc.String); } int j = 0; while (j < 5 && parse.sc.CheckString(",")) @@ -1040,6 +1041,25 @@ DEFINE_MAP_OPTION(specialaction, true) if (parse.format_type == parse.FMT_Old) parse.sc.SetCMode(false); } +DEFINE_MAP_OPTION(PrecacheSounds, true) +{ + parse.ParseAssign(); + + do + { + parse.sc.MustGetString(); + FSoundID snd = parse.sc.String; + if (snd == 0) + { + parse.sc.ScriptMessage("Unknown sound \"%s\"", parse.sc.String); + } + else + { + info->PrecacheSounds.Push(snd); + } + } while (parse.sc.CheckString(",")); +} + DEFINE_MAP_OPTION(redirect, true) { parse.ParseAssign(); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 9749d635c..dadd1a6d7 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -477,7 +477,8 @@ void S_PrecacheLevel () AActor *actor; TThinkerIterator iterator; - while ( (actor = iterator.Next ()) != NULL ) + // Precache all sounds known to be used by the currently spawned actors. + while ( (actor = iterator.Next()) != NULL ) { S_sfx[actor->SeeSound].bUsed = true; S_sfx[actor->AttackSound].bUsed = true; @@ -486,6 +487,11 @@ void S_PrecacheLevel () S_sfx[actor->ActiveSound].bUsed = true; S_sfx[actor->UseSound].bUsed = true; } + // Precache all extra sounds requested by this map. + for (i = 0; i < level.info->PrecacheSounds.Size(); ++i) + { + S_sfx[level.info->PrecacheSounds[i]].bUsed = true; + } for (i = 1; i < S_sfx.Size(); ++i) { From 625482aaebef89aad86da74df30e0d9f04da688b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:17:49 +0000 Subject: [PATCH 059/101] - Added actors' BounceSound, WallBounceSound, and CrushPainSound to preloading. - Moved marking of actor sounds for precaching into a virtual Actor function. SVN r3838 (trunk) --- src/actor.h | 15 +++++++-------- src/p_mobj.cpp | 13 +++++++++++++ src/s_sound.cpp | 9 ++------- src/s_sound.h | 6 ++++++ 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/actor.h b/src/actor.h index 751e3579e..1b4e5ac91 100644 --- a/src/actor.h +++ b/src/actor.h @@ -583,15 +583,14 @@ public: bool AdjustReflectionAngle (AActor *thing, angle_t &angle); // Returns true if this actor is within melee range of its target - bool CheckMeleeRange (); + bool CheckMeleeRange(); - // BeginPlay: Called just after the actor is created - virtual void BeginPlay (); - virtual void PostBeginPlay (); - // LevelSpawned: Called after BeginPlay if this actor was spawned by the world - virtual void LevelSpawned (); - // Translates SpawnFlags into in-game flags. - virtual void HandleSpawnFlags (); + virtual void BeginPlay(); // Called immediately after the actor is created + virtual void PostBeginPlay(); // Called immediately before the actor's first tick + virtual void LevelSpawned(); // Called after BeginPlay if this actor was spawned by the world + virtual void HandleSpawnFlags(); // Translates SpawnFlags into in-game flags. + + virtual void MarkPrecacheSounds() const; // Marks sounds used by this actor for precaching. virtual void Activate (AActor *activator); virtual void Deactivate (AActor *activator); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 4ccd669f7..1acdc2927 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3993,6 +3993,19 @@ void AActor::PostBeginPlay () PrevAngle = angle; } +void AActor::MarkPrecacheSounds() const +{ + SeeSound.MarkUsed(); + AttackSound.MarkUsed(); + PainSound.MarkUsed(); + DeathSound.MarkUsed(); + ActiveSound.MarkUsed(); + UseSound.MarkUsed(); + BounceSound.MarkUsed(); + WallBounceSound.MarkUsed(); + CrushPainSound.MarkUsed(); +} + bool AActor::isFast() { if (flags5&MF5_ALWAYSFAST) return true; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index dadd1a6d7..de383a1f6 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -480,17 +480,12 @@ void S_PrecacheLevel () // Precache all sounds known to be used by the currently spawned actors. while ( (actor = iterator.Next()) != NULL ) { - S_sfx[actor->SeeSound].bUsed = true; - S_sfx[actor->AttackSound].bUsed = true; - S_sfx[actor->PainSound].bUsed = true; - S_sfx[actor->DeathSound].bUsed = true; - S_sfx[actor->ActiveSound].bUsed = true; - S_sfx[actor->UseSound].bUsed = true; + actor->MarkPrecacheSounds(); } // Precache all extra sounds requested by this map. for (i = 0; i < level.info->PrecacheSounds.Size(); ++i) { - S_sfx[level.info->PrecacheSounds[i]].bUsed = true; + level.info->PrecacheSounds[i].MarkUsed(); } for (i = 1; i < S_sfx.Size(); ++i) diff --git a/src/s_sound.h b/src/s_sound.h index 84881862c..2c2a398ae 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -65,6 +65,8 @@ struct sfxinfo_t FRolloffInfo Rolloff; float Attenuation; // Multiplies the attenuation passed to S_Sound. + + void MarkUsed(); // Marks this sound as used. }; // Rolloff types @@ -132,6 +134,10 @@ public: { return ID ? S_sfx[ID].name.GetChars() : NULL; } + void MarkUsed() const + { + S_sfx[ID].MarkUsed(); + } private: int ID; protected: From 1d3c26f088ea27f41c6c3e15cd0240d178e1ff00 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:21:23 +0000 Subject: [PATCH 060/101] - Add the definition for sfxinfo_t::MarkUsed() (poo for incomplete commits). SVN r3840 (trunk) --- src/s_advsound.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index cea8950ac..ad6be7875 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1899,6 +1899,19 @@ bool S_ParseTimeTag(const char *tag, bool *as_samples, unsigned int *time) return true; } +//========================================================================== +// +// sfxinfo_t :: MarkUsed +// +// Marks this sound for precaching. +// +//========================================================================== + +void sfxinfo_t::MarkUsed() +{ + bUsed = true; +} + //========================================================================== // // CCMD soundlist From 0ac94c5265854e08d2ed8fc0eba83a2075a16dae Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:46:47 +0000 Subject: [PATCH 061/101] - Precache player sounds at level load. SVN r3841 (trunk) --- src/d_player.h | 3 ++- src/p_user.cpp | 14 +++++++++++++- src/s_advsound.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/s_sound.h | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 67f03db44..fa14c49a9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -90,6 +90,7 @@ public: virtual void AddInventory (AInventory *item); virtual void RemoveInventory (AInventory *item); virtual bool UseInventory (AInventory *item); + virtual void MarkPrecacheSounds () const; virtual void PlayIdle (); virtual void PlayRunning (); @@ -107,7 +108,7 @@ public: void GiveDefaultInventory (); void PlayAttacking (); void PlayAttacking2 (); - const char *GetSoundClass (); + const char *GetSoundClass () const; enum EInvulState { diff --git a/src/p_user.cpp b/src/p_user.cpp index b8dfd339c..8339262b7 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -475,6 +475,18 @@ void APlayerPawn::Serialize (FArchive &arc) } } +//=========================================================================== +// +// APlayerPawn :: MarkPrecacheSounds +// +//=========================================================================== + +void APlayerPawn::MarkPrecacheSounds() const +{ + Super::MarkPrecacheSounds(); + S_MarkPlayerSounds(GetSoundClass()); +} + //=========================================================================== // // APlayerPawn :: BeginPlay @@ -968,7 +980,7 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer) // //=========================================================================== -const char *APlayerPawn::GetSoundClass () +const char *APlayerPawn::GetSoundClass() const { if (player != NULL && (player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) && diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index ad6be7875..12ebc94a0 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -100,6 +100,7 @@ public: void AddSound (int player_sound_id, int sfx_id); int LookupSound (int player_sound_id); FPlayerSoundHashTable &operator= (const FPlayerSoundHashTable &other); + void MarkUsed(); protected: struct Entry @@ -830,6 +831,25 @@ int FPlayerSoundHashTable::LookupSound (int player_sound_id) return entry != NULL ? entry->SfxID : 0; } +//========================================================================== +// +// FPlayerSoundHashTable :: Mark +// +// Marks all sounds defined for this class/gender as used. +// +//========================================================================== + +void FPlayerSoundHashTable::MarkUsed() +{ + for (size_t i = 0; i < NUM_BUCKETS; ++i) + { + for (Entry *probe = Buckets[i]; probe != NULL; probe = probe->Next) + { + S_sfx[probe->SfxID].bUsed = true; + } + } +} + //========================================================================== // // S_ClearSoundData @@ -1912,6 +1932,31 @@ void sfxinfo_t::MarkUsed() bUsed = true; } +//========================================================================== +// +// S_MarkPlayerSounds +// +// Marks all sounds from a particular player class for precaching. +// +//========================================================================== + +void S_MarkPlayerSounds (const char *playerclass) +{ + int classidx = S_FindPlayerClass(playerclass); + if (classidx < 0) + { + classidx = DefPlayerClass; + } + for (int g = 0; g < 3; ++g) + { + int listidx = PlayerClassLookups[classidx].ListIndex[0]; + if (listidx != 0xffff) + { + PlayerSounds[listidx].MarkUsed(); + } + } +} + //========================================================================== // // CCMD soundlist diff --git a/src/s_sound.h b/src/s_sound.h index 2c2a398ae..8b0e4ddea 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -357,6 +357,7 @@ int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump ind int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname); int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false); int S_AddPlayerSoundExisting (const char *playerclass, const int gender, int refid, int aliasto, bool fromskin=false); +void S_MarkPlayerSounds (const char *playerclass); void S_ShrinkPlayerSoundLists (); void S_UnloadSound (sfxinfo_t *sfx); sfxinfo_t *S_LoadSound(sfxinfo_t *sfx); From 39ff34645fc90ac43194eb7947a72d4b21abae17 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:51:23 +0000 Subject: [PATCH 062/101] - Precache PickupSound, UpSound, and ReadySound. SVN r3842 (trunk) --- src/g_shared/a_pickups.cpp | 12 ++++++++++++ src/g_shared/a_pickups.h | 2 ++ src/g_shared/a_weapons.cpp | 13 +++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 661367753..f071171a7 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -459,6 +459,18 @@ void AInventory::Serialize (FArchive &arc) arc << Owner << Amount << MaxAmount << RespawnTics << ItemFlags << Icon << PickupSound << SpawnPointClass; } +//=========================================================================== +// +// AInventory :: MarkPrecacheSounds +// +//=========================================================================== + +void AInventory::MarkPrecacheSounds() const +{ + Super::MarkPrecacheSounds(); + PickupSound.MarkUsed(); +} + //=========================================================================== // // AInventory :: SpecialDropAction diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 52c2b6d13..beaa65872 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -143,6 +143,7 @@ public: virtual void Touch (AActor *toucher); virtual void Serialize (FArchive &arc); + virtual void MarkPrecacheSounds() const; virtual void BeginPlay (); virtual void Destroy (); virtual void Tick (); @@ -276,6 +277,7 @@ public: bool bAltFire; // Set when this weapon's alternate fire is used. + virtual void MarkPrecacheSounds() const; virtual void Serialize (FArchive &arc); virtual bool ShouldStay (); virtual void AttachToOwner (AActor *other); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 8f45d892a..a59e8f564 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -67,6 +67,19 @@ void AWeapon::Serialize (FArchive &arc) << Crosshair; } +//=========================================================================== +// +// AWeapon :: MarkPrecacheSounds +// +//=========================================================================== + +void AWeapon::MarkPrecacheSounds() const +{ + Super::MarkPrecacheSounds(); + UpSound.MarkUsed(); + ReadySound.MarkUsed(); +} + //=========================================================================== // // AWeapon :: TryPickup From cc4aadbfaf1bf2832513e24f217c4d103556d8a1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:55:30 +0000 Subject: [PATCH 063/101] - Store ambient sound names as FSoundID rather than as FString. SVN r3843 (trunk) --- src/s_advsound.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 12ebc94a0..cf6f3831b 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -123,7 +123,7 @@ struct FAmbientSound int periodmax; // max # of tics for random ambients float volume; // relative volume of sound float attenuation; - FString sound; // Logical name of sound to play + FSoundID sound; // Sound to play }; TMap Ambients; @@ -1004,10 +1004,10 @@ static void S_AddSNDINFO (int lump) ambient->periodmax = 0; ambient->volume = 0; ambient->attenuation = 0; - ambient->sound = ""; + ambient->sound = 0; sc.MustGetString (); - ambient->sound = sc.String; + ambient->sound = FSoundID(S_FindSoundTentative(sc.String)); ambient->attenuation = 0; sc.MustGetString (); @@ -2125,7 +2125,7 @@ void AAmbientSound::Tick () loop = CHAN_LOOP; } - if (ambient->sound.IsNotEmpty()) + if (ambient->sound != 0) { // The second argument scales the ambient sound's volume. // 0 and 100 are normal volume. The maximum volume level From 04f09d9b572315fd5647b8e8bf766a2014aca3cd Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 22 Aug 2012 23:58:18 +0000 Subject: [PATCH 064/101] - Precache $ambient sounds. SVN r3844 (trunk) --- src/s_advsound.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index cf6f3831b..f5b268348 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -2072,6 +2072,7 @@ class AAmbientSound : public AActor public: void Serialize (FArchive &arc); + void MarkPrecacheSounds () const; void BeginPlay (); void Tick (); void Activate (AActor *activator); @@ -2098,6 +2099,22 @@ void AAmbientSound::Serialize (FArchive &arc) arc << bActive << NextCheck; } +//========================================================================== +// +// AmbientSound :: MarkPrecacheSounds +// +//========================================================================== + +void AAmbientSound::MarkPrecacheSounds() const +{ + Super::MarkPrecacheSounds(); + FAmbientSound *ambient = Ambients.CheckKey(args[0]); + if (ambient != NULL) + { + ambient->sound.MarkUsed(); + } +} + //========================================================================== // // AmbientSound :: Tick From 69fc0142ebd9c4422be2e94c8cb4f36c466253c1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 00:15:41 +0000 Subject: [PATCH 065/101] - Precache sounds played by ASoundSequence actors. (This includes Heretic's ambient sounds.) SVN r3845 (trunk) --- src/g_shared/a_soundsequence.cpp | 14 +++++++++++++- src/s_sndseq.cpp | 28 +++++++++++++++++++++++++++- src/s_sndseq.h | 9 +++++---- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/g_shared/a_soundsequence.cpp b/src/g_shared/a_soundsequence.cpp index 94e8e1e60..ab0ee101b 100644 --- a/src/g_shared/a_soundsequence.cpp +++ b/src/g_shared/a_soundsequence.cpp @@ -105,6 +105,7 @@ public: void PostBeginPlay (); void Activate (AActor *activator); void Deactivate (AActor *activator); + void MarkPrecacheSounds () const; }; IMPLEMENT_CLASS (ASoundSequence) @@ -154,6 +155,18 @@ void ASoundSequence::PostBeginPlay () } } +//========================================================================== +// +// ASoundSequence :: MarkPrecacheSounds +// +//========================================================================== + +void ASoundSequence::MarkPrecacheSounds() const +{ + Super::MarkPrecacheSounds(); + SN_MarkPrecacheSounds(args[0], SEQ_ENVIRONMENT); +} + //========================================================================== // // ASoundSequence :: Activate @@ -175,4 +188,3 @@ void ASoundSequence::Deactivate (AActor *activator) { SN_StopSequence (this); } - diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 9ba713dcb..cf2957885 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -760,7 +760,7 @@ static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, c Sequences[curseq] = (FSoundSequence *)M_Malloc (sizeof(FSoundSequence) + sizeof(DWORD)*ScriptTemp.Size()); Sequences[curseq]->SeqName = seqname; Sequences[curseq]->Slot = slot; - Sequences[curseq]->StopSound = stopsound; + Sequences[curseq]->StopSound = FSoundID(stopsound); memcpy (Sequences[curseq]->Script, &ScriptTemp[0], sizeof(DWORD)*ScriptTemp.Size()); Sequences[curseq]->Script[ScriptTemp.Size()] = MakeCommand(SS_CMD_END, 0); } @@ -1311,6 +1311,32 @@ FName SN_GetSequenceSlot (int sequence, seqtype_t type) return NAME_None; } +//========================================================================== +// +// SN_MarkPrecacheSounds +// +// Marks all sounds played by this sequence for precaching. +// +//========================================================================== + +void SN_MarkPrecacheSounds(int sequence, seqtype_t type) +{ + if (TwiddleSeqNum(sequence, type)) + { + FSoundSequence *seq = Sequences[sequence]; + + seq->StopSound.MarkUsed(); + for (int i = 0; GetCommand(seq->Script[i]) != SS_CMD_END; ++i) + { + int cmd = GetCommand(seq->Script[i]); + if (cmd == SS_CMD_PLAY || cmd == SS_CMD_PLAYREPEAT || cmd == SS_CMD_PLAYLOOP) + { + FSoundID(GetData(seq->Script[i])).MarkUsed(); + } + } + } +} + //========================================================================== // // SN_ChangeNodeData diff --git a/src/s_sndseq.h b/src/s_sndseq.h index 41035fb1d..59b9293c0 100644 --- a/src/s_sndseq.h +++ b/src/s_sndseq.h @@ -71,10 +71,10 @@ void SN_StopAllSequences (void); struct FSoundSequence { - FName SeqName; - FName Slot; - int StopSound; - SDWORD Script[1]; // + more until end of sequence script + FName SeqName; + FName Slot; + FSoundID StopSound; + SDWORD Script[1]; // + more until end of sequence script }; void S_ParseSndSeq (int levellump); @@ -98,6 +98,7 @@ void SN_DoStop (void *); void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics, float volume, int currentSoundID); FName SN_GetSequenceSlot (int sequence, seqtype_t type); +void SN_MarkPrecacheSounds (int sequence, seqtype_t type); bool SN_IsMakingLoopingSound (sector_t *sector); #endif //__S_SNDSEQ_H__ From c954fb54773035c984730ce24aec78e21b63bebf Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 00:31:29 +0000 Subject: [PATCH 066/101] - Added the mapinfo flag ForgetState. This prevents a maps state from being remembered in a hub, so when you return to it without leaving the hub, it will be as if you had never set foot in it. RememberState is provided to turn this flag off. SVN r3846 (trunk) --- src/g_level.cpp | 9 ++++++++- src/g_level.h | 1 + src/g_mapinfo.cpp | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index e6b8bad91..32acf14cb 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -737,7 +737,14 @@ void G_DoCompleted (void) if (mode == FINISH_SameHub) { // Remember the level's state for re-entry. - G_SnapshotLevel (); + if (!(level.flags2 & LEVEL2_FORGETSTATE)) + { + G_SnapshotLevel (); + } + else + { // Make sure we don't have a snapshot lying around from before. + level.info->ClearSnapshot(); + } } else { // Forget the states of all existing levels. diff --git a/src/g_level.h b/src/g_level.h index c246e5b7e..488cb3eaf 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -213,6 +213,7 @@ enum ELevelFlags LEVEL2_NOSTATISTICS = 0x10000000, // This level should not have statistics collected LEVEL2_ENDGAME = 0x20000000, // This is an epilogue level that cannot be quit. LEVEL2_NOAUTOSAVEHINT = 0x40000000, // tell the game that an autosave for this level does not need to be kept + LEVEL2_FORGETSTATE = 0x80000000, // forget this map's state in a hub }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 1d229267e..4614afd3d 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1264,6 +1264,8 @@ MapFlagHandlers[] = { "endofgame", MITYPE_SETFLAG2, LEVEL2_ENDGAME, 0 }, { "nostatistics", MITYPE_SETFLAG2, LEVEL2_NOSTATISTICS, 0 }, { "noautosavehint", MITYPE_SETFLAG2, LEVEL2_NOAUTOSAVEHINT, 0 }, + { "forgetstate", MITYPE_SETFLAG2, LEVEL2_FORGETSTATE, 0 }, + { "rememberstate", MITYPE_CLRFLAG2, LEVEL2_FORGETSTATE, 0 }, { "unfreezesingleplayerconversations",MITYPE_SETFLAG2, LEVEL2_CONV_SINGLE_UNFREEZE, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, From 1c71c1dce1544c3c99e3255c16e4ef22d8388557 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 01:00:30 +0000 Subject: [PATCH 067/101] - Added support for random state durations. Instead of defining a frame like this: POSS A 10 A_Look You can define it as: POSS A random(10,20) A_Look and the state will last a random duration between 10 and 20 tics, inclusive. SVN r3847 (trunk) --- src/d_dehacked.cpp | 2 +- src/info.cpp | 2 ++ src/info.h | 17 ++++++++++++----- src/thingdef/olddecorations.cpp | 6 ++++++ src/thingdef/thingdef_states.cpp | 27 +++++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 49e821178..4239ae3d3 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1353,7 +1353,7 @@ static int PatchFrame (int frameNum) if (keylen == 8 && stricmp (Line1, "Duration") == 0) { - tics = clamp (val, -1, 65534); + tics = clamp (val, -1, SHRT_MAX); } else if (keylen == 9 && stricmp (Line1, "Unknown 1") == 0) { diff --git a/src/info.cpp b/src/info.cpp index 69476d290..4d3225344 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -55,6 +55,8 @@ extern void LoadActors (); extern void InitBotStuff(); extern void ClearStrifeTypes(); +FRandom FState::pr_statetics; + //========================================================================== // // diff --git a/src/info.h b/src/info.h index c2962512d..87e623814 100644 --- a/src/info.h +++ b/src/info.h @@ -45,6 +45,7 @@ #include "doomdef.h" #include "m_fixed.h" +#include "m_random.h" struct Baggage; class FScanner; @@ -61,18 +62,19 @@ enum struct FState { + FState *NextState; + actionf_p ActionFunc; WORD sprite; SWORD Tics; - int Misc1; // Was changed to SBYTE, reverted to long for MBF compat - int Misc2; // Was changed to BYTE, reverted to long for MBF compat + WORD TicRange; BYTE Frame; BYTE DefineFlags; // Unused byte so let's use it during state creation. + int Misc1; // Was changed to SBYTE, reverted to long for MBF compat + int Misc2; // Was changed to BYTE, reverted to long for MBF compat short Light; BYTE Fullbright:1; // State is fullbright BYTE SameFrame:1; // Ignore Frame (except when spawning actor) BYTE Fast:1; - FState *NextState; - actionf_p ActionFunc; int ParameterIndex; inline int GetFrame() const @@ -89,7 +91,11 @@ struct FState } inline int GetTics() const { - return Tics; + if (TicRange == 0) + { + return Tics; + } + return Tics + pr_statetics.GenRand32() % (TicRange + 1); } inline int GetMisc1() const { @@ -134,6 +140,7 @@ struct FState } static const PClass *StaticFindStateOwner (const FState *state); static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info); + static FRandom pr_statetics; }; struct FStateLabels; diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index 421ff1e88..d4db28e96 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -199,6 +199,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) if (info->NumOwnedStates == 1) { info->OwnedStates->Tics = -1; + info->OwnedStates->TicRange = 0; info->OwnedStates->Misc1 = 0; } else @@ -226,6 +227,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) else { info->OwnedStates[i].Tics = -1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; } @@ -273,6 +275,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) else { info->OwnedStates[i].Tics = -1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; } @@ -307,12 +310,14 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def) } info->OwnedStates[i].NextState = &info->OwnedStates[info->NumOwnedStates-1]; info->OwnedStates[i].Tics = 5; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeath")); i = info->NumOwnedStates - 1; info->OwnedStates[i].NextState = &info->OwnedStates[i]; info->OwnedStates[i].Tics = 1; + info->OwnedStates[i].TicRange = 0; info->OwnedStates[i].Misc1 = 0; info->OwnedStates[i].SetAction(FindGlobalActionFunction("A_FreezeDeathChunks")); bag.statedef.SetStateLabel("Ice", &info->OwnedStates[extra.IceDeathStart]); @@ -671,6 +676,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray &states, FScanne } state.Tics = rate; + state.TicRange = 0; while (*token) { diff --git a/src/thingdef/thingdef_states.cpp b/src/thingdef/thingdef_states.cpp index 31d49db5d..5c2d81602 100644 --- a/src/thingdef/thingdef_states.cpp +++ b/src/thingdef/thingdef_states.cpp @@ -56,6 +56,7 @@ #include "colormatcher.h" #include "thingdef_exp.h" #include "version.h" +#include "templates.h" //========================================================================== //*** @@ -237,8 +238,30 @@ do_stop: sc.MustGetString(); statestring = sc.String; - sc.MustGetNumber(); - state.Tics = clamp(sc.Number, -1, 32767); + if (sc.CheckString("RANDOM")) + { + int min, max; + + sc.MustGetStringName("("); + sc.MustGetNumber(); + min = clamp(sc.Number, -1, SHRT_MAX); + sc.MustGetStringName(","); + sc.MustGetNumber(); + max = clamp(sc.Number, -1, SHRT_MAX); + sc.MustGetStringName(")"); + if (min > max) + { + swapvalues(min, max); + } + state.Tics = min; + state.TicRange = max - min; + } + else + { + sc.MustGetNumber(); + state.Tics = clamp(sc.Number, -1, SHRT_MAX); + state.TicRange = 0; + } while (sc.GetString() && !sc.Crossed) { From 66451215198511df759d3d49bf65efe09cc01175 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 01:10:28 +0000 Subject: [PATCH 068/101] - Changed the gamma slider in the menu to bottom out at 0.75 instead of 1.0 and to move in increments of 0.05 instead of 0.1. SVN r3848 (trunk) --- wadsrc/static/menudef.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 1b8432462..38ac1bd74 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -651,7 +651,7 @@ OptionMenu "VideoOptions" Submenu "Scoreboard Options", "ScoreboardOptions" StaticText " " Slider "Screen size", "screenblocks", 3.0, 12.0, 1.0, 0 - Slider "Brightness", "Gamma", 1.0, 3.0, 0.1 + Slider "Brightness", "Gamma", 0.75, 3.0, 0.05, 2 Option "Vertical Sync", "vid_vsync", "OnOff" Option "Column render mode", "r_columnmethod", "ColumnMethods" From 980202a18fbf4be0e42c41083bb20d28091fc730 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 01:34:19 +0000 Subject: [PATCH 069/101] - Fixed: PrepWall() and PrepLWall() did not understand negative walxrepeats, which should cause them to flip the texture horizontally. SVN r3849 (trunk) --- src/r_defs.h | 4 ++-- src/r_segs.cpp | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 2d1dc5ca9..27c578e56 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -832,11 +832,11 @@ struct side_t void SetTextureXScale(int which, fixed_t scale) { - textures[which].xscale = scale <= 0? FRACUNIT : scale; + textures[which].xscale = scale == 0 ? FRACUNIT : scale; } void SetTextureXScale(fixed_t scale) { - textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale <= 0? FRACUNIT : scale; + textures[top].xscale = textures[mid].xscale = textures[bottom].xscale = scale == 0 ? FRACUNIT : scale; } fixed_t GetTextureXScale(int which) const { diff --git a/src/r_segs.cpp b/src/r_segs.cpp index a40a2ce35..bfeab506a 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -2769,6 +2769,7 @@ int WallMost (short *mostbuf, const secplane_t &plane) static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) { // fix for rounding errors + walxrepeat = abs(walxrepeat); fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; @@ -2803,7 +2804,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) { // swall = scale, lwall = texturecolumn double top, bot, i; - double xrepeat = walxrepeat; + double xrepeat = fabs((double)walxrepeat); i = WallSX1 - centerx; top = WallUoverZorg + WallUoverZstep * i; @@ -2812,7 +2813,14 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) for (int x = WallSX1; x < WallSX2; x++) { double frac = top / bot; - lwall[x] = xs_RoundToInt(frac * xrepeat); + if (walxrepeat < 0) + { + lwall[x] = xs_RoundToInt(xrepeat - frac * xrepeat); + } + else + { + lwall[x] = xs_RoundToInt(frac * xrepeat); + } swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg); top += WallUoverZstep; bot += WallInvZstep; @@ -2823,7 +2831,7 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) { // lwall = texturecolumn double top, bot, i; - double xrepeat = walxrepeat; + double xrepeat = fabs((double)walxrepeat); double topstep; i = WallSX1 - centerx; @@ -2835,7 +2843,14 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) for (int x = WallSX1; x < WallSX2; x++) { - lwall[x] = xs_RoundToInt(top / bot); + if (walxrepeat < 0) + { + lwall[x] = xs_RoundToInt(xrepeat - top / bot); + } + else + { + lwall[x] = xs_RoundToInt(top / bot); + } top += topstep; bot += WallInvZstep; } From 3bfe7b74f4e4220fdec2d36fc96817a4d9b51f49 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 23 Aug 2012 01:40:00 +0000 Subject: [PATCH 070/101] - Fixed: side_t::SetTextureYScale() did not allow negative scales, even though they are perfectly valid for flipping a texture vertically. SVN r3850 (trunk) --- src/r_defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 27c578e56..c43b6be83 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -850,11 +850,11 @@ struct side_t void SetTextureYScale(int which, fixed_t scale) { - textures[which].yscale = scale <= 0? FRACUNIT : scale; + textures[which].yscale = scale == 0 ? FRACUNIT : scale; } void SetTextureYScale(fixed_t scale) { - textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale <= 0? FRACUNIT : scale; + textures[top].yscale = textures[mid].yscale = textures[bottom].yscale = scale == 0 ? FRACUNIT : scale; } fixed_t GetTextureYScale(int which) const { From a94cf9d54881aad11c22e95c2a7ba1654954c79f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 24 Aug 2012 21:02:49 +0000 Subject: [PATCH 071/101] - Added A_SetTics. SVN r3851 (trunk) --- src/thingdef/thingdef_codeptr.cpp | 14 ++++++++++++++ wadsrc/static/actors/actor.txt | 5 +---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 14e4c3377..372622ccf 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4449,3 +4449,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) } } + +//========================================================================== +// +// A_SetTics +// +//========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics) +{ + ACTION_PARAM_START(1); + ACTION_PARAM_INT(tics_to_set, 0); + + self->tics = tics_to_set; +} \ No newline at end of file diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index c93b82b0b..6e40b6628 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -290,6 +290,7 @@ ACTOR Actor native //: Thinker action native A_SetUserArray(name varname, int index, int value); action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0); action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); + action native A_SetTics(int tics); action native A_CheckSightOrRange(float distance, state label); @@ -323,7 +324,3 @@ ACTOR Actor native //: Thinker Stop } } - - - - From 3a6806942c85262ac6c145cd1cc7142c2c3c4d0c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 28 Aug 2012 02:52:53 +0000 Subject: [PATCH 072/101] - Fixed: Horizontal movement should not trigger bump specials while predicting. SVN r3855 (trunk) --- src/p_map.cpp | 7 +++++-- src/p_mobj.cpp | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 5b54be076..0bf6e645f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -942,8 +942,11 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) || ((thing->activationtype & THINGSPEC_MissileTrigger) && (tm.thing->flags & MF_MISSILE)) ) && (level.maptime > thing->lastbump)) // Leave the bumper enough time to go away { - if (P_ActivateThingSpecial(thing, tm.thing)) - thing->lastbump = level.maptime + TICRATE; + if (tm.thing->player == NULL || !(tm.thing->player->cheats & CF_PREDICTING)) + { + if (P_ActivateThingSpecial(thing, tm.thing)) + thing->lastbump = level.maptime + TICRATE; + } } // Check for skulls slamming into things diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1acdc2927..7ec1224db 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3453,8 +3453,11 @@ void AActor::Tick () || ((onmo->activationtype & THINGSPEC_MissileTrigger) && (flags & MF_MISSILE)) ) && (level.maptime > onmo->lastbump)) // Leave the bumper enough time to go away { - if (P_ActivateThingSpecial(onmo, this)) - onmo->lastbump = level.maptime + TICRATE; + if (player == NULL || !(player->cheats & CF_PREDICTING)) + { + if (P_ActivateThingSpecial(onmo, this)) + onmo->lastbump = level.maptime + TICRATE; + } } if (velz != 0 && (BounceFlags & BOUNCE_Actors)) { From 40cefe6107c8dfeddf0f9084a2c0c8599298c326 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 28 Aug 2012 03:21:13 +0000 Subject: [PATCH 073/101] - Fixed: When r3837 moved SNDINFO parsing before MAPINFO parsing, it broke support for Hexen's $map SNDINFO command. Removed LEVEL2_MUSICDEFINED, since it's no longer needed by the new implementation for this command. SVN r3856 (trunk) --- src/g_level.h | 2 +- src/g_mapinfo.cpp | 13 ++++++++++--- src/s_advsound.cpp | 16 ++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/g_level.h b/src/g_level.h index 488cb3eaf..105b07100 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -181,7 +181,7 @@ enum ELevelFlags LEVEL2_KEEPFULLINVENTORY = 0x00000040, // doesn't reduce the amount of inventory items to 1 - LEVEL2_MUSICDEFINED = 0x00000080, // a marker to disable the $map command in SNDINFO for this map + /* = 0x00000080, */ LEVEL2_MONSTERFALLINGDAMAGE = 0x00000100, LEVEL2_CLIPMIDTEX = 0x00000200, LEVEL2_WRAPMIDTEX = 0x00000400, diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 4614afd3d..7836c4377 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -61,6 +61,8 @@ static cluster_info_t TheDefaultClusterInfo; TArray AllEpisodes; +extern TMap HexenMusic; + //========================================================================== // // @@ -918,8 +920,6 @@ DEFINE_MAP_OPTION(music, true) { parse.ParseAssign(); parse.ParseMusic(info->Music, info->musicorder); - // Flag the level so that the $MAP command doesn't override this. - info->flags2 |= LEVEL2_MUSICDEFINED; } DEFINE_MAP_OPTION(intermusic, true) @@ -1538,6 +1538,14 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) // to teleport to maps with standard names without needing a levelnum. levelinfo->levelnum = GetDefaultLevelNum(levelinfo->mapname); + // Does this map have a song defined via SNDINFO's $map command? + // Set that as this map's default music if it does. + FString *song; + if ((song = HexenMusic.CheckKey(levelinfo->levelnum)) != NULL) + { + levelinfo->Music = *song; + } + return levelinfo; } @@ -1832,7 +1840,6 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i } } - //========================================================================== // // diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index f5b268348..f4c343fac 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -220,6 +220,7 @@ extern int sfx_empty; // PUBLIC DATA DEFINITIONS ------------------------------------------------- TArray S_sfx (128); +TMap HexenMusic; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -886,6 +887,7 @@ static void S_ClearSoundData() DefPlayerClassName = ""; MusicAliases.Clear(); MidiDevices.Clear(); + HexenMusic.Clear(); } //========================================================================== @@ -1084,16 +1086,14 @@ static void S_AddSNDINFO (int lump) case SI_Map: { // Hexen-style $MAP command - level_info_t *info; - char temp[16]; + int mapnum; - sc.MustGetNumber (); - mysnprintf (temp, countof(temp), "MAP%02d", sc.Number); - info = FindLevelInfo (temp); - sc.MustGetString (); - if (info->mapname[0] && (!(info->flags2 & LEVEL2_MUSICDEFINED))) + sc.MustGetNumber(); + mapnum = sc.Number; + sc.MustGetString(); + if (mapnum != 0) { - info->Music = sc.String; + HexenMusic[mapnum] = sc.String; } } break; From 11a0298f3331f8a7b17ff0f97a7b1e208622b57f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 28 Aug 2012 04:08:48 +0000 Subject: [PATCH 074/101] - Deactivate the master DSP unit when pausing the sound on title maps as well as on regular maps. SVN r3857 (trunk) --- src/s_sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index de383a1f6..a52e6cf39 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1784,7 +1784,7 @@ void S_SetSoundPaused (int state) S_PauseSound(false, true); if (GSnd != NULL) { - GSnd->SetInactive(gamestate == GS_LEVEL ? + GSnd->SetInactive(gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL ? SoundRenderer::INACTIVE_Complete : SoundRenderer::INACTIVE_Mute); } From 59638acb7c28413dbf4da8f8373edffbe9440b0c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 30 Aug 2012 03:00:37 +0000 Subject: [PATCH 075/101] - Fixed: MUSINFO must be parsed after MAPINFO, since it needs the entries created by MAPINFO. SVN r3858 (trunk) --- src/d_main.cpp | 3 +++ src/s_sound.cpp | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index c428059e6..ae28f15d8 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2218,6 +2218,9 @@ void D_DoomMain (void) G_ParseMapInfo (iwad_info->MapInfo); ReadStatistics(); + // MUSINFO must be parsed after MAPINFO + S_ParseMusInfo(); + Printf ("Texman.Init: Init texture manager.\n"); TexMan.Init(); C_InitConback(); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index a52e6cf39..dc890c12b 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -326,7 +326,6 @@ void S_InitData () LastLocalSndInfo = LastLocalSndSeq = ""; S_ParseSndInfo (false); S_ParseSndSeq (-1); - S_ParseMusInfo(); } //========================================================================== From 7af13c8d5248222dc6dc59f669983bd3c91c98ba Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 30 Aug 2012 03:24:57 +0000 Subject: [PATCH 076/101] - Use a separate thinker to do suicides, so that console-inflicted suicides will have a chance to put the console up and restore sound before the player days. Needed for actors that make noise on the first tic of their death. (e.g. Heretic's) SVN r3859 (trunk) --- src/m_cheat.cpp | 52 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index d639ec514..45ec78d9f 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -45,6 +45,7 @@ #include "d_net.h" #include "d_dehacked.h" #include "gi.h" +#include "farchive.h" // [RH] Actually handle the cheat. The cheat code in st_stuff.c now just // writes some bytes to the network data stream, and the network code @@ -1055,18 +1056,53 @@ void cht_Take (player_t *player, const char *name, int amount) return; } +class DSuicider : public DThinker +{ + DECLARE_CLASS(DSuicider, DThinker) + HAS_OBJECT_POINTERS; +public: + TObjPtr Pawn; + + void Tick() + { + Pawn->flags |= MF_SHOOTABLE; + Pawn->flags2 &= ~MF2_INVULNERABLE; + // Store the player's current damage factor, to restore it later. + fixed_t plyrdmgfact = Pawn->DamageFactor; + Pawn->DamageFactor = 65536; + P_DamageMobj (Pawn, Pawn, Pawn, TELEFRAG_DAMAGE, NAME_Suicide); + Pawn->DamageFactor = plyrdmgfact; + if (Pawn->health <= 0) + { + Pawn->flags &= ~MF_SHOOTABLE; + } + Destroy(); + } + // You'll probably never be able to catch this in a save game, but + // just in case, add a proper serializer. + void Serialize(FArchive &arc) + { + Super::Serialize(arc); + arc << Pawn; + } +}; + +IMPLEMENT_POINTY_CLASS(DSuicider) + DECLARE_POINTER(Pawn) +END_POINTERS + void cht_Suicide (player_t *plyr) { + // If this cheat was initiated by the suicide ccmd, and this is a single + // player game, the CHT_SUICIDE will be processed before the tic is run, + // so the console has not gone up yet. Use a temporary thinker to delay + // the suicide until the game ticks so that death noises can be heard on + // the initial tick. if (plyr->mo != NULL) { - plyr->mo->flags |= MF_SHOOTABLE; - plyr->mo->flags2 &= ~MF2_INVULNERABLE; - //Store the players current damage factor, to restore it later. - fixed_t plyrdmgfact = plyr->mo->DamageFactor; - plyr->mo->DamageFactor = 65536; - P_DamageMobj (plyr->mo, plyr->mo, plyr->mo, TELEFRAG_DAMAGE, NAME_Suicide); - plyr->mo->DamageFactor = plyrdmgfact; - if (plyr->mo->health <= 0) plyr->mo->flags &= ~MF_SHOOTABLE; + DSuicider *suicide = new DSuicider; + suicide->Pawn = plyr->mo; + GC::WriteBarrier(suicide, suicide->Pawn); } } From 6a91335841b1ee1e45b94fe31a4c4af56ab99e47 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 30 Aug 2012 04:01:50 +0000 Subject: [PATCH 077/101] - Turned A_Explode's affectsource parameter into a flags parameter and added XF_NOTMISSILE and RTF_NOTMISSILE so that you can use A_Explode and A_RadiusThrust with non-missiles without them telling P_RadiusAttack() that the target is the source. SVN r3860 (trunk) --- src/fragglescript/t_func.cpp | 2 +- src/g_doom/a_archvile.cpp | 2 +- src/g_doom/a_fatso.cpp | 2 +- src/g_heretic/a_hereticartifacts.cpp | 2 +- src/g_heretic/a_hereticmisc.cpp | 2 +- src/g_hexen/a_flechette.cpp | 2 +- src/g_strife/a_strifestuff.cpp | 2 +- src/g_strife/a_strifeweapons.cpp | 2 +- src/g_strife/a_thingstoblowup.cpp | 2 +- src/p_enemy.cpp | 2 +- src/p_local.h | 9 +++++++- src/p_map.cpp | 24 +++++++++++++------- src/thingdef/thingdef_codeptr.cpp | 34 ++++++++++++++++------------ wadsrc/static/actors/actor.txt | 4 ++-- wadsrc/static/actors/constants.txt | 5 ++++ 15 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 058741401..946114520 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -3367,7 +3367,7 @@ void FParser::SF_RadiusAttack() if (spot && source) { - P_RadiusAttack(spot, source, damage, damage, NAME_None, true); + P_RadiusAttack(spot, source, damage, damage, NAME_None, RADF_HURTSOURCE); } } } diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp index 53e0ea202..2bd65b7a0 100644 --- a/src/g_doom/a_archvile.cpp +++ b/src/g_doom/a_archvile.cpp @@ -136,7 +136,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack) target->y - FixedMul (24*FRACUNIT, finesine[an]), target->z); - P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, false); + P_RadiusAttack (fire, self, blastdmg, blastrad, dmgtype, 0); } target->velz = Scale(thrust, 1000, target->Mass); } diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index 2a824a072..066e60468 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -141,7 +141,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Mushroom) if (n == 0) n = self->Damage; // GetMissileDamage (0, 1); if (spawntype == NULL) spawntype = PClass::FindClass("FatShot"); - P_RadiusAttack (self, self->target, 128, 128, self->DamageType, !(flags & MSF_DontHurt)); + P_RadiusAttack (self, self->target, 128, 128, self->DamageType, (flags & MSF_DontHurt) ? 0 : RADF_HURTSOURCE); P_CheckSplash(self, 128<z += 32*FRACUNIT; self->RenderStyle = STYLE_Add; self->alpha = FRACUNIT; - P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true); + P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); P_CheckSplash(self, 128<z += 28*FRACUNIT; //self->velz = 3*FRACUNIT; } - P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, true); + P_RadiusAttack (self, self->target, 25, 25, NAME_Fire, RADF_HURTSOURCE); for (i = 0; i < 4; i++) { tiny = Spawn("VolcanoTBlast", self->x, self->y, self->z, ALLOW_REPLACE); diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 97f98f1df..5c28b8358 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -420,7 +420,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PoisonBagDamage) { int bobIndex; - P_RadiusAttack (self, self->target, 4, 40, self->DamageType, true); + P_RadiusAttack (self, self->target, 4, 40, self->DamageType, RADF_HURTSOURCE); bobIndex = self->special2; self->z += finesine[bobIndex << BOBTOFINESHIFT] >> 1; self->special2 = (bobIndex + 1) & 63; diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 41e21f755..d51b618b7 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -683,7 +683,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropFire) { AActor *drop = Spawn("FireDroplet", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE); drop->velz = -FRACUNIT; - P_RadiusAttack (self, self, 64, 64, NAME_Fire, false); + P_RadiusAttack (self, self, 64, 64, NAME_Fire, 0); } DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer) diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp index 596e91e07..8fa71304b 100644 --- a/src/g_strife/a_strifeweapons.cpp +++ b/src/g_strife/a_strifeweapons.cpp @@ -567,7 +567,7 @@ int APhosphorousFire::DoSpecialDamage (AActor *target, int damage, FName damaget DEFINE_ACTION_FUNCTION(AActor, A_BurnArea) { - P_RadiusAttack (self, self->target, 128, 128, self->DamageType, true); + P_RadiusAttack (self, self->target, 128, 128, self->DamageType, RADF_HURTSOURCE); } DEFINE_ACTION_FUNCTION(AActor, A_Burnination) diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp index 9727bccd1..7d2c1ceee 100644 --- a/src/g_strife/a_thingstoblowup.cpp +++ b/src/g_strife/a_thingstoblowup.cpp @@ -69,7 +69,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ExtraLightOff) DEFINE_ACTION_FUNCTION(AActor, A_Explode512) { - P_RadiusAttack (self, self->target, 512, 512, NAME_None, true); + P_RadiusAttack (self, self->target, 512, 512, NAME_None, RADF_HURTSOURCE); if (self->target != NULL && self->target->player != NULL) { self->target->player->extralight = 5; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 3494792e6..a0367123a 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3161,7 +3161,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Die) DEFINE_ACTION_FUNCTION(AActor, A_Detonate) { int damage = self->GetMissileDamage (0, 1); - P_RadiusAttack (self, self->target, damage, damage, self->DamageType, true); + P_RadiusAttack (self, self->target, damage, damage, self->DamageType, RADF_HURTSOURCE); P_CheckSplash(self, damage<x, bombspot->y, bombdistance<flags3 & MF3_NORADIUSDMG && !(bombspot->flags4 & MF4_FORCERADIUSDMG)) continue; - if (!DamageSource && (thing == bombsource || thing == bombspot)) + if (!(flags & RADF_HURTSOURCE) && (thing == bombsource || thing == bombspot)) { // don't damage the source of the explosion continue; } @@ -4488,7 +4493,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b // them far too "active." BossBrains also use the old code // because some user levels require they have a height of 16, // which can make them near impossible to hit with the new code. - if (!bombdodamage || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG)) + if ((flags & RADF_NODAMAGE) || !((bombspot->flags5 | thing->flags5) & MF5_OLDRADIUSDMG)) { // [RH] New code. The bounding box only covers the // height of the thing and not the height of the map. @@ -4547,14 +4552,17 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b double thrust; int damage = (int)points; - if (bombdodamage) P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); - else if (thing->player == NULL && !noimpactdamage) thing->flags2 |= MF2_BLASTED; + if (!(flags & RADF_NODAMAGE)) + P_DamageMobj (thing, bombspot, bombsource, damage, bombmod); + else if (thing->player == NULL && !(flags & RADF_NOIMPACTDAMAGE)) + thing->flags2 |= MF2_BLASTED; if (!(thing->flags & MF_ICECORPSE)) { - if (bombdodamage && !(bombspot->flags3 & MF3_BLOODLESSIMPACT)) P_TraceBleed (damage, thing, bombspot); + if (!(flags & RADF_NODAMAGE) && !(bombspot->flags3 & MF3_BLOODLESSIMPACT)) + P_TraceBleed (damage, thing, bombspot); - if (!bombdodamage || !(bombspot->flags2 & MF2_NODMGTHRUST)) + if (!(flags & RADF_NODAMAGE) || !(bombspot->flags2 & MF2_NODMGTHRUST)) { if (bombsource == NULL || !(bombsource->flags2 & MF2_NODMGTHRUST)) { @@ -4575,7 +4583,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b angle_t ang = R_PointToAngle2 (bombspot->x, bombspot->y, thing->x, thing->y) >> ANGLETOFINESHIFT; thing->velx += fixed_t (finecosine[ang] * thrust); thing->vely += fixed_t (finesine[ang] * thrust); - if (bombdodamage) + if (!(flags & RADF_NODAMAGE)) thing->velz += (fixed_t)velz; // this really doesn't work well } } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 372622ccf..8fe1b24ca 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -727,12 +727,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType) // //========================================================================== +enum +{ + XF_HURTSOURCE = 1, + XF_NOTMISSILE = 4, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) { ACTION_PARAM_START(8); ACTION_PARAM_INT(damage, 0); ACTION_PARAM_INT(distance, 1); - ACTION_PARAM_BOOL(hurtSource, 2); + ACTION_PARAM_INT(flags, 2); ACTION_PARAM_BOOL(alert, 3); ACTION_PARAM_INT(fulldmgdistance, 4); ACTION_PARAM_INT(nails, 5); @@ -743,7 +749,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) { damage = self->GetClass()->Meta.GetMetaInt (ACMETA_ExplosionDamage, 128); distance = self->GetClass()->Meta.GetMetaInt (ACMETA_ExplosionRadius, damage); - hurtSource = !self->GetClass()->Meta.GetMetaInt (ACMETA_DontHurtShooter); + flags = !self->GetClass()->Meta.GetMetaInt (ACMETA_DontHurtShooter); alert = false; } else @@ -766,7 +772,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) } } - P_RadiusAttack (self, self->target, damage, distance, self->DamageType, hurtSource, true, fulldmgdistance); + P_RadiusAttack (self, self->target, damage, distance, self->DamageType, flags, fulldmgdistance); P_CheckSplash(self, distance<target != NULL && self->target->player != NULL) { @@ -775,43 +781,41 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) } } -enum -{ - RTF_AFFECTSOURCE = 1, - RTF_NOIMPACTDAMAGE = 2, -}; - //========================================================================== // // A_RadiusThrust // //========================================================================== +enum +{ + RTF_AFFECTSOURCE = 1, + RTF_NOIMPACTDAMAGE = 2, + RTF_NOTMISSILE = 4, +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust) { ACTION_PARAM_START(3); ACTION_PARAM_INT(force, 0); ACTION_PARAM_INT(distance, 1); - ACTION_PARAM_INT(thrustFlags, 2); + ACTION_PARAM_INT(flags, 2); ACTION_PARAM_INT(fullthrustdistance, 3); - bool affectSource = !!(thrustFlags & RTF_AFFECTSOURCE); - bool noimpactdamage = !!(thrustFlags & RTF_NOIMPACTDAMAGE); - bool sourcenothrust = false; if (force <= 0) force = 128; if (distance <= 0) distance = force; // Temporarily negate MF2_NODMGTHRUST on the shooter, since it renders this function useless. - if (self->target != NULL && self->target->flags2 & MF2_NODMGTHRUST) + if (!(flags & RTF_NOTMISSILE) && self->target != NULL && self->target->flags2 & MF2_NODMGTHRUST) { sourcenothrust = true; self->target->flags2 &= ~MF2_NODMGTHRUST; } int sourceflags2 = self->target != NULL ? self->target->flags2 : 0; - P_RadiusAttack (self, self->target, force, distance, self->DamageType, affectSource, false, fullthrustdistance, noimpactdamage); + P_RadiusAttack (self, self->target, force, distance, self->DamageType, flags | RADF_NODAMAGE, fullthrustdistance); P_CheckSplash(self, distance << FRACBITS); if (sourcenothrust) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 6e40b6628..6bad67ceb 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -253,8 +253,8 @@ ACTOR Actor native //: Thinker action native A_CustomComboAttack(class missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); action native A_Burst(class chunktype); action native A_Blast(int flags = 0, int strength = 255, int radius = 255, float speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius"); - action native A_RadiusThrust(int force = 128, int distance = -1, bool affectsource = true, int fullthrustdistance = 0); - action native A_Explode(int damage = -1, int distance = -1, bool hurtsource = true, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff"); + action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); + action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff"); action native A_Stop(); action native A_Respawn(int flags = 1); action native A_BarrelDestroy(); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 3551cc9b1..761664308 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -124,9 +124,14 @@ const int MSF_Standard = 0; const int MSF_Classic = 1; const int MSF_DontHurt = 2; +// Flags for A_Explode +const int XF_HURTSOURCE = 1; +const int XF_NOTMISSILE = 4; + // Flags for A_RadiusThrust const int RTF_AFFECTSOURCE = 1; const int RTF_NOIMPACTDAMAGE = 2; +const int RTF_NOTMISSILE = 4; // Flags for A_Blast const int BF_USEAMMO = 1; From 111b5c60c173704683db01dfd14771f2e74dbe25 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 1 Sep 2012 22:34:09 +0000 Subject: [PATCH 078/101] - Fixed: The check in P_SpawnBlood() to avoid advancing the state to something not owned by the spawned blood actor was backwards and would only advance to state's NOT owned by it. SVN r3861 (trunk) --- src/p_mobj.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7ec1224db..7e863a825 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4864,14 +4864,15 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc while (cls != RUNTIME_CLASS(AActor)) { FActorInfo *ai = cls->ActorInfo; + int checked_advance = advance; if (ai->OwnsState(th->SpawnState)) { - for (; advance > 0; --advance) + for (; checked_advance > 0; --checked_advance) { // [RH] Do not set to a state we do not own. - if (!ai->OwnsState(th->SpawnState + advance)) + if (ai->OwnsState(th->SpawnState + checked_advance)) { - th->SetState(th->SpawnState + advance); + th->SetState(th->SpawnState + checked_advance); goto statedone; } } From ef55ce8684eee1cd79cf78876837727394386ebc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 1 Sep 2012 22:39:11 +0000 Subject: [PATCH 079/101] - Fixed: P_SpawnBlood() would set Strife's Blood to the Spray state and then promptly go about setting it right back to the Spawn state. SVN r3862 (trunk) --- src/p_mobj.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7e863a825..6c0cd4973 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4839,13 +4839,16 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc // Moved out of the blood actor so that replacing blood is easier if (gameinfo.gametype & GAME_DoomStrifeChex) { - FState *state = th->FindState(NAME_Spray); if (gameinfo.gametype == GAME_Strife) { if (damage > 13) { FState *state = th->FindState(NAME_Spray); - if (state != NULL) th->SetState (state); + if (state != NULL) + { + th->SetState (state); + goto statedone; + } } else damage += 2; } From a77705e04ef329bfd2ad09862c542dce0fc6b967 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 6 Sep 2012 03:36:25 +0000 Subject: [PATCH 080/101] - Added A_JumpIfTargetOutsideMeleeRange and A_JumpIfTargetInsideMeleeRange because I thought I could be clever and have the beggar chase after you some after you attack him, with a random chance to cease pursuit. However, that didn't look much different from his normal wandering animation, and he usually gave up before getting anywhere near you, so it was kind of pointless. I kept the action functions around anyway, since they're simple things that somebody else might find useful. - Added a melee range check to A_SentinelRefire for actors without missile states. This fixes Strife's Beggar trying to attack you when you're nowhere near him. SVN r3863 (trunk) --- src/g_strife/a_sentinel.cpp | 1 + src/thingdef/thingdef_codeptr.cpp | 33 +++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 2 ++ 3 files changed, 36 insertions(+) diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 9f582dcd5..696858f81 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -81,6 +81,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelRefire) self->target->health <= 0 || !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) || P_HitFriend(self) || + (self->MissileState == NULL && !self->CheckMeleeRange()) || pr_sentinelrefire() < 40) { self->SetState (self->SeeState); diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 8fe1b24ca..c55cd32ac 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -607,6 +607,39 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHealthLower) ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! } +//========================================================================== +// +// State jump function +// +//========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetOutsideMeleeRange) +{ + ACTION_PARAM_START(1); + ACTION_PARAM_STATE(jump, 0); + + if (!self->CheckMeleeRange()) + { + ACTION_JUMP(jump); + } + ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! +} + +//========================================================================== +// +// State jump function +// +//========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInsideMeleeRange) +{ + ACTION_PARAM_START(1); + ACTION_PARAM_STATE(jump, 0); + + if (self->CheckMeleeRange()) + { + ACTION_JUMP(jump); + } + ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! +} //========================================================================== // // State jump function diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 6bad67ceb..3b22d5734 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -201,6 +201,8 @@ ACTOR Actor native //: Thinker action native A_JumpIfCloser(float distance, state label); action native A_JumpIfTracerCloser(float distance, state label); action native A_JumpIfMasterCloser(float distance, state label); + action native A_JumpIfTargetOutsideMeleeRange(state label); + action native A_JumpIfTargetInsideMeleeRange(state label); action native A_JumpIfInventory(class itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT); action native A_JumpIfArmorType(string Type, state label, int amount = 1); action native A_GiveInventory(class itemtype, int amount = 0, int giveto = AAPTR_DEFAULT); From 7a99d28e8cccc11b49c4994a6cf6faac4db45dcc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 8 Sep 2012 03:41:31 +0000 Subject: [PATCH 081/101] - Added compatibility entries for Daedalus to fix SPAC_Push-triggered lines that aren't actually pushable. SVN r3864 (trunk) --- wadsrc/static/compatibility.txt | 91 +++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 261b91574..957e8f16f 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -184,3 +184,94 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 limitpain } +// Daedalus: Fix SPAC_Push lines that aren't on lines you can actually push +3ABB618A475BCBC531B457BAA6E4E70A // map04 +{ + // forcefields + // the lines we're setting are already set for repeatable SPAC_Push + clearlinespecial 90 + setlinespecial 3749 ACS_Execute 23 0 1 0 0 + clearlinespecial 94 + setlinespecial 3766 ACS_Execute 23 0 2 0 0 + clearlinespecial 92 + setlinespecial 3777 ACS_Execute 23 0 3 0 0 + clearlinespecial 98 + setlinespecial 3784 ACS_Execute 23 0 4 0 0 +} +795FDE3CC1C97140F326D0152B3FCE2A // map24 +{ + // doors + clearlinespecial 1512 + setlinespecial 1505 Door_Raise 213 50 100 0 0 + setlineflags 1505 0x200 // repeatable + setactivation 1505 16 // SPAC_Push + clearlinespecial 1514 + setlinespecial 1508 Door_Raise 213 50 100 0 0 + setlineflags 1508 0x200 + setactivation 1508 16 + + clearlinespecial 1525 + setlinespecial 1522 Door_Raise 214 50 100 0 0 + setlineflags 1522 0x200 + setactivation 1522 16 + clearlinespecial 1530 + setlinespecial 1527 Door_Raise 214 50 100 0 0 + setlineflags 1527 0x200 + setactivation 1527 16 + + clearlinespecial 5277 + setlinespecial 5209 Door_Raise 24 20 255 0 0 + setlineflags 5209 0x200 + setactivation 5209 16 + clearlinespecial 5714 + setlinespecial 5267 Door_Raise 24 20 255 0 0 + setlineflags 5267 0x200 + setactivation 5267 16 + + clearlinespecial 5715 + setlinespecial 5229 Door_Raise 24 20 255 0 0 + setlineflags 5229 0x200 + setactivation 5229 16 + clearlinespecial 5345 + setlinespecial 5232 Door_Raise 24 20 255 0 0 + setlineflags 5232 0x200 + setactivation 5232 16 + + // consoles? + clearlinespecial 3639 + setlinespecial 3633 ACS_Execute 14 0 0 0 0 + setlinespecial 3635 ACS_Execute 14 0 0 0 0 + setlineflags 3633 0x200 + setlineflags 3635 0x200 + setactivation 3633 16 + setactivation 3635 16 + + clearlinespecial 3647 + setlinespecial 3644 ACS_Execute 14 0 0 0 0 + setlinespecial 3641 ACS_Execute 14 0 0 0 0 + setlineflags 3644 0x200 + setlineflags 3641 0x200 + setactivation 3644 16 + setactivation 3641 16 + + clearlinespecial 3659 + clearlinespecial 3657 + setlinespecial 3653 ACS_Execute 13 0 0 0 0 + setlinespecial 3655 ACS_Execute 13 0 0 0 0 + setlinespecial 3651 ACS_Execute 13 0 0 0 0 + setlinespecial 3654 ACS_Execute 13 0 0 0 0 + setlineflags 3653 0x200 + setlineflags 3655 0x200 + setlineflags 3651 0x200 + setlineflags 3654 0x200 + setactivation 3653 16 + setactivation 3655 16 + setactivation 3651 16 + setactivation 3654 16 +} +70F677BDE192EE0395F9D47DB2634E0A // map31 +{ +} +CDF871C2ADA13DAFB6D26B2E7F5A78EC // map32 +{ +} From a33b2fe2d5b51ffa60d1308bb86df116bb845d6b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 9 Sep 2012 01:50:45 +0000 Subject: [PATCH 082/101] - Daedalus maps 31 and 32 don't need compatibility settings. SVN r3865 (trunk) --- wadsrc/static/compatibility.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 957e8f16f..517e04319 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -269,9 +269,3 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 setactivation 3651 16 setactivation 3654 16 } -70F677BDE192EE0395F9D47DB2634E0A // map31 -{ -} -CDF871C2ADA13DAFB6D26B2E7F5A78EC // map32 -{ -} From c4859261ab3427fa3e72635ab41364f497476482 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 9 Sep 2012 02:36:53 +0000 Subject: [PATCH 083/101] - Reformatted the info ccmd to be less verbose. SVN r3866 (trunk) --- src/p_mobj.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 6c0cd4973..4198069b6 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6106,25 +6106,25 @@ void PrintMiscActorInfo(AActor *query) Printf("\n\tflags6: %x", query->flags6); for (flagi = 0; flagi < 31; flagi++) if (query->flags6 & 1<BounceFlags, FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor), query->BounceFlags); /*for (flagi = 0; flagi < 31; flagi++) if (query->BounceFlags & 1<alpha), query->renderflags); /*for (flagi = 0; flagi < 31; flagi++) if (query->renderflags & 1<special ? LineSpecialsInfo[query->special]->name : "None"), query->args[0], query->args[1], query->args[2], query->args[3], query->args[4], query->special1, query->special2); - Printf("\nTID is %d", query->tid); - Printf("\nIts coordinates are x: %f, y: %f, z:%f, floor:%f, ceiling:%f.", + Printf("\nTID: %d", query->tid); + Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.", FIXED2FLOAT(query->x), FIXED2FLOAT(query->y), FIXED2FLOAT(query->z), FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz)); - Printf("\nIts speed is %f and velocity is x:%f, y:%f, z:%f, combined:%f.\n", + Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n", FIXED2FLOAT(query->Speed), FIXED2FLOAT(query->velx), FIXED2FLOAT(query->vely), FIXED2FLOAT(query->velz), sqrt(pow(FIXED2FLOAT(query->velx), 2) + pow(FIXED2FLOAT(query->vely), 2) + pow(FIXED2FLOAT(query->velz), 2))); } From 9f3a93bfd2f7a05cf564c55ee72ea9bceddb1911 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 9 Sep 2012 02:58:37 +0000 Subject: [PATCH 084/101] - Added compatibility setting for Community Chest 3, map03. SVN r3867 (trunk) --- wadsrc/static/compatibility.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 517e04319..033f87a66 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -269,3 +269,12 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 setactivation 3651 16 setactivation 3654 16 } + +// Community Chest 3 +F481922F4881F74760F3C0437FD5EDD0 // map03 +{ + // I have no idea how this conveyor belt setup manages to work under Boom. + // Set the sector the voodoo doll ends up standing on when sectors tagged + // 1 are raised so that the voodoo doll will be carried. + setlinespecial 3559 Sector_CopyScroller 17 6 0 0 0 +} From a2c761bee6a3aa7c1fc0181856df7e8deff4bd35 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 9 Sep 2012 03:01:49 +0000 Subject: [PATCH 085/101] - The chasecam is now only considered a cheat for deathmatch mode. (For that, there is still the sv_chasecam flag in dmflags2.) SVN r3868 (trunk) --- src/c_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index b1f3a1561..f6bd01a20 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -254,7 +254,7 @@ CCMD (chase) else { // Check if we're allowed to use chasecam. - if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && CheckCheatmode ())) + if (gamestate != GS_LEVEL || (!(dmflags2 & DF2_CHASECAM) && deathmatch && CheckCheatmode ())) return; Net_WriteByte (DEM_GENERICCHEAT); From 8f81f57ce77a316f6e409091d6b2d20123b809ec Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 9 Sep 2012 03:07:41 +0000 Subject: [PATCH 086/101] - Don't notify when other players use the chasecam in deathmatch. SVN r3869 (trunk) --- src/m_cheat.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 45ec78d9f..4249fea5c 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -519,8 +519,8 @@ void cht_DoCheat (player_t *player, int cheat) if (player == &players[consoleplayer]) Printf ("%s\n", msg); - else - Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg); + else if (cheat != CHT_CHASECAM) + Printf ("%s cheats: %s\n", player->userinfo.netname, msg); } const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo) From 077feefb0b83f167c53ba4d3d148acf71091e747 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 11 Sep 2012 01:42:01 +0000 Subject: [PATCH 087/101] - Fixed one small copy-paste error in decaldef.txt for SnakeScorch22. SVN r3870 (trunk) --- wadsrc/static/decaldef.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/decaldef.txt b/wadsrc/static/decaldef.txt index 8b12e637b..0ea9039e5 100644 --- a/wadsrc/static/decaldef.txt +++ b/wadsrc/static/decaldef.txt @@ -758,7 +758,7 @@ decal SnakeScorch21 decal SnakeScorch22 { - pic CBALSCR1 + pic CBALSCR2 shade "00 00 00" x-scale 0.7 y-scale 0.7 From 1e234c98531f1a458e0f4ff04b9007de05973cf5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 14 Sep 2012 03:02:51 +0000 Subject: [PATCH 088/101] - Disable the teleports on lines 1107 and 1108 of nukemine.wad E1M2 so that the map is completable. SVN r3871 (trunk) --- wadsrc/static/compatibility.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 033f87a66..e6b3af2fb 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -278,3 +278,9 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 // 1 are raised so that the voodoo doll will be carried. setlinespecial 3559 Sector_CopyScroller 17 6 0 0 0 } + +7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2 +{ + clearlinespecial 1107 + clearlinespecial 1108 +} From 11ca707485d3e70d0621e967e96db6c52423b7a8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 16 Sep 2012 04:40:56 +0000 Subject: [PATCH 089/101] - Added vid_maxfps cvar to limit the frame rate to some arbitrary rate between 35 and 1000 FPS. It defaults to 200. Setting it to 0 will restore the previous behavior of having no frame rate limit. Note that vid_maxfps 35 is NOT the same as cl_capfps 1. cl_capfps caps the frame rate by tying the video update directly to the game timer. With vid_maxfps 35, the video update and game timer are running on separate timers, and results will not be as good as with cl_capfps 1, which uses only one timer. SVN r3872 (trunk) --- src/d_net.cpp | 14 +++++- src/sdl/hardware.cpp | 4 ++ src/sdl/hardware.h | 2 + src/win32/fb_d3d9.cpp | 5 +++ src/win32/fb_ddraw.cpp | 4 ++ src/win32/hardware.h | 3 ++ src/win32/win32iface.h | 2 + src/win32/win32video.cpp | 93 +++++++++++++++++++++++++++++++++++++++- 8 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 0137d911a..3acee3af4 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -60,6 +60,7 @@ #include "p_lnspec.h" #include "v_video.h" #include "p_spec.h" +#include "hardware.h" #include "intermission/intermission.h" EXTERN_CVAR (Int, disableautosave) @@ -135,7 +136,18 @@ static int oldentertics; extern bool advancedemo; -CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR (Bool, cl_capfps, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +{ + // Do not use the separate FPS limit timer if we are limiting FPS with this. + if (self) + { + I_SetFPSLimit(0); + } + else + { + I_SetFPSLimit(-1); + } +} // [RH] Special "ticcmds" get stored in here static struct TicSpecial diff --git a/src/sdl/hardware.cpp b/src/sdl/hardware.cpp index a7af588ce..ef78b4c31 100644 --- a/src/sdl/hardware.cpp +++ b/src/sdl/hardware.cpp @@ -177,6 +177,10 @@ void I_ClosestResolution (int *width, int *height, int bits) } } +void I_SetFPSLimit(int limit) +{ +} + extern int NewWidth, NewHeight, NewBits, DisplayBits; CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) diff --git a/src/sdl/hardware.h b/src/sdl/hardware.h index f82af7bb4..651d3ee2b 100644 --- a/src/sdl/hardware.h +++ b/src/sdl/hardware.h @@ -59,6 +59,8 @@ void I_InitGraphics (); void I_ShutdownGraphics (); void I_CreateRenderer(); +void I_SetFPSLimit(int limit); + extern IVideo *Video; #endif // __HARDWARE_H__ diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 876ebdbd9..3598f52d1 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -1208,6 +1208,11 @@ void D3DFB::Flip() BlockSurface[BlockNum]->UnlockRect(); } } + // Limiting the frame rate is as simple as waiting for the timer to signal this event. + if (FPSLimitEvent != NULL) + { + WaitForSingleObject(FPSLimitEvent, 1000); + } D3DDevice->Present(NULL, NULL, NULL, NULL); InScene = false; diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index 046c7ed4f..9fb65c2a7 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -1201,6 +1201,10 @@ void DDrawFB::Update () LockCount = 0; UpdatePending = false; + if (FPSLimitEvent != NULL) + { + WaitForSingleObject(FPSLimitEvent, 1000); + } if (!Windowed && AppActive && !SessionState /*&& !UseBlitter && !MustBuffer*/) { HRESULT hr = PrimarySurf->Flip (NULL, FlipFlags); diff --git a/src/win32/hardware.h b/src/win32/hardware.h index 38cb15ea8..e6b23ab2f 100644 --- a/src/win32/hardware.h +++ b/src/win32/hardware.h @@ -62,6 +62,9 @@ void I_CreateRenderer(); void I_SaveWindowedPos (); void I_RestoreWindowedPos (); +void I_SetFPSLimit(int limit); + + extern IVideo *Video; #endif // __HARDWARE_H__ diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index ec64f2164..07151fb02 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -52,6 +52,8 @@ EXTERN_CVAR (Bool, vid_vsync) +extern HANDLE FPSLimitEvent; + class D3DTex; class D3DPal; struct FSoftwareRenderer; diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index adc68af23..b6d6d670e 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -41,6 +41,7 @@ #define _WIN32_WINNT 0x0501 #define WIN32_LEAN_AND_MEAN #include +#include #include #include @@ -87,6 +88,8 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- +static void StopFPSLimit(); + // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern HWND Window; @@ -98,20 +101,38 @@ extern bool VidResizing; EXTERN_CVAR (Bool, fullscreen) EXTERN_CVAR (Float, Gamma) +EXTERN_CVAR (Bool, cl_capfps) // PRIVATE DATA DEFINITIONS ------------------------------------------------ static HMODULE D3D9_dll; static HMODULE DDraw_dll; +static UINT FPSLimitTimer; // PUBLIC DATA DEFINITIONS ------------------------------------------------- IDirectDraw2 *DDraw; IDirect3D9 *D3D; IDirect3DDevice9 *D3Device; +HANDLE FPSLimitEvent; CVAR (Bool, vid_forceddraw, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (vid_maxfps < TICRATE && vid_maxfps != 0) + { + vid_maxfps = TICRATE; + } + else if (vid_maxfps > 1000) + { + vid_maxfps = 1000; + } + else if (cl_capfps == 0) + { + I_SetFPSLimit(vid_maxfps); + } +} #if VID_FILE_DEBUG FILE *dbg; @@ -714,4 +735,74 @@ void Win32Video::SetWindowedScale (float scale) // FIXME } -// FrameBuffer implementation ----------------------------------------------- +//========================================================================== +// +// SetFPSLimit +// +// Initializes an event timer to fire at a rate of /sec. The video +// update will wait for this timer to trigger before updating. +// +// Pass 0 as the limit for unlimited. +// Pass a negative value for the limit to use the value of vid_maxfps. +// +//========================================================================== + +void I_SetFPSLimit(int limit) +{ + if (limit < 0) + { + limit = vid_maxfps; + } + // Kill any leftover timer. + if (FPSLimitTimer != 0) + { + timeKillEvent(FPSLimitTimer); + FPSLimitTimer = 0; + } + if (limit == 0) + { // no limit + if (FPSLimitEvent != NULL) + { + CloseHandle(FPSLimitEvent); + FPSLimitEvent = NULL; + } + DPrintf("FPS timer disabled\n"); + } + else + { + if (FPSLimitEvent == NULL) + { + FPSLimitEvent = CreateEvent(NULL, FALSE, TRUE, NULL); + if (FPSLimitEvent == NULL) + { // Could not create event, so cannot use timer. + Printf("Failed to create FPS limitter event\n"); + return; + } + } + atterm(StopFPSLimit); + // Set timer event as close as we can to limit/sec, in milliseconds. + UINT period = 1000 / limit; + FPSLimitTimer = timeSetEvent(period, 0, (LPTIMECALLBACK)FPSLimitEvent, 0, TIME_PERIODIC | TIME_CALLBACK_EVENT_SET); + if (FPSLimitTimer == 0) + { + CloseHandle(FPSLimitEvent); + FPSLimitEvent = NULL; + Printf("Failed to create FPS limitter timer\n"); + return; + } + DPrintf("FPS timer set to %u ms\n", period); + } +} + +//========================================================================== +// +// StopFPSLimit +// +// Used for cleanup during application shutdown. +// +//========================================================================== + +static void StopFPSLimit() +{ + I_SetFPSLimit(0); +} From 44b1879553ec245e83b88d3f7b3afe3d000a3148 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 16 Sep 2012 04:51:28 +0000 Subject: [PATCH 090/101] - Increased max resolution to 5760x3600, which is enough to do 2x supersampling on the currently largest resolution monitors available (which is the MacBook Pro with Retina Display's 2880x1800). SVN r3873 (trunk) --- src/r_defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index c43b6be83..5f8272b3d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -38,8 +38,8 @@ #include "dthinker.h" -#define MAXWIDTH 2880 -#define MAXHEIGHT 1800 +#define MAXWIDTH 5760 +#define MAXHEIGHT 3600 const WORD NO_INDEX = 0xffffu; const DWORD NO_SIDE = 0xffffffffu; From a0f19fc78879942cdfae1af19802b6e9b7189144 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 16 Sep 2012 04:59:01 +0000 Subject: [PATCH 091/101] - Fixed: When P_MoveThing() moves the current camera, it also needs to reset the view interpolation. SVN r3874 (trunk) --- src/p_things.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_things.cpp b/src/p_things.cpp index aa48fe18b..e0f3936b7 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -137,6 +137,10 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) source->PrevX = x; source->PrevY = y; source->PrevZ = z; + if (source == players[consoleplayer].camera) + { + R_ResetViewInterpolation(); + } return true; } else From d28ebe543b1385af84597ea3e611b32845a63c17 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 19 Sep 2012 01:45:00 +0000 Subject: [PATCH 092/101] - Changed FRemapTable::AddDesaturation() to take doubles as parameters, since the C ABI always passes doubles to functions anyway. - Fixed: FRemapTable::AddDesaturation() excluded the final entry from the loop. Also, it was less forgiving than AddColorRange, in that it did not support ranges in descending order. SVN r3875 (trunk) --- src/r_data/r_translate.cpp | 40 +++++++++++++++++++++++--------------- src/r_data/r_translate.h | 2 +- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index b7f2ca69f..230689ad9 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -403,14 +403,22 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in // //---------------------------------------------------------------------------- -void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2) +void FRemapTable::AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2) { - r1 = clamp(r1, 0.0f, 2.0f); - g1 = clamp(g1, 0.0f, 2.0f); - b1 = clamp(b1, 0.0f, 2.0f); - r2 = clamp(r2, 0.0f, 2.0f); - g2 = clamp(g2, 0.0f, 2.0f); - b2 = clamp(b2, 0.0f, 2.0f); + r1 = clamp(r1, 0.0, 2.0); + g1 = clamp(g1, 0.0, 2.0); + b1 = clamp(b1, 0.0, 2.0); + r2 = clamp(r2, 0.0, 2.0); + g2 = clamp(g2, 0.0, 2.0); + b2 = clamp(b2, 0.0, 2.0); + + if (start > end) + { + swapvalues(start, end); + swapvalues(r1, r2); + swapvalues(g1, g2); + swapvalues(b1, b2); + } r2 -= r1; g2 -= g1; @@ -419,7 +427,7 @@ void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b g1 *= 255; b1 *= 255; - for(int c = start; c < end; c++) + for(int c = start; c <= end; c++) { double intensity = (GPalette.BaseColors[c].r * 77 + GPalette.BaseColors[c].g * 143 + @@ -443,7 +451,7 @@ void FRemapTable::AddDesaturation(int start, int end, float r1,float g1, float b // //---------------------------------------------------------------------------- -void FRemapTable::AddToTranslation(const char * range) +void FRemapTable::AddToTranslation(const char *range) { int start,end; bool desaturated = false; @@ -515,39 +523,39 @@ void FRemapTable::AddToTranslation(const char * range) else if (sc.TokenType == '%') { // translation using RGB values - float r1,g1,b1,r2,g2,b2; + double r1,g1,b1,r2,g2,b2; sc.MustGetToken('['); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r1 = float(sc.Float); + r1 = sc.Float; sc.MustGetToken(','); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g1 = float(sc.Float); + g1 = sc.Float; sc.MustGetToken(','); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b1 = float(sc.Float); + b1 = sc.Float; sc.MustGetToken(']'); sc.MustGetToken(':'); sc.MustGetToken('['); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r2 = float(sc.Float); + r2 = sc.Float; sc.MustGetToken(','); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g2 = float(sc.Float); + g2 = sc.Float; sc.MustGetToken(','); sc.MustGetAnyToken(); if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b2 = float(sc.Float); + b2 = sc.Float; sc.MustGetToken(']'); AddDesaturation(start, end, r1, g1, b1, r2, g2, b2); diff --git a/src/r_data/r_translate.h b/src/r_data/r_translate.h index d61a9a22e..23490cfb8 100644 --- a/src/r_data/r_translate.h +++ b/src/r_data/r_translate.h @@ -38,7 +38,7 @@ struct FRemapTable void Serialize(FArchive &ar); void AddIndexRange(int start, int end, int pal1, int pal2); void AddColorRange(int start, int end, int r1,int g1, int b1, int r2, int g2, int b2); - void AddDesaturation(int start, int end, float r1,float g1, float b1, float r2, float g2, float b2); + void AddDesaturation(int start, int end, double r1, double g1, double b1, double r2, double g2, double b2); void AddToTranslation(const char * range); int StoreTranslation(); From 9a28216e305dcdb70152597ac062e466afdb7e3a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 20 Sep 2012 02:06:50 +0000 Subject: [PATCH 093/101] - Added HUDMSG_ALPHA flag. To use alpha with hud messages, you now need to include this flag, so old mods with extra arguments to hudmessage don't produce unexpected results. SVN r3876 (trunk) --- src/p_acs.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fdba35118..4fe558206 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -92,6 +92,7 @@ FRandom pr_acs ("ACS"); #define HUDMSG_LOG (0x80000000) #define HUDMSG_COLORSTRING (0x40000000) #define HUDMSG_ADDBLEND (0x20000000) +#define HUDMSG_ALPHA (0x10000000) // HUD message layers; these are not flags #define HUDMSG_LAYER_SHIFT 12 @@ -5723,7 +5724,10 @@ scriptwait: break; } msg->SetVisibility((type & HUDMSG_VISIBILITY_MASK) >> HUDMSG_VISIBILITY_SHIFT); - msg->SetAlpha(alpha); + if (type & HUDMSG_ALPHA) + { + msg->SetAlpha(alpha); + } if (type & HUDMSG_ADDBLEND) { msg->SetRenderStyle(STYLE_Add); From 864fb5798e8e6416d9ddfa80d42c34143556da92 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 20 Sep 2012 02:14:43 +0000 Subject: [PATCH 094/101] - Added desaturated translation support to ACS. SVN r3878 (trunk) --- src/p_acs.cpp | 19 +++++++++++++++++++ src/p_acs.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4fe558206..daffe0eae 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6534,6 +6534,25 @@ scriptwait: } break; + case PCD_TRANSLATIONRANGE3: + { // translation using desaturation + int start = STACK(8); + int end = STACK(7); + fixed_t r1 = STACK(6); + fixed_t g1 = STACK(5); + fixed_t b1 = STACK(4); + fixed_t r2 = STACK(3); + fixed_t g2 = STACK(2); + fixed_t b2 = STACK(1); + sp -= 8; + + if (translation != NULL) + translation->AddDesaturation(start, end, + FIXED2DBL(r1), FIXED2DBL(g1), FIXED2DBL(b1), + FIXED2DBL(r2), FIXED2DBL(g2), FIXED2DBL(b2)); + } + break; + case PCD_ENDTRANSLATION: // This might be useful for hardware rendering, but // for software it is superfluous. diff --git a/src/p_acs.h b/src/p_acs.h index df2abdf84..c2e0e9155 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -601,6 +601,7 @@ public: PCD_PUSHFUNCTION, // from Eternity /*360*/ PCD_CALLSTACK, // from Eternity PCD_SCRIPTWAITNAMED, + PCD_TRANSLATIONRANGE3, /*361*/ PCODE_COMMAND_COUNT }; From 12e19011507cccf8e5be9f7e4620ac493851773e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Oct 2012 03:48:51 +0000 Subject: [PATCH 095/101] - Fixed: FListMenuItemPlayerDisplay::Drawer() used the sprite's scale but not the texture's scale. SVN r3880 (trunk) --- src/menu/playerdisplay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index 256ca6a49..c0f353675 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -591,8 +591,8 @@ void FListMenuItemPlayerDisplay::Drawer(bool selected) if (mTranslate) trans = translationtables[TRANSLATION_Players](MAXPLAYERS); screen->DrawTexture (tex, x + 36*CleanXfac, y + 71*CleanYfac, - DTA_DestWidth, MulScale16 (tex->GetWidth() * CleanXfac, scaleX), - DTA_DestHeight, MulScale16 (tex->GetHeight() * CleanYfac, scaleY), + DTA_DestWidth, MulScale16 (tex->GetScaledWidth() * CleanXfac, scaleX), + DTA_DestHeight, MulScale16 (tex->GetScaledHeight() * CleanYfac, scaleY), DTA_Translation, trans, DTA_FlipX, sprframe->Flip & (1 << mRotation), TAG_DONE); From 934c27d34a89d0badf4ba9b9296f57afdabb15cb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Oct 2012 04:21:34 +0000 Subject: [PATCH 096/101] - Fixed: R_GetColumn() needs to clamp negative column indexes to be inside the texture if the texture's width isn't a power of 2. SVN r3881 (trunk) --- src/r_draw.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 60a0e46e4..165394652 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2153,6 +2153,14 @@ void tmvline4_revsubclamp () const BYTE *R_GetColumn (FTexture *tex, int col) { + int width; + + // If the texture's width isn't a power of 2, then we need to make it a + // positive offset for proper clamping. + if (col < 0 && (width = tex->GetWidth()) != (1 << tex->WidthBits)) + { + col = width + (col % width); + } return tex->GetColumn (col, NULL); } From 5011a0dede78e2754209e4e1b3b98f6a15b88291 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 9 Oct 2012 23:05:59 +0000 Subject: [PATCH 097/101] - Fixed: FString::Insert copied too many charactes. SVN r3882 (trunk) --- src/zstring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zstring.cpp b/src/zstring.cpp index 7cc594b14..dc171f398 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -773,7 +773,7 @@ void FString::Insert (size_t index, const char *instr, size_t instrlen) AllocBuffer (mylen + instrlen); StrCopy (Chars, old->Chars(), index); StrCopy (Chars + index, instr, instrlen); - StrCopy (Chars + index + instrlen, old->Chars() + index, mylen - index + 1); + StrCopy (Chars + index + instrlen, old->Chars() + index, mylen - index); old->Release(); } } From 924cd3ef3856822f8754dc75987e04a456134146 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 11 Oct 2012 03:38:12 +0000 Subject: [PATCH 098/101] - Added sqrt, fixedsqrt, and vectorlength to ACS. SVN r3883 (trunk) --- src/p_acs.cpp | 13 +++++++++++++ src/p_acs.h | 3 +++ 2 files changed, 16 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index daffe0eae..8f604e782 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6560,6 +6560,14 @@ scriptwait: translation = NULL; break; + case PCD_SQRT: + STACK(1) = xs_FloorToInt(sqrt(double(STACK(1)))); + break; + + case PCD_FIXEDSQRT: + STACK(1) = FLOAT2FIXED(sqrt(FIXED2DBL(STACK(1)))); + break; + case PCD_SIN: STACK(1) = finesine[angle_t(STACK(1)<<16)>>ANGLETOFINESHIFT]; break; @@ -6573,6 +6581,11 @@ scriptwait: sp--; break; + case PCD_VECTORLENGTH: + STACK(2) = FLOAT2FIXED(TVector2(FIXED2DBL(STACK(2)), FIXED2DBL(STACK(1))).Length()); + sp--; + break; + case PCD_CHECKWEAPON: if (activator == NULL || activator->player == NULL || // Non-players do not have weapons activator->player->ReadyWeapon == NULL) diff --git a/src/p_acs.h b/src/p_acs.h index c2e0e9155..04384dd73 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -602,6 +602,9 @@ public: /*360*/ PCD_CALLSTACK, // from Eternity PCD_SCRIPTWAITNAMED, PCD_TRANSLATIONRANGE3, + PCD_SQRT, + PCD_FIXEDSQRT, + PCD_VECTORLENGTH, /*361*/ PCODE_COMMAND_COUNT }; From 81ce8b28f2923bc277bf459a1c59fcc039661b86 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 11 Oct 2012 04:12:35 +0000 Subject: [PATCH 099/101] - Added the Inventory flag IF_NEVERRESPAWN. SVN r3885 (trunk) --- src/g_shared/a_pickups.cpp | 1 + src/g_shared/a_pickups.h | 1 + src/thingdef/thingdef_data.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index f071171a7..9465a1c3a 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -498,6 +498,7 @@ bool AInventory::SpecialDropAction (AActor *dropper) bool AInventory::ShouldRespawn () { if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags & DF_RESPAWN_SUPER)) return false; + if (ItemFlags & IF_NEVERRESPAWN) return false; return !!(dmflags & DF_ITEMS_RESPAWN); } diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index beaa65872..2358fbe10 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -132,6 +132,7 @@ enum IF_NOATTENPICKUPSOUND = 1<<17, // Play pickup sound with ATTN_NONE IF_PERSISTENTPOWER = 1<<18, // Powerup is kept when travelling between levels IF_RESTRICTABSOLUTELY = 1<<19, // RestrictedTo and ForbiddenTo do not allow pickup in any form by other classes + IF_NEVERRESPAWN = 1<<20, // Never, ever respawns }; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 573970db3..bc75c2105 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -298,6 +298,7 @@ static FFlagDef InventoryFlags[] = DEFINE_FLAG(IF, NOATTENPICKUPSOUND, AInventory, ItemFlags), DEFINE_FLAG(IF, PERSISTENTPOWER, AInventory, ItemFlags), DEFINE_FLAG(IF, RESTRICTABSOLUTELY, AInventory, ItemFlags), + DEFINE_FLAG(IF, NEVERRESPAWN, AInventory, ItemFlags), DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP), From f3b40a9f3630cde5ddadad23bd8d6478d228cbcb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 11 Oct 2012 04:38:52 +0000 Subject: [PATCH 100/101] - Fixed: WeaponGiver needs to set the MF_DROPPED flag of the spawned weapon to match its own (so that it can't be used as an infinite source of ammo when sv_weaponstay is true). - Fixed: WeaponGiver should not remember the given weapon after it is picked up (to avoid giving a weapon owned by one player to a different player when sv_weaponstay is true). SVN r3886 (trunk) --- src/g_shared/a_weapons.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index a59e8f564..c5035e416 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -727,6 +727,7 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) if (weap != NULL) { weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only. + weap->flags = (weap->flags & ~MF_DROPPED) | (this->flags & MF_DROPPED); if (AmmoGive1 >= 0) weap->AmmoGive1 = AmmoGive1; if (AmmoGive2 >= 0) weap->AmmoGive2 = AmmoGive2; weap->BecomeItem(); @@ -736,7 +737,11 @@ bool AWeaponGiver::TryPickup(AActor *&toucher) weap = barrier_cast(master); bool res = weap->CallTryPickup(toucher); - if (res) GoAwayAndDie(); + if (res) + { + GoAwayAndDie(); + master = NULL; + } return res; } } From 441f6339835576bbe015c9984f5593f9ce028dfc Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 13 Oct 2012 22:55:44 +0000 Subject: [PATCH 101/101] - Moved Sqrt, FixedSqrt, and VectorLength to ACSF_ instead of adding new opcodes. SVN r3888 (trunk) --- src/p_acs.cpp | 25 ++++++++++++------------- src/p_acs.h | 5 +---- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 8f604e782..3feafc99e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3377,6 +3377,9 @@ enum EACSFunctions ACSF_ACS_NamedExecuteAlways, ACSF_UniqueTID, ACSF_IsTIDUsed, + ACSF_Sqrt, + ACSF_FixedSqrt, + ACSF_VectorLength, // ZDaemon ACSF_GetTeamScore = 19620, @@ -3901,6 +3904,15 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) return P_IsTIDUsed(args[0]); break; + case ACSF_Sqrt: + return xs_FloorToInt(sqrt(double(args[0]))); + + case ACSF_FixedSqrt: + return FLOAT2FIXED(sqrt(FIXED2DBL(args[0]))); + + case ACSF_VectorLength: + return FLOAT2FIXED(TVector2(FIXED2DBL(args[0]), FIXED2DBL(args[1])).Length()); + default: break; } @@ -6560,14 +6572,6 @@ scriptwait: translation = NULL; break; - case PCD_SQRT: - STACK(1) = xs_FloorToInt(sqrt(double(STACK(1)))); - break; - - case PCD_FIXEDSQRT: - STACK(1) = FLOAT2FIXED(sqrt(FIXED2DBL(STACK(1)))); - break; - case PCD_SIN: STACK(1) = finesine[angle_t(STACK(1)<<16)>>ANGLETOFINESHIFT]; break; @@ -6581,11 +6585,6 @@ scriptwait: sp--; break; - case PCD_VECTORLENGTH: - STACK(2) = FLOAT2FIXED(TVector2(FIXED2DBL(STACK(2)), FIXED2DBL(STACK(1))).Length()); - sp--; - break; - case PCD_CHECKWEAPON: if (activator == NULL || activator->player == NULL || // Non-players do not have weapons activator->player->ReadyWeapon == NULL) diff --git a/src/p_acs.h b/src/p_acs.h index 04384dd73..d2ae2038b 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -602,11 +602,8 @@ public: /*360*/ PCD_CALLSTACK, // from Eternity PCD_SCRIPTWAITNAMED, PCD_TRANSLATIONRANGE3, - PCD_SQRT, - PCD_FIXEDSQRT, - PCD_VECTORLENGTH, -/*361*/ PCODE_COMMAND_COUNT +/*363*/ PCODE_COMMAND_COUNT }; // Some constants used by ACS scripts