From 48bb782b1940a5223b4fa58a2c006a6ad2eda66a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 21 Nov 2006 05:43:34 +0000 Subject: [PATCH] - Fixed: Polyobjects are serialized before players, which means that a call to PO_MovePolyobj() from P_SerializePolyobjs() for a crushing polyobject that touches a player actor will not have a valid actor->player->mo chain for P_DamageMobj and crash if it happens to touch the player. Since the polyobject was presumably in a good spot when the game was saved, we can just skip this step entirely and let it take care of itself the next time it moves (by which time, the players will be valid). - Fixed: When transitioning from fullscreen to windowed mode with D3DFB, the window kept the WS_EX_TOPMOST style. - Slight correctness fix: When in fullscreen, the window should have WS_POPUP style. - Added a NULL target check to P_SpawnMissileXYZ(), A_DemonAttack1(), A_DemonAttack2_1(), and A_DemonAttack2_2(). SVN r384 (trunk) --- docs/rh-log.txt | 15 +++++++++++++++ src/g_hexen/a_demons.cpp | 40 +++++++++++++++++++++++----------------- src/p_local.h | 2 +- src/p_mobj.cpp | 6 ++++++ src/p_saveg.cpp | 2 +- src/po_man.cpp | 34 +++++++++++++++++----------------- src/win32/fb_d3d9.cpp | 17 +++++++++++++---- src/win32/fb_ddraw.cpp | 2 +- 8 files changed, 77 insertions(+), 41 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5a053550e2..fac70c939e 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,18 @@ +November 20, 2006 +- Fixed: Polyobjects are serialized before players, which means that a call + to PO_MovePolyobj() from P_SerializePolyobjs() for a crushing polyobject + that touches a player actor will not have a valid actor->player->mo chain + for P_DamageMobj and crash if it happens to touch the player. Since the + polyobject was presumably in a good spot when the game was saved, we can + just skip this step entirely and let it take care of itself the next time + it moves (by which time, the players will be valid). +- Fixed: When transitioning from fullscreen to windowed mode with D3DFB, the + window kept the WS_EX_TOPMOST style. +- Slight correctness fix: When in fullscreen, the window should have WS_POPUP + style. +- Added a NULL target check to P_SpawnMissileXYZ(), A_DemonAttack1(), + A_DemonAttack2_1(), and A_DemonAttack2_2(). + November 18, 2006 - Fixed: DFrameBuffer and related classes did not use DECLARE_CLASS macros, so there was no guarantee that they would allocate the proper amount of diff --git a/src/g_hexen/a_demons.cpp b/src/g_hexen/a_demons.cpp index a68ef39d0d..1c774f6ecb 100644 --- a/src/g_hexen/a_demons.cpp +++ b/src/g_hexen/a_demons.cpp @@ -548,7 +548,7 @@ END_DEFAULTS void A_DemonAttack1 (AActor *actor) { - if (actor->CheckMeleeRange ()) + if (actor->target != NULL && actor->CheckMeleeRange ()) { int damage = pr_atk.HitDice (2); P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee); @@ -565,15 +565,18 @@ void A_DemonAttack1 (AActor *actor) void A_DemonAttack2_1 (AActor *actor) { - AActor *mo; - - // Improve the aiming of this code! - actor->z += 30*FRACUNIT; - mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon1FX1)); - actor->z -= 30*FRACUNIT; - if (mo) + if (actor->target != NULL) { - S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM); + AActor *mo; + + // Improve the aiming of this code! + actor->z += 30*FRACUNIT; + mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon1FX1)); + actor->z -= 30*FRACUNIT; + if (mo) + { + S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM); + } } } @@ -585,15 +588,18 @@ void A_DemonAttack2_1 (AActor *actor) void A_DemonAttack2_2 (AActor *actor) { - AActor *mo; - - // Improve the aiming of this code! - actor->z += 30*FRACUNIT; - mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon2FX1)); - actor->z -= 30*FRACUNIT; - if (mo) + if (actor->target != NULL) { - S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM); + AActor *mo; + + // Improve the aiming of this code! + actor->z += 30*FRACUNIT; + mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon2FX1)); + actor->z -= 30*FRACUNIT; + if (mo) + { + S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM); + } } } diff --git a/src/p_local.h b/src/p_local.h index 0f3aa2175c..5e254c3a3d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -484,7 +484,7 @@ extern int po_NumPolyobjs; extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn -bool PO_MovePolyobj (int num, int x, int y); +bool PO_MovePolyobj (int num, int x, int y, bool force=false); bool PO_RotatePolyobj (int num, angle_t angle); void PO_Init (); bool PO_Busy (int polyobj); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8f0c375039..e19701baf6 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4269,6 +4269,12 @@ AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, const PClass * AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z, AActor *source, AActor *dest, const PClass *type) { + if (dest == NULL) + { + Printf ("P_SpawnMissilyXYZ: Tried to shoot %s from %s with no dest\n", + type->TypeName.GetChars(), source->GetClass()->TypeName.GetChars()); + return NULL; + } int defflags3 = GetDefaultByType (type)->flags3; if (defflags3 & MF3_FLOORHUGGER) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 074a249838..aac9a22dcb 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -497,7 +497,7 @@ void P_SerializePolyobjs (FArchive &arc) deltaX -= po->startSpot[0]; deltaY -= po->startSpot[1]; deltaZ -= po->startSpot[2]; - PO_MovePolyobj (po->tag, deltaX, deltaY); + PO_MovePolyobj (po->tag, deltaX, deltaY, true); } } } diff --git a/src/po_man.cpp b/src/po_man.cpp index 2b0d14e4f0..7e7a2d439b 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -32,7 +32,6 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- -bool PO_MovePolyobj (int num, int x, int y); bool PO_RotatePolyobj (int num, angle_t angle); void PO_Init (void); @@ -757,12 +756,9 @@ static void UpdateSegBBox (seg_t *seg) // //========================================================================== -bool PO_MovePolyobj (int num, int x, int y) +bool PO_MovePolyobj (int num, int x, int y, bool force) { - int count; - seg_t **segList; polyobj_t *po; - bool blocked; if (!(po = GetPolyobj (num))) { @@ -772,21 +768,25 @@ bool PO_MovePolyobj (int num, int x, int y) UnLinkPolyobj (po); DoMovePolyobj (po, x, y); - segList = po->segs; - blocked = false; - for (count = po->numsegs; count; count--, segList++) + if (!force) { - if (CheckMobjBlocking(*segList, po)) + seg_t **segList = po->segs; + bool blocked = false; + + for (int count = po->numsegs; count; count--, segList++) { - blocked = true; - break; + if (CheckMobjBlocking(*segList, po)) + { + blocked = true; + break; + } + } + if (blocked) + { + DoMovePolyobj (po, -x, -y); + LinkPolyobj(po); + return false; } - } - if (blocked) - { - DoMovePolyobj (po, -x, -y); - LinkPolyobj(po); - return false; } po->startSpot[0] += x; po->startSpot[1] += y; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 1f8ecc3c00..5bce125642 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -295,9 +295,9 @@ bool D3DFB::CreateResources () { if (!Windowed) { - ShowWindow (Window, SW_SHOW); // Remove the window border in fullscreen mode SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU); + ShowWindow (Window, SW_SHOW); } else { @@ -309,10 +309,19 @@ bool D3DFB::CreateResources () VidResizing = true; // Make sure the window has a border in windowed mode SetWindowLongPtr (Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); - if (!SetWindowPos (Window, NULL, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER)) + if (GetWindowLong (Window, GWL_EXSTYLE) & WS_EX_TOPMOST) { - LOG1 ("SetWindowPos failed because %08lx\n", GetLastError()); + // Direct3D 9 will apparently add WS_EX_TOPMOST to fullscreen windows, + // and removing it is a little tricky. Using SetWindowLongPtr to clear it + // will not do the trick, but sending the window behind everything will. + SetWindowPos (Window, HWND_BOTTOM, 0, 0, sizew, sizeh, + SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE); + SetWindowPos (Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); + } + else + { + SetWindowPos (Window, NULL, 0, 0, sizew, sizeh, + SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER); } VidResizing = false; ShowWindow (Window, SW_SHOWNORMAL); diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index bd76cc8f55..ce9d14715c 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -232,7 +232,7 @@ bool DDrawFB::CreateResources () { ShowWindow (Window, SW_SHOW); // Remove the window border in fullscreen mode - SetWindowLongPtr (Window, GWL_STYLE, WS_VISIBLE|WS_SYSMENU); + SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU); TrueHeight = Height; for (Win32Video::ModeInfo *mode = static_cast(Video)->m_Modes; mode != NULL; mode = mode->next)