diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 5a053550e..fac70c939 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 a68ef39d0..1c774f6ec 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 0f3aa2175..5e254c3a3 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 8f0c37503..e19701baf 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 074a24983..aac9a22dc 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 2b0d14e4f..7e7a2d439 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 1f8ecc3c0..5bce12564 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 bd76cc8f5..ce9d14715 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)