From f02303d33cd164cc2773efc47f8008ddcc3b1821 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 17 Feb 2010 22:25:48 +0000 Subject: [PATCH 01/88] - added a lock parameter to Door_Animated. SVN r2167 (trunk) --- src/actionspecials.h | 2 +- src/p_lnspec.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index 5d9471fec..cd49504c3 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -12,7 +12,7 @@ DEFINE_SPECIAL(Door_Close, 10, 2, 3, 3) DEFINE_SPECIAL(Door_Open, 11, 2, 3, 3) DEFINE_SPECIAL(Door_Raise, 12, 3, 4, 4) DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5) -DEFINE_SPECIAL(Door_Animated, 14, 3, 3, 3) +DEFINE_SPECIAL(Door_Animated, 14, 4, 4, 4) DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now* DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2) DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index db2214ec7..cf79e376b 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -189,8 +189,11 @@ FUNC(LS_Door_CloseWaitOpen) } FUNC(LS_Door_Animated) -// Door_Animated (tag, speed, delay) +// Door_Animated (tag, speed, delay, lock) { + if (arg3 != 0 && !P_CheckKeys (it, arg3, arg0 != 0)) + return false; + return EV_SlidingDoor (ln, it, arg0, arg1, arg2); } From 68194d13c80a7e6c35dffc1c138dbc1ae3789a75 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 17 Feb 2010 22:38:17 +0000 Subject: [PATCH 02/88] - fixed some Chex Quest cheat codes. SVN r2168 (trunk) --- src/st_stuff.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/st_stuff.cpp b/src/st_stuff.cpp index a1ac0f290..59b65ef85 100644 --- a/src/st_stuff.cpp +++ b/src/st_stuff.cpp @@ -171,7 +171,7 @@ static BYTE CheatDigitalCafe[] = { 'd','i','g','i','t','a','l','c','a','f','e',2 static BYTE CheatJoshuaStorms[] = { 'j','o','s','h','u','a','s','t','o','r','m','s',255 }; static BYTE CheatLeeSnyder[] = { 'l','e','e','s','n','y','d','e','r',0,0,255 }; static BYTE CheatKimHyers[] = { 'k','i','m','h','y','e','r','s',255 }; -static BYTE CheatShrrill[] = { 's','h','r','r','i','l','l',255 }; +static BYTE CheatShrrill[] = { 's','h','e','r','r','i','l','l',255 }; static BYTE CheatTNTem[] = { 't','n','t','e','m',255 }; @@ -274,8 +274,8 @@ static cheatseq_t ChexCheats[] = { CheatKimHyers, 0, 1, 0, {0,0}, Cht_MyPos }, { CheatShrrill, 0, 0, 0, {0,0}, Cht_AutoMap }, { CheatDavidBrus, 0, 0, 0, {CHT_IDDQD,0}, Cht_Generic }, - { CheatMikeKoenigs, 0, 0, 0, {CHT_IDKFA,0}, Cht_Generic }, - { CheatScottHolman, 0, 0, 0, {CHT_IDFA,0}, Cht_Generic }, + { CheatScottHolman, 0, 0, 0, {CHT_IDKFA,0}, Cht_Generic }, + { CheatMikeKoenigs, 0, 0, 0, {CHT_IDFA,0}, Cht_Generic }, { CheatCharlesJacobi, 0, 0, 0, {CHT_NOCLIP,0}, Cht_Generic }, { CheatAndrewBenson, 0, 0, 0, {CHT_BEHOLDV,0}, Cht_Generic }, { CheatDeanHyers, 0, 0, 0, {CHT_BEHOLDS,0}, Cht_Generic }, From a5c3c95b2fff6c2b430f7f663973bd2274a01cdb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 19 Feb 2010 08:10:04 +0000 Subject: [PATCH 03/88] - added 2 DECORATE keywords from Skulltag as dummies. SVN r2169 (trunk) --- src/thingdef/thingdef_data.cpp | 2 ++ src/thingdef/thingdef_properties.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 8af93f0bd..87ac4f198 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -310,6 +310,7 @@ static FFlagDef WeaponFlags[] = DEFINE_FLAG(WIF, NOAUTOAIM, AWeapon, WeaponFlags), DEFINE_DUMMY_FLAG(NOLMS), + DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL), }; static FFlagDef PlayerPawnFlags[] = @@ -613,3 +614,4 @@ void InitThingdef() qsort(&variables[0], variables.Size(), sizeof(variables[0]), varcmp); } } + diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index cd2537db0..884e596e2 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1570,6 +1570,15 @@ DEFINE_CLASS_PROPERTY(slotpriority, F, Weapon) info->Class->Meta.SetMetaFixed(AWMETA_SlotPriority, i); } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(preferredskin, S, Weapon) +{ + PROP_STRING_PARM(str, 0); + // NoOp - only for Skulltag compatibility +} + //========================================================================== // //========================================================================== From 899c5a006d101a996998ad20cc85b954194c256d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 20 Feb 2010 08:40:48 +0000 Subject: [PATCH 04/88] - added a file 'fmod_version.txt' so that the source always comes with the information which FMod version to use. SVN r2170 (trunk) --- specs/fmod_version.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 specs/fmod_version.txt diff --git a/specs/fmod_version.txt b/specs/fmod_version.txt new file mode 100644 index 000000000..e69de29bb From 28e5e7ccefddc345b647ff356c3a25524d54ebf4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 20 Feb 2010 09:34:07 +0000 Subject: [PATCH 05/88] - it should at least contain something... SVN r2171 (trunk) --- specs/fmod_version.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/specs/fmod_version.txt b/specs/fmod_version.txt index e69de29bb..f5bd8cf60 100644 --- a/specs/fmod_version.txt +++ b/specs/fmod_version.txt @@ -0,0 +1 @@ +This version of ZDoom must be compiled with 4.26 or 4.28. From 350e72fb3eef19a9137b887008c628b31b1a0b2e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 23 Feb 2010 23:03:43 +0000 Subject: [PATCH 06/88] - added an option to disable player translations in single player games. SVN r2173 (trunk) --- src/m_cheat.cpp | 5 ++++- src/p_mobj.cpp | 13 ++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 508043f47..23383a6fe 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -46,6 +46,8 @@ #include "d_dehacked.h" #include "gi.h" +EXTERN_CVAR(Bool, r_forceplayertranslation) + // [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 // later calls us. @@ -319,7 +321,8 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); - player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); + if (multiplayer || r_forceplayertranslation) + player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); player->mo->DamageType = NAME_None; // player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 9a0f9c692..efbe88837 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -114,6 +114,14 @@ CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE) level.gravity = self; } +CUSTOM_CVAR(Bool, r_forceplayertranslation, false, CVAR_ARCHIVE|CVAR_NOINITCALL) +{ + if (!multiplayer && players[0].mo != NULL) + { + players[0].mo->Translation = self? TRANSLATION(TRANSLATION_Players, 0) : 0; + } +} + CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE) CVAR (Bool, addrocketexplosion, false, CVAR_ARCHIVE) @@ -3990,7 +3998,10 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) R_BuildPlayerTranslation (playernum); // [RH] set color translations for player sprites - mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); + if (multiplayer || r_forceplayertranslation) + mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); + else + mobj->Translation = 0; mobj->angle = spawn_angle; mobj->pitch = mobj->roll = 0; From a16c62c069c84889462d6142e5f5203d9398d0df Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 23 Feb 2010 23:40:39 +0000 Subject: [PATCH 07/88] - Pretty sure the minimum FMOD version is 4.22. SVN r2174 (trunk) --- specs/fmod_version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/fmod_version.txt b/specs/fmod_version.txt index f5bd8cf60..a65aec918 100644 --- a/specs/fmod_version.txt +++ b/specs/fmod_version.txt @@ -1 +1 @@ -This version of ZDoom must be compiled with 4.26 or 4.28. +This version of ZDoom must be compiled with any version between 4.22 and 4.28 inclusive. From a1255c059d458774fa1761e28d641772cf248ed1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 24 Feb 2010 02:58:48 +0000 Subject: [PATCH 08/88] - Added -nostartup switch to disable the more graphical startup screens of Heretic, Hexen, and Strife. SVN r2175 (trunk) --- src/win32/st_start.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/win32/st_start.cpp b/src/win32/st_start.cpp index d343fb2b4..f2a62c4c2 100644 --- a/src/win32/st_start.cpp +++ b/src/win32/st_start.cpp @@ -51,6 +51,7 @@ #include "gi.h" #include "w_wad.h" #include "s_sound.h" +#include "m_argv.h" // MACROS ------------------------------------------------------------------ @@ -317,22 +318,25 @@ FStartupScreen *FStartupScreen::CreateInstance(int max_progress) FStartupScreen *scr = NULL; HRESULT hr; - if (gameinfo.gametype == GAME_Hexen) + if (!Args->CheckParm("-nostartup")) { - scr = new FHexenStartupScreen(max_progress, hr); - } - else if (gameinfo.gametype == GAME_Heretic) - { - scr = new FHereticStartupScreen(max_progress, hr); - } - else if (gameinfo.gametype == GAME_Strife) - { - scr = new FStrifeStartupScreen(max_progress, hr); - } - if (scr != NULL && FAILED(hr)) - { - delete scr; - scr = NULL; + if (gameinfo.gametype == GAME_Hexen) + { + scr = new FHexenStartupScreen(max_progress, hr); + } + else if (gameinfo.gametype == GAME_Heretic) + { + scr = new FHereticStartupScreen(max_progress, hr); + } + else if (gameinfo.gametype == GAME_Strife) + { + scr = new FStrifeStartupScreen(max_progress, hr); + } + if (scr != NULL && FAILED(hr)) + { + delete scr; + scr = NULL; + } } if (scr == NULL) { From ad54cfcf94497c1ac12c268b74d4beec3b274b51 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 24 Feb 2010 03:36:42 +0000 Subject: [PATCH 09/88] - Change the log window to use DejaVu Sans instead of Bitstream Vera Sans, because Silverex's X-Chat comes with the former now. Unfortunately, I can't seem to actually set the font when my system default code page is 932, since it wants to use some Kanji- compatible font instead. I wonder if I can still use the Unicode RichEdit control with Windows 9x. (Does it even matter? Windows 9x users make up less than 0.1% of all visitors to zdoom.org these days.) SVN r2176 (trunk) --- src/win32/i_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index af57aaef3..69b1ae749 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -476,7 +476,7 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) format.yHeight = 200; format.crTextColor = RGB(223,223,223); format.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH; - strcpy (format.szFaceName, "Bitstream Vera Sans"); // At least I have it. :p + strcpy(format.szFaceName, "DejaVu Sans"); // At least I have it. :p SendMessage (view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format); ConWindow = view; From 0b2c2e1cb35ea9260807de394baa5e9fd061c60b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 24 Feb 2010 04:17:14 +0000 Subject: [PATCH 10/88] =?UTF-8?q?-=20Use=20the=20Unicode=20RichEdit=20cont?= =?UTF-8?q?rol=20instead=20of=20the=20MBCS=20version,=20so=20as=20to=20enf?= =?UTF-8?q?orce=20the=20use=20=20=20of=20code=20page=201252=20for=20output?= =?UTF-8?q?=20text.=20This=20is=20noticeable,=20for=20example,=20with=20th?= =?UTF-8?q?e=20FMOD=20copyright=20=20=20notice=20where=20the=20copyright?= =?UTF-8?q?=20symbol=20appears=20as=20=EF=BD=A9=20(halfwidth=20katakana=20?= =?UTF-8?q?small=20U)=20with=20code=20page=20932.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SVN r2177 (trunk) --- src/win32/i_main.cpp | 8 ++++---- src/win32/i_system.cpp | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 69b1ae749..b52325972 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -422,7 +422,7 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) TEXTMETRIC tm; HINSTANCE inst = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); DRAWITEMSTRUCT *drawitem; - CHARFORMAT2 format; + CHARFORMAT2W format; switch (msg) { @@ -453,7 +453,7 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) SelectObject (hdc, oldfont); // Create log read-only edit control - view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, RICHEDIT_CLASS, NULL, + view = CreateWindowEx (WS_EX_NOPARENTNOTIFY, "RichEdit20W", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | WS_CLIPSIBLINGS, 0, 0, 0, 0, @@ -476,8 +476,8 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) format.yHeight = 200; format.crTextColor = RGB(223,223,223); format.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH; - strcpy(format.szFaceName, "DejaVu Sans"); // At least I have it. :p - SendMessage (view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format); + wcscpy(format.szFaceName, L"DejaVu Sans"); // At least I have it. :p + SendMessageW(view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format); ConWindow = view; ReleaseDC (hWnd, hdc); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 6320c33f5..36524a093 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -944,7 +944,10 @@ void I_PrintStr(const char *cp) buf[bpos] = 0; if (edit != NULL) { - SendMessage(edit, EM_REPLACESEL, FALSE, (LPARAM)buf); + wchar_t wbuf[countof(buf)]; + MultiByteToWideChar(1252 /* Latin 1 */, 0, buf, bpos, wbuf, countof(wbuf)); + wbuf[bpos] = 0; + SendMessageW(edit, EM_REPLACESEL, FALSE, (LPARAM)wbuf); } if (StdOut != NULL) { From 5523140890d4d8a312a1379a0f67b827176740c2 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 24 Feb 2010 04:23:01 +0000 Subject: [PATCH 11/88] - Explicitly setting the charset for the EM_SETCHARFORMAT message seems to do what I want. SVN r2178 (trunk) --- src/win32/i_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index b52325972..075be9960 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -471,10 +471,11 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) // Setup default font for the log. //SendMessage (view, WM_SETFONT, (WPARAM)GetStockObject (DEFAULT_GUI_FONT), FALSE); format.cbSize = sizeof(format); - format.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_SIZE; + format.dwMask = CFM_BOLD | CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_CHARSET; format.dwEffects = 0; format.yHeight = 200; format.crTextColor = RGB(223,223,223); + format.bCharSet = ANSI_CHARSET; format.bPitchAndFamily = FF_SWISS | VARIABLE_PITCH; wcscpy(format.szFaceName, L"DejaVu Sans"); // At least I have it. :p SendMessageW(view, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format); From 8ecafcc15a8550def390142029e64ac8aa297e21 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 26 Feb 2010 00:08:25 +0000 Subject: [PATCH 12/88] - Added A_CheckSightOrRange, with changes. SVN r2179 (trunk) --- src/thingdef/thingdef_codeptr.cpp | 53 +++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 2 ++ 2 files changed, 55 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 2c8eb2684..f709b06a9 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1897,7 +1897,60 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight) } ACTION_JUMP(jump); +} +//=========================================================================== +// +// A_CheckSightOrRange +// Jumps if this actor is out of range of all players *and* out of sight. +// Useful for maps with many multi-actor special effects. +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) +{ + ACTION_PARAM_START(2); + double range = EvalExpressionF(ParameterIndex+0, self); + ACTION_PARAM_STATE(jump, 1); + + ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! + + range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + { + AActor *camera = players[i].camera; + + // Check distance first, since it's cheaper than checking sight. + double dx = self->x - camera->x; + double dy = self->y - camera->y; + double dz; + fixed_t eyez = (camera->z + camera->height - (camera->height>>2)); // same eye height as P_CheckSight + if (eyez > self->z + self->height) + { + dz = self->z + self->height - eyez; + } + else if (eyez < self->z) + { + dz = self->z - eyez; + } + else + { + dz = 0; + } + if ((dx*dx) + (dy*dy) + (dz*dz) <= range) + { // Within range + return; + } + + // Now check LOS. + if (P_CheckSight(camera, self, true)) + { // Visible + return; + } + } + } + ACTION_JUMP(jump); } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 90a592c3a..1b8be9933 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -270,6 +270,8 @@ ACTOR Actor native //: Thinker 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_CheckSightOrRange(float distance, state label); + States { Spawn: From d530fd7f90cd2e6bd2257eef16b63384055b2771 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 26 Feb 2010 05:34:30 +0000 Subject: [PATCH 13/88] - Added BMF (ByteMap Font) support. This was complicated somewhat by the fact that BMF can specify a character advance separately from the glyph width. GetChar and GetCharWidth now return this value in place of the glyph width. (For non-BMF fonts, these should still return the same values as before.) SVN r2180 (trunk) --- src/v_font.cpp | 410 ++++++++++++++++++++++++++++++++++--------- src/v_font.h | 4 + src/wi_stuff.cpp | 6 +- src/win32/i_main.cpp | 2 +- 4 files changed, 331 insertions(+), 91 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index ead32a8c5..f55e201e7 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -130,7 +130,10 @@ protected: bool rescale, PalEntry *out_palette); 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); }; class FSinglePicFont : public FFont @@ -175,7 +178,7 @@ protected: class FFontChar2 : public FTexture { public: - FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height); + FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); const BYTE *GetColumn (unsigned int column, const Span **spans_out); @@ -399,21 +402,26 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, 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 ('N'-first>=0 && 'N'-first= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) { - SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2; + SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } else { SpaceWidth = 4; } + + FixXMoves(); + BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); delete[] luminosity; @@ -717,6 +725,33 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const return &Ranges[range]; } +//========================================================================== +// +// FFont :: GetCharCode +// +// If the character code is in the font, returns it. If it is not, but it +// is lowercase and has an uppercase variant present, return that. Otherwise +// return -1. +// +//========================================================================== + +int FFont::GetCharCode(int code, bool needpic) const +{ + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL)) + { + return code; + } + if (myislower[code]) + { + code -= 32; + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL)) + { + return code; + } + } + return -1; +} + //========================================================================== // // FFont :: GetChar @@ -725,31 +760,28 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const FTexture *FFont::GetChar (int code, int *const width) const { - if (code < FirstChar || - code > LastChar || - Chars[code - FirstChar].Pic == NULL) + code = GetCharCode(code, false); + int xmove = SpaceWidth; + + if (code >= 0) { - if (myislower[code]) + code -= FirstChar; + xmove = Chars[code].XMove; + if (Chars[code].Pic == NULL) { - code -= 32; - if (code < FirstChar || - code > LastChar || - Chars[code - FirstChar].Pic == NULL) + code = GetCharCode(code + FirstChar, true); + if (code >= 0) { - if (width != NULL) *width = SpaceWidth; - return NULL; + code -= FirstChar; + xmove = Chars[code].XMove; } } - else - { - if (width != NULL) *width = SpaceWidth; - return NULL; - } } - - code -= FirstChar; - if (width != NULL) *width = Chars[code].Pic->GetScaledWidth(); - return Chars[code].Pic; + if (width != NULL) + { + *width = xmove; + } + return (code < 0) ? NULL : Chars[code].Pic; } //========================================================================== @@ -760,27 +792,8 @@ FTexture *FFont::GetChar (int code, int *const width) const int FFont::GetCharWidth (int code) const { - if (code < FirstChar || - code > LastChar || - Chars[code - FirstChar].Pic == NULL) - { - if (myislower[code]) - { - code -= 32; - if (code < FirstChar || - code > LastChar || - Chars[code - FirstChar].Pic == NULL) - { - return SpaceWidth; - } - } - else - { - return SpaceWidth; - } - } - - return Chars[code - FirstChar].Pic->GetScaledWidth(); + code = GetCharCode(code, false); + return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove; } //========================================================================== @@ -858,7 +871,11 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) FMemLump data1 = Wads.ReadLump (lump); const BYTE *data = (const BYTE *)data1.GetMem(); - if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' || + if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) + { + LoadBMF(lump, data); + } + else if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' || (data[3] != '1' && data[3] != '2')) { I_FatalError ("%s is not a recognizable font", name); @@ -1012,6 +1029,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) for (i = 0; i < count; ++i) { int destSize = widths2[i] * FontHeight; + Chars[i].XMove = widths2[i]; if (destSize <= 0) { Chars[i].Pic = NULL; @@ -1045,6 +1063,157 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) delete[] widths2; } +//========================================================================== +// +// FSingleLumpFont :: LoadBMF +// +// Loads a BMF font. The file format is described at +// +// +//========================================================================== + +void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) +{ + const BYTE *chardata; + int numchars, count, totalwidth, nwidth; + int infolen; + int i, chari; + BYTE raw_palette[256*3]; + PalEntry sort_palette[256]; + PalEntry local_palette[256]; + double luminosity[256]; + BYTE identity[256]; + + FontHeight = data[5]; + GlobalKerning = (SBYTE)data[8]; + ActiveColors = data[16]; + SpaceWidth = -1; + nwidth = -1; + + infolen = data[17 + ActiveColors*3]; + chardata = data + 18 + ActiveColors*3 + infolen; + numchars = chardata[0] + 256*chardata[1]; + chardata += 2; + + // Scan for lowest and highest characters defined and total font width. + FirstChar = 256; + LastChar = 0; + totalwidth = 0; + for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2]) + { + if ((chardata[chari+1] == 0 || chardata[chari+2] == 0) && chardata[chari+5] == 0) + { // Don't count empty characters. + continue; + } + if (chardata[chari] < FirstChar) + { + FirstChar = chardata[chari]; + } + if (chardata[chari] > LastChar) + { + LastChar = chardata[chari]; + } + totalwidth += chardata[chari+1]; + } + if (LastChar < FirstChar) + { + I_FatalError("BMF font defines no characters"); + } + count = LastChar - FirstChar + 1; + Chars = new CharData[count]; + for (i = 0; i < count; ++i) + { + Chars[i].Pic = NULL; + Chars[i].XMove = INT_MIN; + } + + // BMF palettes are only six bits per component. Fix that. + for (i = 0; i < ActiveColors*3; ++i) + { + raw_palette[i] = (data[17 + i] << 2) | (data[17 + i] >> 4); + } + + // Sort the palette by increasing brightness + for (i = 0; i < ActiveColors; ++i) + { + PalEntry *pal = &sort_palette[i]; + pal->a = i; // Use alpha part to point back to original entry + pal->r = raw_palette[i*3 + 0]; + pal->g = raw_palette[i*3 + 1]; + pal->b = raw_palette[i*3 + 2]; + } + qsort(sort_palette + 1, ActiveColors - 1, sizeof(PalEntry), BMFCompare); + + // Create the PatchRemap table from the sorted "alpha" values. + PatchRemap = new BYTE[ActiveColors]; + PatchRemap[0] = 0; + for (i = 1; i < ActiveColors; ++i) + { + PatchRemap[sort_palette[i].a] = i; + } + + FixupPalette(identity, luminosity, raw_palette, true, local_palette); + + // 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]) + { + assert(chardata[chari] - FirstChar >= 0); + assert(chardata[chari] - FirstChar < count); + if (chardata[chari] == ' ') + { + SpaceWidth = chardata[chari+5]; + } + else if (chardata[chari] == 'N') + { + nwidth = chardata[chari+5]; + } + Chars[chardata[chari] - FirstChar].XMove = chardata[chari+5]; + if (chardata[chari+1] == 0 || chardata[chari+2] == 0) + { // Empty character: skip it. + continue; + } + Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data), + chardata[chari+1], // width + chardata[chari+2], // height + -(SBYTE)chardata[chari+3], // x offset + -(SBYTE)chardata[chari+4] // y offset + ); + } + + // If the font did not define a space character, determine a suitable space width now. + if (SpaceWidth < 0) + { + if (nwidth >= 0) + { + SpaceWidth = nwidth; + } + else + { + SpaceWidth = totalwidth * 2 / (3 * count); + } + } + + FixXMoves(); + BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette); +} + +//========================================================================== +// +// FSingleLumpFont :: BMFCompare STATIC +// +// Helper to sort BMF palettes. +// +//========================================================================== + +int STACK_ARGS FSingleLumpFont::BMFCompare(const void *a, const void *b) +{ + const PalEntry *pa = (const PalEntry *)a; + const PalEntry *pb = (const PalEntry *)b; + + return (pa->r * 299 + pa->g * 587 + pa->b * 114) - + (pb->r * 299 + pb->g * 587 + pb->b * 114); +} + //========================================================================== // // FSingleLumpFont :: CheckFON1Chars @@ -1069,6 +1238,7 @@ 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; // Advance to next char's data and count the used colors. do @@ -1332,14 +1502,14 @@ FFontChar1::~FFontChar1 () // //========================================================================== -FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height) +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) { UseType = TEX_FontChar; Width = width; Height = height; - TopOffset = 0; - LeftOffset = 0; + LeftOffset = leftofs; + TopOffset = topofs; CalcBitSize (); } @@ -1427,10 +1597,11 @@ void FFontChar2::MakeTexture () FWadLump lump = Wads.OpenLumpNum (SourceLump); int destSize = Width * Height; BYTE max = 255; + bool rle = true; // This is to "fix" bad fonts { - BYTE buff[8]; + BYTE buff[16]; lump.Read (buff, 4); if (buff[3] == '2') { @@ -1438,6 +1609,13 @@ void FFontChar2::MakeTexture () max = buff[6]; lump.Seek (SourcePos - 11, SEEK_CUR); } + else if (buff[3] == 0x1A) + { + lump.Read(buff, 13); + max = buff[12] - 1; + lump.Seek (SourcePos - 17, SEEK_CUR); + rle = false; + } else { lump.Seek (SourcePos - 4, SEEK_CUR); @@ -1452,55 +1630,81 @@ void FFontChar2::MakeTexture () int dest_adv = Height; int dest_rew = destSize - 1; - for (int y = Height; y != 0; --y) + if (rle) { - for (int x = Width; x != 0; ) + for (int y = Height; y != 0; --y) { - if (runlen != 0) + for (int x = Width; x != 0; ) { - BYTE color; - - lump >> color; - *dest_p = MIN (color, max); - if (SourceRemap != NULL) - { - *dest_p = SourceRemap[*dest_p]; - } - dest_p += dest_adv; - x--; - runlen--; - } - else if (setlen != 0) - { - *dest_p = setval; - dest_p += dest_adv; - x--; - setlen--; - } - else - { - SBYTE code; - - lump >> code; - if (code >= 0) - { - runlen = code + 1; - } - else if (code != -128) + if (runlen != 0) { BYTE color; lump >> color; - setlen = (-code) + 1; - setval = MIN (color, max); + color = MIN (color, max); if (SourceRemap != NULL) { - setval = SourceRemap[setval]; + color = SourceRemap[color]; + } + *dest_p = color; + dest_p += dest_adv; + x--; + runlen--; + } + else if (setlen != 0) + { + *dest_p = setval; + dest_p += dest_adv; + x--; + setlen--; + } + else + { + SBYTE code; + + lump >> code; + if (code >= 0) + { + runlen = code + 1; + } + else if (code != -128) + { + BYTE color; + + lump >> color; + setlen = (-code) + 1; + setval = MIN (color, max); + if (SourceRemap != NULL) + { + setval = SourceRemap[setval]; + } } } } + dest_p -= dest_rew; + } + } + else + { + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; --x) + { + BYTE color; + lump >> color; + if (color > max) + { + color = max; + } + if (SourceRemap != NULL) + { + color = SourceRemap[color]; + } + *dest_p = color; + dest_p += dest_adv; + } + dest_p -= dest_rew; } - dest_p -= dest_rew; } if (destSize < 0) @@ -1593,23 +1797,27 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l 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; } } // Special fonts normally don't have all characters so be careful here! - if ('N'-first>=0 && 'N'-first= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) { - SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2; + 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 @@ -1632,6 +1840,36 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l delete[] charlumps; } +//========================================================================== +// +// FFont :: FixXMoves +// +// If a font has gaps in its characters, set the missing characters' +// XMoves to either SpaceWidth or the uppercase variant's XMove. Missing +// XMoves must be initialized with INT_MIN beforehand. +// +//========================================================================== + +void FFont::FixXMoves() +{ + for (int i = 0; i <= LastChar - FirstChar; ++i) + { + if (Chars[i].XMove == INT_MIN) + { + if (myislower[i + FirstChar]) + { + int upper = i - 32; + if (upper >= 0) + { + Chars[i].XMove = Chars[upper].XMove; + continue; + } + } + Chars[i].XMove = SpaceWidth; + } + } +} + //========================================================================== // diff --git a/src/v_font.h b/src/v_font.h index 123b70ff1..4cdba31af 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -94,11 +94,14 @@ public: int StringWidth (const BYTE *str) const; inline int StringWidth (const char *str) const { return StringWidth ((const BYTE *)str); } + int GetCharCode(int code, bool needpic) const; + protected: FFont (); void BuildTranslations (const double *luminosity, const BYTE *identity, const void *ranges, int total_colors, const PalEntry *palette); + void FixXMoves(); static int SimpleTranslation (BYTE *colorsused, BYTE *translation, BYTE *identity, double **luminosity); @@ -110,6 +113,7 @@ protected: struct CharData { FTexture *Pic; + int XMove; } *Chars; int ActiveColors; TArray Ranges; diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index a01d15346..7c07ae783 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1935,15 +1935,13 @@ void WI_loadData(void) } else { - int dummywidth; - star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used + star = BigFont->GetChar('*', NULL); bstar = star; } } else // Strife needs some handling, too! { - int dummywidth; - star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used + star = BigFont->GetChar('*', NULL); bstar = star; } diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 075be9960..026c86637 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1291,7 +1291,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n _CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF); // Use this to break at a specific allocation number. - //_crtBreakAlloc = 3660; + //_crtBreakAlloc = 30055; #endif DoMain (hInstance); From 54b792a97fb70f6cbffbb55c906c163c842a78d3 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 26 Feb 2010 20:19:43 +0000 Subject: [PATCH 14/88] - V_GetFont() needs to check the font header. SVN r2181 (trunk) --- src/v_font.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index f55e201e7..56a7ad811 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -264,12 +264,13 @@ FFont *V_GetFont(const char *name) if (lump != -1) { - char head[3]; + uint32 head; { FWadLump lumpy = Wads.OpenLumpNum (lump); - lumpy.Read (head, 3); + lumpy.Read (&head, 4); } - if (head[0] == 'F' && head[1] == 'O' && head[2] == 'N') + if ((head & MAKE_ID(255,255,255,0)) == MAKE_ID('F','O','N',0) || + head == MAKE_ID(0xE1,0xE6,0xD5,0x1A)) { font = new FSingleLumpFont (name, lump); } From 4e2ca33ea924f408b6730de03e31464229e99f60 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 2 Mar 2010 01:59:16 +0000 Subject: [PATCH 15/88] - Fixed: DrawHudText() needs to verify that the character glyph is valid before accessing its fields. SVN r2182 (trunk) --- src/g_shared/shared_hud.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 87664c204..31dc116a6 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -168,20 +168,23 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, int t { int width; FTexture *texc = font->GetChar(text[i], &width); - int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight(); - screen->DrawChar(font, color, x, y, text[i], - DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans, - DTA_LeftOffset, width/2, DTA_TopOffset, offset, - /*DTA_CenterBottomOffset, 1,*/ TAG_DONE); - x+=zerowidth; + if (texc != NULL) + { + int offset = texc->TopOffset - tex_zero->TopOffset + tex_zero->GetHeight(); + screen->DrawChar(font, color, x, y, text[i], + DTA_KeepRatio, true, + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, trans, + DTA_LeftOffset, width/2, DTA_TopOffset, offset, + /*DTA_CenterBottomOffset, 1,*/ TAG_DONE); + } + x += zerowidth; } } //--------------------------------------------------------------------------- // -// Draws a numberses a fixed widh for all characters +// Draws a number with a fixed width for all digits // //--------------------------------------------------------------------------- From 5da2885d880d94924c667c074baed557a1a90fd7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 2 Mar 2010 04:51:16 +0000 Subject: [PATCH 16/88] - Changed DArgs to use a TArray of FStrings instead of doing its own string vector management in preparation for doing GatherFiles the "right" way. SVN r2183 (trunk) --- src/c_dispatch.cpp | 26 ++++ src/c_dispatch.h | 1 + src/d_main.cpp | 33 +++--- src/g_game.cpp | 10 +- src/g_game.h | 6 +- src/gameconfigfile.cpp | 5 +- src/i_net.cpp | 23 ++-- src/m_argv.cpp | 264 +++++++++++++++++++++++++++-------------- src/m_argv.h | 38 +++--- src/m_misc.cpp | 28 +++-- src/r_things.cpp | 2 +- src/v_video.cpp | 2 +- src/win32/i_system.cpp | 2 +- 13 files changed, 277 insertions(+), 163 deletions(-) diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 5ebe450b6..2fbafd2a9 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -1035,6 +1035,32 @@ FString BuildString (int argc, char **argv) } } +FString BuildString (int argc, FString *argv) +{ + if (argc == 1) + { + return *argv; + } + else + { + FString buf; + int arg; + + for (arg = 0; arg < argc; arg++) + { + if (strchr (argv[arg], ' ')) + { + buf << '"' << argv[arg] << "\" "; + } + else + { + buf << argv[arg] << ' '; + } + } + return buf; + } +} + //=========================================================================== // // SubstituteAliasParams diff --git a/src/c_dispatch.h b/src/c_dispatch.h index cde53996a..fb76f1aee 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -59,6 +59,7 @@ void C_SetAlias (const char *name, const char *cmd); // build a single string out of multiple strings FString BuildString (int argc, char **argv); +FString BuildString (int argc, FString *argv); // Class that can parse command lines class FCommandLine diff --git a/src/d_main.cpp b/src/d_main.cpp index 534f30afe..828545387 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1753,7 +1753,7 @@ static FString CheckGameInfo(TArray & pwads) void D_DoomMain (void) { int p, flags; - char *v; + const char *v; const char *wad; DArgs *execFiles; TArray pwads; @@ -1965,21 +1965,23 @@ void D_DoomMain (void) autostart = true; } - // [RH] Hack to handle +map - p = Args->CheckParm ("+map"); - if (p && p < Args->NumArgs()-1) + // [RH] Hack to handle +map. The standard console command line handler + // won't be able to handle it, so we take it out of the command line and set + // it up like -warp. + FString mapvalue = Args->TakeValue("+map"); + if (mapvalue.IsNotEmpty()) { - if (!P_CheckMapData(Args->GetArg (p+1))) + if (!P_CheckMapData(mapvalue)) { - Printf ("Can't find map %s\n", Args->GetArg (p+1)); + Printf ("Can't find map %s\n", mapvalue.GetChars()); } else { - startmap = Args->GetArg (p + 1); - Args->GetArg (p)[0] = '-'; + startmap = mapvalue; autostart = true; } } + if (devparm) { Printf ("%s", GStrings("D_DEVSTR")); @@ -1998,16 +2000,11 @@ void D_DoomMain (void) // turbo option // [RH] (now a cvar) { - UCVarValue value; - static char one_hundred[] = "100"; - - value.String = Args->CheckValue ("-turbo"); - if (value.String == NULL) - value.String = one_hundred; - else - Printf ("turbo scale: %s%%\n", value.String); - - turbo.SetGenericRepDefault (value, CVAR_String); + double amt; + const char *value = Args->CheckValue("-turbo"); + amt = value != NULL ? atof(value) : 100; + Printf ("turbo scale: %.0f%%\n", amt); + turbo = (float)amt; } v = Args->CheckValue ("-timer"); diff --git a/src/g_game.cpp b/src/g_game.cpp index dc576c2fc..e9a4d4f1e 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2189,18 +2189,14 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf) // // G_RecordDemo // -void G_RecordDemo (char* name) +void G_RecordDemo (const char* name) { - char *v; - usergame = false; strcpy (demoname, name); FixPathSeperator (demoname); DefaultExtension (demoname, ".lmp"); - v = Args->CheckValue ("-maxdemo"); maxdemosize = 0x20000; demobuffer = (BYTE *)M_Malloc (maxdemosize); - demorecording = true; } @@ -2285,7 +2281,7 @@ void G_BeginRecording (const char *startmap) FString defdemoname; -void G_DeferedPlayDemo (char *name) +void G_DeferedPlayDemo (const char *name) { defdemoname = name; gameaction = ga_playdemo; @@ -2513,7 +2509,7 @@ void G_DoPlayDemo (void) // // G_TimeDemo // -void G_TimeDemo (char* name) +void G_TimeDemo (const char* name) { nodrawers = !!Args->CheckParm ("-nodraw"); noblit = !!Args->CheckParm ("-noblit"); diff --git a/src/g_game.h b/src/g_game.h index 72afcd3c5..56f16081b 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -32,7 +32,7 @@ struct PNGHandle; // void G_DeathMatchSpawnPlayer (int playernum); -void G_DeferedPlayDemo (char* demo); +void G_DeferedPlayDemo (const char* demo); // Can be called by the startup code or M_Responder, // calls P_SetupLevel or W_EnterWorld. @@ -44,12 +44,12 @@ void G_DoLoadGame (void); void G_SaveGame (const char *filename, const char *description); // Only called by startup code. -void G_RecordDemo (char* name); +void G_RecordDemo (const char* name); void G_BeginRecording (const char *startmap); void G_PlayDemo (char* name); -void G_TimeDemo (char* name); +void G_TimeDemo (const char* name); bool G_CheckDemoStatus (void); void G_WorldDone (void); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index e9f90a23d..936d4e7f7 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -536,13 +536,14 @@ void FGameConfigFile::ArchiveGlobalData () FString FGameConfigFile::GetConfigPath (bool tryProg) { - char *pathval; + const char *pathval; FString path; pathval = Args->CheckValue ("-config"); if (pathval != NULL) + { return FString(pathval); - + } #ifdef _WIN32 path = NULL; HRESULT hr; diff --git a/src/i_net.cpp b/src/i_net.cpp index 3ff86f7ec..633c75d1a 100644 --- a/src/i_net.cpp +++ b/src/i_net.cpp @@ -338,20 +338,21 @@ void PreSend (const void *buffer, int bufferlen, const sockaddr_in *to) sendto (mysocket, (const char *)buffer, bufferlen, 0, (const sockaddr *)to, sizeof(*to)); } -void BuildAddress (sockaddr_in *address, char *name) +void BuildAddress (sockaddr_in *address, const char *name) { hostent *hostentry; // host information entry u_short port; - char *portpart; + const char *portpart; bool isnamed = false; int curchar; char c; + FString target; address->sin_family = AF_INET; if ( (portpart = strchr (name, ':')) ) { - *portpart = 0; + target = FString(name, portpart - name); port = atoi (portpart + 1); if (!port) { @@ -361,11 +362,12 @@ void BuildAddress (sockaddr_in *address, char *name) } else { + target = name; port = DOOMPORT; } address->sin_port = htons(port); - for (curchar = 0; (c = name[curchar]) ; curchar++) + for (curchar = 0; (c = target[curchar]) ; curchar++) { if ((c < '0' || c > '9') && c != '.') { @@ -376,21 +378,18 @@ void BuildAddress (sockaddr_in *address, char *name) if (!isnamed) { - address->sin_addr.s_addr = inet_addr (name); - Printf ("Node number %d, address %s\n", doomcom.numnodes, name); + address->sin_addr.s_addr = inet_addr (target); + Printf ("Node number %d, address %s\n", doomcom.numnodes, target.GetChars()); } else { - hostentry = gethostbyname (name); + hostentry = gethostbyname (target); if (!hostentry) - I_FatalError ("gethostbyname: couldn't find %s\n%s", name, neterror()); + I_FatalError ("gethostbyname: couldn't find %s\n%s", target.GetChars(), neterror()); address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; Printf ("Node number %d, hostname %s\n", doomcom.numnodes, hostentry->h_name); } - - if (portpart) - *portpart = ':'; } void CloseNetwork (void) @@ -910,7 +909,7 @@ static bool NodesOnSameNetwork() bool I_InitNetwork (void) { int i; - char *v; + const char *v; memset (&doomcom, 0, sizeof(doomcom)); diff --git a/src/m_argv.cpp b/src/m_argv.cpp index 155374c60..b45315eeb 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -38,138 +38,226 @@ IMPLEMENT_CLASS (DArgs) -DArgs::DArgs () +//=========================================================================== +// +// DArgs Default Constructor +// +//=========================================================================== + +DArgs::DArgs() { - m_ArgC = 0; - m_ArgV = NULL; } -DArgs::DArgs (int argc, char **argv) +//=========================================================================== +// +// DArgs Copy Constructor +// +//=========================================================================== + +DArgs::DArgs(const DArgs &other) { - CopyArgs (argc, argv); + Argv = other.Argv; } -DArgs::DArgs (const DArgs &other) +//=========================================================================== +// +// DArgs Argv Constructor +// +//=========================================================================== + +DArgs::DArgs(int argc, char **argv) { - CopyArgs (other.m_ArgC, other.m_ArgV); + SetArgs(argc, argv); } +//=========================================================================== +// +// DArgs Copy Operator +// +//=========================================================================== -DArgs::~DArgs () +DArgs &DArgs::operator=(const DArgs &other) { - FlushArgs (); -} - -DArgs &DArgs::operator= (const DArgs &other) -{ - FlushArgs (); - CopyArgs (other.m_ArgC, other.m_ArgV); + Argv = other.Argv; return *this; } -void DArgs::SetArgs (int argc, char **argv) +//=========================================================================== +// +// DArgs :: SetArgs +// +//=========================================================================== + +void DArgs::SetArgs(int argc, char **argv) { - FlushArgs (); - CopyArgs (argc, argv); + Argv.Resize(argc); + for (int i = 0; i < argc; ++i) + { + Argv[i] = argv[i]; + } } -void DArgs::CopyArgs (int argc, char **argv) -{ - int i; +//=========================================================================== +// +// DArgs :: FlushArgs +// +//=========================================================================== - m_ArgC = argc; - m_ArgV = new char *[argc]; - for (i = 0; i < argc; i++) - m_ArgV[i] = copystring (argv[i]); -} - -void DArgs::FlushArgs () +void DArgs::FlushArgs() { - int i; - - for (i = 0; i < m_ArgC; i++) - delete[] m_ArgV[i]; - delete[] m_ArgV; - m_ArgC = 0; - m_ArgV = NULL; + Argv.Clear(); } +//=========================================================================== +// +// DArgs :: CheckParm // -// CheckParm // Checks for the given parameter in the program's command line arguments. // Returns the argument number (1 to argc-1) or 0 if not present // -int DArgs::CheckParm (const char *check, int start) const -{ - for (int i = start; i < m_ArgC; ++i) - if (!stricmp (check, m_ArgV[i])) - return i; +//=========================================================================== +int DArgs::CheckParm(const char *check, int start) const +{ + for (unsigned i = start; i < Argv.Size(); ++i) + { + if (0 == stricmp(check, Argv[i])) + { + return i; + } + } return 0; } -char *DArgs::CheckValue (const char *check) const -{ - int i = CheckParm (check); +//=========================================================================== +// +// DArgs :: CheckValue +// +// Like CheckParm, but it also checks that the parameter has a value after +// it and returns that or NULL if not present. +// +//=========================================================================== - if (i > 0 && i < m_ArgC - 1) - return m_ArgV[i+1][0] != '+' && m_ArgV[i+1][0] != '-' ? m_ArgV[i+1] : NULL; - else - return NULL; -} - -char *DArgs::GetArg (int arg) const +const char *DArgs::CheckValue(const char *check) const { - if (arg >= 0 && arg < m_ArgC) - return m_ArgV[arg]; - else - return NULL; -} + int i = CheckParm(check); -char **DArgs::GetArgList (int arg) const -{ - if (arg >= 0 && arg < m_ArgC) - return &m_ArgV[arg]; - else - return NULL; -} - -int DArgs::NumArgs () const -{ - return m_ArgC; -} - -void DArgs::AppendArg (const char *arg) -{ - char **temp = new char *[m_ArgC + 1]; - if (m_ArgV) + if (i > 0 && i < (int)Argv.Size() - 1) { - memcpy (temp, m_ArgV, sizeof(*m_ArgV) * m_ArgC); - delete[] m_ArgV; + i++; + return Argv[i][0] != '+' && Argv[i][0] != '-' ? Argv[i].GetChars() : NULL; + } + else + { + return NULL; } - temp[m_ArgC] = copystring (arg); - m_ArgV = temp; - m_ArgC++; } +//=========================================================================== +// +// DArgs :: TakeValue +// +// Like CheckValue, except it also removes the parameter and its argument +// (if present) from argv. +// +//=========================================================================== + +FString DArgs::TakeValue(const char *check) +{ + int i = CheckParm(check); + FString out; + + if (i > 0 && i < (int)Argv.Size() - 1 && + Argv[i+1][0] != '+' && Argv[i+1][0] != '-') + { + out = Argv[i+1]; + Argv.Delete(i, 2); // Delete the parm and its value. + } + else + { + Argv.Delete(i); // Just delete the parm, since it has no value. + } + return out; +} + +//=========================================================================== +// +// DArgs :: GetArg +// +// Gets the argument at a particular position. +// +//=========================================================================== + +const char *DArgs::GetArg(int arg) const +{ + return ((unsigned)arg < Argv.Size()) ? Argv[arg].GetChars() : NULL; + return Argv[arg]; +} + +//=========================================================================== +// +// DArgs :: GetArgList +// +// Returns a pointer to the FString at a particular position. +// +//=========================================================================== + +FString *DArgs::GetArgList(int arg) const +{ + return ((unsigned)arg < Argv.Size()) ? &Argv[arg] : NULL; +} + +//=========================================================================== +// +// DArgs :: NumArgs +// +//=========================================================================== + +int DArgs::NumArgs() const +{ + return (int)Argv.Size(); +} + +//=========================================================================== +// +// DArgs :: AppendArg +// +// Adds another argument to argv. Invalidates any previous results from +// GetArgList(). +// +//=========================================================================== + +void DArgs::AppendArg(FString arg) +{ + Argv.Push(arg); +} + +//=========================================================================== +// +// DArgs :: GatherFiles +// +//=========================================================================== + DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool acceptNoExt) const { DArgs *out = new DArgs; - int i; + unsigned int i; size_t extlen = strlen (extension); if (extlen > 0) { - for (i = 1; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; i++) + for (i = 1; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; i++) { - size_t len = strlen (m_ArgV[i]); - if (len >= extlen && stricmp (m_ArgV[i] + len - extlen, extension) == 0) - out->AppendArg (m_ArgV[i]); + size_t len = Argv[i].Len(); + if (len >= extlen && stricmp(&Argv[i][0] + len - extlen, extension) == 0) + { + out->AppendArg(Argv[i]); + } else if (acceptNoExt) { - const char *src = m_ArgV[i] + len - 1; + const char *src = &Argv[i][0] + len - 1; - while (src != m_ArgV[i] && *src != '/' + while (src != Argv[i] && *src != '/' #ifdef _WIN32 && *src != '\\' #endif @@ -179,7 +267,7 @@ DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool accept goto morefor; // it has an extension src--; } - out->AppendArg (m_ArgV[i]); + out->AppendArg(Argv[i]); morefor: ; } @@ -190,8 +278,8 @@ morefor: i = 1; while (0 != (i = CheckParm (param, i))) { - for (++i; i < m_ArgC && *m_ArgV[i] != '-' && *m_ArgV[i] != '+'; ++i) - out->AppendArg (m_ArgV[i]); + for (++i; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; ++i) + out->Argv.Push(Argv[i]); } } return out; diff --git a/src/m_argv.h b/src/m_argv.h index b0d44076a..83f86a517 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -35,40 +35,38 @@ #define __M_ARGV_H__ #include "dobject.h" +#include "zstring.h" // // MISC // class DArgs : public DObject { - DECLARE_CLASS (DArgs, DObject) + DECLARE_CLASS(DArgs, DObject) public: - DArgs (); - DArgs (const DArgs &args); - DArgs (int argc, char **argv); - ~DArgs (); + DArgs(); + DArgs(const DArgs &args); + DArgs(int argc, char **argv); - DArgs &operator= (const DArgs &other); + DArgs &operator=(const DArgs &other); - void AppendArg (const char *arg); - void SetArgs (int argc, char **argv); - DArgs *GatherFiles (const char *param, const char *extension, bool acceptNoExt) const; - void SetArg (int argnum, const char *arg); + void AppendArg(FString arg); + void SetArgs(int argc, char **argv); + DArgs *GatherFiles(const char *param, const char *extension, bool acceptNoExt) const; + void SetArg(int argnum, const char *arg); // Returns the position of the given parameter // in the arg list (0 if not found). - int CheckParm (const char *check, int start=1) const; - char *CheckValue (const char *check) const; - char *GetArg (int arg) const; - char **GetArgList (int arg) const; - int NumArgs () const; - void FlushArgs (); + int CheckParm(const char *check, int start=1) const; + const char *CheckValue(const char *check) const; + const char *GetArg(int arg) const; + FString *GetArgList(int arg) const; + FString TakeValue(const char *check); + int NumArgs() const; + void FlushArgs(); private: - int m_ArgC; - char **m_ArgV; - - void CopyArgs (int argc, char **argv); + TArray Argv; }; extern DArgs *Args; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index e973a4ca9..c828a965a 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -159,7 +159,6 @@ void M_FindResponseFile (void) char **argv; char *file; int argc; - int argcinresp; FILE *handle; int size; long argsize; @@ -183,23 +182,32 @@ void M_FindResponseFile (void) file[size] = 0; fclose (handle); - argsize = ParseCommandLine (file, &argcinresp, NULL); - argc = argcinresp + Args->NumArgs() - 1; + argsize = ParseCommandLine (file, &argc, NULL); + argc = Args->NumArgs() - 1; if (argc != 0) { argv = (char **)M_Malloc (argc*sizeof(char *) + argsize); - argv[i] = (char *)argv + argc*sizeof(char *); - ParseCommandLine (file, NULL, argv+i); + argv[0] = (char *)argv + argc*sizeof(char *); + ParseCommandLine (file, NULL, argv); + // Create a new argument vector + DArgs *newargs = new DArgs; + + // Copy parameters before response file. for (index = 0; index < i; ++index) - argv[index] = Args->GetArg (index); + newargs->AppendArg(Args->GetArg(index)); - for (index = i + 1, i += argcinresp; index < Args->NumArgs (); ++index) - argv[i++] = Args->GetArg (index); + // Copy parameters from response file. + for (index = 0; index < argc; ++i) + newargs->AppendArg(argv[index]); - Args->Destroy(); - Args = new DArgs(i, argv); + // Copy parameters after response file. + for (index = i + 1, i = newargs->NumArgs(); index < Args->NumArgs(); ++index) + newargs->AppendArg(Args->GetArg(index)); + + // Use the new argument vector as the global Args object. + Args = newargs; } delete[] file; diff --git a/src/r_things.cpp b/src/r_things.cpp index a2f18de5f..5815ca484 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2345,7 +2345,7 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE ) void R_InitParticles () { - char *i; + const char *i; if ((i = Args->CheckValue ("-numparticles"))) NumParticles = atoi (i); diff --git a/src/v_video.cpp b/src/v_video.cpp index f6e0eb546..24ed1a562 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1523,7 +1523,7 @@ CCMD (vid_setmode) void V_Init (void) { - char *i; + const char *i; int width, height, bits; atterm (V_Shutdown); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 36524a093..e99ac91b3 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -233,7 +233,7 @@ static void I_SelectTimer() if (NewTicArrived) { UINT delay; - char *cmdDelay; + const char *cmdDelay; cmdDelay = Args->CheckValue("-timerdelay"); delay = 0; From dfde55d2496432ea11a8b9b91dca6c93e14801aa Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 3 Mar 2010 04:29:40 +0000 Subject: [PATCH 17/88] - Everything on the command line before the first switch with an unrecognized switch is now added to -file. This was previously restricted to only .wad, .zip, .pk3, and .txt. - You can now pass -file/-deh/-bex more than once on the command line, and they will all have effect. SVN r2184 (trunk) --- src/d_main.cpp | 103 +++++++++++---------------- src/m_argv.cpp | 187 +++++++++++++++++++++++++++++++++++++------------ src/m_argv.h | 10 +-- 3 files changed, 190 insertions(+), 110 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 828545387..f75540983 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -129,7 +129,7 @@ void D_CheckNetGame (); void D_ProcessEvents (); void G_BuildTiccmd (ticcmd_t* cmd); void D_DoAdvanceDemo (); -void D_AddWildFile (const char *pattern); +void D_AddWildFile (TArray &wadfiles, const char *pattern); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- @@ -1478,27 +1478,22 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf // //========================================================================== -bool ConsiderPatches (const char *arg, const char *ext) +bool ConsiderPatches (const char *arg) { - bool noDef = false; - DArgs *files = Args->GatherFiles (arg, ext, false); + int i, argc; + FString *args; + const char *f; - if (files->NumArgs() > 0) + argc = Args->CheckParmList(arg, &args); + for (i = 0; i < argc; ++i) { - int i; - const char *f; - - for (i = 0; i < files->NumArgs(); ++i) + if ( (f = BaseFileSearch(args[i], ".deh")) || + (f = BaseFileSearch(args[i], ".bex")) ) { - if ( (f = BaseFileSearch (files->GetArg (i), ".deh")) ) - D_LoadDehFile(f); - else if ( (f = BaseFileSearch (files->GetArg (i), ".bex")) ) - D_LoadDehFile(f); + D_LoadDehFile(f); } - noDef = true; } - files->Destroy(); - return noDef; + return argc > 0; } //========================================================================== @@ -1591,40 +1586,18 @@ void D_MultiExec (DArgs *list, bool usePullin) static void GetCmdLineFiles(TArray &wadfiles) { - DArgs *files = Args->GatherFiles ("-file", ".wad", true); - DArgs *files1 = Args->GatherFiles (NULL, ".zip", false); - DArgs *files2 = Args->GatherFiles (NULL, ".pk3", false); - DArgs *files3 = Args->GatherFiles (NULL, ".txt", false); - if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0) - { - // Check for -file in shareware - if (gameinfo.flags & GI_SHAREWARE) - { - I_FatalError ("You cannot -file with the shareware version. Register!"); - } + FString *args; + int i, argc; - // the files gathered are wadfile/lump names - for (int i = 0; i < files->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files->GetArg (i)); - } - for (int i = 0; i < files1->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files1->GetArg (i)); - } - for (int i = 0; i < files2->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files2->GetArg (i)); - } - for (int i = 0; i < files3->NumArgs(); i++) - { - D_AddWildFile (wadfiles, files3->GetArg (i)); - } + argc = Args->CheckParmList("-file", &args); + if ((gameinfo.flags & GI_SHAREWARE) && argc > 0) + { + I_FatalError ("You cannot -file with the shareware version. Register!"); + } + for (i = 0; i < argc; ++i) + { + D_AddWildFile(wadfiles, args[i]); } - files->Destroy(); - files1->Destroy(); - files2->Destroy(); - files3->Destroy(); } static void CopyFiles(TArray &to, TArray &from) @@ -1757,6 +1730,8 @@ void D_DoomMain (void) const char *wad; DArgs *execFiles; TArray pwads; + FString *args; + int argcount; // Set the FPU precision to 53 significant bits. This is the default // for Visual C++, but not for GCC, so some slight math variances @@ -1775,6 +1750,13 @@ void D_DoomMain (void) #endif #endif + // Combine different file parameters with their pre-switch bits. + Args->CollectFiles("-deh", ".deh"); + Args->CollectFiles("-bex", ".bex"); + Args->CollectFiles("-exec", ".cfg"); + Args->CollectFiles("-playdemo", ".lmp"); + Args->CollectFiles("-file", NULL); // anythnig left goes after -file + PClass::StaticInit (); atterm (C_DeinitConsole); @@ -1859,12 +1841,10 @@ void D_DoomMain (void) execFiles = new DArgs; GameConfig->AddAutoexec (execFiles, GameNames[gameinfo.gametype]); D_MultiExec (execFiles, true); - execFiles->Destroy(); // Run .cfg files at the start of the command line. - execFiles = Args->GatherFiles (NULL, ".cfg", false); + execFiles = Args->GatherFiles ("-exec"); D_MultiExec (execFiles, true); - execFiles->Destroy(); C_ExecCmdLineParams (); // [RH] do all +set commands on the command line @@ -1999,10 +1979,10 @@ void D_DoomMain (void) #endif // turbo option // [RH] (now a cvar) + v = Args->CheckValue("-turbo"); + if (v != NULL) { - double amt; - const char *value = Args->CheckValue("-turbo"); - amt = value != NULL ? atof(value) : 100; + double amt = atof(v); Printf ("turbo scale: %.0f%%\n", amt); turbo = (float)amt; } @@ -2082,7 +2062,7 @@ void D_DoomMain (void) // If there are none, try adding any in the config file. // Note that the command line overrides defaults from the config. - if ((ConsiderPatches("-deh", ".deh") | ConsiderPatches("-bex", ".bex")) == 0 && + if ((ConsiderPatches("-deh") | ConsiderPatches("-bex")) == 0 && gameinfo.gametype == GAME_Doom && GameConfig->SetSection ("Doom.DefaultDehacked")) { const char *key; @@ -2120,10 +2100,10 @@ void D_DoomMain (void) } //Added by MC: - DArgs *bots = Args->GatherFiles("-bots", "", false); - for (p = 0; p < bots->NumArgs(); ++p) + argcount = Args->CheckParmList("-bots", &args); + for (p = 0; p < argcount; ++p) { - bglobal.getspawned.Push(bots->GetArg(p)); + bglobal.getspawned.Push(args[p]); } bglobal.spawn_tries = 0; bglobal.wanted_botnum = bglobal.getspawned.Size(); @@ -2173,14 +2153,13 @@ void D_DoomMain (void) V_Init2(); - DArgs *files = Args->GatherFiles ("-playdemo", ".lmp", false); - if (files->NumArgs() > 0) + v = Args->CheckValue("-playdemo"); + if (v != NULL) { singledemo = true; // quit after one demo - G_DeferedPlayDemo (files->GetArg (0)); + G_DeferedPlayDemo (v); D_DoomLoop (); // never returns } - files->Destroy(); v = Args->CheckValue ("-timedemo"); if (v) diff --git a/src/m_argv.cpp b/src/m_argv.cpp index b45315eeb..5dbdc4d3d 100644 --- a/src/m_argv.cpp +++ b/src/m_argv.cpp @@ -70,6 +70,19 @@ DArgs::DArgs(int argc, char **argv) SetArgs(argc, argv); } +//=========================================================================== +// +// DArgs String Argv Constructor +// +//=========================================================================== + +DArgs::DArgs(int argc, FString *argv) +{ + AppendArgs(argc, argv); +} + + + //=========================================================================== // // DArgs Copy Operator @@ -129,6 +142,41 @@ int DArgs::CheckParm(const char *check, int start) const return 0; } +//=========================================================================== +// +// DArgs :: CheckParmList +// +// Returns the number of arguments after the parameter (if found) and also +// returns a pointer to the first argument. +// +//=========================================================================== + +int DArgs::CheckParmList(const char *check, FString **strings, int start) const +{ + unsigned int i, parmat = CheckParm(check, start); + + if (parmat == 0) + { + if (strings != NULL) + { + *strings = NULL; + } + return 0; + } + for (i = ++parmat; i < Argv.Size(); ++i) + { + if (Argv[i][0] == '-' || Argv[i][1] == '+') + { + break; + } + } + if (strings != NULL) + { + *strings = &Argv[parmat]; + } + return i - parmat; +} + //=========================================================================== // // DArgs :: CheckValue @@ -167,15 +215,17 @@ FString DArgs::TakeValue(const char *check) int i = CheckParm(check); FString out; - if (i > 0 && i < (int)Argv.Size() - 1 && - Argv[i+1][0] != '+' && Argv[i+1][0] != '-') + if (i > 0 && i < (int)Argv.Size()) { - out = Argv[i+1]; - Argv.Delete(i, 2); // Delete the parm and its value. - } - else - { - Argv.Delete(i); // Just delete the parm, since it has no value. + if (i < (int)Argv.Size() - 1 && Argv[i+1][0] != '+' && Argv[i+1][0] != '-') + { + out = Argv[i+1]; + Argv.Delete(i, 2); // Delete the parm and its value. + } + else + { + Argv.Delete(i); // Just delete the parm, since it has no value. + } } return out; } @@ -234,53 +284,102 @@ void DArgs::AppendArg(FString arg) //=========================================================================== // -// DArgs :: GatherFiles +// DArgs :: AppendArgs +// +// Adds an array of FStrings to argv. // //=========================================================================== -DArgs *DArgs::GatherFiles (const char *param, const char *extension, bool acceptNoExt) const +void DArgs::AppendArgs(int argc, const FString *argv) { + if (argv != NULL && argc > 0) + { + Argv.Grow(argc); + for (int i = 0; i < argc; ++i) + { + Argv.Push(argv[i]); + } + } +} + +//=========================================================================== +// +// DArgs :: CollectFiles +// +// Takes all arguments after any instance of -param and any arguments before +// all switches that end in .extension and combines them into a single +// -switch block at the end of the arguments. If extension is NULL, then +// every parameter before the first switch is added after this -param. +// +//=========================================================================== + +void DArgs::CollectFiles(const char *param, const char *extension) +{ + TArray work; DArgs *out = new DArgs; unsigned int i; - size_t extlen = strlen (extension); + size_t extlen = extension == NULL ? 0 : strlen(extension); - if (extlen > 0) + // Step 1: Find suitable arguments before the first switch. + i = 1; + while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+') { - for (i = 1; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; i++) - { + bool useit; + + if (extlen > 0) + { // Argument's extension must match. size_t len = Argv[i].Len(); - if (len >= extlen && stricmp(&Argv[i][0] + len - extlen, extension) == 0) - { - out->AppendArg(Argv[i]); - } - else if (acceptNoExt) - { - const char *src = &Argv[i][0] + len - 1; - - while (src != Argv[i] && *src != '/' - #ifdef _WIN32 - && *src != '\\' - #endif - ) - { - if (*src == '.') - goto morefor; // it has an extension - src--; - } - out->AppendArg(Argv[i]); -morefor: - ; - } + useit = (len >= extlen && stricmp(&Argv[i][len - extlen], extension) == 0); } - } - if (param != NULL) - { - i = 1; - while (0 != (i = CheckParm (param, i))) + else + { // Anything will do so long as it's before the first switch. + useit = true; + } + if (useit) { - for (++i; i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+'; ++i) - out->Argv.Push(Argv[i]); + work.Push(Argv[i]); + Argv.Delete(i); + } + else + { + i++; } } - return out; + + // Step 2: Find each occurence of -param and add its arguments to work. + while ((i = CheckParm(param, i)) > 0) + { + Argv.Delete(i); + while (i < Argv.Size() && Argv[i][0] != '-' && Argv[i][0] != '+') + { + work.Push(Argv[i]); + Argv.Delete(i); + } + } + + // Step 3: Add work back to Argv, as long as it's non-empty. + if (work.Size() > 0) + { + Argv.Push(param); + AppendArgs(work.Size(), &work[0]); + } +} + +//=========================================================================== +// +// DArgs :: GatherFiles +// +// Returns all the arguments after the first instance of -param. If you want +// to combine more than one or get switchless stuff included, you need to +// call CollectFiles first. +// +//=========================================================================== + +DArgs *DArgs::GatherFiles(const char *param) const +{ + FString *files; + int filecount; + + filecount = CheckParmList(param, &files); + return new DArgs(filecount, files); } diff --git a/src/m_argv.h b/src/m_argv.h index 83f86a517..b2a432edb 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -47,17 +47,19 @@ public: DArgs(); DArgs(const DArgs &args); DArgs(int argc, char **argv); + DArgs(int argc, FString *argv); DArgs &operator=(const DArgs &other); void AppendArg(FString arg); + void AppendArgs(int argc, const FString *argv); void SetArgs(int argc, char **argv); - DArgs *GatherFiles(const char *param, const char *extension, bool acceptNoExt) const; + void CollectFiles(const char *param, const char *extension); + DArgs *GatherFiles(const char *param) const; void SetArg(int argnum, const char *arg); - // Returns the position of the given parameter - // in the arg list (0 if not found). - int CheckParm(const char *check, int start=1) const; + int CheckParm(const char *check, int start=1) const; // Returns the position of the given parameter in the arg list (0 if not found). + int CheckParmList(const char *check, FString **strings, int start=1) const; const char *CheckValue(const char *check) const; const char *GetArg(int arg) const; FString *GetArgList(int arg) const; From 0ebace48833a7ba4a3ae7462727486d28d37e791 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 4 Mar 2010 02:17:34 +0000 Subject: [PATCH 18/88] - Add the game log to the crash report. I don't know why I didn't think to do this sooner. Since we're already sending everything to a rich edit control hidden in the background, we can just grab its contents for the report. - Use code page 1252 when previewing text files in the crash dialog. SVN r2185 (trunk) --- src/win32/i_crash.cpp | 97 +++++++++++++++++++++++++++++++++++++------ src/win32/i_main.cpp | 8 ++-- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index 5996be87a..727e4b7ed 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -503,6 +503,71 @@ void __cdecl Writef (HANDLE file, const char *format, ...) WriteFile (file, buffer, len, &len, NULL); } +//========================================================================== +// +// WriteLogFileStreamer +// +// The callback function to stream a Rich Edit's contents to a file. +// +//========================================================================== + +static DWORD CALLBACK WriteLogFileStreamer(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG *pcb) +{ + DWORD didwrite; + LONG p, pp; + + // Replace gray foreground color with black. + static const char *badfg = "\\red223\\green223\\blue223;"; + // 4321098 765432109 876543210 + // 2 1 0 + for (p = pp = 0; p < cb; ++p) + { + if (buffer[p] == badfg[pp]) + { + ++pp; + if (pp == 25) + { + buffer[p - 1] = buffer[p - 2] = buffer[p - 3] = + buffer[p - 9] = buffer[p -10] = buffer[p -11] = + buffer[p -18] = buffer[p -19] = buffer[p -20] = '0'; + break; + } + } + else + { + pp = 0; + } + } + + if (!WriteFile((HANDLE)cookie, buffer, cb, &didwrite, NULL)) + { + return 1; + } + *pcb = didwrite; + return 0; +} + +//========================================================================== +// +// WriteLogFile +// +// Writes the contents of a Rich Edit control to a file. +// +//========================================================================== + +HANDLE WriteLogFile(HWND edit) +{ + HANDLE file; + + file = CreateTempFile(); + if (file != INVALID_HANDLE_VALUE) + { + EDITSTREAM streamer = { (DWORD_PTR)file, 0, WriteLogFileStreamer }; + SendMessage(edit, EM_STREAMOUT, SF_RTF, (LPARAM)&streamer); + } + return file; +} + //========================================================================== // // CreateCrashLog @@ -511,7 +576,7 @@ void __cdecl Writef (HANDLE file, const char *format, ...) // //========================================================================== -void CreateCrashLog (char *custominfo, DWORD customsize) +void CreateCrashLog (char *custominfo, DWORD customsize, HWND richlog) { // Do not collect information more than once. if (NumFiles != 0) @@ -561,6 +626,10 @@ void CreateCrashLog (char *custominfo, DWORD customsize) AddFile (file, "local.txt"); } } + if (richlog != NULL) + { + AddFile (WriteLogFile(richlog), "log.rtf"); + } CloseHandle (DbgProcess); } @@ -1984,7 +2053,6 @@ static INT_PTR CALLBACK CrashDlgProc (HWND hDlg, UINT message, WPARAM wParam, LP static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - HGDIOBJ font; HWND ctrl; int i, j; @@ -1996,15 +2064,9 @@ static INT_PTR CALLBACK DetailsDlgProc (HWND hDlg, UINT message, WPARAM wParam, pEnableThemeDialogTexture (hDlg, ETDT_ENABLETAB); } - // Set up the file contents display: Use a fixed width font, - // no undos. The control's userdata stores the index of the - // file currently displayed. + // Set up the file contents display: No undos. The control's + // userdata stores the index of the file currently displayed. ctrl = GetDlgItem (hDlg, IDC_CRASHFILECONTENTS); - font = GetStockObject (ANSI_FIXED_FONT); - if (font != INVALID_HANDLE_VALUE) - { - SendMessage (ctrl, WM_SETFONT, (WPARAM)font, FALSE); - } SendMessage (ctrl, EM_SETUNDOLIMIT, 0, 0); SetWindowLongPtr (ctrl, GWLP_USERDATA, -1); SetEditControl (ctrl, GetDlgItem(hDlg, IDC_CRASHFILESIZE), 0); @@ -2178,6 +2240,8 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum) EDITSTREAM stream; DWORD size; POINT pt = { 0, 0 }; + const char *rtf = NULL; + HGDIOBJ font; // Don't refresh the control if it's already showing the file we want. if (GetWindowLongPtr (edit, GWLP_USERDATA) == filenum) @@ -2201,10 +2265,19 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum) SetFilePointer (TarFiles[filenum].File, 0, NULL, FILE_BEGIN); SendMessage (edit, EM_SETSCROLLPOS, 0, (LPARAM)&pt); + // Set the font now, in case log.rtf was previously viewed, because + // that file changes it. + font = GetStockObject (ANSI_FIXED_FONT); + if (font != INVALID_HANDLE_VALUE) + { + SendMessage (edit, WM_SETFONT, (WPARAM)font, FALSE); + } + // Text files are streamed in as-is. // Binary files are streamed in as color-coded hex dumps. stream.dwError = 0; - if (strstr (TarFiles[filenum].Filename, ".txt") != NULL) + if (strstr (TarFiles[filenum].Filename, ".txt") != NULL || + (rtf = strstr (TarFiles[filenum].Filename, ".rtf")) != NULL) { CHARFORMAT beBlack; @@ -2215,7 +2288,7 @@ static void SetEditControl (HWND edit, HWND sizedisplay, int filenum) SendMessage (edit, EM_SETCHARFORMAT, 0, (LPARAM)&beBlack); stream.dwCookie = (DWORD_PTR)TarFiles[filenum].File; stream.pfnCallback = StreamEditText; - SendMessage (edit, EM_STREAMIN, SF_TEXT, (LPARAM)&stream); + SendMessage (edit, EM_STREAMIN, rtf ? SF_RTF : SF_TEXT | SF_USECODEPAGE | (1252 << 16), (LPARAM)&stream); } else { diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 026c86637..a76380bda 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -105,7 +105,7 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); -void CreateCrashLog (char *custominfo, DWORD customsize); +void CreateCrashLog (char *custominfo, DWORD customsize, HWND richedit); void DisplayCrashLog (); extern BYTE *ST_Util_BitsForBitmap (BITMAPINFO *bitmap_info); @@ -1176,7 +1176,7 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info) CrashPointers = *info; DoomSpecificInfo (custominfo, 16384); - CreateCrashLog (custominfo, (DWORD)strlen(custominfo)); + CreateCrashLog (custominfo, (DWORD)strlen(custominfo), ConWindow); // If the main thread crashed, then make it clean up after itself. // Otherwise, put the crashing thread to sleep and signal the main thread to clean up. @@ -1248,7 +1248,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n *(int *)0 = 0; } __except(CrashPointers = *GetExceptionInformation(), - CreateCrashLog (__argv[1], 9), EXCEPTION_EXECUTE_HANDLER) + CreateCrashLog (__argv[1], 9, NULL), EXCEPTION_EXECUTE_HANDLER) { } DisplayCrashLog (); @@ -1261,7 +1261,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n infiniterecursion(1); } __except(CrashPointers = *GetExceptionInformation(), - CreateCrashLog (__argv[1], 14), EXCEPTION_EXECUTE_HANDLER) + CreateCrashLog (__argv[1], 14, NULL), EXCEPTION_EXECUTE_HANDLER) { } DisplayCrashLog (); From ac042a7e93d0ccc68fad95d008e393e4754fe140 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 4 Mar 2010 04:45:48 +0000 Subject: [PATCH 19/88] - The console separator bars now get converted to something printable in Unicode for the log. - Fixed: Only the last line of multi-line log output received Unicode treatment. SVN r2186 (trunk) --- src/win32/i_system.cpp | 76 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index e99ac91b3..04e2694d6 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -832,6 +832,74 @@ void I_SetIWADInfo(const IWADInfo *info) LayoutMainWindow(Window, NULL); } +//========================================================================== +// +// ToEditControl +// +// Converts string to Unicode and inserts it into the control. +// +//========================================================================== + +void ToEditControl(HWND edit, const char *buf, wchar_t *wbuf, int bpos) +{ + // Let's just do this ourself. It's not hard, and we can compensate for + // special console characters at the same time. +#if 0 + MultiByteToWideChar(1252 /* Western */, 0, buf, bpos, wbuf, countof(wbuf)); + wbuf[bpos] = 0; +#else + static wchar_t notlatin1[32] = // code points 0x80-0x9F + { + 0x20AC, // Euro sign + 0x0081, // Undefined + 0x201A, // Single low-9 quotation mark + 0x0192, // Latin small letter f with hook + 0x201E, // Double low-9 quotation mark + 0x2026, // Horizontal ellipsis + 0x2020, // Dagger + 0x2021, // Double dagger + 0x02C6, // Modifier letter circumflex accent + 0x2030, // Per mille sign + 0x0160, // Latin capital letter S with caron + 0x2039, // Single left-pointing angle quotation mark + 0x0152, // Latin capital ligature OE + 0x008D, // Undefined + 0x017D, // Latin capital letter Z with caron + 0x008F, // Undefined + 0x0090, // Undefined + 0x2018, // Left single quotation mark + 0x2019, // Right single quotation mark + 0x201C, // Left double quotation mark + 0x201D, // Right double quotation mark + 0x2022, // Bullet + 0x2013, // En dash + 0x2014, // Em dash + 0x02DC, // Small tilde + 0x2122, // Trade mark sign + 0x0161, // Latin small letter s with caron + 0x203A, // Single right-pointing angle quotation mark + 0x0153, // Latin small ligature oe + 0x009D, // Undefined + 0x017E, // Latin small letter z with caron + 0x0178 // Latin capital letter Y with diaeresis + }; + for (int i = 0; i <= bpos; ++i) + { + wchar_t code = (BYTE)buf[i]; + if (code >= 0x1D && code <= 0x1F) + { // The bar characters, most commonly used to indicate map changes + code = 0x2550; // Box Drawings Double Horizontal + } + else if (code >= 0x80 && code <= 0x9F) + { + code = notlatin1[code - 0x80]; + } + wbuf[i] = code; + } +#endif + SendMessageW(edit, EM_REPLACESEL, FALSE, (LPARAM)wbuf); +} + //========================================================================== // // I_PrintStr @@ -848,6 +916,7 @@ void I_PrintStr(const char *cp) HWND edit = ConWindow; char buf[256]; + wchar_t wbuf[countof(buf)]; int bpos = 0; CHARRANGE selection; CHARRANGE endselection; @@ -877,7 +946,7 @@ void I_PrintStr(const char *cp) buf[bpos] = 0; if (edit != NULL) { - SendMessage(edit, EM_REPLACESEL, FALSE, (LPARAM)buf); + ToEditControl(edit, buf, wbuf, bpos); } if (StdOut != NULL) { @@ -944,10 +1013,7 @@ void I_PrintStr(const char *cp) buf[bpos] = 0; if (edit != NULL) { - wchar_t wbuf[countof(buf)]; - MultiByteToWideChar(1252 /* Latin 1 */, 0, buf, bpos, wbuf, countof(wbuf)); - wbuf[bpos] = 0; - SendMessageW(edit, EM_REPLACESEL, FALSE, (LPARAM)wbuf); + ToEditControl(edit, buf, wbuf, bpos); } if (StdOut != NULL) { From 61865b30bed35559d80a46dea9cae0eaf97f5b6f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 4 Mar 2010 08:24:49 +0000 Subject: [PATCH 20/88] - Yet another piece of essentially broken code that has to go back in because some people had to abuse it: Reinstated Doom's original code that made projectiles with the MF_NOCLIP flag set continue to exist even though the movement itself was never properly handled. Fortunately the game mode check formerly associated with this can be removed because none of the other games have any projectiles using MF_NOCLIP so at least it's no longer restricted to Doom... SVN r2187 (trunk) --- src/p_mobj.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index efbe88837..bf858a165 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2237,12 +2237,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) // teleported the actor so it is no longer below the floor. if (mo->z <= mo->floorz) { - // old code for boss cube disabled - //if ((mo->flags & MF_MISSILE) && (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) - - // We can't remove this completely because it was abused by some DECORATE definitions - // (e.g. the monster pack's Afrit) - if ((mo->flags & MF_MISSILE) && ((mo->flags & MF_NOGRAVITY) || !(mo->flags & MF_NOCLIP))) + if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { mo->z = mo->floorz; if (mo->BounceFlags & BOUNCE_Floors) @@ -2353,8 +2348,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } if (mo->velz > 0) mo->velz = 0; - if (mo->flags & MF_MISSILE) - //&& (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) + if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { if (mo->flags3 & MF3_CEILINGHUGGER) { From 758327f4b3c560ef8cf678d1040c4133f7c96f58 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Mar 2010 03:11:10 +0000 Subject: [PATCH 21/88] - Fixed: snd_musicvolume needs to check GSnd for NULL, since somebody might have set an atexit for it, which gets executed after the sound system shuts down. - Fixed: FPlayList::Backup() failed to wrap around below entry 0 because Position is unsigned now. SVN r2188 (trunk) --- src/s_playlist.cpp | 2 +- src/sound/i_music.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/s_playlist.cpp b/src/s_playlist.cpp index 1ab294dc1..e92a5ceea 100644 --- a/src/s_playlist.cpp +++ b/src/s_playlist.cpp @@ -198,7 +198,7 @@ int FPlayList::Advance () int FPlayList::Backup () { - if (--Position < 0) + if (Position-- == 0) { Position = Songs.Size() - 1; } diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 83c75410d..38e820c8b 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -112,7 +112,10 @@ CUSTOM_CVAR (Float, snd_musicvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) else { // Set general music volume. - GSnd->SetMusicVolume(clamp(self * relative_volume, 0, 1)); + if (GSnd != NULL) + { + GSnd->SetMusicVolume(clamp(self * relative_volume, 0, 1)); + } // For music not implemented through the digital sound system, // let them know about the change. if (currSong != NULL) From fad9f251eca6a25519d4d3941a6272eefa864ed0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Mar 2010 03:31:20 +0000 Subject: [PATCH 22/88] - Fixed: FSinglePicFont should set the character size by the scaled size of the texture. SVN r2189 (trunk) --- src/v_font.cpp | 4 ++-- src/v_text.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 56a7ad811..ea6feb149 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1352,8 +1352,8 @@ FSinglePicFont::FSinglePicFont(const char *picname) FTexture *pic = TexMan[picnum]; Name = copystring(picname); - FontHeight = pic->GetHeight(); - SpaceWidth = pic->GetWidth(); + FontHeight = pic->GetScaledHeight(); + SpaceWidth = pic->GetScaledWidth(); GlobalKerning = 0; FirstChar = LastChar = 'A'; ActiveColors = 0; diff --git a/src/v_text.cpp b/src/v_text.cpp index be386e992..6cba83c9c 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -324,7 +324,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) i = w = 0; - while ( (c = *string++) && i < 128 ) + while ( (c = *string++) && i < countof(lines) ) { if (c == TEXTCOLOR_ESCAPE) { @@ -400,7 +400,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) } // String here is pointing one character after the '\0' - if (i < 128 && --string - start >= 1) + if (i < countof(lines) && --string - start >= 1) { const BYTE *s = start; From f014b8f98b471d54b1caafd3a41c579a6e60bd96 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Mar 2010 03:41:48 +0000 Subject: [PATCH 23/88] - Fixed: FFont::StringWidth() counted the ']' character of a named color escape sequence in its width calculation. SVN r2190 (trunk) --- src/v_text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_text.cpp b/src/v_text.cpp index 6cba83c9c..715e06093 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -276,7 +276,7 @@ int FFont::StringWidth (const BYTE *string) const ++string; } } - else if (*string != '\0') + if (*string != '\0') { ++string; } From 5c4af020d9dbcd66408c872c24adce41a104a8ea Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Mar 2010 03:43:51 +0000 Subject: [PATCH 24/88] - Fixed: CheckActorClass needed a NULL check. SVN r2191 (trunk) --- src/p_acs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index c899c5844..846b699eb 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3284,8 +3284,8 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_CheckActorClass: { - AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL); - return a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1])); + AActor *a = args[0] == 0 ? (AActor *)activator : SingleActorFromTID(args[0], NULL); + return a == NULL ? false : a->GetClass()->TypeName == FName(FBehavior::StaticLookupString(args[1])); } case ACSF_SoundSequenceOnActor: From dfd963ba1a4c742976c1a03a53987a289ce311ad Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 5 Mar 2010 23:09:31 +0000 Subject: [PATCH 25/88] - Revert r2173. SVN r2192 (trunk) --- src/m_cheat.cpp | 5 +---- src/p_mobj.cpp | 13 +------------ 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 23383a6fe..508043f47 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -46,8 +46,6 @@ #include "d_dehacked.h" #include "gi.h" -EXTERN_CVAR(Bool, r_forceplayertranslation) - // [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 // later calls us. @@ -321,8 +319,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); - if (multiplayer || r_forceplayertranslation) - player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); + player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); player->mo->DamageType = NAME_None; // player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index bf858a165..19712dd14 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -114,14 +114,6 @@ CUSTOM_CVAR (Float, sv_gravity, 800.f, CVAR_SERVERINFO|CVAR_NOSAVE) level.gravity = self; } -CUSTOM_CVAR(Bool, r_forceplayertranslation, false, CVAR_ARCHIVE|CVAR_NOINITCALL) -{ - if (!multiplayer && players[0].mo != NULL) - { - players[0].mo->Translation = self? TRANSLATION(TRANSLATION_Players, 0) : 0; - } -} - CVAR (Bool, cl_missiledecals, true, CVAR_ARCHIVE) CVAR (Bool, addrocketexplosion, false, CVAR_ARCHIVE) @@ -3992,10 +3984,7 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) R_BuildPlayerTranslation (playernum); // [RH] set color translations for player sprites - if (multiplayer || r_forceplayertranslation) - mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); - else - mobj->Translation = 0; + mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); mobj->angle = spawn_angle; mobj->pitch = mobj->roll = 0; From e78fd195d874cd2518f7d599662e0aecf18cbd25 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 Mar 2010 02:51:23 +0000 Subject: [PATCH 26/88] - Added support for the original games' player translations, including Hexen's table-based ones. SVN r2193 (trunk) --- src/am_map.cpp | 2 +- src/d_netinf.h | 3 +- src/d_netinfo.cpp | 47 +++++++- src/d_player.h | 16 +++ src/hu_scores.cpp | 2 +- src/m_menu.cpp | 111 +++++++++++++++--- src/p_user.cpp | 66 +++++++++++ src/r_translate.cpp | 76 ++++++++++-- src/thingdef/thingdef_properties.cpp | 51 ++++++++ wadsrc/static/actors/doom/doomplayer.txt | 12 +- .../static/actors/heretic/hereticplayer.txt | 16 ++- wadsrc/static/actors/hexen/clericplayer.txt | 11 +- wadsrc/static/actors/hexen/fighterplayer.txt | 11 +- wadsrc/static/actors/hexen/mageplayer.txt | 11 +- wadsrc/static/actors/strife/strifeplayer.txt | 11 +- 15 files changed, 406 insertions(+), 40 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 8f6871f99..28739c856 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1850,7 +1850,7 @@ void AM_drawPlayers () { float h, s, v, r, g, b; - D_GetPlayerColor (i, &h, &s, &v); + D_GetPlayerColor (i, &h, &s, &v, NULL); HSVtoRGB (&r, &g, &b, h, s, v); color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255)); diff --git a/src/d_netinf.h b/src/d_netinf.h index c2d49630c..728bad327 100644 --- a/src/d_netinf.h +++ b/src/d_netinf.h @@ -54,7 +54,8 @@ void D_DoServerInfoChange (BYTE **stream, bool singlebit); void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false); void D_ReadUserInfoStrings (int player, BYTE **stream, bool update); -void D_GetPlayerColor (int player, float *h, float *s, float *v); +struct FPlayerColorSet; +void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **colorset); void D_PickRandomTeam (int player); int D_PickRandomTeam (); class player_t; diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index e31354a6e..c415ebe4a 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -65,6 +65,7 @@ EXTERN_CVAR (Bool, teamplay) CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); +CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); @@ -85,6 +86,7 @@ enum INFO_MoveBob, INFO_StillBob, INFO_PlayerClass, + INFO_ColorSet, }; const char *GenderNames[3] = { "male", "female", "other" }; @@ -101,6 +103,7 @@ static const char *UserInfoStrings[] = "movebob", "stillbob", "playerclass", + "colorset", NULL }; @@ -184,10 +187,24 @@ int D_PlayerClassToInt (const char *classname) } } -void D_GetPlayerColor (int player, float *h, float *s, float *v) +void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **set) { userinfo_t *info = &players[player].userinfo; - int color = info->color; + FPlayerColorSet *colorset = NULL; + int color; + + if (players[player].mo != NULL) + { + colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->colorset); + } + if (colorset != NULL) + { + color = GPalette.BaseColors[GPalette.Remap[colorset->RepresentativeColor]]; + } + else + { + color = info->color; + } RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, h, s, v); @@ -206,6 +223,10 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v) *s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f); *v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f); } + if (set != NULL) + { + *set = colorset; + } } // Find out which teams are present. If there is only one, @@ -379,6 +400,7 @@ void D_SetupUserInfo () coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1)); } coninfo->color = color; + coninfo->colorset = colorset; coninfo->skin = R_FindSkin (skin, 0); coninfo->gender = D_GenderToInt (gender); coninfo->neverswitch = neverswitchonpickup; @@ -564,6 +586,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) "\\name\\%s" "\\autoaim\\%g" "\\color\\%x %x %x" + "\\colorset\\%d" "\\skin\\%s" "\\team\\%d" "\\gender\\%s" @@ -574,6 +597,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) , D_EscapeUserInfo(info->netname).GetChars(), (double)info->aimdist / (float)ANGLE_1, + info->colorset, RPART(info->color), GPART(info->color), BPART(info->color), D_EscapeUserInfo(skins[info->skin].name).GetChars(), info->team, @@ -600,6 +624,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) "\\%g" // movebob "\\%g" // stillbob "\\%s" // playerclass + "\\%d" // colorset , D_EscapeUserInfo(info->netname).GetChars(), (double)info->aimdist / (float)ANGLE_1, @@ -612,7 +637,8 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) (float)(info->MoveBob) / 65536.f, (float)(info->StillBob) / 65536.f, info->PlayerClass == -1 ? "Random" : - D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars() + D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars(), + info->colorset ); } } @@ -716,7 +742,15 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update) break; case INFO_Color: - info->color = V_GetColorFromString (NULL, value); + case INFO_ColorSet: + if (infotype == INFO_Color) + { + info->color = V_GetColorFromString (NULL, value); + } + else + { + info->colorset = atoi(value); + } R_BuildPlayerTranslation (i); if (StatusBar != NULL && i == StatusBar->GetPlayer()) { @@ -806,6 +840,10 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info) arc.Read (&info.netname, sizeof(info.netname)); } arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch; + if (SaveVersion >= 2193) + { + arc << info.colorset; + } return arc; } @@ -831,6 +869,7 @@ CCMD (playerinfo) Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team); Printf ("Aimdist: %d\n", ui->aimdist); Printf ("Color: %06x\n", ui->color); + Printf ("ColorSet: %d\n", ui->colorset); Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin); Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender); Printf ("NeverSwitch: %d\n", ui->neverswitch); diff --git a/src/d_player.h b/src/d_player.h index 3c9ad954c..64d901329 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -71,6 +71,21 @@ enum APMETA_Slot9, }; +// Standard pre-defined skin colors +struct FPlayerColorSet +{ + FName Name; // Name of this color + + int Lump; // Lump to read the translation from, otherwise use next 2 fields + BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation + + BYTE RepresentativeColor; // A palette entry representative of this translation, + // for map arrows and status bar backgrounds and such +}; +void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset); +FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum); +void P_EnumPlayerColorSets(FName classname, TArray *out); + class player_t; class APlayerPawn : public AActor @@ -223,6 +238,7 @@ struct userinfo_t BYTE team; int aimdist; int color; + int colorset; int skin; int gender; bool neverswitch; diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 456652bc7..1d881bd3d 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -418,7 +418,7 @@ void HU_DrawColorBar(int x, int y, int height, int playernum) { float h, s, v, r, g, b; - D_GetPlayerColor (playernum, &h, &s, &v); + D_GetPlayerColor (playernum, &h, &s, &v, NULL); HSVtoRGB (&r, &g, &b, h, s, v); screen->Clear (x, y, x + 24*CleanXfac, y + height, -1, diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 88eac1edf..7628b336e 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -118,7 +118,7 @@ protected: // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- -void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table); +void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -188,6 +188,7 @@ static void M_EditPlayerName (int choice); static void M_ChangePlayerTeam (int choice); static void M_PlayerNameChanged (FSaveGameNode *dummy); static void M_PlayerNameNotChanged (); +static void M_ChangeColorSet (int choice); static void M_SlidePlayerRed (int choice); static void M_SlidePlayerGreen (int choice); static void M_SlidePlayerBlue (int choice); @@ -269,6 +270,7 @@ static int PlayerSkin; static FState *PlayerState; static int PlayerTics; static int PlayerRotation; +static TArray PlayerColorSets; static FTexture *SavePic; static FBrokenLines *SaveComment; @@ -536,10 +538,11 @@ static oldmenuitem_t PlayerSetupMenu[] = { { 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED}, { 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED}, + { 2,0,'c',NULL,M_ChangeColorSet, CR_UNTRANSLATED}, { 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED}, { 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED}, { 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED}, - { 2,0,'c',NULL,M_ChangeClass, CR_UNTRANSLATED}, + { 2,0,'t',NULL,M_ChangeClass, CR_UNTRANSLATED}, { 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED}, { 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED}, { 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED} @@ -2088,13 +2091,16 @@ void M_PlayerSetup (void) PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass]; } PlayerSkin = players[consoleplayer].userinfo.skin; - R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState; PlayerTics = PlayerState->GetTics(); if (FireTexture == NULL) { FireTexture = new FBackdropTexture; } + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } static void M_PlayerSetupTicker (void) @@ -2112,6 +2118,7 @@ static void M_PlayerSetupTicker (void) item = (MenuTime>>2) % (ClassMenuDef.numitems-1); PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)]; + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } else { @@ -2125,6 +2132,7 @@ static void M_PlayerSetupTicker (void) PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0])); R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } @@ -2280,19 +2288,27 @@ static void M_PlayerSetupDrawer () DTA_Clean, true, TAG_DONE); } - // Draw player color sliders - //V_DrawTextCleanMove (CR_GREY, PSetupDef.x, PSetupDef.y + LINEHEIGHT, "Color"); + // Draw player color selection and sliders + FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset); + x = SmallFont->StringWidth("Color") + 8 + PSetupDef.x; + screen->DrawText(SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Color", DTA_Clean, true, TAG_DONE); + screen->DrawText(SmallFont, value, x, PSetupDef.y + LINEHEIGHT*2+yo, + colorset != NULL ? colorset->Name.GetChars() : "Custom", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Red", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*3+yo, "Green", DTA_Clean, true, TAG_DONE); - screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*4+yo, "Blue", DTA_Clean, true, TAG_DONE); + // Only show the sliders for a custom color set. + if (colorset == NULL) + { + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, "Red", DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, "Green", DTA_Clean, true, TAG_DONE); + screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, "Blue", DTA_Clean, true, TAG_DONE); - x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; - color = players[consoleplayer].userinfo.color; + x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; + color = players[consoleplayer].userinfo.color; - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color)); - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color)); - M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, RPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, GPART(color)); + M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, BPART(color)); + } // [GRB] Draw class setting int pclass = players[consoleplayer].userinfo.PlayerClass; @@ -2587,7 +2603,9 @@ static void M_ChangeSkin (int choice) PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0; } while (!PlayerClass->CheckSkin (PlayerSkin)); - R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation (players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); cvar_set ("skin", skins[PlayerSkin].name); } @@ -2708,13 +2726,50 @@ static void M_ChangePlayerTeam (int choice) } } +static void M_ChangeColorSet (int choice) +{ + int curpos = (int)PlayerColorSets.Size(); + int mycolorset = players[consoleplayer].userinfo.colorset; + while (--curpos >= 0) + { + if (PlayerColorSets[curpos] == mycolorset) + break; + } + if (choice == 0) + { + curpos--; + } + else + { + curpos++; + } + if (curpos < -1) + { + curpos = (int)PlayerColorSets.Size() - 1; + } + else if (curpos >= (int)PlayerColorSets.Size()) + { + curpos = -1; + } + mycolorset = (curpos >= 0) ? PlayerColorSets[curpos] : -1; + + char command[24]; + mysnprintf(command, countof(command), "colorset %d", mycolorset); + C_DoCommand(command); + R_GetPlayerTranslation(players[consoleplayer].userinfo.color, + P_GetPlayerColorSet(PlayerClass->Type->TypeName, mycolorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); +} + static void SendNewColor (int red, int green, int blue) { char command[24]; mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue); C_DoCommand (command); - R_GetPlayerTranslation (MAKERGB (red, green, blue), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); + R_GetPlayerTranslation(MAKERGB (red, green, blue), + P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset), + &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); } static void M_SlidePlayerRed (int choice) @@ -3646,8 +3701,31 @@ void M_Drawer () // [RH] Use options menu cursor for the player setup menu. if (skullAnimCounter < 6) { + double item; + // The green slider is halfway between lines, and the red and + // blue ones are offset slightly to make room for it. + if (itemOn < 3) + { + item = itemOn; + } + else if (itemOn > 5) + { + item = itemOn - 1; + } + else if (itemOn == 3) + { + item = 2.875; + } + else if (itemOn == 4) + { + item = 3.5; + } + else + { + item = 4.125; + } screen->DrawText (ConFont, CR_RED, x - 16, - currentMenu->y + itemOn*PLAYERSETUP_LINEHEIGHT + + currentMenu->y + int(item*PLAYERSETUP_LINEHEIGHT) + (!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd", DTA_Clean, true, TAG_DONE); } @@ -4037,4 +4115,5 @@ static void PickPlayerClass () } PlayerClass = &PlayerClasses[pclass]; + P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets); } diff --git a/src/p_user.cpp b/src/p_user.cpp index ff1a80dae..78e6eeb2e 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -55,6 +55,9 @@ static FRandom pr_skullpop ("SkullPop"); +// Color set class name -> mapping table +typedef TMap FPlayerColorSetMap; +TMap PlayerToColorsMap; // [RH] # of ticks to complete a turn180 #define TURN180_TICKS ((TICRATE / 4) + 1) @@ -2631,3 +2634,66 @@ void player_t::Serialize (FArchive &arc) } } + +static FPlayerColorSetMap *GetPlayerColors(FName classname, bool create) +{ + FPlayerColorSetMap *map, **value; + + value = PlayerToColorsMap.CheckKey(classname); + if (value == NULL) + { + if (create) + { + map = new FPlayerColorSetMap; + PlayerToColorsMap.Insert(classname, map); + } + else + { + map = NULL; + } + } + else + { + map = *value; + } + return map; +} + +void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset) +{ + FPlayerColorSetMap *map = GetPlayerColors(classname, true); + (*map)[setnum] = *colorset; +} + +FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum) +{ + FPlayerColorSetMap *map = GetPlayerColors(classname, false); + if (map == NULL) + { + return NULL; + } + return map->CheckKey(setnum); +} + +static int STACK_ARGS intcmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +void P_EnumPlayerColorSets(FName classname, TArray *out) +{ + out->Clear(); + FPlayerColorSetMap *map = GetPlayerColors(classname, false); + if (map != NULL) + { + FPlayerColorSetMap::Iterator it(*map); + FPlayerColorSetMap::Pair *pair; + + while (it.NextPair(pair)) + { + out->Push(pair->Key); + } + qsort(&(*out)[0], out->Size(), sizeof(int), intcmp); + } +} + diff --git a/src/r_translate.cpp b/src/r_translate.cpp index 8e74f4443..553d4fcf1 100644 --- a/src/r_translate.cpp +++ b/src/r_translate.cpp @@ -46,6 +46,7 @@ #include "sc_man.h" #include "doomerrors.h" #include "i_system.h" +#include "w_wad.h" #include "gi.h" #include "stats.h" @@ -892,7 +893,8 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b) // //---------------------------------------------------------------------------- -static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) +static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerColorSet *colorset, + FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) { int i; BYTE start = skin->range0start; @@ -936,7 +938,46 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s bases = s; basev = v; - if (gameinfo.gametype & GAME_DoomStrifeChex) + if (colorset != NULL && colorset->Lump >= 0 && Wads.LumpLength(colorset->Lump) < 256) + { // Bad table length. Ignore it. + colorset = NULL; + } + + if (colorset != NULL) + { + // Use the pre-defined range instead of a custom one. + if (colorset->Lump < 0) + { + int first = colorset->FirstColor; + if (start == end) + { + table->Remap[i] = (first + colorset->LastColor) / 2; + } + else + { + int palrange = colorset->LastColor - first; + for (i = start; i <= end; ++i) + { + table->Remap[i] = GPalette.Remap[first + palrange * (i - start) / (end - start)]; + } + } + } + else + { + FMemLump translump = Wads.ReadLump(colorset->Lump); + const BYTE *trans = (const BYTE *)translump.GetMem(); + for (i = start; i <= end; ++i) + { + table->Remap[i] = GPalette.Remap[trans[i]]; + } + } + for (i = start; i <= end; ++i) + { + table->Palette[i] = GPalette.BaseColors[table->Remap[i]]; + table->Palette[i].a = 255; + } + } + else if (gameinfo.gametype & GAME_DoomStrifeChex) { // Build player sprite translation s -= 0.23f; @@ -1014,9 +1055,19 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s SetRemap(table, i, r, g, b); } } - - // Build lifegem translation - if (alttable) + } + if (gameinfo.gametype == GAME_Hexen && alttable != NULL) + { + // Build Hexen's lifegem translation. + + // Is the player's translation range the same as the gem's and we are using a + // predefined translation? If so, then use the same one for the gem. Otherwise, + // build one as per usual. + if (colorset != NULL && start == 164 && end == 185) + { + *alttable = *table; + } + else { for (i = 164; i <= 185; ++i) { @@ -1027,8 +1078,8 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s HSVtoRGB (&r, &g, &b, h, s*bases, v*basev); SetRemap(alttable, i, r, g, b); } - alttable->UpdateNative(); } + alttable->UpdateNative(); } table->UpdateNative(); } @@ -1042,10 +1093,11 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s void R_BuildPlayerTranslation (int player) { float h, s, v; + FPlayerColorSet *colorset; - D_GetPlayerColor (player, &h, &s, &v); + D_GetPlayerColor (player, &h, &s, &v, &colorset); - R_CreatePlayerTranslation (h, s, v, + R_CreatePlayerTranslation (h, s, v, colorset, &skins[players[player].userinfo.skin], translationtables[TRANSLATION_Players][player], translationtables[TRANSLATION_PlayersExtra][player]); @@ -1057,13 +1109,17 @@ void R_BuildPlayerTranslation (int player) // //---------------------------------------------------------------------------- -void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table) +void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table) { float h, s, v; + if (colorset != NULL) + { + color = colorset->RepresentativeColor; + } RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, &h, &s, &v); - R_CreatePlayerTranslation (h, s, v, skin, table, NULL); + R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL); } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 884e596e2..5a8bfe0f5 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1860,6 +1860,57 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn) info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn) +{ + PROP_INT_PARM(setnum, 0); + PROP_STRING_PARM(setname, 1); + PROP_INT_PARM(rangestart, 2); + PROP_INT_PARM(rangeend, 3); + PROP_INT_PARM(representative_color, 4); + + FPlayerColorSet color; + color.Name = setname; + color.Lump = -1; + color.FirstColor = rangestart; + color.LastColor = rangeend; + color.RepresentativeColor = representative_color; + + if (setnum < 0) + { + bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n"); + } + else + { + P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + } +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn) +{ + PROP_INT_PARM(setnum, 0); + PROP_STRING_PARM(setname, 1); + PROP_STRING_PARM(rangefile, 2); + PROP_INT_PARM(representative_color, 3); + + FPlayerColorSet color; + color.Name = setname; + color.Lump = Wads.CheckNumForName(rangefile); + color.RepresentativeColor = representative_color; + if (setnum < 0) + { + bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n"); + } + else if (color.Lump >= 0) + { + P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + } +} //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/doom/doomplayer.txt b/wadsrc/static/actors/doom/doomplayer.txt index 9138fc649..3f81eaaca 100644 --- a/wadsrc/static/actors/doom/doomplayer.txt +++ b/wadsrc/static/actors/doom/doomplayer.txt @@ -11,7 +11,6 @@ ACTOR DoomPlayer : PlayerPawn Height 56 Mass 100 PainChance 255 - Player.ColorRange 112, 127 Player.DisplayName "Marine" Player.CrouchSprite "PLYC" Player.StartItem "Pistol" @@ -24,6 +23,17 @@ ACTOR DoomPlayer : PlayerPawn Player.WeaponSlot 5, RocketLauncher Player.WeaponSlot 6, PlasmaRifle Player.WeaponSlot 7, BFG9000 + + Player.ColorRange 112, 127 + Player.Colorset 0, "Green", 0x70, 0x7F, 0x72 + Player.Colorset 1, "Gray", 0x60, 0x6F, 0x62 + Player.Colorset 2, "Brown", 0x40, 0x4F, 0x42 + Player.Colorset 3, "Red", 0x20, 0x2F, 0x22 + // Doom Legacy additions + Player.Colorset 4, "Light Gray", 0x58, 0x67, 0x5A + Player.Colorset 5, "Light Brown", 0x38, 0x47, 0x3A + Player.Colorset 6, "Light Red", 0xB0, 0xBF, 0xB2 + Player.Colorset 7, "Light Blue", 0xC0, 0xCF, 0xC2 States { diff --git a/wadsrc/static/actors/heretic/hereticplayer.txt b/wadsrc/static/actors/heretic/hereticplayer.txt index 9e36f8d7f..77ec994d8 100644 --- a/wadsrc/static/actors/heretic/hereticplayer.txt +++ b/wadsrc/static/actors/heretic/hereticplayer.txt @@ -6,7 +6,6 @@ ACTOR HereticPlayer : PlayerPawn Mass 100 Painchance 255 Speed 1 - Player.ColorRange 225, 240 Player.DisplayName "Corvus" Player.StartItem "GoldWand" Player.StartItem "Staff" @@ -18,7 +17,20 @@ ACTOR HereticPlayer : PlayerPawn Player.WeaponSlot 5, SkullRod Player.WeaponSlot 6, PhoenixRod Player.WeaponSlot 7, Mace - + + Player.ColorRange 225, 240 + Player.Colorset 0, "Green", 225, 240, 238 + Player.Colorset 1, "Yellow", 114, 129, 127 + Player.Colorset 2, "Red", 145, 160, 158 + Player.Colorset 3, "Blue", 190, 205, 203 + // Doom Legacy additions + Player.Colorset 4, "Brown", 67, 82, 80 + Player.Colorset 5, "Light Gray", 9, 24, 22 + Player.Colorset 6, "Light Brown", 74, 89, 87 + Player.Colorset 7, "Light Red", 150, 165, 163 + Player.Colorset 8, "Light Blue", 192, 207, 205 + Player.Colorset 9, "Beige", 95, 110, 108 + States { Spawn: diff --git a/wadsrc/static/actors/hexen/clericplayer.txt b/wadsrc/static/actors/hexen/clericplayer.txt index 493faffde..4fe6629e2 100644 --- a/wadsrc/static/actors/hexen/clericplayer.txt +++ b/wadsrc/static/actors/hexen/clericplayer.txt @@ -15,7 +15,6 @@ ACTOR ClericPlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 146, 163 Player.SpawnClass "Cleric" Player.DisplayName "Cleric" Player.SoundClass "cleric" @@ -29,6 +28,16 @@ ACTOR ClericPlayer : PlayerPawn Player.WeaponSlot 3, CWeapFlame Player.WeaponSlot 4, CWeapWraithverge + Player.ColorRange 146, 163 + Player.Colorset 0, "Blue", 146, 163, 161 + Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3 + Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C + Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41 + Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9 + Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30 + Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72 + Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/hexen/fighterplayer.txt b/wadsrc/static/actors/hexen/fighterplayer.txt index 5c307bd60..277a2986b 100644 --- a/wadsrc/static/actors/hexen/fighterplayer.txt +++ b/wadsrc/static/actors/hexen/fighterplayer.txt @@ -14,7 +14,6 @@ ACTOR FighterPlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 246, 254 Player.SpawnClass "Fighter" Player.DisplayName "Fighter" Player.SoundClass "fighter" @@ -29,6 +28,16 @@ ACTOR FighterPlayer : PlayerPawn Player.WeaponSlot 3, FWeapHammer Player.WeaponSlot 4, FWeapQuietus + Player.ColorRange 246, 254 + Player.Colorset 0, "Gold", 246, 254, 253 + Player.ColorsetFile 1, "Red", "TRANTBL0", 0xAC + Player.ColorsetFile 2, "Blue", "TRANTBL1", 0x9D + Player.ColorsetFile 3, "Dull Green", "TRANTBL2", 0x3E + Player.ColorsetFile 4, "Green", "TRANTBL3", 0xC8 + Player.ColorsetFile 5, "Gray", "TRANTBL4", 0x2D + Player.ColorsetFile 6, "Brown", "TRANTBL5", 0x6F + Player.ColorsetFile 7, "Purple", "TRANTBL6", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/hexen/mageplayer.txt b/wadsrc/static/actors/hexen/mageplayer.txt index 2f67d35bf..a34698366 100644 --- a/wadsrc/static/actors/hexen/mageplayer.txt +++ b/wadsrc/static/actors/hexen/mageplayer.txt @@ -15,7 +15,6 @@ ACTOR MagePlayer : PlayerPawn RadiusDamageFactor 0.25 Player.JumpZ 9 Player.Viewheight 48 - Player.ColorRange 146, 163 Player.SpawnClass "Mage" Player.DisplayName "Mage" Player.SoundClass "mage" @@ -31,6 +30,16 @@ ACTOR MagePlayer : PlayerPawn Player.WeaponSlot 3, MWeapLightning Player.WeaponSlot 4, MWeapBloodscourge + Player.ColorRange 146, 163 + Player.Colorset 0, "Blue", 146, 163, 161 + Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3 + Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C + Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41 + Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9 + Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30 + Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72 + Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE + States { Spawn: diff --git a/wadsrc/static/actors/strife/strifeplayer.txt b/wadsrc/static/actors/strife/strifeplayer.txt index d42dc1ba4..1dabeff4c 100644 --- a/wadsrc/static/actors/strife/strifeplayer.txt +++ b/wadsrc/static/actors/strife/strifeplayer.txt @@ -9,7 +9,6 @@ ACTOR StrifePlayer : PlayerPawn PainChance 255 Speed 1 MaxStepHeight 16 - Player.ColorRange 128, 143 Player.DisplayName "Rebel" Player.StartItem "PunchDagger" Player.RunHealth 15 @@ -22,6 +21,16 @@ ACTOR StrifePlayer : PlayerPawn Player.WeaponSlot 7, Mauler2, Mauler Player.WeaponSlot 8, Sigil + Player.ColorRange 128, 143 + Player.Colorset 0, "Brown", 0x80, 0x8F, 0x82 + Player.Colorset 1, "Red", 0x40, 0x4F, 0x42 + Player.Colorset 2, "Rust", 0xB0, 0xBF, 0xB2 + Player.Colorset 3, "Gray", 0x10, 0x1F, 0x12 + Player.Colorset 4, "Dark Green", 0x30, 0x3F, 0x32 + Player.Colorset 5, "Gold", 0x50, 0x5F, 0x52 + Player.Colorset 6, "Bright Green", 0x60, 0x6F, 0x62 + Player.Colorset 7, "Blue", 0x90, 0x9F, 0x92 + action native A_ItBurnsItBurns(); action native A_CrispyPlayer(); action native A_HandLower(); From 38c9bb1900409a055ebe72d790fd1844f5c365be Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 Mar 2010 03:02:24 +0000 Subject: [PATCH 27/88] - Setting a Player.ColorRange now completely disables the translation rather than just making it an identity map. SVN r2194 (trunk) --- src/r_draw.cpp | 2 +- src/r_translate.cpp | 5 ++++- src/r_translate.h | 1 + src/v_draw.cpp | 4 ++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 12cf3c51f..ce836f839 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2181,7 +2181,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, if (translation != 0) { FRemapTable *table = TranslationToTable(translation); - if (table != NULL) + if (table != NULL && !table->Inactive) { dc_translation = table->Remap; } diff --git a/src/r_translate.cpp b/src/r_translate.cpp index 553d4fcf1..045dc3f41 100644 --- a/src/r_translate.cpp +++ b/src/r_translate.cpp @@ -79,7 +79,7 @@ const BYTE IcePalette[16][3] = FRemapTable::FRemapTable(int count) { assert(count <= 256); - + Inactive = false; Alloc(count); // Note that the tables are left uninitialized. It is assumed that @@ -164,6 +164,7 @@ FRemapTable &FRemapTable::operator=(const FRemapTable &o) { Alloc(o.NumEntries); } + Inactive = o.Inactive; memcpy(Remap, o.Remap, NumEntries*sizeof(*Remap) + NumEntries*sizeof(*Palette)); return *this; } @@ -929,6 +930,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC // [GRB] Don't translate skins with color range 0-0 (APlayerPawn default) if (start == 0 && end == 0) { + table->Inactive = true; table->UpdateNative(); return; } @@ -1081,6 +1083,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC } alttable->UpdateNative(); } + table->Inactive = false; table->UpdateNative(); } diff --git a/src/r_translate.h b/src/r_translate.h index 730dac541..21488155b 100644 --- a/src/r_translate.h +++ b/src/r_translate.h @@ -46,6 +46,7 @@ struct FRemapTable PalEntry *Palette; // The ideal palette this maps to FNativePalette *Native; // The Palette stored in a HW texture int NumEntries; // # of elements in this table (usually 256) + bool Inactive; // This table is inactive and should be treated as if it was passed as NULL private: void Free(); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index e46a99d12..42b0b5145 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -527,6 +527,10 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag case DTA_Translation: parms->remap = va_arg(tags, FRemapTable *); + if (parms->remap != NULL && parms->remap->Inactive) + { // If it's inactive, pretend we were passed NULL instead. + parms->remap = NULL; + } break; case DTA_ColorOverlay: From d19878efcb3f2ad766bc8d3636ceea7baf32c711 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 Mar 2010 03:28:22 +0000 Subject: [PATCH 28/88] - Added BOOM/MBF BEX-style narrative background text substitution. There are two changes because of this: * A cluster's flat definition can now be preceded by a $ to do a string table lookup. * Since the standard flat names are now in the LANGUAGE lump, the normal Dehacked substitution for these is no longer handled specially and so will not be automatically disabled merely by providing your own MAPINFO. SVN r2195 (trunk) --- src/d_dehacked.cpp | 15 +-------------- src/f_finale.cpp | 6 +++++- src/g_level.cpp | 6 +++--- src/g_level.h | 3 ++- src/g_mapinfo.cpp | 12 +++++++++--- wadsrc/static/language.enu | 13 +++++++++++++ wadsrc/static/mapinfo/doom1.txt | 8 ++++---- wadsrc/static/mapinfo/doom2.txt | 12 ++++++------ 8 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index c90eabe90..62c5090e2 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2138,20 +2138,7 @@ static int PatchText (int oldSize) if (!good) { - // search cluster text background flats (only if no user-defined MAPINFO is used!) - if (strlen(newStr) <= 8 && Wads.CheckNumForName("MAPINFO") >= 0) - { - for (unsigned int i = 0; i < wadclusterinfos.Size(); i++) - { - if (!strcmp(wadclusterinfos[i].finaleflat, oldStr)) - { - strcpy(wadclusterinfos[i].finaleflat, newStr); - good = true; - } - } - } - - if (!good) DPrintf (" (Unmatched)\n"); + DPrintf (" (Unmatched)\n"); } } diff --git a/src/f_finale.cpp b/src/f_finale.cpp index e08f249eb..2b220fddb 100644 --- a/src/f_finale.cpp +++ b/src/f_finale.cpp @@ -117,6 +117,10 @@ void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int } FinaleFlat = (flat != NULL && *flat != 0) ? flat : gameinfo.finaleFlat; + if (FinaleFlat != NULL && FinaleFlat[0] == '$') + { + FinaleFlat = GStrings(FinaleFlat + 1); + } if (textInLump) { @@ -758,7 +762,7 @@ void F_CastDrawer (void) FTexture* pic; // erase the entire screen to a background - screen->DrawTexture (TexMan["BOSSBACK"], 0, 0, + screen->DrawTexture (TexMan[GStrings("BOSSBACK")], 0, 0, DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), TAG_DONE); diff --git a/src/g_level.cpp b/src/g_level.cpp index 1b0bd1130..cc3042941 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1039,7 +1039,7 @@ void G_WorldDone (void) { F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, thiscluster->cdid, - thiscluster->finaleflat, thiscluster->ExitText, + thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, @@ -1057,7 +1057,7 @@ void G_WorldDone (void) { F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder, nextcluster->cdtrack, nextcluster->cdid, - nextcluster->finaleflat, nextcluster->EnterText, + nextcluster->FinaleFlat, nextcluster->EnterText, nextcluster->flags & CLUSTER_ENTERTEXTINLUMP, nextcluster->flags & CLUSTER_FINALEPIC, nextcluster->flags & CLUSTER_LOOKUPENTERTEXT, @@ -1067,7 +1067,7 @@ void G_WorldDone (void) { F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, nextcluster->cdid, - thiscluster->finaleflat, thiscluster->ExitText, + thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, diff --git a/src/g_level.h b/src/g_level.h index 3b0851636..7ea2e3147 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -77,6 +77,7 @@ struct FMapInfoParser bool ParseLookupName(FString &dest); void ParseMusic(FString &name, int &order); void ParseLumpOrTextureName(char *name); + void ParseLumpOrTextureName(FString &name); void ParseCluster(); void ParseNextMap(char *mapname); @@ -439,7 +440,7 @@ extern TArray EndSequences; struct cluster_info_t { int cluster; - char finaleflat[9]; + FString FinaleFlat; FString ExitText; FString EnterText; FString MessageMusic; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index f85b08960..f9fe5e829 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -389,7 +389,7 @@ bool level_info_t::isValid() void cluster_info_t::Reset() { cluster = 0; - finaleflat[0] = 0; + FinaleFlat = ""; ExitText = ""; EnterText = ""; MessageMusic = ""; @@ -615,6 +615,12 @@ void FMapInfoParser::ParseLumpOrTextureName(char *name) name[8]=0; } +void FMapInfoParser::ParseLumpOrTextureName(FString &name) +{ + sc.MustGetString(); + name = sc.String; +} + //========================================================================== // @@ -691,12 +697,12 @@ void FMapInfoParser::ParseCluster() else if (sc.Compare("flat")) { ParseAssign(); - ParseLumpOrTextureName(clusterinfo->finaleflat); + ParseLumpOrTextureName(clusterinfo->FinaleFlat); } else if (sc.Compare("pic")) { ParseAssign(); - ParseLumpOrTextureName(clusterinfo->finaleflat); + ParseLumpOrTextureName(clusterinfo->FinaleFlat); clusterinfo->flags |= CLUSTER_FINALEPIC; } else if (sc.Compare("hub")) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 4cb444d0f..53d74a483 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -570,6 +570,19 @@ PD_ALL6 = "You need all six keys to open this door"; PD_ALL6O = "You need all six keys to activate this object"; PD_ALLKEYS = "You need all the keys"; +// MBF (BOOM?) narration backgrounds +bgflatE1 = "FLOOR4_8"; +bgflatE2 = "SFLR6_1"; +bgflatE3 = "MFLR8_4"; +bgflatE4 = "MFLR8_3"; +bgflat06 = "SLIME16"; +bgflat11 = "RROCK14"; +bgflat20 = "RROCK07"; +bgflat30 = "RROCK17"; +bgflat15 = "RROCK13"; +bgflat31 = "RROCK19"; +bgcastcall = "BOSSBACK"; + // Gameflow messages TXT_FRAGLIMIT = "Fraglimit hit."; TXT_TIMELIMIT = "Timelimit hit."; diff --git a/wadsrc/static/mapinfo/doom1.txt b/wadsrc/static/mapinfo/doom1.txt index 5c8fc1dc9..b3e631650 100644 --- a/wadsrc/static/mapinfo/doom1.txt +++ b/wadsrc/static/mapinfo/doom1.txt @@ -501,28 +501,28 @@ map E4M9 lookup "HUSTR_E4M9" cluster 1 { - flat = "FLOOR4_8" + flat = "$bgflatE1" music = "$MUSIC_VICTOR" exittext = lookup, "E1TEXT" } cluster 2 { - flat = "SFLR6_1" + flat = "$bgflatE2" music = "$MUSIC_VICTOR" exittext = lookup, "E2TEXT" } cluster 3 { - flat = "MFLR8_4" + flat = "$bgflatE3" music = "$MUSIC_VICTOR" exittext = lookup, "E3TEXT" } cluster 4 { - flat = "MFLR8_3" + flat = "$bgflatE4" music = "$MUSIC_VICTOR" exittext = lookup, "E4TEXT" } diff --git a/wadsrc/static/mapinfo/doom2.txt b/wadsrc/static/mapinfo/doom2.txt index 50bae7d9d..6dc9815b1 100644 --- a/wadsrc/static/mapinfo/doom2.txt +++ b/wadsrc/static/mapinfo/doom2.txt @@ -372,7 +372,7 @@ map MAP32 lookup "HUSTR_32" cluster 5 { - flat = "SLIME16" + flat = "$BGFLAT06" music = "$MUSIC_READ_M" exittext = lookup, "C1TEXT" @@ -382,7 +382,7 @@ cluster 5 cluster 6 { - flat = "RROCK14" + flat = "$BGFLAT11" music = "$MUSIC_READ_M" exittext = lookup, "C2TEXT" @@ -392,7 +392,7 @@ cluster 6 cluster 7 { - flat = "RROCK07" + flat = "$BGFLAT20" music = "$MUSIC_READ_M" exittext = lookup, "C3TEXT" } @@ -401,7 +401,7 @@ cluster 7 cluster 8 { - flat = "RROCK17" + flat = "$BGFLAT30" music = "$MUSIC_READ_M" exittext = lookup, "C4TEXT" } @@ -410,7 +410,7 @@ cluster 8 cluster 9 { - flat = "RROCK13" + flat = "$BGFLAT15" music = "$MUSIC_READ_M" entertext = lookup, "C5TEXT" } @@ -419,7 +419,7 @@ cluster 9 cluster 10 { - flat = "RROCK19" + flat = "$BGFLAT31" music = "$MUSIC_READ_M" entertext = lookup, "C6TEXT" } From 47a835698a3bb7cbf5646824d9d4b1fcf8ffa513 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 Mar 2010 04:01:32 +0000 Subject: [PATCH 29/88] - Final Doom needs its finale flats changed, too. - It's "BGCASTCALL", not "BOSSBACK". SVN r2196 (trunk) --- src/f_finale.cpp | 2 +- wadsrc/static/mapinfo/plutonia.txt | 12 ++++++------ wadsrc/static/mapinfo/tnt.txt | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/f_finale.cpp b/src/f_finale.cpp index 2b220fddb..2b9fc8773 100644 --- a/src/f_finale.cpp +++ b/src/f_finale.cpp @@ -762,7 +762,7 @@ void F_CastDrawer (void) FTexture* pic; // erase the entire screen to a background - screen->DrawTexture (TexMan[GStrings("BOSSBACK")], 0, 0, + screen->DrawTexture (TexMan[GStrings("bgcastcall")], 0, 0, DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), TAG_DONE); diff --git a/wadsrc/static/mapinfo/plutonia.txt b/wadsrc/static/mapinfo/plutonia.txt index 612aaf264..34101541b 100644 --- a/wadsrc/static/mapinfo/plutonia.txt +++ b/wadsrc/static/mapinfo/plutonia.txt @@ -373,7 +373,7 @@ map MAP32 lookup "PHUSTR_32" cluster 5 { - flat = "SLIME16" + flat = "$BGFLAT06" music = "$MUSIC_READ_M" exittext = lookup, "P1TEXT" } @@ -382,7 +382,7 @@ cluster 5 cluster 6 { - flat = "RROCK14" + flat = "$BGFLAT11" music = "$MUSIC_READ_M" exittext = lookup, "P2TEXT" } @@ -391,7 +391,7 @@ cluster 6 cluster 7 { - flat = "RROCK07" + flat = "$BGFLAT20" music = "$MUSIC_READ_M" exittext = lookup, "P3TEXT" } @@ -400,7 +400,7 @@ cluster 7 cluster 8 { - flat = "RROCK17" + flat = "$BGFLAT30" music = "$MUSIC_READ_M" exittext = lookup, "P4TEXT" } @@ -409,7 +409,7 @@ cluster 8 cluster 9 { - flat = "RROCK13" + flat = "$BGFLAT15" music = "$MUSIC_READ_M" entertext = lookup, "P5TEXT" } @@ -418,7 +418,7 @@ cluster 9 cluster 10 { - flat = "RROCK19" + flat = "$BGFLAT31" music = "$MUSIC_READ_M" entertext = lookup, "P6TEXT" } diff --git a/wadsrc/static/mapinfo/tnt.txt b/wadsrc/static/mapinfo/tnt.txt index 438b61ff1..9d069c8d5 100644 --- a/wadsrc/static/mapinfo/tnt.txt +++ b/wadsrc/static/mapinfo/tnt.txt @@ -373,7 +373,7 @@ map MAP32 lookup "THUSTR_32" cluster 5 { - flat = "SLIME16" + flat = "$BGFLAT06" music = "$MUSIC_READ_M" exittext = lookup, "T1TEXT" } @@ -382,7 +382,7 @@ cluster 5 cluster 6 { - flat = "RROCK14" + flat = "$BGFLAT11" music = "$MUSIC_READ_M" exittext = lookup, "T2TEXT" } @@ -391,7 +391,7 @@ cluster 6 cluster 7 { - flat = "RROCK07" + flat = "$BGFLAT20" music = "$MUSIC_READ_M" exittext = lookup, "T3TEXT" } @@ -400,7 +400,7 @@ cluster 7 cluster 8 { - flat = "RROCK17" + flat = "$BGFLAT30" music = "$MUSIC_READ_M" exittext = lookup, "T4TEXT" } @@ -409,7 +409,7 @@ cluster 8 cluster 9 { - flat = "RROCK13" + flat = "$BGFLAT15" music = "$MUSIC_READ_M" entertext = lookup, "T5TEXT" } @@ -418,7 +418,7 @@ cluster 9 cluster 10 { - flat = "RROCK19" + flat = "$BGFLAT31" music = "$MUSIC_READ_M" entertext = lookup, "T6TEXT" } From 017fc7bd6abac37bb4550eabf6fa36e130c306ee Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 6 Mar 2010 09:10:40 +0000 Subject: [PATCH 30/88] - fixed: The ChexPlayer was missing default colorset definitions. SVN r2197 (trunk) --- wadsrc/static/actors/chex/chexplayer.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wadsrc/static/actors/chex/chexplayer.txt b/wadsrc/static/actors/chex/chexplayer.txt index 5003ea809..210a68470 100644 --- a/wadsrc/static/actors/chex/chexplayer.txt +++ b/wadsrc/static/actors/chex/chexplayer.txt @@ -16,4 +16,14 @@ actor ChexPlayer : DoomPlayer player.WeaponSlot 5, ZorchPropulsor player.WeaponSlot 6, PhasingZorcher player.WeaponSlot 7, LAZDevice + + Player.Colorset 0, "Light Blue", 0xC0, 0xCF, 0xC2 + Player.Colorset 1, "Green", 0x70, 0x7F, 0x72 + Player.Colorset 2, "Gray", 0x60, 0x6F, 0x62 + Player.Colorset 3, "Brown", 0x40, 0x4F, 0x42 + Player.Colorset 4, "Red", 0x20, 0x2F, 0x22 + Player.Colorset 5, "Light Gray", 0x58, 0x67, 0x5A + Player.Colorset 6, "Light Brown", 0x38, 0x47, 0x3A + Player.Colorset 7, "Light Red", 0xB0, 0xBF, 0xB2 + } From d2a4c19955578c98dd8fec285d923608804b931d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 6 Mar 2010 09:30:38 +0000 Subject: [PATCH 31/88] - let players check MF2_NOTRANSLATE so that mods can create player classes which are not subject to default player color handling. SVN r2198 (trunk) --- src/m_cheat.cpp | 5 ++++- src/p_mobj.cpp | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 508043f47..2b87900b0 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -319,7 +319,10 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); - player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); + if (!(player->mo->flags2 & MF2_DONTTRANSLATE)) + { + player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); + } player->mo->DamageType = NAME_None; // player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 19712dd14..f581312f9 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3980,11 +3980,15 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass); StatusBar->SetFace (&skins[p->userinfo.skin]); - // [RH] Be sure the player has the right translation - R_BuildPlayerTranslation (playernum); - // [RH] set color translations for player sprites - mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); + if (!(mobj->flags2 & MF2_DONTTRANSLATE)) + { + // [RH] Be sure the player has the right translation + R_BuildPlayerTranslation (playernum); + + // [RH] set color translations for player sprites + mobj->Translation = TRANSLATION(TRANSLATION_Players,playernum); + } mobj->angle = spawn_angle; mobj->pitch = mobj->roll = 0; From d773dcb6fb6f9d95054784b95ab2fed98ba2744e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 6 Mar 2010 14:58:15 +0000 Subject: [PATCH 32/88] - fixed: The 'any key' lock always returned success when checking for keys, even if the player had none. SVN r2199 (trunk) --- src/g_shared/a_keys.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_shared/a_keys.cpp b/src/g_shared/a_keys.cpp index 5ec5479e5..575d13592 100644 --- a/src/g_shared/a_keys.cpp +++ b/src/g_shared/a_keys.cpp @@ -68,6 +68,7 @@ struct Lock return true; } } + return false; } else for(unsigned int i=0;i Date: Sat, 6 Mar 2010 16:24:09 +0000 Subject: [PATCH 33/88] - check player translations for identity maps during creation. - fixed: When creating the initial identity translation for player translations the global palette remapping was not taken into account. SVN r2200 (trunk) --- src/r_translate.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/r_translate.cpp b/src/r_translate.cpp index 045dc3f41..d5ef79a1f 100644 --- a/src/r_translate.cpp +++ b/src/r_translate.cpp @@ -918,7 +918,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC { for (i = 0; i < table->NumEntries; ++i) { - table->Remap[i] = i; + table->Remap[i] = GPalette.Remap[i]; } memcpy(table->Palette, GPalette.BaseColors, sizeof(*table->Palette) * table->NumEntries); } @@ -935,6 +935,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC return; } + table->Inactive = false; range = (float)(end-start+1); bases = s; @@ -947,6 +948,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC if (colorset != NULL) { + bool identity = true; // Use the pre-defined range instead of a custom one. if (colorset->Lump < 0) { @@ -960,7 +962,9 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC int palrange = colorset->LastColor - first; for (i = start; i <= end; ++i) { - table->Remap[i] = GPalette.Remap[first + palrange * (i - start) / (end - start)]; + int pi = first + palrange * (i - start) / (end - start); + table->Remap[i] = GPalette.Remap[pi]; + if (pi != i) identity = false; } } } @@ -971,6 +975,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC for (i = start; i <= end; ++i) { table->Remap[i] = GPalette.Remap[trans[i]]; + if (trans[i] != i) identity = false; } } for (i = start; i <= end; ++i) @@ -978,6 +983,8 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC table->Palette[i] = GPalette.BaseColors[table->Remap[i]]; table->Palette[i].a = 255; } + // If the colorset created an identity translation mark it as inactive + table->Inactive = identity; } else if (gameinfo.gametype & GAME_DoomStrifeChex) { @@ -1083,7 +1090,6 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC } alttable->UpdateNative(); } - table->Inactive = false; table->UpdateNative(); } From 5a72e8d20e3ad8e6eb05002ad75c268bfc0d7525 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 7 Mar 2010 04:38:02 +0000 Subject: [PATCH 34/88] - Some minor changes to DUMB to match http://kode54.foobar2000.org/foo_dumb-dumb-lib_source.rar dated 2009-10-18. This version also added DSMI AMF support, but since I can't find a single song in this format, I'll hold off on including that unless somebody specifically requests it. SVN r2201 (trunk) --- dumb/src/helpers/resamp3.inc | 2 +- dumb/src/it/readam.c | 3 --- dumb/src/it/readoldpsm.c | 2 +- dumb/src/it/readpsm.c | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dumb/src/helpers/resamp3.inc b/dumb/src/helpers/resamp3.inc index a820e94c1..3d61bfff1 100644 --- a/dumb/src/helpers/resamp3.inc +++ b/dumb/src/helpers/resamp3.inc @@ -58,7 +58,7 @@ int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VO done = 0; dt = (int)(delta * 65536.0 + 0.5); - if (dt == 0) return 0; + if (dt == 0 || dt == 0x80000000) return 0; SET_VOLUME_VARIABLES; if (VOLUMES_ARE_ZERO) dst = NULL; diff --git a/dumb/src/it/readam.c b/dumb/src/it/readam.c index 70dafadcf..9910b1d82 100644 --- a/dumb/src/it/readam.c +++ b/dumb/src/it/readam.c @@ -24,9 +24,6 @@ #include "internal/it.h" #include "internal/riff.h" -DUH *dumb_read_riff_amff( struct riff * stream ); -DUH *dumb_read_riff_am( struct riff * stream ); - static int it_riff_am_process_sample( IT_SAMPLE * sample, const unsigned char * data, int len, int ver ) { int header_length; diff --git a/dumb/src/it/readoldpsm.c b/dumb/src/it/readoldpsm.c index 1d7260508..3c764af25 100644 --- a/dumb/src/it/readoldpsm.c +++ b/dumb/src/it/readoldpsm.c @@ -291,7 +291,7 @@ static int it_old_psm_read_patterns(IT_PATTERN * pattern, DUMBFILE * f, int num, if (channel >= chans) { //channel = 0; - goto error_fb; + //goto error_fb; } if (flags & 0x80) { if ((*ptr < 60) && (channel < pchans)) { diff --git a/dumb/src/it/readpsm.c b/dumb/src/it/readpsm.c index fa19943b9..68d7ab7dc 100644 --- a/dumb/src/it/readpsm.c +++ b/dumb/src/it/readpsm.c @@ -1271,7 +1271,7 @@ DUH *DUMBEXPORT dumb_read_psm_quick(DUMBFILE *f, int subsong) if ( ver ) { tag[2][0] = "FORMATVERSION"; - sprintf(version, "%d", ver); + itoa(ver, version, 10); tag[2][1] = (const char *) &version; ++n_tags; } From 0569d948dfd18041d707acdfb4c68b8e5fb2be37 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 7 Mar 2010 09:13:41 +0000 Subject: [PATCH 35/88] - added a 'player.clearcolorset' property so that inherited color sets can be removed. - fixed: Player color sets were not inheritable. SVN r2202 (trunk) --- src/d_player.h | 12 --------- src/dobjtype.cpp | 6 +++++ src/info.cpp | 19 ++++++++++++++ src/info.h | 19 ++++++++++++-- src/p_user.cpp | 38 ++++++++-------------------- src/thingdef/thingdef.cpp | 6 +++++ src/thingdef/thingdef_properties.cpp | 29 ++++++++++++++++----- 7 files changed, 80 insertions(+), 49 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 64d901329..2c77872e8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -71,18 +71,6 @@ enum APMETA_Slot9, }; -// Standard pre-defined skin colors -struct FPlayerColorSet -{ - FName Name; // Name of this color - - int Lump; // Lump to read the translation from, otherwise use next 2 fields - BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation - - BYTE RepresentativeColor; // A palette entry representative of this translation, - // for map arrows and status bar backgrounds and such -}; -void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset); FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum); void P_EnumPlayerColorSets(FName classname, TArray *out); diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 63d4a8423..b2622d1db 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -141,6 +141,11 @@ void PClass::StaticFreeData (PClass *type) delete type->ActorInfo->PainChances; type->ActorInfo->PainChances = NULL; } + if (type->ActorInfo->ColorSets != NULL) + { + delete type->ActorInfo->ColorSets; + type->ActorInfo->ColorSets = NULL; + } delete type->ActorInfo; type->ActorInfo = NULL; } @@ -311,6 +316,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size) info->StateList = NULL; info->DamageFactors = NULL; info->PainChances = NULL; + info->ColorSets = NULL; m_RuntimeActors.Push (type); } return type; diff --git a/src/info.cpp b/src/info.cpp index 89628e5b7..c3e5ac63e 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -309,6 +309,25 @@ void FActorInfo::SetPainChance(FName type, int chance) // //========================================================================== +void FActorInfo::SetColorSet(int index, const FPlayerColorSet *set) +{ + if (set != NULL) + { + if (ColorSets == NULL) ColorSets = new FPlayerColorSetMap; + ColorSets->Insert(index, *set); + } + else + { + if (ColorSets != NULL) + ColorSets->Remove(index); + } +} + +//========================================================================== +// +// +//========================================================================== + FDoomEdMap DoomEdMap; FDoomEdMap::FDoomEdEntry *FDoomEdMap::DoomEdHash[DOOMED_HASHSIZE]; diff --git a/src/info.h b/src/info.h index da248b9ce..82de9486c 100644 --- a/src/info.h +++ b/src/info.h @@ -145,8 +145,21 @@ FArchive &operator<< (FArchive &arc, FState *&state); #include "gametype.h" +// Standard pre-defined skin colors +struct FPlayerColorSet +{ + FName Name; // Name of this color + + int Lump; // Lump to read the translation from, otherwise use next 2 fields + BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation + + BYTE RepresentativeColor; // A palette entry representative of this translation, + // for map arrows and status bar backgrounds and such +}; + typedef TMap DmgFactors; typedef TMap PainChanceList; +typedef TMap FPlayerColorSetMap; struct FActorInfo { @@ -158,6 +171,7 @@ struct FActorInfo void RegisterIDs (); void SetDamageFactor(FName type, fixed_t factor); void SetPainChance(FName type, int chance); + void SetColorSet(int index, const FPlayerColorSet *set); FState *FindState (int numnames, FName *names, bool exact=false) const; FState *FindStateByString(const char *name, bool exact=false); @@ -177,9 +191,10 @@ struct FActorInfo BYTE GameFilter; BYTE SpawnID; SWORD DoomEdNum; - FStateLabels * StateList; + FStateLabels *StateList; DmgFactors *DamageFactors; - PainChanceList * PainChances; + PainChanceList *PainChances; + FPlayerColorSetMap *ColorSets; }; class FDoomEdMap diff --git a/src/p_user.cpp b/src/p_user.cpp index 78e6eeb2e..ec80954b4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -55,10 +55,6 @@ static FRandom pr_skullpop ("SkullPop"); -// Color set class name -> mapping table -typedef TMap FPlayerColorSetMap; -TMap PlayerToColorsMap; - // [RH] # of ticks to complete a turn180 #define TURN180_TICKS ((TICRATE / 4) + 1) @@ -2635,39 +2631,25 @@ void player_t::Serialize (FArchive &arc) } -static FPlayerColorSetMap *GetPlayerColors(FName classname, bool create) +static FPlayerColorSetMap *GetPlayerColors(FName classname) { - FPlayerColorSetMap *map, **value; + const PClass *cls = PClass::FindClass(classname); - value = PlayerToColorsMap.CheckKey(classname); - if (value == NULL) + if (cls != NULL) { - if (create) + FActorInfo *inf = cls->ActorInfo; + + if (inf != NULL) { - map = new FPlayerColorSetMap; - PlayerToColorsMap.Insert(classname, map); - } - else - { - map = NULL; + return inf->ColorSets; } } - else - { - map = *value; - } - return map; -} - -void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset) -{ - FPlayerColorSetMap *map = GetPlayerColors(classname, true); - (*map)[setnum] = *colorset; + return NULL; } FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum) { - FPlayerColorSetMap *map = GetPlayerColors(classname, false); + FPlayerColorSetMap *map = GetPlayerColors(classname); if (map == NULL) { return NULL; @@ -2683,7 +2665,7 @@ static int STACK_ARGS intcmp(const void *a, const void *b) void P_EnumPlayerColorSets(FName classname, TArray *out) { out->Clear(); - FPlayerColorSetMap *map = GetPlayerColors(classname, false); + FPlayerColorSetMap *map = GetPlayerColors(classname); if (map != NULL) { FPlayerColorSetMap::Iterator it(*map); diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index 5dcab6c60..6362c62fe 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -159,6 +159,12 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare info->PainChances = new PainChanceList; *info->PainChances = *parent->ActorInfo->PainChances; } + if (parent->ActorInfo->ColorSets != NULL) + { + // copy color sets from parent + info->ColorSets = new FPlayerColorSetMap; + *info->ColorSets = *parent->ActorInfo->ColorSets; + } info->Replacee = info->Replacement = NULL; info->DoomEdNum = -1; return info; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 5a8bfe0f5..0c2a8c96d 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -358,8 +358,7 @@ DEFINE_PROPERTY(painchance, ZI, Actor) if (!stricmp(str, "Normal")) painType = NAME_None; else painType=str; - if (info->PainChances == NULL) info->PainChances=new PainChanceList; - (*info->PainChances)[painType] = (BYTE)id; + info->SetPainChance(painType, id); } } @@ -953,13 +952,11 @@ DEFINE_PROPERTY(damagefactor, ZF, Actor) } else { - if (info->DamageFactors == NULL) info->DamageFactors=new DmgFactors; - FName dmgType; if (!stricmp(str, "Normal")) dmgType = NAME_None; else dmgType=str; - (*info->DamageFactors)[dmgType]=id; + info->SetDamageFactor(dmgType, id); } } @@ -1884,7 +1881,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn) } else { - P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + info->SetColorSet(setnum, &color); } } @@ -1908,9 +1905,27 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn) } else if (color.Lump >= 0) { - P_AddPlayerColorSet(info->Class->TypeName, setnum, &color); + info->SetColorSet(setnum, &color); } } + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(player, clearcolorset, I, PlayerPawn) +{ + PROP_INT_PARM(setnum, 0); + + if (setnum < 0) + { + bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n"); + } + else + { + info->SetColorSet(setnum, NULL); + } +} + //========================================================================== // //========================================================================== From 88269d5d60eece85ca602451f2b0ea2658174ed0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 7 Mar 2010 11:05:52 +0000 Subject: [PATCH 36/88] - fixed: The color sliders on the player setup menu were not disabled when a predefined colorset was selected. SVN r2203 (trunk) --- src/m_menu.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 7628b336e..299dbc53f 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -548,6 +548,14 @@ static oldmenuitem_t PlayerSetupMenu[] = { 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED} }; +enum +{ + // These must be changed if the menu definition is altered + PSM_RED = 3, + PSM_GREEN = 4, + PSM_BLUE = 5, +}; + static oldmenu_t PSetupDef = { countof(PlayerSetupMenu), @@ -2753,6 +2761,11 @@ static void M_ChangeColorSet (int choice) } mycolorset = (curpos >= 0) ? PlayerColorSets[curpos] : -1; + // disable the sliders if a valid colorset is selected + PlayerSetupMenu[PSM_RED].status = + PlayerSetupMenu[PSM_GREEN].status = + PlayerSetupMenu[PSM_BLUE].status = (mycolorset == -1? 2:-1); + char command[24]; mysnprintf(command, countof(command), "colorset %d", mycolorset); C_DoCommand(command); From 593a05077894b9436e0853b5ed6cb83d5e8fce98 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 7 Mar 2010 11:13:57 +0000 Subject: [PATCH 37/88] - fixed: Items spawned internally by ADehackedPickup::TryPickup must not count towards item statistics. SVN r2204 (trunk) --- src/d_dehacked.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 62c5090e2..a1ed9262f 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2894,6 +2894,12 @@ bool ADehackedPickup::TryPickup (AActor *&toucher) RealPickup = static_cast(Spawn (type, x, y, z, NO_REPLACE)); if (RealPickup != NULL) { + // The internally spawned item should never count towards statistics. + if (RealPickup->flags & MF_COUNTITEM) + { + RealPickup->flags &= ~MF_COUNTITEM; + level.total_items--; + } if (!(flags & MF_DROPPED)) { RealPickup->flags &= ~MF_DROPPED; From 1f12c3dd8e3b61ad41a5f05a1a4020e73f46e3c8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 9 Mar 2010 03:18:31 +0000 Subject: [PATCH 38/88] - Whoops. DXT5 decompression got the alpha values wrong. That's "wrong" as in "garbage", since yalphaslice was never initialized to anything. (I should probably test this to make sure I actually got it right now...) SVN r2205 (trunk) --- src/textures/ddstexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 3d68c4177..ab5b4505d 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -831,7 +831,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu break; } // Alpha values are stored in 3 bytes for 2 rows - if ((y & 0) == 0) + if ((y & 1) == 0) { yalphaslice = block[y*3] | (block[y*3+1] << 8) | (block[y*3+2] << 16); } From cf06cd68bc1def355dc45c54046f4c874375ca52 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 13 Mar 2010 00:08:33 +0000 Subject: [PATCH 39/88] - Changed FileExists() to use stat instead of fopen/fclose, which ought to be lower overhead for files that are present. SVN r2206 (trunk) --- src/cmdlib.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index 9942d27fc..dd32cdb55 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -148,17 +148,13 @@ int Q_filelength (FILE *f) bool FileExists (const char *filename) { - FILE *f; + struct stat buff; // [RH] Empty filenames are never there if (filename == NULL || *filename == 0) return false; - f = fopen (filename, "r"); - if (!f) - return false; - fclose (f); - return true; + return stat(filename, &buff) == 0 && !(buff.st_mode & S_IFDIR); } //========================================================================== From c191d95110f49299d9cfcfd550531a2004941c6f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 13 Mar 2010 08:28:13 +0000 Subject: [PATCH 40/88] - Fixed: Hexen's fighter's skull has a different animation than Heretic's so it needs to be a separate class. - Added an option to parse lumps named ZMAPINFO in place of MAPINFO. Any MAPINFO lumps in files containing a ZMAPINFO lump will be completely ignored. This is to allow ZDoom specific definitions which are incompatible with other engines capable of reading MAPINFO. Any ZMAPINFO lump must be in the new MAPINFO format. SVN r2208 (trunk) --- src/g_level.h | 4 +- src/g_mapinfo.cpp | 17 ++++++++- src/w_wad.cpp | 40 ++++++++++++++++++++ src/w_wad.h | 1 + wadsrc/static/actors/hexen/fighterplayer.txt | 27 ++++++++++++- 5 files changed, 84 insertions(+), 5 deletions(-) diff --git a/src/g_level.h b/src/g_level.h index 7ea2e3147..0e17b02b1 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -68,9 +68,9 @@ struct FMapInfoParser int format_type; bool HexenHack; - FMapInfoParser() + FMapInfoParser(int format = FMT_Unknown) { - format_type = FMT_Unknown; + format_type = format; HexenHack = false; } diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index f9fe5e829..09e8eb96a 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1929,10 +1929,23 @@ void G_ParseMapInfo (const char *basemapinfo) parse.ParseMapInfo(Wads.GetNumForFullName(basemapinfo), gamedefaults, defaultinfo); } + static const char *mapinfonames[] = { "MAPINFO", "ZMAPINFO", NULL }; + int nindex; + // Parse any extra MAPINFOs. - while ((lump = Wads.FindLump ("MAPINFO", &lastlump)) != -1) + while ((lump = Wads.FindLumpMulti (mapinfonames, &lastlump, false, &nindex)) != -1) { - FMapInfoParser parse; + if (nindex == 0) + { + // If this lump is named MAPINFO we need to check if the same WAD contains a ZMAPINFO lump. + // If that exists we need to skip this one. + + int wad = Wads.GetLumpFile(lump); + int altlump = Wads.CheckNumForName("ZMAPINFO", ns_global, wad, true); + + if (altlump >= 0) continue; + } + FMapInfoParser parse(nindex == 1? FMapInfoParser::FMT_New : FMapInfoParser::FMT_Unknown); level_info_t defaultinfo; parse.ParseMapInfo(lump, gamedefaults, defaultinfo); } diff --git a/src/w_wad.cpp b/src/w_wad.cpp index bb8deb384..68a8d4c3e 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -848,6 +848,46 @@ int FWadCollection::FindLump (const char *name, int *lastlump, bool anyns) return -1; } +//========================================================================== +// +// W_FindLumpMulti +// +// Find a named lump. Specifically allows duplicates for merging of e.g. +// SNDINFO lumps. Returns everything having one of the passed names. +// +//========================================================================== + +int FWadCollection::FindLumpMulti (const char **names, int *lastlump, bool anyns, int *nameindex) +{ + LumpRecord *lump_p; + + assert(lastlump != NULL && *lastlump >= 0); + lump_p = &LumpInfo[*lastlump]; + while (lump_p < &LumpInfo[NumLumps]) + { + FResourceLump *lump = lump_p->lump; + + if (anyns || lump->Namespace == ns_global) + { + + for(const char **name = names; *name != NULL; name++) + { + if (!strnicmp(*name, lump->Name, 8)) + { + int lump = int(lump_p - &LumpInfo[0]); + *lastlump = lump + 1; + if (nameindex != NULL) *nameindex = int(name - names); + return lump; + } + } + } + lump_p++; + } + + *lastlump = NumLumps; + return -1; +} + //========================================================================== // // W_CheckLumpName diff --git a/src/w_wad.h b/src/w_wad.h index 2edd71587..19129476f 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -182,6 +182,7 @@ public: FileReader * GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD int FindLump (const char *name, int *lastlump, bool anyns=false); // [RH] Find lumps with duplication + int FindLumpMulti (const char **names, int *lastlump, bool anyns = false, int *nameindex = NULL); // same with multiple possible names bool CheckLumpName (int lump, const char *name); // [RH] True if lump's name == name static DWORD LumpNameHash (const char *name); // [RH] Create hash key from an 8-char name diff --git a/wadsrc/static/actors/hexen/fighterplayer.txt b/wadsrc/static/actors/hexen/fighterplayer.txt index 277a2986b..2253ba5b6 100644 --- a/wadsrc/static/actors/hexen/fighterplayer.txt +++ b/wadsrc/static/actors/hexen/fighterplayer.txt @@ -64,7 +64,7 @@ ACTOR FighterPlayer : PlayerPawn Stop XDeath: PLAY O 5 A_PlayerScream - PLAY P 5 A_SkullPop + PLAY P 5 A_SkullPop("BloodyFighterSkull") PLAY R 5 A_NoBlocking PLAY STUV 5 PLAY W -1 @@ -99,3 +99,28 @@ ACTOR FighterPlayer : PlayerPawn } } +// The fighter's bloody skull -------------------------------------------------------------- + +Actor BloodyFighterSkull : PlayerChunk +{ + Game Hexen + Radius 4 + Height 4 + +NOBLOCKMAP + +DROPOFF + +LOWGRAVITY + +CANNOTPUSH + +SKYEXPLODE + +NOBLOCKMONST + +NOSKIN + States + { + Spawn: + BSKL A 0 + BSKL ABCDFGH 5 A_CheckFloor("Hit") + Goto Spawn+1 + Hit: + BSKL I 16 A_CheckPlayerDone + Wait + } +} From f24c0cf292eab9b84c26af3bc98107563abdb07d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 14 Mar 2010 04:03:07 +0000 Subject: [PATCH 41/88] - Merge scanner changes from the scripting branch, since I'm pretty sure the token names were out of sync here, too. SVN r2209 (trunk) --- src/sc_man.cpp | 114 +------------------------------------- src/sc_man.h | 116 +-------------------------------------- src/sc_man_scanner.re | 13 +++++ src/sc_man_tokens.h | 125 ++++++++++++++++++++++++++++++++++++++++++ zdoom.vcproj | 4 ++ 5 files changed, 148 insertions(+), 224 deletions(-) create mode 100644 src/sc_man_tokens.h diff --git a/src/sc_man.cpp b/src/sc_man.cpp index b69aa1ce0..298676dc6 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -812,116 +812,8 @@ FString FScanner::TokenName (int token, const char *string) { static const char *const names[] = { - "identifier", - "string constant", - "name constant", - "integer constant", - "float constant", - "'...'", - "'>>='", - "'<<='", - "'+='", - "'-='", - "'*='", - "'/='", - "'%='", - "'&='", - "'^='", - "'|='", - "'>>'", - "'>>>'", - "'<<'", - "'++'", - "'--'", - "'&&'", - "'||'", - "'<='", - "'>='", - "'=='", - "'!='", - "'action'", - "'break'", - "'case'", - "'const'", - "'continue'", - "'default'", - "'do'", - "'else'", - "'for'", - "'if'", - "'return'", - "'states'", - "'switch'", - "'until'", - "'while'", - "'bool'", - "'float'", - "'double'", - "'char'", - "'byte'", - "'sbyte'", - "'short'", - "'ushort'", - "'int'", - "'uint'", - "'long'", - "'ulong'", - "'void'", - "'struct'", - "'class'", - "'mode'", - "'enum'", - "'name'", - "'string'", - "'sound'", - "'state'", - "'color'", - "'goto'", - "'abstract'", - "'foreach'", - "'true'", - "'false'", - "'none'", - "'new'", - "'instanceof'", - "'auto'", - "'exec'", - "'defaultproperties'", - "'native'", - "'out'", - "'ref'", - "'event'", - "'static'", - "'transient'", - "'volatile'", - "'final'", - "'throws'", - "'extends'", - "'public'", - "'protected'", - "'private'", - "'dot'", - "'cross'", - "'ignores'", - "'localized'", - "'latent'", - "'singular'", - "'config'", - "'coerce'", - "'iterator'", - "'optional'", - "'export'", - "'virtual'", - "'super'", - "'global'", - "'self'", - "'stop'", - "'#include'", - "'fixed_t'", - "'angle_t'", - "'abs'", - "'random'", - "'random2'" +#define xx(sym,str) str, +#include "sc_man_tokens.h" }; FString work; @@ -992,7 +884,7 @@ void STACK_ARGS FScanner::ScriptError (const char *message, ...) //========================================================================== // -// FScanner::ScriptError +// FScanner::ScriptMessage // //========================================================================== diff --git a/src/sc_man.h b/src/sc_man.h index 1e5dc289d..777e8cdcd 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -99,119 +99,9 @@ protected: enum { - TK_Identifier = 257, - TK_StringConst, - TK_NameConst, - TK_IntConst, - TK_FloatConst, - TK_Ellipsis, // ... - TK_RShiftEq, // >>= - TK_URShiftEq, // >>>= - TK_LShiftEq, // <<= - TK_AddEq, // += - TK_SubEq, // -= - TK_MulEq, // *= - TK_DivEq, // /= - TK_ModEq, // %= - TK_AndEq, // &= - TK_XorEq, // ^= - TK_OrEq, // |= - TK_RShift, // >> - TK_URShift, // >>> - TK_LShift, // << - TK_Incr, // ++ - TK_Decr, // -- - TK_AndAnd, // && - TK_OrOr, // || - TK_Leq, // <= - TK_Geq, // >= - TK_Eq, // == - TK_Neq, // != - TK_Action, - TK_Break, - TK_Case, - TK_Const, - TK_Continue, - TK_Default, - TK_Do, - TK_Else, - TK_For, - TK_If, - TK_Return, - TK_Switch, - TK_Until, - TK_While, - TK_Bool, - TK_Float, - TK_Double, - TK_Char, - TK_Byte, - TK_SByte, - TK_Short, - TK_UShort, - TK_Int, - TK_UInt, - TK_Long, - TK_ULong, - TK_Void, - TK_Struct, - TK_Class, - TK_Mode, - TK_Enum, - TK_Name, - TK_String, - TK_Sound, - TK_State, - TK_Color, - TK_Goto, - TK_Abstract, - TK_ForEach, - TK_True, - TK_False, - TK_None, - TK_New, - TK_InstanceOf, - TK_Auto, - TK_Exec, - TK_DefaultProperties, - TK_Native, - TK_Var, - TK_Out, - TK_Ref, - TK_Event, - TK_Static, - TK_Transient, - TK_Volatile, - TK_Final, - TK_Throws, - TK_Extends, - TK_Public, - TK_Protected, - TK_Private, - TK_Dot, - TK_Cross, - TK_Ignores, - TK_Localized, - TK_Latent, - TK_Singular, - TK_Config, - TK_Coerce, - TK_Iterator, - TK_Optional, - TK_Export, - TK_Virtual, - TK_Super, - TK_Global, - TK_Self, - TK_Stop, - TK_Include, - TK_Fixed_t, - TK_Angle_t, - TK_Abs, - TK_Random, - TK_Random2, - TK_FRandom, - + TK_SequenceStart = 256, +#define xx(sym,str) sym, +#include "sc_man_tokens.h" TK_LastToken }; diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index ff0945db3..66058ac8c 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -96,6 +96,12 @@ std2: 'sound' { RET(TK_Sound); } 'state' { RET(TK_State); } 'color' { RET(TK_Color); } + 'vector' { RET(TK_Vector); } + 'map' { RET(TK_Map); } + 'array' { RET(TK_Array); } + 'in' { RET(TK_In); } + 'sizeof' { RET(TK_SizeOf); } + 'alignof' { RET(TK_AlignOf); } /* Other keywords from UnrealScript */ 'abstract' { RET(TK_Abstract); } @@ -138,6 +144,9 @@ std2: 'self' { RET(TK_Self); } 'stop' { RET(TK_Stop); } + 'is' { RET(TK_Is); } + 'replaces' { RET(TK_Replaces); } + /* Needed for decorate action functions */ 'action' { RET(TK_Action); } @@ -164,6 +173,7 @@ std2: (['] (any\[\n'])* [']) { RET(TK_NameConst); } + ".." { RET(TK_DotDot); } "..." { RET(TK_Ellipsis); } ">>>=" { RET(TK_URShiftEq); } ">>=" { RET(TK_RShiftEq); } @@ -187,6 +197,9 @@ std2: ">=" { RET(TK_Geq); } "==" { RET(TK_Eq); } "!=" { RET(TK_Neq); } + "~==" { RET(TK_ApproxEq); } + "<>=" { RET(TK_LtGtEq); } + "**" { RET(TK_MulMul); } ";" { RET(';'); } "{" { RET('{'); } "}" { RET('}'); } diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h new file mode 100644 index 000000000..9dde74972 --- /dev/null +++ b/src/sc_man_tokens.h @@ -0,0 +1,125 @@ +xx(TK_Identifier, "identifier") +xx(TK_StringConst, "string constant") +xx(TK_NameConst, "name constant") +xx(TK_IntConst, "integer constant") +xx(TK_FloatConst, "float constant") +xx(TK_DotDot, "'..'") +xx(TK_Ellipsis, "'...'") +xx(TK_RShiftEq, "'>>='") +xx(TK_URShiftEq, "'>>>='") +xx(TK_LShiftEq, "'<<='") +xx(TK_AddEq, "'+='") +xx(TK_SubEq, "'-='") +xx(TK_MulEq, "'*='") +xx(TK_DivEq, "'/='") +xx(TK_ModEq, "'%='") +xx(TK_AndEq, "'&='") +xx(TK_XorEq, "'^='") +xx(TK_OrEq, "'|='") +xx(TK_RShift, "'>>'") +xx(TK_URShift, "'>>>'") +xx(TK_LShift, "'<<'") +xx(TK_Incr, "'++'") +xx(TK_Decr, "'--'") +xx(TK_AndAnd, "'&&'") +xx(TK_OrOr, "'||'") +xx(TK_Leq, "'<='") +xx(TK_Geq, "'>='") +xx(TK_Eq, "'=='") +xx(TK_Neq, "'!='") +xx(TK_ApproxEq, "'~=='") +xx(TK_LtGtEq, "'<>='") +xx(TK_MulMul, "'**'") +xx(TK_Action, "'action'") +xx(TK_Break, "'break'") +xx(TK_Case, "'case'") +xx(TK_Const, "'const'") +xx(TK_Continue, "'continue'") +xx(TK_Default, "'default'") +xx(TK_Do, "'do'") +xx(TK_Else, "'else'") +xx(TK_For, "'for'") +xx(TK_If, "'if'") +xx(TK_Return, "'return'") +xx(TK_Switch, "'switch'") +xx(TK_Until, "'until'") +xx(TK_While, "'while'") +xx(TK_Bool, "'bool'") +xx(TK_Float, "'float'") +xx(TK_Double, "'double'") +xx(TK_Char, "'char'") +xx(TK_Byte, "'byte'") +xx(TK_SByte, "'sbyte'") +xx(TK_Short, "'short'") +xx(TK_UShort, "'ushort'") +xx(TK_Int, "'int'") +xx(TK_UInt, "'uint'") +xx(TK_Long, "'long'") +xx(TK_ULong, "'ulong'") +xx(TK_Void, "'void'") +xx(TK_Struct, "'struct'") +xx(TK_Class, "'class'") +xx(TK_Mode, "'mode'") +xx(TK_Enum, "'enum'") +xx(TK_Name, "'name'") +xx(TK_String, "'string'") +xx(TK_Sound, "'sound'") +xx(TK_State, "'state'") +xx(TK_Color, "'color'") +xx(TK_Goto, "'goto'") +xx(TK_Abstract, "'abstract'") +xx(TK_ForEach, "'foreach'") +xx(TK_True, "'true'") +xx(TK_False, "'false'") +xx(TK_None, "'none'") +xx(TK_New, "'new'") +xx(TK_InstanceOf, "'instanceof'") +xx(TK_Auto, "'auto'") +xx(TK_Exec, "'exec'") +xx(TK_DefaultProperties, "'defaultproperties'") +xx(TK_Native, "'native'") +xx(TK_Var, "'var'") +xx(TK_Out, "'out'") +xx(TK_Ref, "'ref'") +xx(TK_Event, "'event'") +xx(TK_Static, "'static'") +xx(TK_Transient, "'transient'") +xx(TK_Volatile, "'volatile'") +xx(TK_Final, "'final'") +xx(TK_Throws, "'throws'") +xx(TK_Extends, "'extends'") +xx(TK_Public, "'public'") +xx(TK_Protected, "'protected'") +xx(TK_Private, "'private'") +xx(TK_Dot, "'dot'") +xx(TK_Cross, "'cross'") +xx(TK_Ignores, "'ignores'") +xx(TK_Localized, "'localized'") +xx(TK_Latent, "'latent'") +xx(TK_Singular, "'singular'") +xx(TK_Config, "'config'") +xx(TK_Coerce, "'coerce'") +xx(TK_Iterator, "'iterator'") +xx(TK_Optional, "'optional'") +xx(TK_Export, "'expert'") +xx(TK_Virtual, "'virtual'") +xx(TK_Super, "'super'") +xx(TK_Global, "'global'") +xx(TK_Self, "'self'") +xx(TK_Stop, "'stop'") +xx(TK_Include, "'include'") +xx(TK_Fixed_t, "'fixed_t'") +xx(TK_Angle_t, "'angle_t'") +xx(TK_Abs, "'abs'") +xx(TK_Random, "'random'") +xx(TK_Random2, "'random2'") +xx(TK_FRandom, "'frandom'") +xx(TK_Is, "'is'") +xx(TK_Replaces, "'replaces'") +xx(TK_Vector, "'vector'") +xx(TK_Map, "'map'") +xx(TK_Array, "'array'") +xx(TK_In, "'in'") +xx(TK_SizeOf, "'sizeof'") +xx(TK_AlignOf, "'alignof'") +#undef xx diff --git a/zdoom.vcproj b/zdoom.vcproj index 793cce76c..2cee5d413 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1501,6 +1501,10 @@ RelativePath=".\src\sc_man.h" > + + From 635759ee2cc1618c96855aff3346dbea4d5186c8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 14 Mar 2010 15:17:36 +0000 Subject: [PATCH 42/88] - fixed: UpdateSegBBox only used the first seg of a linedef to calculate the linedef's bounding box. SVN r2210 (trunk) --- src/po_man.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/po_man.cpp b/src/po_man.cpp index 8ed58cf8c..13a5bda91 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -795,25 +795,25 @@ static void UpdateSegBBox (seg_t *seg) line = seg->linedef; - if (seg->v1->x < seg->v2->x) + if (line->v1->x < line->v2->x) { - line->bbox[BOXLEFT] = seg->v1->x; - line->bbox[BOXRIGHT] = seg->v2->x; + line->bbox[BOXLEFT] = line->v1->x; + line->bbox[BOXRIGHT] = line->v2->x; } else { - line->bbox[BOXLEFT] = seg->v2->x; - line->bbox[BOXRIGHT] = seg->v1->x; + line->bbox[BOXLEFT] = line->v2->x; + line->bbox[BOXRIGHT] = line->v1->x; } - if (seg->v1->y < seg->v2->y) + if (line->v1->y < line->v2->y) { - line->bbox[BOXBOTTOM] = seg->v1->y; - line->bbox[BOXTOP] = seg->v2->y; + line->bbox[BOXBOTTOM] = line->v1->y; + line->bbox[BOXTOP] = line->v2->y; } else { - line->bbox[BOXBOTTOM] = seg->v2->y; - line->bbox[BOXTOP] = seg->v1->y; + line->bbox[BOXBOTTOM] = line->v2->y; + line->bbox[BOXTOP] = line->v1->y; } // Update the line's slopetype From 4963f5d35a77d134abf4230581d1687cbff7ee07 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 14 Mar 2010 17:24:08 +0000 Subject: [PATCH 43/88] - Meh. Linux does not have itoa. SVN r2211 (trunk) --- dumb/CMakeLists.txt | 7 +++++++ dumb/src/it/readpsm.c | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/dumb/CMakeLists.txt b/dumb/CMakeLists.txt index 85cbaeb55..c2cbe8d1b 100644 --- a/dumb/CMakeLists.txt +++ b/dumb/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) +include( CheckFunctionExists ) + # DUMB is much slower in a Debug build than a Release build, so we force a Release # build here, since we're not maintaining DUMB, only using it. # Comment out the below line to allow Debug builds. @@ -13,6 +15,11 @@ if( CMAKE_COMPILER_IS_GNUC ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-pointer-sign -Wno-uninitialized" ) endif( CMAKE_COMPILER_IS_GNUC ) +CHECK_FUNCTION_EXISTS( itoa ITOA_EXISTS ) +if( NOT ITOA_EXISTS ) + add_definitions( -DNEED_ITOA=1 ) +endif( NOT ITOA_EXISTS ) + include_directories( include ) add_library( dumb diff --git a/dumb/src/it/readpsm.c b/dumb/src/it/readpsm.c index 68d7ab7dc..d6fc099c5 100644 --- a/dumb/src/it/readpsm.c +++ b/dumb/src/it/readpsm.c @@ -1271,7 +1271,11 @@ DUH *DUMBEXPORT dumb_read_psm_quick(DUMBFILE *f, int subsong) if ( ver ) { tag[2][0] = "FORMATVERSION"; +#if NEED_ITOA + sprintf(version, "%d", ver); +#else itoa(ver, version, 10); +#endif tag[2][1] = (const char *) &version; ++n_tags; } From 4d7029296440afba0101a921687777886e990743 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 17 Mar 2010 23:17:39 +0000 Subject: [PATCH 44/88] - fixed: Save percentage of Doom's armor bonus was too low. SVN r2212 (trunk) --- wadsrc/static/actors/doom/doomarmor.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/actors/doom/doomarmor.txt b/wadsrc/static/actors/doom/doomarmor.txt index 0474ee041..486fc0611 100644 --- a/wadsrc/static/actors/doom/doomarmor.txt +++ b/wadsrc/static/actors/doom/doomarmor.txt @@ -9,7 +9,7 @@ Actor ArmorBonus : BasicArmorBonus 2015 Height 16 Inventory.Pickupmessage "$GOTARMBONUS" Inventory.Icon "ARM1A0" - Armor.Savepercent 33.33333 + Armor.Savepercent 33.335 Armor.Saveamount 1 Armor.Maxsaveamount 200 +COUNTITEM From c8b8f4035665259f80bdfc077c6958f8a99a4a97 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 00:30:45 +0000 Subject: [PATCH 45/88] - Fix some GCC warnings. SVN r2213 (trunk) --- src/nodebuild.cpp | 2 +- src/textures/ddstexture.cpp | 2 +- src/v_text.cpp | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/nodebuild.cpp b/src/nodebuild.cpp index 90aaff492..83393f7c3 100644 --- a/src/nodebuild.cpp +++ b/src/nodebuild.cpp @@ -789,7 +789,7 @@ void FNodeBuilder::SplitSegs (DWORD set, node_t &node, DWORD splitseg, DWORD &ou newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y)); vertnum = VertexMap->SelectVertexClose (newvert); - if (vertnum == seg->v1 || vertnum == seg->v2) + if (vertnum == (unsigned int)seg->v1 || vertnum == (unsigned int)seg->v2) { Printf("SelectVertexClose selected endpoint of seg %u\n", set); } diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index ab5b4505d..da9ec5955 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -769,7 +769,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu BYTE *block; PalEntry color[4]; BYTE palcol[4]; - DWORD yalphaslice; + DWORD yalphaslice = 0; int ox, oy, x, y, i; for (oy = 0; oy < Height; oy += 4) diff --git a/src/v_text.cpp b/src/v_text.cpp index 715e06093..55dbcc774 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -317,7 +317,8 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) FBrokenLines lines[128]; // Support up to 128 lines (should be plenty) const BYTE *space = NULL, *start = string; - int i, c, w, nw; + size_t i, ii; + int c, w, nw; FString lastcolor, linecolor; bool lastWasSpace = false; int kerning = font->GetDefaultKerning (); @@ -418,11 +419,11 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string) // Make a copy of the broken lines and return them FBrokenLines *broken = new FBrokenLines[i+1]; - for (c = 0; c < i; ++c) + for (ii = 0; ii < i; ++ii) { - broken[c] = lines[c]; + broken[ii] = lines[ii]; } - broken[c].Width = -1; + broken[ii].Width = -1; return broken; } From c079a3ea5b3fe92aa583289acfbf87ba96501e1a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 00:32:35 +0000 Subject: [PATCH 46/88] - Add more parameters to the ambient sound things: * Second argument: Volume scalar. 0 and 128 are normal volume. (Where "normal" is whatever it was defined with in SNDINFO.) Other values scale it accordingly. * Third argument: Minimum distance before volume fading starts. * Fourth argument: Maximum distance at which the sound is audible. Setting either of these to 0 will use whatever they were defined with in SNDINFO. SVN r2214 (trunk) --- src/s_advsound.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++- src/s_sound.cpp | 49 ++++++++++++++++++++++++++++++++++----- src/s_sound.h | 1 + 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 14742f55d..aa9de0039 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1912,6 +1912,12 @@ private: IMPLEMENT_CLASS (AAmbientSound) +//========================================================================== +// +// AmbientSound :: Serialize +// +//========================================================================== + void AAmbientSound::Serialize (FArchive &arc) { Super::Serialize (arc); @@ -1948,6 +1954,11 @@ void AAmbientSound::Serialize (FArchive &arc) } } +//========================================================================== +// +// AmbientSound :: Tick +// +//========================================================================== void AAmbientSound::Tick () { @@ -1966,7 +1977,24 @@ void AAmbientSound::Tick () if (ambient->sound[0]) { - S_Sound(this, CHAN_BODY | loop, ambient->sound, ambient->volume, ambient->attenuation); + // The second argumens scales the ambient sound's volume. + // 0 and 128 are normal volume. The maximum volume level + // possible is always 1. + float volscale = args[1] == 0 ? 1 : args[1] / 128.f; + float usevol = clamp(ambient->volume * volscale, 0.f, 1.f); + + // The third argument is the minimum distance for audible fading, and + // the fourth argument is the maximum distance for audibility. Setting + // either of these to 0 or setting min distance > max distance will + // use the standard rolloff. + if ((args[2] | args[3]) == 0 || args[2] > args[3]) + { + S_Sound(this, CHAN_BODY | loop, ambient->sound, usevol, ambient->attenuation); + } + else + { + S_SoundMinMaxDist(this, CHAN_BODY | loop, ambient->sound, usevol, float(args[2]), float(args[3])); + } if (!loop) { SetTicker (ambient); @@ -1982,6 +2010,11 @@ void AAmbientSound::Tick () } } +//========================================================================== +// +// AmbientSound :: SetTicker +// +//========================================================================== void AAmbientSound::SetTicker (struct AmbientSound *ambient) { @@ -2001,12 +2034,26 @@ void AAmbientSound::SetTicker (struct AmbientSound *ambient) } } +//========================================================================== +// +// AmbientSound :: BeginPlay +// +//========================================================================== + void AAmbientSound::BeginPlay () { Super::BeginPlay (); Activate (NULL); } +//========================================================================== +// +// AmbientSound :: Activate +// +// Starts playing a sound (or does nothing of the sound is already playing). +// +//========================================================================== + void AAmbientSound::Activate (AActor *activator) { Super::Activate (activator); @@ -2040,6 +2087,15 @@ void AAmbientSound::Activate (AActor *activator) } } +//========================================================================== +// +// AmbientSound :: Deactivate +// +// Stops playing CONTINUOUS sounds immediately. Also prevents further +// occurrences of repeated sounds. +// +//========================================================================== + void AAmbientSound::Deactivate (AActor *activator) { Super::Deactivate (activator); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 48f5e9e9d..f309499df 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -108,7 +108,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, co static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z); static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z); static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly, - const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation); + const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff); static void S_SetListener(SoundListener &listener, AActor *listenactor); // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -808,7 +808,8 @@ static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fi //========================================================================== static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyObj *poly, - const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation) + const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, + FRolloffInfo *forcedrolloff=NULL) { sfxinfo_t *sfx; int chanflags; @@ -894,7 +895,10 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO near_limit = S_sfx[sound_id].NearLimit; limit_range = S_sfx[sound_id].LimitRange; } - if (rolloff->MinDistance == 0) rolloff = &S_sfx[sound_id].Rolloff; + if (rolloff->MinDistance == 0) + { + rolloff = &S_sfx[sound_id].Rolloff; + } } else { @@ -904,13 +908,25 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO near_limit = S_sfx[sound_id].NearLimit; limit_range = S_sfx[sound_id].LimitRange; } - if (rolloff->MinDistance == 0) rolloff = &S_sfx[sound_id].Rolloff; + if (rolloff->MinDistance == 0) + { + rolloff = &S_sfx[sound_id].Rolloff; + } } sfx = &S_sfx[sound_id]; } - // If no valid rolloff was set use the global default - if (rolloff->MinDistance == 0) rolloff = &S_Rolloff; + // The passed rolloff overrides any sound-specific rolloff. + if (forcedrolloff != NULL && forcedrolloff->MinDistance != 0) + { + rolloff = forcedrolloff; + } + + // If no valid rolloff was set, use the global default. + if (rolloff->MinDistance == 0) + { + rolloff = &S_Rolloff; + } // If this is a singular sound, don't play it if it's already playing. if (sfx->bSingular && S_CheckSingular(sound_id)) @@ -1180,6 +1196,27 @@ void S_Sound (AActor *ent, int channel, FSoundID sound_id, float volume, float a S_StartSound (ent, NULL, NULL, NULL, channel, sound_id, volume, attenuation); } +//========================================================================== +// +// S_SoundMinMaxDist - An actor is source +// +// Attenuation is specified as min and max distances, rather than a scalar. +// +//========================================================================== + +void S_SoundMinMaxDist(AActor *ent, int channel, FSoundID sound_id, float volume, float mindist, float maxdist) +{ + if (ent == NULL || ent->Sector->Flags & SECF_SILENT) + return; + + FRolloffInfo rolloff; + + rolloff.RolloffType = ROLLOFF_Doom; + rolloff.MinDistance = mindist; + rolloff.MaxDistance = maxdist; + S_StartSound(ent, NULL, NULL, NULL, channel, sound_id, volume, 1, &rolloff); +} + //========================================================================== // // S_Sound - A polyobject is source diff --git a/src/s_sound.h b/src/s_sound.h index 4dbf52aac..9ba10ac73 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -218,6 +218,7 @@ void S_CacheSound (sfxinfo_t *sfx); // Start sound for thing at void S_Sound (int channel, FSoundID sfxid, float volume, float attenuation); void S_Sound (AActor *ent, int channel, FSoundID sfxid, float volume, float attenuation); +void S_SoundMinMaxDist (AActor *ent, int channel, FSoundID sfxid, float volume, float mindist, float maxdist); void S_Sound (const FPolyObj *poly, int channel, FSoundID sfxid, float volume, float attenuation); void S_Sound (const sector_t *sec, int channel, FSoundID sfxid, float volume, float attenuation); void S_Sound (fixed_t x, fixed_t y, fixed_t z, int channel, FSoundID sfxid, float volume, float attenuation); From 970cf6f71b8894123793abcd4ed26c8a860da22d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 00:48:56 +0000 Subject: [PATCH 47/88] - Fixed endianness assumption when loading external map files. SVN r2215 (trunk) --- src/p_setup.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 0afb49be4..c1a345d8e 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -404,7 +404,8 @@ MapData *P_OpenMapData(const char * mapname) } } DWORD id; - (*map->file) >> id; + + map->file->Read(&id, sizeof(id)); if (id == IWAD_ID || id == PWAD_ID) { From 054e5411bd9cd996a35b177b84ceb20636076d20 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 01:07:50 +0000 Subject: [PATCH 48/88] - Fixed: Checking for BUILD maps only worked if they came from unencrypted and uncompressed sources. SVN r2216 (trunk) --- src/p_buildmap.cpp | 6 ++++-- src/p_setup.cpp | 17 ++++++++++------- src/resourcefiles/file_rff.cpp | 10 ++++++++-- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 5799ef563..2ea8632b3 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -145,8 +145,10 @@ static void Decrypt (void *to, const void *from, int len, int key); bool P_IsBuildMap(MapData *map) { DWORD len = map->Size(ML_LABEL); - if (len < 4) return false; - + if (len < 4) + { + return false; + } BYTE *data = new BYTE[len]; map->Seek(ML_LABEL); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c1a345d8e..f4d2fb379 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -294,8 +294,10 @@ MapData *P_OpenMapData(const char * mapname) { // The following lump is from a different file so whatever this is, // it is not a multi-lump Doom level so let's assume it is a Build map. - map->MapLumps[0].FilePos = Wads.GetLumpOffset(lump_name); + map->MapLumps[0].FilePos = 0; map->MapLumps[0].Size = Wads.LumpLength(lump_name); + map->file = Wads.ReopenLumpNum(lump_name); + map->CloseOnDestruct = true; if (!P_IsBuildMap(map)) { delete map; @@ -312,6 +314,9 @@ MapData *P_OpenMapData(const char * mapname) if (map->Encrypted) { // If it's encrypted, then it's a Blood file, presumably a map. + map->file = Wads.ReopenLumpNum(lump_name); + map->CloseOnDestruct = true; + map->MapLumps[0].FilePos = 0; if (!P_IsBuildMap(map)) { delete map; @@ -322,7 +327,7 @@ MapData *P_OpenMapData(const char * mapname) int index = 0; - if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP")) + if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP") != 0) { for(int i = 1;; i++) { @@ -3380,7 +3385,7 @@ void P_SetupLevel (char *lumpname, int position) P_FreeLevelData (); interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. - MapData * map = P_OpenMapData(lumpname); + MapData *map = P_OpenMapData(lumpname); if (map == NULL) { I_Error("Unable to open map '%s'\n", lumpname); @@ -3396,11 +3401,9 @@ void P_SetupLevel (char *lumpname, int position) BYTE *mapdata = new BYTE[map->MapLumps[0].Size]; map->Seek(0); map->file->Read(mapdata, map->MapLumps[0].Size); - if (map->Encrypted) - { - BloodCrypt (mapdata, 0, MIN (map->MapLumps[0].Size, 256)); - } + times[0].Clock(); buildmap = P_LoadBuildMap (mapdata, map->MapLumps[0].Size, &buildthings, &numbuildthings); + times[0].Unclock(); delete[] mapdata; } diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index bb2616c2b..f2854031c 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -197,8 +197,14 @@ FileReader *FRFFLump::GetReader() { // Don't return the reader if this lump is encrypted // In that case always force caching of the lump - if (!(Flags & LUMPF_BLOODCRYPT)) return FUncompressedLump::GetReader(); - else return NULL; + if (!(Flags & LUMPF_BLOODCRYPT)) + { + return FUncompressedLump::GetReader(); + } + else + { + return NULL; + } } //========================================================================== From 8e104d0a287253a7e770096da7ea1314e999e2c0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 01:48:48 +0000 Subject: [PATCH 49/88] - Fixed: RFF files constructed incorrect full names for the files they contained. SVN r2217 (trunk) --- src/resourcefiles/file_rff.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index f2854031c..902784ae3 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -163,17 +163,19 @@ bool FRFFFile::Open(bool quiet) { Lumps[i].Namespace = ns_global; } - Lumps[i].Position = LittleLong(lumps[i].FilePos); Lumps[i].LumpSize = LittleLong(lumps[i].Size); Lumps[i].Owner = this; - if (lumps[i].Flags & 0x10) Lumps[i].Flags |= LUMPF_BLOODCRYPT; - + if (lumps[i].Flags & 0x10) + { + Lumps[i].Flags |= LUMPF_BLOODCRYPT; + } // Rearrange the name and extension in a part of the lump record - // that I don't have any use for in order to cnstruct the fullname. + // that I don't have any use for in order to construct the fullname. lumps[i].Name[8] = '\0'; strcpy ((char *)lumps[i].IDontKnow, lumps[i].Name); strcat ((char *)lumps[i].IDontKnow, "."); + lumps[i].Name[0] = '\0'; strcat ((char *)lumps[i].IDontKnow, lumps[i].Extension); Lumps[i].LumpNameSetup((char *)lumps[i].IDontKnow); } @@ -183,7 +185,10 @@ bool FRFFFile::Open(bool quiet) FRFFFile::~FRFFFile() { - if (Lumps != NULL) delete [] Lumps; + if (Lumps != NULL) + { + delete[] Lumps; + } } From 92890066b6fa1740445a3f6bd04dc0b33e06e6b8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 02:09:08 +0000 Subject: [PATCH 50/88] - Fixed: The BUILD map loader did not create extsector information, and it also did not set valid sidedef references for the backs of one-sided lines. SVN r2218 (trunk) --- src/p_buildmap.cpp | 26 ++++++++++++++++---------- src/p_setup.cpp | 6 ++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 2ea8632b3..581665f76 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -253,11 +253,11 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * { memcpy (infoBlock, data + 6, 37); } - numRevisions = *(DWORD *)(infoBlock + 27); - numsectors = *(WORD *)(infoBlock + 31); - numWalls = *(WORD *)(infoBlock + 33); - numsprites = *(WORD *)(infoBlock + 35); - skyLen = 2 << *(WORD *)(infoBlock + 16); + numRevisions = LittleLong(*(DWORD *)(infoBlock + 27)); + numsectors = LittleShort(*(WORD *)(infoBlock + 31)); + numWalls = LittleShort(*(WORD *)(infoBlock + 33)); + numsprites = LittleShort(*(WORD *)(infoBlock + 35)); + skyLen = 2 << LittleShort(*(WORD *)(infoBlock + 16)); if (mapver == 7) { @@ -365,6 +365,8 @@ static void LoadSectors (sectortype *bsec) sec = sectors = new sector_t[numsectors]; memset (sectors, 0, sizeof(sector_t)*numsectors); + sectors[0].e = new extsector_t[numsectors]; + for (int i = 0; i < numsectors; ++i, ++bsec, ++sec) { bsec->wallptr = WORD(bsec->wallptr); @@ -372,6 +374,7 @@ static void LoadSectors (sectortype *bsec) bsec->ceilingstat = WORD(bsec->ceilingstat); bsec->floorstat = WORD(bsec->floorstat); + sec->e = §ors[0].e[i]; sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8)); sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor); sec->floorplane.c = FRACUNIT; @@ -633,14 +636,17 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) R_AlignFlat (linenum, sidenum == bsec->wallptr, 0); } } - for(i = 0; i < numsides; i++) + for (i = 0; i < numlines; i++) { - sides[i].linedef = &lines[intptr_t(sides[i].linedef)]; + intptr_t front = intptr_t(lines[i].sidedef[0]); + intptr_t back = intptr_t(lines[i].sidedef[1]); + lines[i].sidedef[0] = front >= 0 ? &sides[front] : NULL; + lines[i].sidedef[1] = back >= 0 ? &sides[back] : NULL; } - for(i = 0; i < numlines; i++) + for (i = 0; i < numsides; i++) { - lines[i].sidedef[0] = &sides[intptr_t(lines[i].sidedef[0])]; - lines[i].sidedef[1] = &sides[intptr_t(lines[i].sidedef[1])]; + assert(sides[i].sector != NULL); + sides[i].linedef = &lines[intptr_t(sides[i].linedef)]; } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f4d2fb379..3f55dbe23 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -711,9 +711,15 @@ void P_FloodZone (sector_t *sec, int zonenum) continue; if (check->frontsector == sec) + { + assert(check->backsector != NULL); other = check->backsector; + } else + { + assert(check->frontsector != NULL); other = check->frontsector; + } if (other->ZoneNumber != zonenum) P_FloodZone (other, zonenum); From 8b98a3510efa385ea8f0971d4d44894047902597 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 02:21:01 +0000 Subject: [PATCH 51/88] - Fixed: The Build loader did not set the wall texture scaling properly, either. SVN r2219 (trunk) --- src/p_buildmap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 581665f76..88ce27c01 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -517,6 +517,8 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) } sides[i].TexelLength = walls[i].xrepeat * 8; + sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3)); + sides[i].SetTextureXScale(FRACUNIT); sides[i].SetLight(SHADE2LIGHT(walls[i].shade)); sides[i].Flags = WALLF_ABSLIGHTING; sides[i].RightSide = walls[i].point2; From aedb646a52d63d3494cb795c5bcd7d32070e2993 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 03:55:51 +0000 Subject: [PATCH 52/88] - Fixed: Blood sound effect namespacing was broken. SVN r2220 (trunk) --- src/resourcefiles/file_rff.cpp | 53 ++++++++++++++++++---------------- src/s_advsound.cpp | 2 +- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index 902784ae3..a4eea88e7 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -56,13 +56,15 @@ struct RFFInfo struct RFFLump { - BYTE IDontKnow[16]; + DWORD DontKnow1[4]; DWORD FilePos; DWORD Size; - BYTE IStillDontKnow[8]; + DWORD DontKnow2; + DWORD Time; BYTE Flags; char Extension[3]; - char Name[8+4]; // 4 bytes that I don't know what they are for + char Name[8]; + DWORD IndexNum; // Used by .sfx, possibly others }; //========================================================================== @@ -75,6 +77,8 @@ struct FRFFLump : public FUncompressedLump { virtual FileReader *GetReader(); virtual int FillCache(); + + DWORD IndexNum; }; //========================================================================== @@ -149,20 +153,6 @@ bool FRFFFile::Open(bool quiet) if (!quiet) Printf(", %d lumps\n", NumLumps); for (DWORD i = 0; i < NumLumps; ++i) { - if (lumps[i].Extension[0] == 'S' && lumps[i].Extension[1] == 'F' && - lumps[i].Extension[2] == 'X') - { - Lumps[i].Namespace = ns_bloodsfx; - } - else if (lumps[i].Extension[0] == 'R' && lumps[i].Extension[1] == 'A' && - lumps[i].Extension[2] == 'W') - { - Lumps[i].Namespace = ns_bloodraw; - } - else - { - Lumps[i].Namespace = ns_global; - } Lumps[i].Position = LittleLong(lumps[i].FilePos); Lumps[i].LumpSize = LittleLong(lumps[i].Size); Lumps[i].Owner = this; @@ -170,14 +160,27 @@ bool FRFFFile::Open(bool quiet) { Lumps[i].Flags |= LUMPF_BLOODCRYPT; } - // Rearrange the name and extension in a part of the lump record - // that I don't have any use for in order to construct the fullname. - lumps[i].Name[8] = '\0'; - strcpy ((char *)lumps[i].IDontKnow, lumps[i].Name); - strcat ((char *)lumps[i].IDontKnow, "."); - lumps[i].Name[0] = '\0'; - strcat ((char *)lumps[i].IDontKnow, lumps[i].Extension); - Lumps[i].LumpNameSetup((char *)lumps[i].IDontKnow); + Lumps[i].IndexNum = LittleLong(lumps[i].IndexNum); + // Rearrange the name and extension to construct the fullname. + char name[13]; + strncpy(name, lumps[i].Name, 8); + name[8] = 0; + size_t len = strlen(name); + assert(len + 4 <= 12); + name[len+0] = '.'; + name[len+1] = lumps[i].Extension[0]; + name[len+2] = lumps[i].Extension[1]; + name[len+3] = lumps[i].Extension[2]; + name[len+4] = 0; + Lumps[i].LumpNameSetup(name); + if (name[len+1] == 'S' && name[len+2] == 'F' && name[len+3] == 'X') + { + Lumps[i].Namespace = ns_bloodsfx; + } + else if (name[len+1] == 'R' && name[len+2] == 'A' && name[len+3] == 'W') + { + Lumps[i].Namespace = ns_bloodraw; + } } delete[] lumps; return true; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index aa9de0039..59ec131d4 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1977,7 +1977,7 @@ void AAmbientSound::Tick () if (ambient->sound[0]) { - // The second argumens scales the ambient sound's volume. + // The second argument scales the ambient sound's volume. // 0 and 128 are normal volume. The maximum volume level // possible is always 1. float volscale = args[1] == 0 ? 1 : args[1] / 128.f; From 740d52cf5b0ad71419fe30b3465041755907f0ac Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 04:26:22 +0000 Subject: [PATCH 53/88] - Added support for Blood's SFX loop start markers. SVN r2221 (trunk) --- src/s_advsound.cpp | 13 ++++++------- src/s_sound.cpp | 8 +++++++- src/s_sound.h | 2 ++ src/sound/fmodsound.cpp | 17 +++++++++++++++-- src/sound/fmodsound.h | 2 +- src/sound/i_sound.cpp | 2 +- src/sound/i_sound.h | 2 +- 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 59ec131d4..2d02432b5 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -509,6 +509,7 @@ int S_AddSoundLump (const char *logicalname, int lump) newsfx.Rolloff.RolloffType = ROLLOFF_Doom; newsfx.Rolloff.MinDistance = 0; newsfx.Rolloff.MaxDistance = 0; + newsfx.LoopStart = -1; return (int)S_sfx.Push (newsfx); } @@ -1366,18 +1367,15 @@ static void S_AddSNDINFO (int lump) static void S_AddBloodSFX (int lumpnum) { - char name[13]; - FMemLump sfxlump = Wads.ReadLump (lumpnum); + FMemLump sfxlump = Wads.ReadLump(lumpnum); const FBloodSFX *sfx = (FBloodSFX *)sfxlump.GetMem(); - int rawlump = Wads.CheckNumForName (sfx->RawName, ns_bloodraw); + int rawlump = Wads.CheckNumForName(sfx->RawName, ns_bloodraw); int sfxnum; if (rawlump != -1) { - Wads.GetLumpName (name, lumpnum); - name[8] = 0; - strcat (name, ".SFX"); - sfxnum = S_AddSound (name, rawlump); + const char *name = Wads.GetLumpFullName(lumpnum); + sfxnum = S_AddSound(name, rawlump); if (sfx->Format == 5) { S_sfx[sfxnum].bForce22050 = true; @@ -1387,6 +1385,7 @@ static void S_AddBloodSFX (int lumpnum) S_sfx[sfxnum].bForce11025 = true; } S_sfx[sfxnum].bLoadRAW = true; + S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart); } } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index f309499df..356d5ac33 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -165,6 +165,7 @@ void S_NoiseDebug (void) screen->DrawText (SmallFont, CR_GOLD, 340, y, "pri", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 380, y, "flags", TAG_DONE); screen->DrawText (SmallFont, CR_GOLD, 460, y, "aud", TAG_DONE); + screen->DrawText (SmallFont, CR_GOLD, 520, y, "pos", TAG_DONE); y += 8; if (Channels == NULL) @@ -253,6 +254,11 @@ void S_NoiseDebug (void) mysnprintf(temp, countof(temp), "%.4f", GSnd->GetAudibility(chan)); screen->DrawText(SmallFont, color, 460, y, temp, TAG_DONE); + // Position + mysnprintf(temp, countof(temp), "%u", GSnd->GetPosition(chan)); + screen->DrawText(SmallFont, color, 520, y, temp, TAG_DONE); + + y += 8; if (chan->PrevChan == &Channels) { @@ -1322,7 +1328,7 @@ sfxinfo_t *S_LoadSound(sfxinfo_t *sfx) } sfxstart = sfxdata + 8; } - sfx->data = GSnd->LoadSoundRaw(sfxstart, len, frequency, 1, 8); + sfx->data = GSnd->LoadSoundRaw(sfxstart, len, frequency, 1, 8, sfx->LoopStart); } else { diff --git a/src/s_sound.h b/src/s_sound.h index 9ba10ac73..b616b9137 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -59,6 +59,8 @@ struct sfxinfo_t WORD bSingular:1; WORD bTentative:1; + int LoopStart; // -1 means no specific loop defined + unsigned int link; enum { NO_LINK = 0xffffffff }; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index f8f01f2a9..f5b338295 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -2190,12 +2190,16 @@ void FMODSoundRenderer::UpdateSounds() // //========================================================================== -SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) +SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart) { FMOD_CREATESOUNDEXINFO exinfo; SoundHandle retval = { NULL }; + int numsamples; - if (length == 0) return retval; + if (length <= 0) + { + return retval; + } InitCreateSoundExInfo(&exinfo); exinfo.length = length; @@ -2212,14 +2216,17 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ case -8: exinfo.format = FMOD_SOUND_FORMAT_PCM8; + numsamples = length; break; case 16: exinfo.format = FMOD_SOUND_FORMAT_PCM16; + numsamples = length >> 1; break; case 32: exinfo.format = FMOD_SOUND_FORMAT_PCM32; + numsamples = length >> 2; break; default: @@ -2236,6 +2243,12 @@ SoundHandle FMODSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int length, int frequ DPrintf("Failed to allocate sample: Error %d\n", result); return retval; } + + if (loopstart >= 0) + { + sample->setLoopPoints(loopstart, FMOD_TIMEUNIT_PCM, numsamples - 1, FMOD_TIMEUNIT_PCM); + } + retval.data = sample; return retval; } diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 3f31481bf..1460b697b 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -14,7 +14,7 @@ public: void SetSfxVolume (float volume); void SetMusicVolume (float volume); SoundHandle LoadSound(BYTE *sfxdata, int length); - SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits); + SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart); void UnloadSound (SoundHandle sfx); unsigned int GetMSLength(SoundHandle sfx); unsigned int GetSampleLength(SoundHandle sfx); diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index 0009b48e2..b25bbd6fb 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -123,7 +123,7 @@ public: SoundHandle retval = { NULL }; return retval; } - SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) + SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart) { SoundHandle retval = { NULL }; return retval; diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 31f401093..d8cf166fc 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -92,7 +92,7 @@ public: virtual void SetSfxVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0; virtual SoundHandle LoadSound(BYTE *sfxdata, int length) = 0; - virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) = 0; + virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits, int loopstart) = 0; virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency From 264950839326c25c54288f4491ebb0c53cf41a82 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 04:34:14 +0000 Subject: [PATCH 54/88] - Changed the ambient sounds list into a map so that it can handle more than 256 entries. SVN r2222 (trunk) --- src/s_advsound.cpp | 51 +++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 2d02432b5..dd22a5874 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -114,7 +114,7 @@ protected: void Free (); }; -static struct AmbientSound +struct FAmbientSound { unsigned type; // type of ambient sound int periodmin; // # of tics between repeats @@ -122,7 +122,8 @@ static struct AmbientSound float volume; // relative volume of sound float attenuation; FString sound; // Logical name of sound to play -} *Ambients[256]; +}; +TMap Ambients; enum SICommands { @@ -837,15 +838,7 @@ static void S_ClearSoundData() S_UnloadSound(&S_sfx[i]); } S_sfx.Clear(); - - for(i = 0; i < countof(Ambients); i++) - { - if (Ambients[i] != NULL) - { - delete Ambients[i]; - Ambients[i] = NULL; - } - } + Ambients.Clear(); while (MusicVolumes != NULL) { FMusicVolume *me = MusicVolumes; @@ -968,23 +961,10 @@ static void S_AddSNDINFO (int lump) // $ambient [point [atten] | surround | [world]] // | periodic > // - AmbientSound *ambient, dummy; + FAmbientSound *ambient; sc.MustGetNumber (); - if (sc.Number < 0 || sc.Number > 255) - { - Printf ("Bad ambient index (%d)\n", sc.Number); - ambient = &dummy; - } - else if (Ambients[sc.Number] == NULL) - { - ambient = new AmbientSound; - Ambients[sc.Number] = ambient; - } - else - { - ambient = Ambients[sc.Number]; - } + ambient = &Ambients[sc.Number]; ambient->type = 0; ambient->periodmin = 0; ambient->periodmax = 0; @@ -1905,7 +1885,7 @@ public: protected: bool bActive; private: - void SetTicker (struct AmbientSound *ambient); + void SetTicker (struct FAmbientSound *ambient); int NextCheck; }; @@ -1966,15 +1946,21 @@ void AAmbientSound::Tick () if (!bActive || gametic < NextCheck) return; - AmbientSound *ambient = Ambients[args[0]]; + FAmbientSound *ambient; int loop = 0; + ambient = Ambients.CheckKey(args[0]); + if (ambient == NULL) + { + return; + } + if ((ambient->type & CONTINUOUS) == CONTINUOUS) { loop = CHAN_LOOP; } - if (ambient->sound[0]) + if (ambient->sound.IsNotEmpty()) { // The second argument scales the ambient sound's volume. // 0 and 128 are normal volume. The maximum volume level @@ -2015,7 +2001,7 @@ void AAmbientSound::Tick () // //========================================================================== -void AAmbientSound::SetTicker (struct AmbientSound *ambient) +void AAmbientSound::SetTicker (struct FAmbientSound *ambient) { if ((ambient->type & CONTINUOUS) == CONTINUOUS) { @@ -2057,7 +2043,7 @@ void AAmbientSound::Activate (AActor *activator) { Super::Activate (activator); - AmbientSound *amb = Ambients[args[0]]; + FAmbientSound *amb = Ambients.CheckKey(args[0]); if (amb == NULL) { @@ -2101,7 +2087,8 @@ void AAmbientSound::Deactivate (AActor *activator) if (bActive) { bActive = false; - if ((Ambients[args[0]]->type & CONTINUOUS) == CONTINUOUS) + FAmbientSound *ambient = Ambients.CheckKey(args[0]); + if (ambient != NULL && (ambient->type & CONTINUOUS) == CONTINUOUS) { S_StopSound (this, CHAN_BODY); } From b53baf5f46d8fcf8ee6799ea885cfccc3daf3b45 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 05:01:10 +0000 Subject: [PATCH 55/88] - Added support for Blood's ambient sounds, because I thought it would be an easy way to test the new ambient sound range parameters. (Hahaha! If I hadn't had to fix all the Build/Blood stuff first, it would have been.) SVN r2223 (trunk) --- src/p_buildmap.cpp | 68 ++++++++++++++++++++++++-------- src/resourcefiles/file_rff.cpp | 2 + src/resourcefiles/resourcefile.h | 1 + src/s_advsound.cpp | 11 +++++- src/w_wad.cpp | 18 +++++++++ src/w_wad.h | 1 + 6 files changed, 84 insertions(+), 17 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 88ce27c01..739c515cf 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -109,6 +109,21 @@ struct spritetype SWORD lotag, hitag, extra; }; +// I used to have all the Xobjects mapped out. Not anymore. +// (Thanks for the great firmware, Seagate!) +struct Xsprite +{ + BYTE NotReallyPadding[16]; + WORD Data1; + WORD Data2; + WORD Data3; + WORD ThisIsntPaddingEither; + DWORD NorThis:2; + DWORD Data4:16; + DWORD WhatIsThisIDontEven:14; + BYTE ThisNeedsToBe56Bytes[28]; +}; + struct SlopeWork { walltype *wal; @@ -128,7 +143,7 @@ void P_AdjustLine (line_t *line); static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **sprites, int *numsprites); static void LoadSectors (sectortype *bsectors); static void LoadWalls (walltype *walls, int numwalls, sectortype *bsectors); -static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, FMapThing *mapthings); +static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, sectortype *bsectors, FMapThing *mapthings); static vertex_t *FindVertex (fixed_t x, fixed_t y); static void CreateStartSpot (fixed_t *pos, FMapThing *start); static void CalcPlane (SlopeWork &slope, secplane_t &plane); @@ -217,7 +232,7 @@ bool P_LoadBuildMap (BYTE *data, size_t len, FMapThing **sprites, int *numspr) *sprites = new FMapThing[numsprites + 1]; CreateStartSpot ((fixed_t *)(data + 4), *sprites); *numspr = 1 + LoadSprites ((spritetype *)(data + 26 + numsectors*sizeof(sectortype) + numwalls*sizeof(walltype)), - numsprites, (sectortype *)(data + 22), *sprites + 1); + NULL, numsprites, (sectortype *)(data + 22), *sprites + 1); return true; } @@ -277,6 +292,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * sectortype *bsec = new sectortype[numsectors]; walltype *bwal = new walltype[numWalls]; spritetype *bspr = new spritetype[numsprites]; + Xsprite *xspr = new Xsprite[numsprites]; // Read sectors k = numRevisions * sizeof(sectortype); @@ -329,9 +345,15 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * memcpy (&bspr[i], data, sizeof(spritetype)); } data += sizeof(spritetype); - if (bspr[i].extra > 0) // skip Xsprite + if (bspr[i].extra > 0) // copy Xsprite { - data += 56; + assert(sizeof Xsprite == 56); + memcpy(&xspr[i], data, sizeof(Xsprite)); + data += sizeof(Xsprite); + } + else + { + memset(&xspr[i], 0, sizeof(Xsprite)); } } @@ -341,11 +363,12 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * LoadWalls (bwal, numWalls, bsec); *mapthings = new FMapThing[numsprites + 1]; CreateStartSpot ((fixed_t *)infoBlock, *mapthings); - *numspr = 1 + LoadSprites (bspr, numsprites, bsec, *mapthings + 1); + *numspr = 1 + LoadSprites (bspr, xspr, numsprites, bsec, *mapthings + 1); delete[] bsec; delete[] bwal; delete[] bspr; + delete[] xspr; return true; } @@ -658,32 +681,45 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) // //========================================================================== -static int LoadSprites (spritetype *sprites, int numsprites, sectortype *bsectors, - FMapThing *mapthings) +static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, + sectortype *bsectors, FMapThing *mapthings) { int count = 0; for (int i = 0; i < numsprites; ++i) { - if (sprites[i].cstat & (16|32|32768)) continue; - if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; - mapthings[count].thingid = 0; mapthings[count].x = (sprites[i].x << 12); mapthings[count].y = -(sprites[i].y << 12); mapthings[count].z = (bsectors[sprites[i].sectnum].floorz - sprites[i].z) << 8; mapthings[count].angle = (((2048-sprites[i].ang) & 2047) * 360) >> 11; - mapthings[count].type = 9988; mapthings[count].ClassFilter = 0xffff; mapthings[count].SkillFilter = 0xffff; mapthings[count].flags = MTF_SINGLE|MTF_COOPERATIVE|MTF_DEATHMATCH; mapthings[count].special = 0; - mapthings[count].args[0] = sprites[i].picnum & 255; - mapthings[count].args[1] = sprites[i].picnum >> 8; - mapthings[count].args[2] = sprites[i].xrepeat; - mapthings[count].args[3] = sprites[i].yrepeat; - mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1); + if (xsprites != NULL && sprites[i].lotag == 710) + { // Blood ambient sound + mapthings[count].args[0] = xsprites[i].Data3; + // I am totally guessing abount the volume level. 50 seems to be a pretty + // typical value for Blood's standard maps, so I assume it's 100-based. + mapthings[count].args[1] = xsprites[i].Data4 * 128 / 100; + mapthings[count].args[2] = xsprites[i].Data1; + mapthings[count].args[3] = xsprites[i].Data2; + mapthings[count].type = 14065; + } + else + { + if (sprites[i].cstat & (16|32|32768)) continue; + if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; + + mapthings[count].type = 9988; + mapthings[count].args[0] = sprites[i].picnum & 255; + mapthings[count].args[1] = sprites[i].picnum >> 8; + mapthings[count].args[2] = sprites[i].xrepeat; + mapthings[count].args[3] = sprites[i].yrepeat; + mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1); + } count++; } return count; diff --git a/src/resourcefiles/file_rff.cpp b/src/resourcefiles/file_rff.cpp index a4eea88e7..2e6a3bc5a 100644 --- a/src/resourcefiles/file_rff.cpp +++ b/src/resourcefiles/file_rff.cpp @@ -79,6 +79,8 @@ struct FRFFLump : public FUncompressedLump virtual int FillCache(); DWORD IndexNum; + + int GetIndexNum() const { return IndexNum; } }; //========================================================================== diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index ac8499944..e531ddbb3 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -41,6 +41,7 @@ struct FResourceLump virtual FileReader *GetReader(); virtual FileReader *NewReader(); virtual int GetFileOffset() { return -1; } + virtual int GetIndexNum() const { return 0; } void LumpNameSetup(const char *iname); void CheckEmbedded(); diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index dd22a5874..55788919b 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1365,7 +1365,16 @@ static void S_AddBloodSFX (int lumpnum) S_sfx[sfxnum].bForce11025 = true; } S_sfx[sfxnum].bLoadRAW = true; - S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart); + // Make an ambient sound out of it, whether it has a loop point + // defined or not. (Because none of the standard Blood ambient + // sounds are explicitly defined as looping.) + FAmbientSound *ambient = &Ambients[Wads.GetLumpIndexNum(lumpnum)]; + ambient->type = CONTINUOUS; + ambient->periodmin = 0; + ambient->periodmax = 0; + ambient->volume = 1; + ambient->attenuation = 1; + ambient->sound = name; } } diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 68a8d4c3e..5727c8bcc 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -967,6 +967,24 @@ int FWadCollection::GetLumpNamespace (int lump) const return LumpInfo[lump].lump->Namespace; } +//========================================================================== +// +// FWadCollection :: GetLumpIndexNum +// +// Returns the index number for this lump. This is *not* the lump's position +// in the lump directory, but rather a special value that RFF can associate +// with files. Other archive types will return 0, since they don't have it. +// +//========================================================================== + +int FWadCollection::GetLumpIndexNum(int lump) const +{ + if ((size_t)lump >= NumLumps) + return 0; + else + return LumpInfo[lump].lump->GetIndexNum(); +} + //========================================================================== // // W_GetLumpFile diff --git a/src/w_wad.h b/src/w_wad.h index 19129476f..dc1ea7794 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -195,6 +195,7 @@ public: FString GetLumpFullPath (int lump) const; // [RH] Returns wad's name + lump's full name int GetLumpFile (int lump) const; // [RH] Returns wadnum for a specified lump int GetLumpNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to + int GetLumpIndexNum (int lump) const; // Returns the RFF index number for this lump bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match bool IsUncompressedFile(int lump) const; From f712d128a3917e02f1eaedcb44ef30b587152bc8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 05:22:47 +0000 Subject: [PATCH 56/88] - Oops. Accidentally removed Blood loop point support. SVN r2224 (trunk) --- src/s_advsound.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 55788919b..40bf0f95c 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1365,6 +1365,7 @@ static void S_AddBloodSFX (int lumpnum) S_sfx[sfxnum].bForce11025 = true; } S_sfx[sfxnum].bLoadRAW = true; + S_sfx[sfxnum].LoopStart = LittleLong(sfx->LoopStart); // Make an ambient sound out of it, whether it has a loop point // defined or not. (Because none of the standard Blood ambient // sounds are explicitly defined as looping.) From 44e877a24355dfe576618222d3da1949067be3ca Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 05:27:36 +0000 Subject: [PATCH 57/88] - After experimenting with Blood, I think ROLLOFF_Linear is a better choice for ambient sounds than ROLLOFF_Doom. SVN r2225 (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 356d5ac33..159323d9b 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1217,7 +1217,7 @@ void S_SoundMinMaxDist(AActor *ent, int channel, FSoundID sound_id, float volume FRolloffInfo rolloff; - rolloff.RolloffType = ROLLOFF_Doom; + rolloff.RolloffType = ROLLOFF_Linear; rolloff.MinDistance = mindist; rolloff.MaxDistance = maxdist; S_StartSound(ent, NULL, NULL, NULL, channel, sound_id, volume, 1, &rolloff); From d69eb3acd1e7a4c9064bce5f80bbb033b2e13963 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 18 Mar 2010 07:54:16 +0000 Subject: [PATCH 58/88] - fixed: True color texture generation for DDS was broken. SVN r2226 (trunk) --- src/textures/ddstexture.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index da9ec5955..9c8eaf978 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -634,7 +634,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf) bMasked = true; } // Pick colors from the palette for each of the four colors. - if (!tcbuf) for (i = 3; i >= 0; --i) + /*if (!tcbuf)*/ for (i = 3; i >= 0; --i) { palcol[i] = color[i].a ? RGB32k[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0; } @@ -652,18 +652,18 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf) { break; } + int ci = (yslice >> (x + x)) & 3; if (!tcbuf) { - Pixels[oy + y + (ox + x) * Height] = palcol[(yslice >> (x + x)) & 3]; + Pixels[oy + y + (ox + x) * Height] = palcol[ci]; } else { - BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4]; - int c = (yslice >> (x + x)) & 3; - tcp[0] = color[c].r; - tcp[1] = color[c].g; - tcp[2] = color[c].b; - tcp[3] = color[c].a; + BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; + tcp[0] = color[ci].r; + tcp[1] = color[ci].g; + tcp[2] = color[ci].b; + tcp[3] = color[ci].a; } } } @@ -740,7 +740,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbu } else { - BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4]; + BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; tcp[0] = color[c].r; tcp[1] = color[c].g; @@ -831,7 +831,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu break; } // Alpha values are stored in 3 bytes for 2 rows - if ((y & 1) == 0) + if ((y & 0) == 0) { yalphaslice = block[y*3] | (block[y*3+1] << 8) | (block[y*3+2] << 16); } @@ -853,7 +853,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu } else { - BYTE * tcp = &tcbuf[ox + x + (oy + y) * Width*4]; + BYTE * tcp = &tcbuf[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; tcp[0] = color[c].r; tcp[1] = color[c].g; From 9d8a9bc981c2c65091fadb91a08bf4ea70930b67 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 17:50:00 +0000 Subject: [PATCH 59/88] - Reverted the part of r2226 than reverted r2205 (accidentally, I assume). SVN r2227 (trunk) --- src/textures/ddstexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 9c8eaf978..f26180f02 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -831,7 +831,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu break; } // Alpha values are stored in 3 bytes for 2 rows - if ((y & 0) == 0) + if ((y & 1) == 0) { yalphaslice = block[y*3] | (block[y*3+1] << 8) | (block[y*3+2] << 16); } From 226a513e6efb821c9c166083d3e66398fd8cea17 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 21:03:58 +0000 Subject: [PATCH 60/88] - Fixed: Blood's sprite rotations were broken. SVN r2228 (trunk) --- src/textures/buildtexture.cpp | 22 +++++++++++----------- src/textures/texturemanager.cpp | 2 +- src/textures/textures.h | 2 ++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 21e3cc41f..5f4172a60 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -158,7 +158,7 @@ const BYTE *FBuildTexture::GetColumn (unsigned int column, const Span **spans_ou // //=========================================================================== -static void AddTiles (void *tiles) +void AddTiles (void *tiles) { // int numtiles = LittleLong(((DWORD *)tiles)[1]); // This value is not reliable int tilestart = LittleLong(((DWORD *)tiles)[2]); @@ -224,29 +224,29 @@ static void AddTiles (void *tiles) if (rotType == 1) { spriteframe_t rot; - rot.Texture[0] = texnum; + rot.Texture[0] = rot.Texture[1] = texnum; for (int j = 1; j < 4; ++j) { - rot.Texture[j*2] = texnum + j; - rot.Texture[j*2+1] = texnum + j; - rot.Texture[16-j*2] = texnum + j; - rot.Texture[17-j*2] = texnum + j; + rot.Texture[j*2] = + rot.Texture[j*2+1] = + rot.Texture[16-j*2] = + rot.Texture[17-j*2] = texnum.GetIndex() + j; } - rot.Texture[8] = texnum + 4; - rot.Texture[9] = texnum + 4; + rot.Texture[8] = + rot.Texture[9] = texnum.GetIndex() + 4; rot.Flip = 0x00FC; tex->Rotations = SpriteFrames.Push (rot); } else if (rotType == 2) { spriteframe_t rot; - rot.Texture[0] = texnum; + rot.Texture[0] = rot.Texture[1] = texnum; for (int j = 1; j < 8; ++j) { - rot.Texture[16-j*2] = texnum + j; - rot.Texture[17-j*2] = texnum + j; + rot.Texture[16-j*2] = + rot.Texture[17-j*2] = texnum.GetIndex() + j; } rot.Flip = 0; tex->Rotations = SpriteFrames.Push (rot); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 2d3e2fc9f..33c6e38e3 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1005,7 +1005,7 @@ FArchive &operator<< (FArchive &arc, FTextureID &tex) //========================================================================== // // FTextureID::operator+ -// Does not return incvalid texture IDs +// Does not return invalid texture IDs // //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 0146b7355..2045a19fb 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -41,6 +41,8 @@ protected: FTextureID(int num) { texnum = num; } private: int texnum; + + friend void AddTiles (void *tiles); }; class FNullTextureID : public FTextureID From d012165f5731e0b7dd6e63a93c56dd28c3777a51 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 21:09:23 +0000 Subject: [PATCH 61/88] - Changed ambient sound things so that 100 volume is normal. - The fifth argument for the ambient sound things is now a scalar for the min and max distances. SVN r2229 (trunk) --- src/p_buildmap.cpp | 3 ++- src/s_advsound.cpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 739c515cf..82a709571 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -703,9 +703,10 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, mapthings[count].args[0] = xsprites[i].Data3; // I am totally guessing abount the volume level. 50 seems to be a pretty // typical value for Blood's standard maps, so I assume it's 100-based. - mapthings[count].args[1] = xsprites[i].Data4 * 128 / 100; + mapthings[count].args[1] = xsprites[i].Data4; mapthings[count].args[2] = xsprites[i].Data1; mapthings[count].args[3] = xsprites[i].Data2; + mapthings[count].args[4] = 0; mapthings[count].type = 14065; } else diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 40bf0f95c..1ab3558ac 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1975,7 +1975,7 @@ void AAmbientSound::Tick () // The second argument scales the ambient sound's volume. // 0 and 128 are normal volume. The maximum volume level // possible is always 1. - float volscale = args[1] == 0 ? 1 : args[1] / 128.f; + float volscale = args[1] == 0 ? 1 : args[1] / 100.f; float usevol = clamp(ambient->volume * volscale, 0.f, 1.f); // The third argument is the minimum distance for audible fading, and @@ -1988,7 +1988,14 @@ void AAmbientSound::Tick () } else { - S_SoundMinMaxDist(this, CHAN_BODY | loop, ambient->sound, usevol, float(args[2]), float(args[3])); + float min = float(args[2]), max = float(args[3]); + // The fifth argument acts as a scalar for the preceding two, if it's non-zero. + if (args[4] != 0) + { + min *= args[4]; + max *= args[4]; + } + S_SoundMinMaxDist(this, CHAN_BODY | loop, ambient->sound, usevol, min, max); } if (!loop) { From 5ec5d742673f5fb659738f905139a3a89eacb467 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 21:10:15 +0000 Subject: [PATCH 62/88] - Probably shouldn't allow negative range scalars for ambient sound things... SVN r2230 (trunk) --- src/s_advsound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 1ab3558ac..94e2c4ac8 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1990,7 +1990,7 @@ void AAmbientSound::Tick () { float min = float(args[2]), max = float(args[3]); // The fifth argument acts as a scalar for the preceding two, if it's non-zero. - if (args[4] != 0) + if (args[4] > 0) { min *= args[4]; max *= args[4]; From 6c63ce51e4472a75afd955404cbbe9706a7cdc50 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 21:54:24 +0000 Subject: [PATCH 63/88] - Fixed: The listener used a different coordinate system than sounds, which meant that sounds were never made head-relative, so stereo effects would disappear if they were played by the listener. SVN r2231 (trunk) --- src/s_sound.cpp | 4 ++-- src/sound/fmodsound.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 159323d9b..d65cbaf0b 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1922,8 +1922,8 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor) */ listener.velocity.Zero(); listener.position.X = FIXED2FLOAT(listenactor->x); - listener.position.Y = FIXED2FLOAT(listenactor->y); - listener.position.Z = FIXED2FLOAT(listenactor->z); + listener.position.Y = FIXED2FLOAT(listenactor->z); + listener.position.Z = FIXED2FLOAT(listenactor->y); listener.underwater = listenactor->waterlevel == 3; assert(zones != NULL); listener.Environment = zones[listenactor->Sector->ZoneNumber].Environment; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index f5b338295..6a480f0f9 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1994,11 +1994,11 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener) // Set velocity to 0 to prevent crazy doppler shifts just from running. vel.x = listener->velocity.X; - vel.z = listener->velocity.Y; - vel.y = listener->velocity.Z; + vel.y = listener->velocity.Y; + vel.z = listener->velocity.Z; pos.x = listener->position.X; - pos.z = listener->position.Y; - pos.y = listener->position.Z; + pos.y = listener->position.Y; + pos.z = listener->position.Z; float angle = listener->angle; forward.x = cos(angle); From 1eed01244c3ae8355a663554491c917259fd1100 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 18 Mar 2010 21:59:45 +0000 Subject: [PATCH 64/88] - Comment fix. SVN r2232 (trunk) --- src/s_advsound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 94e2c4ac8..b5cfc1d82 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -1973,7 +1973,7 @@ void AAmbientSound::Tick () if (ambient->sound.IsNotEmpty()) { // The second argument scales the ambient sound's volume. - // 0 and 128 are normal volume. The maximum volume level + // 0 and 100 are normal volume. The maximum volume level // possible is always 1. float volscale = args[1] == 0 ? 1 : args[1] / 100.f; float usevol = clamp(ambient->volume * volscale, 0.f, 1.f); From a2cfbec3cf0b8b96d614f2419dba5ed22c71712f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 21 Mar 2010 08:09:45 +0000 Subject: [PATCH 65/88] - added a CrushPainSound actor property for Strife. - fixed memory leaks in SBARINFO and WAD loading code. - added GetBloodColor and GetBloodType inline functions to AActor to wrap the GetMeta calls used for this. SVN r2234 (trunk) --- src/actor.h | 23 ++++++++ src/d_main.cpp | 5 ++ src/g_shared/sbarinfo.cpp | 4 ++ src/p_map.cpp | 52 +++++++++++-------- src/p_mobj.cpp | 28 +++++----- src/thingdef/thingdef_properties.cpp | 9 ++++ wadsrc/static/actors/strife/macil.txt | 1 + wadsrc/static/actors/strife/merchants.txt | 1 + .../static/actors/strife/strifehumanoid.txt | 1 + wadsrc/static/actors/strife/strifeplayer.txt | 1 + wadsrc/static/actors/strife/templar.txt | 1 + wadsrc/static/actors/strife/zombie.txt | 3 +- wadsrc/static/sndinfo.txt | 1 + 13 files changed, 94 insertions(+), 36 deletions(-) diff --git a/src/actor.h b/src/actor.h index 6e8af2498..0f9a90e0e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -716,6 +716,28 @@ public: return ( abs(x - other->x) < blockdist && abs(y - other->y) < blockdist); } + PalEntry GetBloodColor() const + { + return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor); + } + + const PClass *GetBloodType(int type = 0) const + { + if (type == 0) + { + return PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + } + else if (type == 1) + { + return PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter)); + } + else if (type == 2) + { + return PClass::FindClass((ENamedName)GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood)); + } + else return NULL; + } + // Calculate amount of missile damage virtual int GetMissileDamage(int mask, int add); @@ -846,6 +868,7 @@ public: FSoundIDNoInit UseSound; // [RH] Sound to play when an actor is used. FSoundIDNoInit BounceSound; FSoundIDNoInit WallBounceSound; + FSoundIDNoInit CrushPainSound; fixed_t Speed; fixed_t FloatSpeed; diff --git a/src/d_main.cpp b/src/d_main.cpp index f75540983..19db0885d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1850,9 +1850,14 @@ void D_DoomMain (void) CopyFiles(allwads, pwads); + // Since this function will never leave we must delete this array here manually. + pwads.Clear(); + pwads.ShrinkToFit(); + Printf ("W_Init: Init WADfiles.\n"); Wads.InitMultipleFiles (allwads); allwads.Clear(); + allwads.ShrinkToFit(); // [RH] Initialize localizable strings. GStrings.LoadStrings (false); diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index 1344ad1c0..e020d4258 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -542,6 +542,10 @@ void SBarInfo::ParseSBarInfo(int lump) sc.MustGetToken(TK_Identifier); barNum = sc.MustMatchString(StatusBars); } + if (this->huds[barNum] != NULL) + { + delete this->huds[barNum]; + } this->huds[barNum] = new SBarInfoMainBlock(this); if(barNum == STBAR_AUTOMAP) { diff --git a/src/p_map.cpp b/src/p_map.cpp index ebcb701f6..019c8087a 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3588,7 +3588,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, a { if (bleedtrace.HitType == TRACE_HitWall) { - PalEntry bloodcolor = (PalEntry)actor->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); + PalEntry bloodcolor = actor->GetBloodColor(); if (bloodcolor != 0) { bloodcolor.r>>=1; // the full color is too bright for blood decals @@ -4592,34 +4592,40 @@ void P_DoCrunch (AActor *thing, FChangePosition *cpos) P_DamageMobj (thing, NULL, NULL, cpos->crushchange, NAME_Crush); // spray blood in a random direction - if ((!(thing->flags&MF_NOBLOOD)) && - (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))) + if (!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT))) { - PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); - - P_TraceBleed (cpos->crushchange, thing); - if (cl_bloodtype <= 1 && bloodcls != NULL) + if (!(thing->flags&MF_NOBLOOD)) { - AActor *mo; - - mo = Spawn (bloodcls, thing->x, thing->y, - thing->z + thing->height/2, ALLOW_REPLACE); - - mo->velx = pr_crunch.Random2 () << 12; - mo->vely = pr_crunch.Random2 () << 12; - if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) + PalEntry bloodcolor = thing->GetBloodColor(); + const PClass *bloodcls = thing->GetBloodType(); + + P_TraceBleed (cpos->crushchange, thing); + if (cl_bloodtype <= 1 && bloodcls != NULL) { - mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); + AActor *mo; + + mo = Spawn (bloodcls, thing->x, thing->y, + thing->z + thing->height/2, ALLOW_REPLACE); + + mo->velx = pr_crunch.Random2 () << 12; + mo->vely = pr_crunch.Random2 () << 12; + if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE)) + { + mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); + } + } + if (cl_bloodtype >= 1) + { + angle_t an; + + an = (M_Random () - 128) << 24; + P_DrawSplash2 (32, thing->x, thing->y, + thing->z + thing->height/2, an, 2, bloodcolor); } } - if (cl_bloodtype >= 1) + if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound)) { - angle_t an; - - an = (M_Random () - 128) << 24; - P_DrawSplash2 (32, thing->x, thing->y, - thing->z + thing->height/2, an, 2, bloodcolor); + S_Sound(thing, CHAN_VOICE, thing->CrushPainSound, 1.f, ATTN_NORM); } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f581312f9..8fa00645f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -270,8 +270,12 @@ void AActor::Serialize (FArchive &arc) << ActiveSound << UseSound << BounceSound - << WallBounceSound - << Speed + << WallBounceSound; + if (SaveVersion >= 2234) + { + arc << CrushPainSound; + } + arc << Speed << FloatSpeed << Mass << PainChance @@ -1068,7 +1072,7 @@ bool AActor::Grind(bool items) if (isgeneric) // Not a custom crush state, so colorize it appropriately. { S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); - PalEntry bloodcolor = PalEntry(GetClass()->Meta.GetMetaInt(AMETA_BloodColor)); + PalEntry bloodcolor = GetBloodColor(); if (bloodcolor!=0) Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } return false; @@ -1112,7 +1116,7 @@ bool AActor::Grind(bool items) } S_Sound (this, CHAN_BODY, "misc/fallingsplat", 1, ATTN_IDLE); - PalEntry bloodcolor = (PalEntry)this->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); + PalEntry bloodcolor = GetBloodColor(); if (bloodcolor!=0) gib->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a); } if (flags & MF_ICECORPSE) @@ -4502,8 +4506,8 @@ AActor *P_SpawnPuff (AActor *source, const PClass *pufftype, fixed_t x, fixed_t void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator) { AActor *th; - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + PalEntry bloodcolor = originator->GetBloodColor(); + const PClass *bloodcls = originator->GetBloodType(); int bloodtype = cl_bloodtype; @@ -4564,8 +4568,8 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter)); + PalEntry bloodcolor = originator->GetBloodColor(); + const PClass *bloodcls = originator->GetBloodType(1); int bloodtype = cl_bloodtype; @@ -4602,8 +4606,8 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { - PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood)); + PalEntry bloodcolor = originator->GetBloodColor(); + const PClass *bloodcls = originator->GetBloodType(2); int bloodtype = cl_bloodtype; @@ -4641,8 +4645,8 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator) void P_RipperBlood (AActor *mo, AActor *bleeder) { fixed_t x, y, z; - PalEntry bloodcolor = (PalEntry)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodColor); - const PClass *bloodcls = PClass::FindClass((ENamedName)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood)); + PalEntry bloodcolor = bleeder->GetBloodColor(); + const PClass *bloodcls = bleeder->GetBloodType(); x = mo->x + (pr_ripperblood.Random2 () << 12); y = mo->y + (pr_ripperblood.Random2 () << 12); diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 0c2a8c96d..f58eb6500 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -554,6 +554,15 @@ DEFINE_PROPERTY(howlsound, S, Actor) info->Class->Meta.SetMetaInt (AMETA_HowlSound, S_FindSound(str)); } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(crushpainsound, S, Actor) +{ + PROP_STRING_PARM(str, 0); + defaults->CrushPainSound = str; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/strife/macil.txt b/wadsrc/static/actors/strife/macil.txt index ea701dd9f..ba99be435 100644 --- a/wadsrc/static/actors/strife/macil.txt +++ b/wadsrc/static/actors/strife/macil.txt @@ -21,6 +21,7 @@ ACTOR Macil1 64 SeeSound "macil/sight" PainSound "macil/pain" ActiveSound "macil/active" + CrushPainSound "misc/pcrush" Tag "MACIL" Obituary "$OB_MACIL" DropItem "BoxOfBullets" diff --git a/wadsrc/static/actors/strife/merchants.txt b/wadsrc/static/actors/strife/merchants.txt index d06ee607d..65f5ac653 100644 --- a/wadsrc/static/actors/strife/merchants.txt +++ b/wadsrc/static/actors/strife/merchants.txt @@ -7,6 +7,7 @@ ACTOR Merchant Radius 20 Height 56 Mass 5000 + CrushPainSound "misc/pcrush" +SOLID +SHOOTABLE +NOTDMATCH diff --git a/wadsrc/static/actors/strife/strifehumanoid.txt b/wadsrc/static/actors/strife/strifehumanoid.txt index c81f40f34..375f5bbcf 100644 --- a/wadsrc/static/actors/strife/strifehumanoid.txt +++ b/wadsrc/static/actors/strife/strifehumanoid.txt @@ -7,6 +7,7 @@ ACTOR StrifeHumanoid MaxStepHeight 16 MaxDropoffHeight 32 + CrushPainSound "misc/pcrush" States { Burn: diff --git a/wadsrc/static/actors/strife/strifeplayer.txt b/wadsrc/static/actors/strife/strifeplayer.txt index 1dabeff4c..5b0bdc750 100644 --- a/wadsrc/static/actors/strife/strifeplayer.txt +++ b/wadsrc/static/actors/strife/strifeplayer.txt @@ -9,6 +9,7 @@ ACTOR StrifePlayer : PlayerPawn PainChance 255 Speed 1 MaxStepHeight 16 + CrushPainSound "misc/pcrush" Player.DisplayName "Rebel" Player.StartItem "PunchDagger" Player.RunHealth 15 diff --git a/wadsrc/static/actors/strife/templar.txt b/wadsrc/static/actors/strife/templar.txt index fd8351c89..214804b34 100644 --- a/wadsrc/static/actors/strife/templar.txt +++ b/wadsrc/static/actors/strife/templar.txt @@ -19,6 +19,7 @@ ACTOR Templar 3003 PainSound "templar/pain" DeathSound "templar/death" ActiveSound "templar/active" + CrushPainSound "misc/pcrush" Tag "TEMPLAR" HitObituary "$OB_TEMPLARHIT" Obituary "$OB_TEMPLAR" diff --git a/wadsrc/static/actors/strife/zombie.txt b/wadsrc/static/actors/strife/zombie.txt index e26f8b266..9788bc00f 100644 --- a/wadsrc/static/actors/strife/zombie.txt +++ b/wadsrc/static/actors/strife/zombie.txt @@ -20,6 +20,7 @@ ACTOR Zombie : StrifeHumanoid 169 Translation 0 ConversationID 28, -1, -1 DeathSound "zombie/death" + CrushPainSound "misc/pcrush" States { Spawn: @@ -34,7 +35,7 @@ ACTOR Zombie : StrifeHumanoid 169 GIBS O 5 A_NoBlocking GIBS PQRST 4 A_TossGib GIBS U 5 - GIBS V 1400 + GIBS V -1 Stop } } diff --git a/wadsrc/static/sndinfo.txt b/wadsrc/static/sndinfo.txt index c534808bb..100485e28 100644 --- a/wadsrc/static/sndinfo.txt +++ b/wadsrc/static/sndinfo.txt @@ -1124,6 +1124,7 @@ misc/teleport dstelept misc/swish dsswish misc/meathit dsmeatht misc/metalhit dsmtalht +misc/pcrush dspcrush misc/gibbed dsslop misc/explosion dsexplod misc/reactor dsreactr From 41df8242c178db504af84bc23fb19f3ae8b9d8c5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 21 Mar 2010 21:05:27 +0000 Subject: [PATCH 66/88] - Changed A_SetUserVar and A_SetUserArray so they affect the actor that called it, which is not necessarily "self". The only visible change from this should be that inventory items now set their own variables and not their owners'. SVN r2235 (trunk) --- src/thingdef/thingdef_codeptr.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f709b06a9..7e5f92f3c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3009,7 +3009,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserVar) ACTION_PARAM_NAME(varname, 0); ACTION_PARAM_INT(value, 1); - PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true); + PSymbol *sym = stateowner->GetClass()->Symbols.FindSymbol(varname, true); PSymbolVariable *var; if (sym == NULL || sym->SymbolType != SYM_Variable || @@ -3017,11 +3017,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserVar) var->ValueType.Type != VAL_Int) { Printf("%s is not a user variable in class %s\n", varname.GetChars(), - self->GetClass()->TypeName.GetChars()); + stateowner->GetClass()->TypeName.GetChars()); return; } // Set the value of the specified user variable. - *(int *)(reinterpret_cast(self) + var->offset) = value; + *(int *)(reinterpret_cast(stateowner) + var->offset) = value; } //=========================================================================== @@ -3037,7 +3037,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray) ACTION_PARAM_INT(pos, 1); ACTION_PARAM_INT(value, 2); - PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true); + PSymbol *sym = stateowner->GetClass()->Symbols.FindSymbol(varname, true); PSymbolVariable *var; if (sym == NULL || sym->SymbolType != SYM_Variable || @@ -3045,17 +3045,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray) var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int) { Printf("%s is not a user array in class %s\n", varname.GetChars(), - self->GetClass()->TypeName.GetChars()); + stateowner->GetClass()->TypeName.GetChars()); return; } if (pos < 0 || pos >= var->ValueType.size) { Printf("%d is out of bounds in array %s in class %s\n", pos, varname.GetChars(), - self->GetClass()->TypeName.GetChars()); + stateowner->GetClass()->TypeName.GetChars()); return; } // Set the value of the specified user array at index pos. - ((int *)(reinterpret_cast(self) + var->offset))[pos] = value; + ((int *)(reinterpret_cast(stateowner) + var->offset))[pos] = value; } //=========================================================================== From d1f9b94743114f7418a3e2aa59e6fb1bc2fe78af Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 22 Mar 2010 21:09:33 +0000 Subject: [PATCH 67/88] - Fixed: TMap::DelKey failed if the key's main position was nil, because it tried checking for it at the "next" position, which is an invalid pointer in that case. SVN r2236 (trunk) --- src/tarray.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tarray.h b/src/tarray.h index 92a6552e4..f93636f99 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -730,7 +730,11 @@ protected: Node *mp = MainPosition(key), **mpp; HashTraits Traits; - if (!mp->IsNil() && !Traits.Compare(mp->Pair.Key, key)) /* the key is in its main position */ + if (mp->IsNil()) + { + /* the key is definitely not present, because there is nothing at its main position */ + } + else if (!Traits.Compare(mp->Pair.Key, key)) /* the key is in its main position */ { if (mp->Next != NULL) /* move next node to its main position */ { From 0ca693771be03cdbd6ed8315faec221052fa3783 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 22 Mar 2010 21:18:54 +0000 Subject: [PATCH 68/88] - Keep all damage factors in the table, even those that are 1.0. - 256 is a valid pain chance, so clamp to that, not 255. SVN r2237 (trunk) --- src/info.cpp | 13 ++++--------- src/info.h | 2 +- src/p_interaction.cpp | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/info.cpp b/src/info.cpp index c3e5ac63e..1006f2b9c 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -273,16 +273,11 @@ FActorInfo *FActorInfo::GetReplacee (bool lookskill) void FActorInfo::SetDamageFactor(FName type, fixed_t factor) { - if (factor != FRACUNIT) + if (DamageFactors == NULL) { - if (DamageFactors == NULL) DamageFactors=new DmgFactors; - DamageFactors->Insert(type, factor); - } - else - { - if (DamageFactors != NULL) - DamageFactors->Remove(type); + DamageFactors = new DmgFactors; } + DamageFactors->Insert(type, factor); } //========================================================================== @@ -295,7 +290,7 @@ void FActorInfo::SetPainChance(FName type, int chance) if (chance >= 0) { if (PainChances == NULL) PainChances=new PainChanceList; - PainChances->Insert(type, MIN(chance, 255)); + PainChances->Insert(type, MIN(chance, 256)); } else { diff --git a/src/info.h b/src/info.h index 82de9486c..034c63196 100644 --- a/src/info.h +++ b/src/info.h @@ -158,7 +158,7 @@ struct FPlayerColorSet }; typedef TMap DmgFactors; -typedef TMap PainChanceList; +typedef TMap PainChanceList; typedef TMap FPlayerColorSetMap; struct FActorInfo diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 24d6cfd83..6cdf86ab5 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1285,7 +1285,7 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage painchance = target->PainChance; if (pc != NULL) { - BYTE * ppc = pc->CheckKey(mod); + int *ppc = pc->CheckKey(mod); if (ppc != NULL) { painchance = *ppc; From 4c5edf00b00db48c7d3a59a264b6dc94fa2246ae Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 22 Mar 2010 22:02:31 +0000 Subject: [PATCH 69/88] - P_ZMovement() temporarily disables jumping after a landing. Don't do this if the jump timer is already running or for short falls (e.g. along the edges of slopes, since the slope floorz calculation is pretty crappy.) SVN r2238 (trunk) --- src/p_mobj.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8fa00645f..8332d489d 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2132,8 +2132,9 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) { fixed_t dist; fixed_t delta; - fixed_t oldz = mo->z; - + fixed_t oldz = mo->z; + fixed_t grav = mo->GetGravity(); + // // check for smooth step up // @@ -2158,8 +2159,6 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player && !(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove))) { - fixed_t grav = mo->GetGravity(); - // [RH] Double gravity only if running off a ledge. Coming down from // an upward thrust (e.g. a jump) should not double it. if (mo->velz == 0 && oldfloorz > mo->floorz && mo->z == oldfloorz) @@ -2295,7 +2294,10 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) mo->HitFloor (); if (mo->player) { - mo->player->jumpTics = 7; // delay any jumping for a short while + if (mo->player->jumpTics != 0 && mo->velz < -grav*4) + { // delay any jumping for a short while + mo->player->jumpTics = 7; + } if (mo->velz < minvel && !(mo->flags & MF_NOGRAVITY)) { // Squat down. From 039b64899d58a018931dbbef633eafb114644a06 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 22 Mar 2010 22:15:56 +0000 Subject: [PATCH 70/88] - Fixed: ClearActorInventory used the wrong stack index to get its parameter. SVN r2239 (trunk) --- src/p_acs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 846b699eb..5c681a4d2 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5365,13 +5365,13 @@ int DLevelScript::RunScript () break; case PCD_CLEARACTORINVENTORY: - if (STACK(3) == 0) + if (STACK(1) == 0) { ClearInventory(NULL); } else { - FActorIterator it(STACK(3)); + FActorIterator it(STACK(1)); AActor *actor; for (actor = it.Next(); actor != NULL; actor = it.Next()) { From 0f0c02f9d6e1c39477305c6b0f524b082ab2504e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Mar 2010 17:07:07 +0000 Subject: [PATCH 71/88] - fixed: Level redirection checked the wrong level. SVN r2241 (trunk) --- src/g_level.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index cc3042941..478a01491 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -572,7 +572,7 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex if (strncmp(levelname, "enDSeQ", 6) != 0) { - nextinfo = FindLevelInfo (nextlevel); + nextinfo = FindLevelInfo (levelname); if (nextinfo != NULL) { level_info_t *nextredir = nextinfo->CheckLevelRedirect(); From a6a303f438524797bbcbd242668272597f6a3050 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Mar 2010 23:29:41 +0000 Subject: [PATCH 72/88] - fix division by 0. SVN r2243 (trunk) --- src/sound/fmodsound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 6a480f0f9..671b73d21 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1737,7 +1737,7 @@ bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel * if (FMOD_OK == chan->getCurrentSound(&sound)) { unsigned int len; - if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS)) + if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS) && len) { difftime %= len; } From 0529ffa0434affcdabb6f3bb4530d7ac72aa1786 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Mar 2010 16:57:00 +0000 Subject: [PATCH 73/88] - fixed: P_SpawnMapThing always reduced the angular precision to 45 degrees. - removed AngleIncrements because it's not really useful. SVN r2246 (trunk) --- src/actor.h | 3 --- src/g_shared/a_camera.cpp | 6 ------ src/g_shared/a_hatetarget.cpp | 5 ----- src/g_shared/a_spark.cpp | 6 ------ src/p_mobj.cpp | 17 +++++++++-------- 5 files changed, 9 insertions(+), 28 deletions(-) diff --git a/src/actor.h b/src/actor.h index 0f9a90e0e..ad622b3b4 100644 --- a/src/actor.h +++ b/src/actor.h @@ -581,9 +581,6 @@ public: virtual void Tick (); - // Smallest yaw interval for a mapthing to be spawned with - virtual angle_t AngleIncrements (); - // Called when actor dies virtual void Die (AActor *source, AActor *inflictor); diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp index c47c7c22d..99da16ae7 100644 --- a/src/g_shared/a_camera.cpp +++ b/src/g_shared/a_camera.cpp @@ -53,7 +53,6 @@ class ASecurityCamera : public AActor public: void PostBeginPlay (); void Tick (); - angle_t AngleIncrements (); void Serialize (FArchive &arc); protected: @@ -71,11 +70,6 @@ void ASecurityCamera::Serialize (FArchive &arc) arc << Center << Acc << Delta << Range; } -angle_t ASecurityCamera::AngleIncrements () -{ - return ANGLE_1; -} - void ASecurityCamera::PostBeginPlay () { Super::PostBeginPlay (); diff --git a/src/g_shared/a_hatetarget.cpp b/src/g_shared/a_hatetarget.cpp index 71c254bad..3753d0bb9 100644 --- a/src/g_shared/a_hatetarget.cpp +++ b/src/g_shared/a_hatetarget.cpp @@ -43,7 +43,6 @@ class AHateTarget : public AActor DECLARE_CLASS (AHateTarget, AActor) public: void BeginPlay (); - angle_t AngleIncrements (void); int TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FName damagetype); }; @@ -77,7 +76,3 @@ int AHateTarget::TakeSpecialDamage (AActor *inflictor, AActor *source, int damag } } -angle_t AHateTarget::AngleIncrements (void) -{ - return ANGLE_1; -} diff --git a/src/g_shared/a_spark.cpp b/src/g_shared/a_spark.cpp index c86d6600b..18b27d9ff 100644 --- a/src/g_shared/a_spark.cpp +++ b/src/g_shared/a_spark.cpp @@ -42,17 +42,11 @@ class ASpark : public AActor { DECLARE_CLASS (ASpark, AActor) public: - angle_t AngleIncrements (); void Activate (AActor *activator); }; IMPLEMENT_CLASS (ASpark) -angle_t ASpark::AngleIncrements () -{ - return ANGLE_1; -} - void ASpark::Activate (AActor *activator) { Super::Activate (activator); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8332d489d..ae376f148 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2614,11 +2614,6 @@ void AActor::RemoveFromHash () tid = 0; } -angle_t AActor::AngleIncrements () -{ - return ANGLE_45; -} - //========================================================================== // // AActor :: GetMissileDamage @@ -3700,8 +3695,6 @@ void AActor::LevelSpawned () { if (tics > 0 && !(flags4 & MF4_SYNCHRONIZED)) tics = 1 + (pr_spawnmapthing() % tics); - angle_t incs = AngleIncrements (); - angle -= angle % incs; flags &= ~MF_DROPPED; // [RH] clear MF_DROPPED flag HandleSpawnFlags (); } @@ -3960,7 +3953,15 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) { spawn_x = mthing->x; spawn_y = mthing->y; - spawn_angle = ANG45 * (mthing->angle/45); + // Allow full angular precision but avoid roundoff errors for multiples of 45 degrees. + if (mthing->angle % 45 != 0) + { + spawn_angle = mthing->angle * (ANG45 / 45); + } + else + { + spawn_angle = ANG45 * (mthing->angle / 45); + } } mobj = static_cast From 7f2ab00abe613e206efb065f363c7a31780d034e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 26 Mar 2010 22:26:50 +0000 Subject: [PATCH 74/88] - fixed: IDBEHOLD altered the item counter. SVN r2247 (trunk) --- src/g_shared/a_artifacts.cpp | 1 - src/g_shared/a_artifacts.h | 6 ------ src/m_cheat.cpp | 24 +++++++++++------------ wadsrc/static/actors/shared/inventory.txt | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index fa2c1e59f..1fe00931d 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -537,7 +537,6 @@ PalEntry APowerStrength::GetBlend () // Invisibility Powerup ------------------------------------------------------ IMPLEMENT_CLASS (APowerInvisibility) -IMPLEMENT_CLASS (APowerShadow) // Invisibility flag combos #define INVISIBILITY_FLAGS1 (MF_SHADOW) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 93352a719..00e39247e 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -81,12 +81,6 @@ protected: // fixed_t OwnersNormalAlpha; }; -// Needed only for m_cheat.cpp now -class APowerShadow : public APowerInvisibility -{ - DECLARE_CLASS (APowerShadow, APowerInvisibility) -}; - class APowerIronFeet : public APowerup { DECLARE_CLASS (APowerIronFeet, APowerup) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 2b87900b0..270ecf421 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -52,17 +52,17 @@ void cht_DoCheat (player_t *player, int cheat) { - static const PClass * const BeholdPowers[9] = + static const char * BeholdPowers[9] = { - RUNTIME_CLASS(APowerInvulnerable), - RUNTIME_CLASS(APowerStrength), - RUNTIME_CLASS(APowerInvisibility), - RUNTIME_CLASS(APowerIronFeet), - NULL, // MapRevealer - RUNTIME_CLASS(APowerLightAmp), - RUNTIME_CLASS(APowerShadow), - RUNTIME_CLASS(APowerMask), - RUNTIME_CLASS(APowerTargeter) + { "PowerInvulnerable" }, + { "PowerStrength" }, + { "PowerInvisibility" }, + { "PowerIronFeet" }, + { "MapRevealer" }, + { "PowerLightAmp" }, + { "PowerShadow" }, + { "PowerMask" }, + { "PowerTargeter" }, }; const PClass *type; AInventory *item; @@ -253,7 +253,7 @@ void cht_DoCheat (player_t *player, int cheat) { if (i != 0) { - player->mo->GiveInventoryType (BeholdPowers[i]); + cht_Give(player, BeholdPowers[i]); if (cheat == CHT_BEHOLDS) { P_GiveBody (player->mo, -100); @@ -262,7 +262,7 @@ void cht_DoCheat (player_t *player, int cheat) else { // Let's give the item here so that the power doesn't need colormap information. - player->mo->GiveInventoryType(PClass::FindClass("InvulnerabilitySphere")); + cht_Give(player, "InvulnerabilitySphere"); } } else diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index 659bab632..3e805ed05 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -184,7 +184,7 @@ ACTOR PowerGhost : PowerInvisibility Powerup.Mode "None" } -ACTOR PowerShadow : PowerInvisibility native +ACTOR PowerShadow : PowerInvisibility { +INVENTORY.HUBPOWER Powerup.Duration -55 From e83a9a2a001fbe24ebcf7a78b8a3caf310894451 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 27 Mar 2010 03:30:02 +0000 Subject: [PATCH 75/88] - Use normal texture animation for the main menu cursors. This required updating animations all the time and not just when inside a level. SVN r2248 (trunk) --- src/d_main.cpp | 4 ++++ src/m_menu.cpp | 15 +++------------ wadsrc/static/animdefs.txt | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 19db0885d..c2dbf761b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -657,6 +657,7 @@ void D_Display () switch (gamestate) { case GS_FULLCONSOLE: + R_UpdateAnimations(I_MSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); C_DrawConsole (false); @@ -721,6 +722,7 @@ void D_Display () break; case GS_INTERMISSION: + R_UpdateAnimations(I_MSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); WI_Drawer (); @@ -728,6 +730,7 @@ void D_Display () break; case GS_FINALE: + R_UpdateAnimations(I_MSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); F_Drawer (); @@ -735,6 +738,7 @@ void D_Display () break; case GS_DEMOSCREEN: + R_UpdateAnimations(I_MSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); D_PageDrawer (); diff --git a/src/m_menu.cpp b/src/m_menu.cpp index 299dbc53f..802477a3d 100644 --- a/src/m_menu.cpp +++ b/src/m_menu.cpp @@ -247,17 +247,10 @@ static char savegamestring[SAVESTRINGSIZE]; static FString EndString; static short itemOn; // menu item skull is on -static short whichSkull; // which skull to draw static int MenuTime; static int InfoType; static int InfoTic; -static const char skullName[2][9] = {"M_SKULL1", "M_SKULL2"}; // graphic name of skulls -static const char cursName[8][8] = // graphic names of Strife menu selector -{ - "M_CURS1", "M_CURS2", "M_CURS3", "M_CURS4", "M_CURS5", "M_CURS6", "M_CURS7", "M_CURS8" -}; - static oldmenu_t *currentMenu; // current menudef static oldmenu_t *TopLevelMenu; // The main menu everything hangs off of @@ -3745,19 +3738,19 @@ void M_Drawer () } else if (gameinfo.gametype & GAME_DoomChex) { - screen->DrawTexture (TexMan[skullName[whichSkull]], + screen->DrawTexture (TexMan("M_SKULL1"), x + SKULLXOFF, currentMenu->y - 5 + itemOn*LINEHEIGHT, DTA_Clean, true, TAG_DONE); } else if (gameinfo.gametype == GAME_Strife) { - screen->DrawTexture (TexMan[cursName[(MenuTime >> 2) & 7]], + screen->DrawTexture (TexMan("M_CURS1"), x - 28, currentMenu->y - 5 + itemOn*LINEHEIGHT, DTA_Clean, true, TAG_DONE); } else { - screen->DrawTexture (TexMan[MenuTime & 16 ? "M_SLCTR1" : "M_SLCTR2"], + screen->DrawTexture (TexMan("M_SLCTR1"), x + SELECTOR_XOFFSET, currentMenu->y + itemOn*LINEHEIGHT + SELECTOR_YOFFSET, DTA_Clean, true, TAG_DONE); @@ -3951,7 +3944,6 @@ void M_Ticker (void) MenuTime++; if (--skullAnimCounter <= 0) { - whichSkull ^= 1; skullAnimCounter = 8; } if (currentMenu == &PSetupDef || currentMenu == &ClassMenuDef) @@ -4005,7 +3997,6 @@ void M_Init (void) menuactive = MENU_Off; InfoType = 0; itemOn = currentMenu->lastOn; - whichSkull = 0; skullAnimCounter = 10; drawSkull = true; messageToPrint = 0; diff --git a/wadsrc/static/animdefs.txt b/wadsrc/static/animdefs.txt index 388a4f360..f4b33eaab 100644 --- a/wadsrc/static/animdefs.txt +++ b/wadsrc/static/animdefs.txt @@ -1,3 +1,24 @@ +// Doom menu cursor +texture optional M_SKULL1 +pic M_SKULL1 tics 8 +pic M_SKULL2 tics 8 + +// Heretic/Hexen menu cursor +texture optional M_SLCTR1 +pic M_SLCTR1 tics 16 +pic M_SLCTR2 tics 16 + +// Strife menu cursor +texture optional M_CURS1 +pic M_CURS1 tics 4 +pic M_CURS2 tics 4 +pic M_CURS3 tics 4 +pic M_CURS4 tics 4 +pic M_CURS5 tics 4 +pic M_CURS6 tics 4 +pic M_CURS7 tics 4 +pic M_CURS8 tics 4 + // Tome of Power texture optional SPINBK0 pic SPINBK0 tics 3 From a357a70f820b89e452a0bf42f722a50b05af8af3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Mar 2010 07:42:31 +0000 Subject: [PATCH 76/88] - fixed: Explosions directly under a water surface would not hurt any actor directly above this surface. - cleaned up P_CheckSight flag handling. SVN r2249 (trunk) --- src/b_func.cpp | 6 ++--- src/p_enemy.cpp | 20 +++++++------- src/p_local.h | 9 +++++++ src/p_map.cpp | 6 ++--- src/p_mobj.cpp | 2 +- src/p_sight.cpp | 43 +++++++++++++++++-------------- src/p_spec.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 10 +++---- 8 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/b_func.cpp b/src/b_func.cpp index adaa755c2..efc3f7f57 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -118,7 +118,7 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) //in doom is 90 degrees infront. bool FCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle) { - if (!P_CheckSight (from, to, 2)) + if (!P_CheckSight (from, to, SF_SEEPASTBLOCKEVERYTHING)) return false; // out of sight if (vangle == ANGLE_MAX) return true; @@ -339,7 +339,7 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot) && !p_leader[count]) //taken? { - if (P_CheckSight (bot, client->mo, 1)) + if (P_CheckSight (bot, client->mo, SF_IGNOREVISIBILITY)) { test = P_AproxDistance (client->mo->x - bot->x, client->mo->y - bot->y); @@ -525,7 +525,7 @@ angle_t FCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd) enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1); dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y); //try the predicted location - if (P_CheckSight (actor, bglobal.body1, 1)) //See the predicted location, so give a test missile + if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { FCheckPosition tm; if (SafeCheckPosition (bot, actor->x, actor->y, tm)) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index eff234af9..422ed845c 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -198,16 +198,16 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun // //---------------------------------------------------------------------------- -void P_NoiseAlert (AActor *target, AActor *emmiter, bool splash) +void P_NoiseAlert (AActor *target, AActor *emitter, bool splash) { - if (emmiter == NULL) + if (emitter == NULL) return; if (target != NULL && target->player && (target->player->cheats & CF_NOTARGET)) return; validcount++; - P_RecursiveSound (emmiter->Sector, target, splash, 0); + P_RecursiveSound (emitter->Sector, target, splash, 0); } @@ -308,7 +308,7 @@ bool P_CheckMissileRange (AActor *actor) { fixed_t dist; - if (!P_CheckSight (actor, actor->target, 4)) + if (!P_CheckSight (actor, actor->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES)) return false; if (actor->flags & MF_JUSTHIT) @@ -1136,7 +1136,7 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams } // P_CheckSight is by far the most expensive operation in here so let's do it last. - return P_CheckSight(lookee, other, 2); + return P_CheckSight(lookee, other, SF_SEEPASTBLOCKEVERYTHING); } //--------------------------------------------------------------------------- @@ -1154,7 +1154,7 @@ bool P_LookForMonsters (AActor *actor) AActor *mo; TThinkerIterator iterator; - if (!P_CheckSight (players[0].mo, actor, 2)) + if (!P_CheckSight (players[0].mo, actor, SF_SEEPASTBLOCKEVERYTHING)) { // Player can't see monster return false; } @@ -1183,7 +1183,7 @@ bool P_LookForMonsters (AActor *actor) { // [RH] Don't go after same species continue; } - if (!P_CheckSight (actor, mo, 2)) + if (!P_CheckSight (actor, mo, SF_SEEPASTBLOCKEVERYTHING)) { // Out of sight continue; } @@ -1764,7 +1764,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look) if (self->flags & MF_AMBUSH) { - if (P_CheckSight (self, self->target, 2)) + if (P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING)) goto seeyou; } else @@ -1931,7 +1931,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx) { dist = P_AproxDistance (self->target->x - self->x, self->target->y - self->y); - if (P_CheckSight (self, self->target, 2) && + if (P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING) && (!minseedist || dist > minseedist) && (!maxseedist || dist < maxseedist)) { @@ -2062,7 +2062,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Look2) { if (self->flags & MF_AMBUSH) { - if (!P_CheckSight (self, targ, 2)) + if (!P_CheckSight (self, targ, SF_SEEPASTBLOCKEVERYTHING)) goto nosee; } self->target = targ; diff --git a/src/p_local.h b/src/p_local.h index 1707db26e..134a627ed 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -390,6 +390,15 @@ void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); bool P_BounceWall (AActor *mo); bool P_BounceActor (AActor *mo, AActor * BlockingMobj); bool P_CheckSight (const AActor* t1, const AActor* t2, int flags=0); + +enum ESightFlags +{ + SF_IGNOREVISIBILITY=1, + SF_SEEPASTSHOOTABLELINES=2, + SF_SEEPASTBLOCKEVERYTHING=4, + SF_IGNOREWATERBOUNDARY=8 +}; + void P_ResetSightCounters (bool full); bool P_TalkFacing (AActor *player); void P_UseLines (player_t* player); diff --git a/src/p_map.cpp b/src/p_map.cpp index 019c8087a..5759f59c0 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3053,7 +3053,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e if (crossedffloors) { // if 3D floors were in the way do an extra visibility check for safety - if (!P_CheckSight(shootthing, th, 1)) + if (!P_CheckSight(shootthing, th, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) { // the thing can't be seen so we can safely exclude its range from our aiming field if (thingtoppitchGetClass()->Meta.GetMetaFixed(AMETA_RDFactor, FRACUNIT)/(float)FRACUNIT; - if (points > 0.f && P_CheckSight (thing, bombspot, 1)) + if (points > 0.f && P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path float velz; float thrust; @@ -4382,7 +4382,7 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b if (dist >= bombdistance) continue; // out of range - if (P_CheckSight (thing, bombspot, 1)) + if (P_CheckSight (thing, bombspot, SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY)) { // OK to damage; target is in direct path dist = clamp(dist - fulldamagedistance, 0, dist); int damage = Scale (bombdamage, bombdistance-dist, bombdistance); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index ae376f148..a3d739bea 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3016,7 +3016,7 @@ void AActor::Tick () && !players[i].enemy && player ? !IsTeammate (players[i].mo) : true && P_AproxDistance (players[i].mo->x-x, players[i].mo->y-y) < MAX_MONSTER_TARGET_DIST - && P_CheckSight (players[i].mo, this, 2)) + && P_CheckSight (players[i].mo, this, SF_SEEPASTBLOCKEVERYTHING)) { //Probably a monster, so go kill it. players[i].enemy = this; } diff --git a/src/p_sight.cpp b/src/p_sight.cpp index cc2940d7d..55ab3f13a 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -53,7 +53,7 @@ class SightCheck fixed_t lastzbottom; // z at last line sector_t * lastsector; // last sector being entered by trace fixed_t topslope, bottomslope; // slopes to top and bottom of target - int SeePastBlockEverything, SeePastShootableLines; + int Flags; divline_t trace; int myseethrough; @@ -73,9 +73,8 @@ public: seeingthing=t2; bottomslope = t2->z - sightzstart; topslope = bottomslope + t2->height; + Flags = flags; - SeePastBlockEverything = flags & 6; - SeePastShootableLines = flags & 4; myseethrough = FF_SEETHROUGH; } }; @@ -144,6 +143,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) F3DFloor* rover=s->e->XFloor.ffloors[j]; if((rover->flags & FF_SEETHROUGH) == myseethrough || !(rover->flags & FF_EXISTS)) continue; + if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; fixed_t ff_bottom=rover->bottom.plane->ZatPoint(trX, trY); fixed_t ff_top=rover->top.plane->ZatPoint(trX, trY); @@ -176,6 +176,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) F3DFloor* rover2=sb->e->XFloor.ffloors[k]; if((rover2->flags & FF_SEETHROUGH) == myseethrough || !(rover2->flags & FF_EXISTS)) continue; + if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; fixed_t ffb_bottom=rover2->bottom.plane->ZatPoint(trX, trY); fixed_t ffb_top=rover2->top.plane->ZatPoint(trX, trY); @@ -255,7 +256,7 @@ bool SightCheck::P_SightCheckLine (line_t *ld) // [RH] don't see past block everything lines if (ld->flags & ML_BLOCKEVERYTHING) { - if (!SeePastBlockEverything) + if (!(Flags & SF_SEEPASTBLOCKEVERYTHING)) { return false; } @@ -263,7 +264,7 @@ bool SightCheck::P_SightCheckLine (line_t *ld) // that runs a script on the current map. Used to prevent monsters // from trying to attack through a block everything line unless // there's a chance their attack will make it nonblocking. - if (!SeePastShootableLines) + if (!(Flags & SF_SEEPASTSHOOTABLELINES)) { if (!(ld->activation & SPAC_Impact)) { @@ -407,6 +408,7 @@ bool SightCheck::P_SightTraverseIntercepts () F3DFloor* rover = lastsector->e->XFloor.ffloors[i]; if((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue; + if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue; fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing->x, seeingthing->y); fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing->x, seeingthing->y); @@ -670,7 +672,7 @@ sightcounts[0]++; // // [RH] Andy Baker's stealth monsters: // Cannot see an invisible object - if ((flags & 1) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha))) + if ((flags & SF_IGNOREVISIBILITY) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha))) { // small chance of an attack being made anyway if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50) { @@ -681,20 +683,23 @@ sightcounts[0]++; // killough 4/19/98: make fake floors and ceilings block monster view - if ((s1->GetHeightSec() && - ((t1->z + t1->height <= s1->heightsec->floorplane.ZatPoint (t1->x, t1->y) && - t2->z >= s1->heightsec->floorplane.ZatPoint (t2->x, t2->y)) || - (t1->z >= s1->heightsec->ceilingplane.ZatPoint (t1->x, t1->y) && - t2->z + t1->height <= s1->heightsec->ceilingplane.ZatPoint (t2->x, t2->y)))) - || - (s2->GetHeightSec() && - ((t2->z + t2->height <= s2->heightsec->floorplane.ZatPoint (t2->x, t2->y) && - t1->z >= s2->heightsec->floorplane.ZatPoint (t1->x, t1->y)) || - (t2->z >= s2->heightsec->ceilingplane.ZatPoint (t2->x, t2->y) && - t1->z + t2->height <= s2->heightsec->ceilingplane.ZatPoint (t1->x, t1->y))))) + if (!(flags & SF_IGNOREWATERBOUNDARY)) { - res = false; - goto done; + if ((s1->GetHeightSec() && + ((t1->z + t1->height <= s1->heightsec->floorplane.ZatPoint (t1->x, t1->y) && + t2->z >= s1->heightsec->floorplane.ZatPoint (t2->x, t2->y)) || + (t1->z >= s1->heightsec->ceilingplane.ZatPoint (t1->x, t1->y) && + t2->z + t1->height <= s1->heightsec->ceilingplane.ZatPoint (t2->x, t2->y)))) + || + (s2->GetHeightSec() && + ((t2->z + t2->height <= s2->heightsec->floorplane.ZatPoint (t2->x, t2->y) && + t1->z >= s2->heightsec->floorplane.ZatPoint (t1->x, t1->y)) || + (t2->z >= s2->heightsec->ceilingplane.ZatPoint (t2->x, t2->y) && + t1->z + t2->height <= s2->heightsec->ceilingplane.ZatPoint (t1->x, t1->y))))) + { + res = false; + goto done; + } } // An unobstructed LOS is possible. diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 95bee9eb3..737ccc226 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1939,7 +1939,7 @@ void DPusher::Tick () // If speed <= 0, you're outside the effective radius. You also have // to be able to see the push/pull source point. - if ((speed > 0) && (P_CheckSight (thing, m_Source, 1))) + if ((speed > 0) && (P_CheckSight (thing, m_Source, SF_IGNOREVISIBILITY))) { angle_t pushangle = R_PointToAngle2 (thing->x, thing->y, sx, sy); if (m_Source->GetClass()->TypeName == NAME_PointPusher) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 7e5f92f3c..59ca172cb 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1891,9 +1891,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSight) ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! - for (int i=0;i Date: Sat, 27 Mar 2010 21:12:08 +0000 Subject: [PATCH 77/88] - added Gez's patch to move Hexen's startup notches out of the EXE. SVN r2250 (trunk) --- src/win32/st_start.cpp | 82 +++++++++++++++---------------------- wadsrc/static/netnotch.dat | 1 + wadsrc/static/notch.dat | Bin 0 -> 184 bytes 3 files changed, 33 insertions(+), 50 deletions(-) create mode 100644 wadsrc/static/netnotch.dat create mode 100644 wadsrc/static/notch.dat diff --git a/src/win32/st_start.cpp b/src/win32/st_start.cpp index f2a62c4c2..8fe844f70 100644 --- a/src/win32/st_start.cpp +++ b/src/win32/st_start.cpp @@ -153,10 +153,15 @@ class FHexenStartupScreen : public FGraphicalStartupScreen { public: FHexenStartupScreen(int max_progress, HRESULT &hr); + ~FHexenStartupScreen(); void Progress(); void NetProgress(int count); void NetDone(); + + // Hexen's notch graphics, converted to chunky pixels. + BYTE * NotchBits; + BYTE * NetNotchBits; }; class FStrifeStartupScreen : public FGraphicalStartupScreen @@ -253,55 +258,6 @@ static const RGBQUAD TextModePalette[16] = { HI, HI, HI, 0 }, // F white }; -// Hexen's notch graphics, converted to chunky pixels. - -static const BYTE NotchBits[] = -{ - 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x68, 0x86, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x78, 0x87, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x8d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x8d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x8d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x8d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x87, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd7, 0x7d, 0x60, 0x00, 0x00, - 0x00, 0x66, 0x99, 0x99, 0x96, 0x69, 0x66, 0x00, - 0x00, 0x69, 0x96, 0x99, 0x69, 0x96, 0x96, 0x00, - 0x06, 0x9d, 0x99, 0x69, 0x96, 0xd9, 0x79, 0x60, - 0x06, 0x7d, 0xdd, 0xdd, 0xdd, 0xdd, 0x77, 0x60, - 0x06, 0x78, 0x88, 0x88, 0x88, 0x88, 0xd6, 0x60, - 0x06, 0x7a, 0xaa, 0xaa, 0xaa, 0xaa, 0xd6, 0x60, - 0x06, 0x7a, 0x77, 0x77, 0x77, 0xa7, 0x96, 0x60, - 0x06, 0x77, 0xa7, 0x77, 0x77, 0xa7, 0x96, 0x60, - 0x06, 0x97, 0xa7, 0x79, 0x77, 0x77, 0x96, 0x60, - 0x00, 0x67, 0x79, 0x99, 0x99, 0xd7, 0x96, 0x60, - 0x00, 0x69, 0x99, 0x66, 0x69, 0x69, 0x66, 0x00 -}; - -static const BYTE NetNotchBits[] = -{ - 0x52, 0x20, - 0x23, 0x25, - 0x33, 0x25, - 0x31, 0x35, - 0x31, 0x35, - 0x31, 0x35, - 0x33, 0x35, - 0x31, 0x35, - 0x31, 0x35, - 0x31, 0x25, - 0x33, 0x35, - 0x31, 0x20, - 0x21, 0x35, - 0x23, 0x25, - 0x52, 0x20, - 0x05, 0x50 -}; - // CODE -------------------------------------------------------------------- //========================================================================== @@ -678,13 +634,23 @@ FHexenStartupScreen::FHexenStartupScreen(int max_progress, HRESULT &hr) : FGraphicalStartupScreen(max_progress) { int startup_lump = Wads.CheckNumForName ("STARTUP"); + int netnotch_lump = Wads.CheckNumForName ("NETNOTCH"); + int notch_lump = Wads.CheckNumForName ("NOTCH"); hr = E_FAIL; - if (startup_lump < 0 || Wads.LumpLength (startup_lump) != 153648 || !ST_Util_CreateStartupWindow()) + if (startup_lump < 0 || Wads.LumpLength (startup_lump) != 153648 || !ST_Util_CreateStartupWindow() || + netnotch_lump < 0 || Wads.LumpLength (netnotch_lump) != ST_NETNOTCH_WIDTH / 2 * ST_NETNOTCH_HEIGHT || + notch_lump < 0 || Wads.LumpLength (notch_lump) != ST_NOTCH_WIDTH / 2 * ST_NOTCH_HEIGHT) { + NetNotchBits = NotchBits = NULL; return; } + NetNotchBits = new BYTE[ST_NETNOTCH_WIDTH / 2 * ST_NETNOTCH_HEIGHT]; + Wads.ReadLump (netnotch_lump, NetNotchBits); + NotchBits = new BYTE[ST_NOTCH_WIDTH / 2 * ST_NOTCH_HEIGHT]; + Wads.ReadLump (notch_lump, NotchBits); + BYTE startup_screen[153648]; union { @@ -723,6 +689,22 @@ FHexenStartupScreen::FHexenStartupScreen(int max_progress, HRESULT &hr) hr = S_OK; } +//========================================================================== +// +// FHexenStartupScreen Deconstructor +// +// Frees the notch pictures. +// +//========================================================================== + +FHexenStartupScreen::~FHexenStartupScreen() +{ + if (NotchBits) + delete[] NotchBits; + if (NetNotchBits) + delete[] NetNotchBits; +} + //========================================================================== // // FHexenStartupScreen :: Progress diff --git a/wadsrc/static/netnotch.dat b/wadsrc/static/netnotch.dat new file mode 100644 index 000000000..d1a430adf --- /dev/null +++ b/wadsrc/static/netnotch.dat @@ -0,0 +1 @@ +R #%3%1515153515151%351 !5#%R P \ No newline at end of file diff --git a/wadsrc/static/notch.dat b/wadsrc/static/notch.dat new file mode 100644 index 0000000000000000000000000000000000000000..ef0b13af671f8e1d07acf79ac67dace823912955 GIT binary patch literal 184 zcmZQzU|=W!5ey9MP@3legwN3cp)=YbbVWOazR^p7hN`<>o4~-pkT!GXw9GUHhRkU* zGp9{sV4FKLbK1?y1h(3{ckkXUPhhL)=;-LUmcUlEYSpS$AiBJ~eEGBlw({i=diwIp Z^73g34C$3KXI`I{z>qmJEi*HX0RUirH8=nO literal 0 HcmV?d00001 From 70c21c8314f61eab318e1ded68cd5dcaff9d70ab Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 28 Mar 2010 03:46:46 +0000 Subject: [PATCH 78/88] - Changed FTextureManager::CheckForTexture() search algorithm so that inexact matches on textures of type TEX_MiscPatch will return the first such texture, as it does with all the other types. (It will still prefer to return a texture of a different type. Why are these treated differently, anyway?) SVN r2251 (trunk) --- src/textures/texturemanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 33c6e38e3..34e2f4ae6 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -140,7 +140,9 @@ FTextureID FTextureManager::CheckForTexture (const char *name, int usetype, BITF else { if (firsttype == FTexture::TEX_Null || - (firsttype == FTexture::TEX_MiscPatch && tex->UseType != FTexture::TEX_Null) + (firsttype == FTexture::TEX_MiscPatch && + tex->UseType != firsttype && + tex->UseType != FTexture::TEX_Null) ) { firstfound = i; From b3005ab16ccf3d67d6629d8b42e86ea1c2139997 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 28 Mar 2010 04:02:57 +0000 Subject: [PATCH 79/88] - Fixed: APowerup::EndEffect() needs to cancel any special colormaps applied by the powerup. This means all subclasses also need to call their superclass's EndEffect(), which they were not doing. For consistency, all the subclasses now do the same for InitEffect(), though APowerup::InitEffect() is still a no-op. SVN r2252 (trunk) --- src/g_shared/a_artifacts.cpp | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 1fe00931d..49971acd8 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -193,6 +193,12 @@ void APowerup::DoEffect () void APowerup::EndEffect () { + int colormap = GetSpecialColormap(BlendColor); + + if (colormap != NOFIXEDCOLORMAP && Owner->player->fixedcolormap == colormap) + { // only unset if the fixed colormap comes from this item + Owner->player->fixedcolormap = NOFIXEDCOLORMAP; + } } //=========================================================================== @@ -347,6 +353,7 @@ IMPLEMENT_CLASS (APowerInvulnerable) void APowerInvulnerable::InitEffect () { + Super::InitEffect(); Owner->effects &= ~FX_RESPAWNINVUL; Owner->flags2 |= MF2_INVULNERABLE; if (Mode == NAME_None) @@ -421,6 +428,8 @@ void APowerInvulnerable::DoEffect () void APowerInvulnerable::EndEffect () { + Super::EndEffect(); + if (Owner == NULL) { return; @@ -498,6 +507,7 @@ bool APowerStrength::HandlePickup (AInventory *item) void APowerStrength::InitEffect () { + Super::InitEffect(); } //=========================================================================== @@ -551,6 +561,7 @@ IMPLEMENT_CLASS (APowerInvisibility) void APowerInvisibility::InitEffect () { + Super::InitEffect(); // This used to call CommonInit(), which used to contain all the code that's repeated every // tic, plus the following code that needs to happen once and only once. // The CommonInit() code has been moved to DoEffect(), so this now ends with a call to DoEffect(), @@ -614,6 +625,7 @@ void APowerInvisibility::DoEffect () void APowerInvisibility::EndEffect () { + Super::EndEffect(); if (Owner != NULL) { Owner->flags &= ~(flags & INVISIBILITY_FLAGS1); @@ -821,6 +833,7 @@ void APowerLightAmp::DoEffect () void APowerLightAmp::EndEffect () { + Super::EndEffect(); if (Owner != NULL && Owner->player != NULL && Owner->player->fixedcolormap < NUMCOLORMAPS) { Owner->player->fixedlightlevel = -1; @@ -913,6 +926,7 @@ void APowerFlight::Serialize (FArchive &arc) void APowerFlight::InitEffect () { + Super::InitEffect(); Owner->flags2 |= MF2_FLY; Owner->flags |= MF_NOGRAVITY; if (Owner->z <= Owner->floorz) @@ -954,6 +968,7 @@ void APowerFlight::Tick () void APowerFlight::EndEffect () { + Super::EndEffect(); if (Owner == NULL || Owner->player == NULL) { return; @@ -1034,6 +1049,8 @@ void APowerWeaponLevel2::InitEffect () { AWeapon *weapon, *sister; + Super::InitEffect(); + if (Owner->player == NULL) return; @@ -1070,6 +1087,7 @@ void APowerWeaponLevel2::EndEffect () { player_t *player = Owner != NULL ? Owner->player : NULL; + Super::EndEffect(); if (player != NULL) { @@ -1198,6 +1216,8 @@ void APowerTargeter::InitEffect () { player_t *player; + Super::InitEffect(); + if ((player = Owner->player) == NULL) return; @@ -1249,6 +1269,7 @@ void APowerTargeter::DoEffect () void APowerTargeter::EndEffect () { + Super::EndEffect(); if (Owner != NULL && Owner->player != NULL) { P_SetPsprite (Owner->player, ps_targetcenter, NULL); @@ -1280,6 +1301,8 @@ IMPLEMENT_CLASS (APowerFrightener) void APowerFrightener::InitEffect () { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1294,6 +1317,8 @@ void APowerFrightener::InitEffect () void APowerFrightener::EndEffect () { + Super::EndEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1318,6 +1343,8 @@ void APowerTimeFreezer::InitEffect( ) { int ulIdx; + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1393,6 +1420,8 @@ void APowerTimeFreezer::EndEffect( ) { int ulIdx; + Super::EndEffect(); + // Allow other actors to move about freely once again. level.flags2 &= ~LEVEL2_FROZEN; @@ -1431,6 +1460,8 @@ IMPLEMENT_CLASS( APowerDamage) void APowerDamage::InitEffect( ) { + Super::InitEffect(); + // Use sound channel 5 to avoid interference with other actions. if (Owner != NULL) S_Sound(Owner, 5, SeeSound, 1.0f, ATTN_NONE); } @@ -1443,6 +1474,7 @@ void APowerDamage::InitEffect( ) void APowerDamage::EndEffect( ) { + Super::EndEffect(); // Use sound channel 5 to avoid interference with other actions. if (Owner != NULL) S_Sound(Owner, 5, DeathSound, 1.0f, ATTN_NONE); } @@ -1494,6 +1526,8 @@ IMPLEMENT_CLASS(APowerProtection) void APowerProtection::InitEffect( ) { + Super::InitEffect(); + if (Owner != NULL) { S_Sound(Owner, CHAN_AUTO, SeeSound, 1.0f, ATTN_NONE); @@ -1517,6 +1551,7 @@ void APowerProtection::InitEffect( ) void APowerProtection::EndEffect( ) { + Super::EndEffect(); if (Owner != NULL) { S_Sound(Owner, CHAN_AUTO, DeathSound, 1.0f, ATTN_NONE); @@ -1569,6 +1604,8 @@ IMPLEMENT_CLASS(APowerDrain) void APowerDrain::InitEffect( ) { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1584,6 +1621,8 @@ void APowerDrain::InitEffect( ) void APowerDrain::EndEffect( ) { + Super::EndEffect(); + // Nothing to do if there's no owner. if (Owner != NULL && Owner->player != NULL) { @@ -1605,6 +1644,8 @@ IMPLEMENT_CLASS(APowerRegeneration) void APowerRegeneration::InitEffect( ) { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1620,6 +1661,7 @@ void APowerRegeneration::InitEffect( ) void APowerRegeneration::EndEffect( ) { + Super::EndEffect(); // Nothing to do if there's no owner. if (Owner != NULL && Owner->player != NULL) { @@ -1640,6 +1682,8 @@ IMPLEMENT_CLASS(APowerHighJump) void APowerHighJump::InitEffect( ) { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1655,6 +1699,7 @@ void APowerHighJump::InitEffect( ) void APowerHighJump::EndEffect( ) { + Super::EndEffect(); // Nothing to do if there's no owner. if (Owner != NULL && Owner->player != NULL) { @@ -1675,6 +1720,8 @@ IMPLEMENT_CLASS(APowerDoubleFiringSpeed) void APowerDoubleFiringSpeed::InitEffect( ) { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1690,6 +1737,7 @@ void APowerDoubleFiringSpeed::InitEffect( ) void APowerDoubleFiringSpeed::EndEffect( ) { + Super::EndEffect(); // Nothing to do if there's no owner. if (Owner != NULL && Owner->player != NULL) { @@ -1723,6 +1771,8 @@ void APowerMorph::Serialize (FArchive &arc) void APowerMorph::InitEffect( ) { + Super::InitEffect(); + if (Owner != NULL && Owner->player != NULL && PlayerClass != NAME_None) { player_t *realplayer = Owner->player; // Remember the identity of the player @@ -1750,6 +1800,8 @@ void APowerMorph::InitEffect( ) void APowerMorph::EndEffect( ) { + Super::EndEffect(); + // Abort if owner already destroyed if (Owner == NULL) { @@ -1805,6 +1857,8 @@ IMPLEMENT_CLASS(APowerInfiniteAmmo) void APowerInfiniteAmmo::InitEffect( ) { + Super::InitEffect(); + if (Owner== NULL || Owner->player == NULL) return; @@ -1820,6 +1874,8 @@ void APowerInfiniteAmmo::InitEffect( ) void APowerInfiniteAmmo::EndEffect( ) { + Super::EndEffect(); + // Nothing to do if there's no owner. if (Owner != NULL && Owner->player != NULL) { From 7f96531dc05c0b968021b297c07c8606d4d01560 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 28 Mar 2010 04:04:44 +0000 Subject: [PATCH 80/88] - Use I_FPSTime() instead of I_MSTime() to drive R_UpdateAnimations(). SVN r2253 (trunk) --- src/d_main.cpp | 8 ++++---- src/r_main.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index c2dbf761b..4a3d631ca 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -657,7 +657,7 @@ void D_Display () switch (gamestate) { case GS_FULLCONSOLE: - R_UpdateAnimations(I_MSTime()); + R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); C_DrawConsole (false); @@ -722,7 +722,7 @@ void D_Display () break; case GS_INTERMISSION: - R_UpdateAnimations(I_MSTime()); + R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); WI_Drawer (); @@ -730,7 +730,7 @@ void D_Display () break; case GS_FINALE: - R_UpdateAnimations(I_MSTime()); + R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); F_Drawer (); @@ -738,7 +738,7 @@ void D_Display () break; case GS_DEMOSCREEN: - R_UpdateAnimations(I_MSTime()); + R_UpdateAnimations(I_FPSTime()); screen->SetBlendingRect(0,0,0,0); hw2d = screen->Begin2D(false); D_PageDrawer (); diff --git a/src/r_main.cpp b/src/r_main.cpp index 789388842..68a017986 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1081,7 +1081,7 @@ void R_SetupFrame (AActor *actor) iview->otic = nowtic; } - R_UpdateAnimations (I_MSTime()); + R_UpdateAnimations (I_FPSTime()); r_TicFrac = I_GetTimeFrac (&r_FrameTime); if (cl_capfps || r_NoInterpolate) { From 1436f0a4fae1b8a3c9ddff2587b690b55065d16b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 28 Mar 2010 10:51:35 +0000 Subject: [PATCH 81/88] - Fixed: It was no longer possible to talk to non-shootable NPCs. Also took the opportunity to merge the various boolean parameters to P_AimLineAttack into one flag parameter. SVN r2254 (trunk) --- src/c_cmds.cpp | 17 +++++++-- src/g_hexen/a_clericstaff.cpp | 4 +-- src/g_hexen/a_fighterhammer.cpp | 6 ++-- src/g_hexen/a_magecone.cpp | 2 +- src/g_strife/a_crusader.cpp | 4 +-- src/p_enemy.cpp | 2 +- src/p_local.h | 11 +++++- src/p_map.cpp | 57 ++++++++++++++++--------------- src/thingdef/thingdef_codeptr.cpp | 2 +- 9 files changed, 64 insertions(+), 41 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 4e0aa8b32..0567427cf 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -788,8 +788,8 @@ CCMD(info) AActor *linetarget; if (CheckCheatmode () || players[consoleplayer].mo == NULL) return; - P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &linetarget, 0, - false, false, true); + P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, + &linetarget, 0, ALF_CHECKNONSHOOTABLE|ALF_FORCENOSMART); if (linetarget) { Printf("Target=%s, Health=%d, Spawnhealth=%d\n", @@ -923,3 +923,16 @@ CCMD(nextsecret) Printf("no next secret map!\n"); } } + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- +CCMD(currentpos) +{ + AActor *mo = players[consoleplayer].mo; + Printf("Current player position: (%1.3f,%1.3f,%1.3f), angle: %1.3f, floorheight: %1.3f, sector:%d, lightlevel: %d\n", + FIXED2FLOAT(mo->x), FIXED2FLOAT(mo->y), FIXED2FLOAT(mo->z), mo->angle/float(ANGLE_1), FIXED2FLOAT(mo->floorz), mo->Sector->sectornum, mo->Sector->lightlevel); +} + diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp index 829e45127..03b8c7518 100644 --- a/src/g_hexen/a_clericstaff.cpp +++ b/src/g_hexen/a_clericstaff.cpp @@ -67,7 +67,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) for (i = 0; i < 3; i++) { angle = pmo->angle+i*(ANG45/16); - slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, false, true); + slope = P_AimLineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); if (linetarget) { P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff")); @@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) break; } angle = pmo->angle-i*(ANG45/16); - slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, false, true); + slope = P_AimLineAttack (player->mo, angle, fixed_t(1.5*MELEERANGE), &linetarget, 0, ALF_CHECK3D); if (linetarget) { P_LineAttack (pmo, angle, fixed_t(1.5*MELEERANGE), slope, damage, NAME_Melee, PClass::FindClass ("CStaffPuff")); diff --git a/src/g_hexen/a_fighterhammer.cpp b/src/g_hexen/a_fighterhammer.cpp index edb618bea..2c457c035 100644 --- a/src/g_hexen/a_fighterhammer.cpp +++ b/src/g_hexen/a_fighterhammer.cpp @@ -46,7 +46,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) for (i = 0; i < 16; i++) { angle = pmo->angle + i*(ANG45/32); - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true); + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); if (linetarget) { P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true); @@ -59,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) goto hammerdone; } angle = pmo->angle-i*(ANG45/32); - slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true); + slope = P_AimLineAttack(pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); if(linetarget) { P_LineAttack(pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true); @@ -74,7 +74,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FHammerAttack) } // didn't find any targets in meleerange, so set to throw out a hammer angle = pmo->angle; - slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, false, true); + slope = P_AimLineAttack (pmo, angle, HAMMER_RANGE, &linetarget, 0, ALF_CHECK3D); if (P_LineAttack (pmo, angle, HAMMER_RANGE, slope, damage, NAME_Melee, PClass::FindClass ("HammerPuff"), true) != NULL) { pmo->special1 = false; diff --git a/src/g_hexen/a_magecone.cpp b/src/g_hexen/a_magecone.cpp index a80eae659..84d53db56 100644 --- a/src/g_hexen/a_magecone.cpp +++ b/src/g_hexen/a_magecone.cpp @@ -77,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireConePL1) for (i = 0; i < 16; i++) { angle = self->angle+i*(ANG45/16); - slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, false, true); + slope = P_AimLineAttack (self, angle, MELEERANGE, &linetarget, 0, ALF_CHECK3D); if (linetarget) { P_DamageMobj (linetarget, self, self, damage, NAME_Ice); diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp index f4f0024fd..6d34182f4 100644 --- a/src/g_strife/a_crusader.cpp +++ b/src/g_strife/a_crusader.cpp @@ -9,7 +9,7 @@ #include "thingdef/thingdef.h" */ -bool Sys_1ed64 (AActor *self) +static bool CrusaderCheckRange (AActor *self) { if (P_CheckSight (self, self->target) && self->reactiontime == 0) { @@ -23,7 +23,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose) if (self->target == NULL) return; - if (Sys_1ed64 (self)) + if (CrusaderCheckRange (self)) { A_FaceTarget (self); self->angle -= ANGLE_180/16; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 422ed845c..c216baa00 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2726,7 +2726,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail) self->target->x, self->target->y); - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, false, false, false, self->target); + self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, self->target); if (linetarget == NULL) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. diff --git a/src/p_local.h b/src/p_local.h index 134a627ed..3aff45bf0 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -407,7 +407,16 @@ void P_FindFloorCeiling (AActor *actor, bool onlymidtex = false); bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset); -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, bool forcenosmart=false, bool check3d = false, bool checknonshootable = false, AActor *target=NULL); +fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, int flags = 0, AActor *target=NULL); + +enum +{ + ALF_FORCENOSMART = 1, + ALF_CHECK3D = 2, + ALF_CHECKNONSHOOTABLE = 4, + ALF_CHECKCONVERSATION = 8, +}; + AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, bool ismelee = false); AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, bool ismelee = false); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch); diff --git a/src/p_map.cpp b/src/p_map.cpp index 5759f59c0..6e5807066 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2807,8 +2807,7 @@ struct aim_t AActor * linetarget; AActor * thing_friend, * thing_other; angle_t pitch_friend, pitch_other; - bool notsmart; - bool check3d; + int flags; #ifdef _3DFLOORS sector_t * lastsector; secplane_t * lastfloorplane; @@ -2819,7 +2818,7 @@ struct aim_t bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in); #endif - void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable = false, AActor *target=NULL); + void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target=NULL); }; @@ -2936,7 +2935,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in) // //============================================================================ -void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable, AActor *target) +void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, AActor *target) { FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; @@ -2994,18 +2993,23 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e if (target != NULL && th != target) continue; // only care about target, and you're not it - if (!checknonshootable) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags + // If we want to start a conversation anything that has one should be + // found, regardless of other settings. + if (!(flags & ALF_CHECKCONVERSATION) || th->Conversation == NULL) { - if (!(th->flags&MF_SHOOTABLE)) - continue; // corpse or something - - // check for physical attacks on a ghost - if ((th->flags3 & MF3_GHOST) && - shootthing->player && // [RH] Be sure shootthing is a player - shootthing->player->ReadyWeapon && - (shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) + if (!(flags & ALF_CHECKNONSHOOTABLE)) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags { - continue; + if (!(th->flags&MF_SHOOTABLE)) + continue; // corpse or something + + // check for physical attacks on a ghost + if ((th->flags3 & MF3_GHOST) && + shootthing->player && // [RH] Be sure shootthing is a player + shootthing->player->ReadyWeapon && + (shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST)) + { + continue; + } } } dist = FixedMul (attackrange, in->frac); @@ -3079,7 +3083,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e thingpitch = thingtoppitch/2 + thingbottompitch/2; - if (check3d) + if (flags & ALF_CHECK3D) { // We need to do a 3D distance check here because this is nearly always used in // combination with P_LineAttack. P_LineAttack uses 3D distance but FPathTraverse @@ -3096,7 +3100,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e } } - if (sv_smartaim && !notsmart) + if (sv_smartaim != 0 && !(flags & ALF_FORCENOSMART)) { // try to be a little smarter about what to aim at! // In particular avoid autoaiming at friends amd barrels. @@ -3131,11 +3135,6 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e aimpitch = thingpitch; return; } - if (checknonshootable) - { - linetarget = th; - aimpitch = thingpitch; - } } } @@ -3145,15 +3144,16 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e // //============================================================================ -fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d, bool checknonshootable, AActor *target) +fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, + int flags, AActor *target) { fixed_t x2; fixed_t y2; aim_t aim; angle >>= ANGLETOFINESHIFT; + aim.flags = flags; aim.shootthing = t1; - aim.check3d = check3d; x2 = t1->x + (distance>>FRACBITS)*finecosine[angle]; y2 = t1->y + (distance>>FRACBITS)*finesine[angle]; @@ -3194,7 +3194,6 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p } aim.toppitch = t1->pitch - vrange; aim.bottompitch = t1->pitch + vrange; - aim.notsmart = forcenosmart; aim.attackrange = distance; aim.linetarget = NULL; @@ -3223,7 +3222,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p } #endif - aim.AimTraverse (t1->x, t1->y, x2, y2, checknonshootable, target); + aim.AimTraverse (t1->x, t1->y, x2, y2, target); if (!aim.linetarget) { @@ -3239,7 +3238,9 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p } } if (pLineTarget) + { *pLineTarget = aim.linetarget; + } return aim.linetarget ? aim.aimpitch : t1->pitch; } @@ -3918,13 +3919,13 @@ bool P_TalkFacing(AActor *player) { AActor *linetarget; - P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1*35, true); + P_AimLineAttack(player, player->angle, TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); if (linetarget == NULL) { - P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, true); + P_AimLineAttack(player, player->angle + (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); if (linetarget == NULL) { - P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, true); + P_AimLineAttack(player, player->angle - (ANGLE_90 >> 4), TALKRANGE, &linetarget, ANGLE_1*35, ALF_FORCENOSMART|ALF_CHECKCONVERSATION); if (linetarget == NULL) { return false; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 59ca172cb..095540caa 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1206,7 +1206,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun) self->target->x, self->target->y); } - self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, false, false, false, aim ? self->target : NULL); + self->pitch = P_AimLineAttack (self, self->angle, MISSILERANGE, &linetarget, ANGLE_1*60, 0, aim ? self->target : NULL); if (linetarget == NULL && aim) { // We probably won't hit the target, but aim at it anyway so we don't look stupid. From 18d58ef1c5dfdb42001307bbc18e088197b9ed82 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Mar 2010 06:08:22 +0000 Subject: [PATCH 82/88] - fixed: APowerup::EndEffect could crash if the item was not owned by a valid player actor. SVN r2256 (trunk) --- src/g_shared/a_artifacts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 49971acd8..304c9059e 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -195,7 +195,7 @@ void APowerup::EndEffect () { int colormap = GetSpecialColormap(BlendColor); - if (colormap != NOFIXEDCOLORMAP && Owner->player->fixedcolormap == colormap) + if (colormap != NOFIXEDCOLORMAP && Owner && Owner->player && Owner->player->fixedcolormap == colormap) { // only unset if the fixed colormap comes from this item Owner->player->fixedcolormap = NOFIXEDCOLORMAP; } From ba29ffd4051e6381e50d2b0a4d92539bd2c50181 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Mar 2010 20:25:08 +0000 Subject: [PATCH 83/88] - GCC fixes. SVN r2257 (trunk) --- src/m_cheat.cpp | 18 +++++++++--------- src/p_buildmap.cpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 270ecf421..a79ca3ad7 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -54,15 +54,15 @@ void cht_DoCheat (player_t *player, int cheat) { static const char * BeholdPowers[9] = { - { "PowerInvulnerable" }, - { "PowerStrength" }, - { "PowerInvisibility" }, - { "PowerIronFeet" }, - { "MapRevealer" }, - { "PowerLightAmp" }, - { "PowerShadow" }, - { "PowerMask" }, - { "PowerTargeter" }, + "PowerInvulnerable", + "PowerStrength", + "PowerInvisibility", + "PowerIronFeet", + "MapRevealer", + "PowerLightAmp", + "PowerShadow", + "PowerMask", + "PowerTargeter", }; const PClass *type; AInventory *item; diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 82a709571..86d7575ad 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -347,7 +347,7 @@ static bool P_LoadBloodMap (BYTE *data, size_t len, FMapThing **mapthings, int * data += sizeof(spritetype); if (bspr[i].extra > 0) // copy Xsprite { - assert(sizeof Xsprite == 56); + assert(sizeof(Xsprite) == 56); memcpy(&xspr[i], data, sizeof(Xsprite)); data += sizeof(Xsprite); } From aa86e62693983a573290de01dce3ac1ee44af456 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 31 Mar 2010 03:48:16 +0000 Subject: [PATCH 84/88] - Added DefaultEnvironment MAPINFO option to set the default sound environment for the whole map. SVN r2261 (trunk) --- src/g_level.cpp | 2 ++ src/g_level.h | 2 ++ src/g_mapinfo.cpp | 15 +++++++++++++++ src/p_setup.cpp | 9 ++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 478a01491..1fd0130dc 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1319,6 +1319,8 @@ void G_InitLevelLocals () compatflags.Callback(); NormalLight.ChangeFade (level.fadeto); + + level.DefaultEnvironment = info->DefaultEnvironment; } //========================================================================== diff --git a/src/g_level.h b/src/g_level.h index 0e17b02b1..58ddf9d5c 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -279,6 +279,7 @@ struct level_info_t DWORD compatflags; DWORD compatmask; FString Translator; // for converting Doom-format linedef and sector types. + int DefaultEnvironment; // Default sound environment for the map. // Redirection: If any player is carrying the specified item, then // you go to the RedirectMap instead of this one. @@ -391,6 +392,7 @@ struct FLevelLocals fixed_t aircontrol; fixed_t airfriction; int airsupply; + int DefaultEnvironment; // Default sound environment. FSectorScrollValues *Scrolls; // NULL if no DScrollers in this level diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 09e8eb96a..6131c7017 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -265,6 +265,7 @@ void level_info_t::Reset() bordertexture[0] = 0; teamdamage = 0.f; specialactions.Clear(); + DefaultEnvironment = 0; } @@ -1250,6 +1251,20 @@ DEFINE_MAP_OPTION(mapbackground, true) parse.ParseLumpOrTextureName(info->mapbg); } +DEFINE_MAP_OPTION(defaultenvironment, false) +{ + int id; + + parse.ParseAssign(); + parse.sc.MustGetNumber(); + id = parse.sc.Number << 8; + if (parse.CheckNumber()) + { + id |= parse.sc.Number; + } + info->DefaultEnvironment = id; +} + //========================================================================== // diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 3f55dbe23..c27da8e56 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -729,6 +729,7 @@ void P_FloodZone (sector_t *sec, int zonenum) void P_FloodZones () { int z = 0, i; + ReverbContainer *reverb; for (i = 0; i < numsectors; ++i) { @@ -739,9 +740,15 @@ void P_FloodZones () } numzones = z; zones = new zone_t[z]; + reverb = S_FindEnvironment(level.DefaultEnvironment); + if (reverb == NULL) + { + Printf("Sound environment %d, %d not found\n", level.DefaultEnvironment >> 8, level.DefaultEnvironment & 255); + reverb = DefaultEnvironments[0]; + } for (i = 0; i < z; ++i) { - zones[i].Environment = DefaultEnvironments[0]; + zones[i].Environment = reverb; } } From 69c777df4c83279417d3bc2919f73b4d93347379 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 31 Mar 2010 23:33:18 +0000 Subject: [PATCH 85/88] - Allow defaultenvironment to take names as well as numeric IDs. SVN r2262 (trunk) --- src/d_main.cpp | 4 +++- src/g_mapinfo.cpp | 26 +++++++++++++++++++++----- src/s_sound.cpp | 1 - 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 4a3d631ca..61e76da0d 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2027,6 +2027,9 @@ void D_DoomMain (void) StartScreen->AppendStatusLine(temp); } + // [RH] Load sound environments + S_ParseReverbDef (); + // [RH] Parse through all loaded mapinfo lumps Printf ("G_ParseMapInfo: Load map definitions.\n"); G_ParseMapInfo (iwad_info->MapInfo); @@ -2035,7 +2038,6 @@ void D_DoomMain (void) Printf ("S_InitData: Load sound definitions.\n"); S_InitData (); - Printf ("Texman.Init: Init texture manager.\n"); TexMan.Init(); diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 6131c7017..f8c087459 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1256,11 +1256,27 @@ DEFINE_MAP_OPTION(defaultenvironment, false) int id; parse.ParseAssign(); - parse.sc.MustGetNumber(); - id = parse.sc.Number << 8; - if (parse.CheckNumber()) - { - id |= parse.sc.Number; + if (parse.sc.CheckNumber()) + { // Numeric ID XXX [, YYY] + id = parse.sc.Number << 8; + if (parse.CheckNumber()) + { + id |= parse.sc.Number; + } + } + else + { // Named environment + parse.sc.MustGetString(); + ReverbContainer *reverb = S_FindEnvironment(parse.sc.String); + if (reverb == NULL) + { + parse.sc.ScriptMessage("Unknown sound environment '%s'\n", parse.sc.String); + id = 0; + } + else + { + id = reverb->ID; + } } info->DefaultEnvironment = id; } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index d65cbaf0b..f31f1c2da 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -323,7 +323,6 @@ void S_InitData () LastLocalSndInfo = LastLocalSndSeq = ""; S_ParseSndInfo (); S_ParseSndSeq (-1); - S_ParseReverbDef (); } //========================================================================== From 7da0badf3c899b0cfeb8dc089a98a18e604c217d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 2 Apr 2010 07:24:57 +0000 Subject: [PATCH 86/88] - fixed: The thing id in Hexen map things needs to be treated as a signed short. This is how Hexen defined it and how older ZDooms before the implementation of UDMF used them internally. SVN r2263 (trunk) --- src/doomdata.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index 37e7190d6..d066277a7 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -227,10 +227,10 @@ struct mapseg_t { WORD v1; WORD v2; - short angle; + SWORD angle; WORD linedef; - short side; - short offset; + SWORD side; + SWORD offset; }; @@ -242,11 +242,11 @@ struct mapseg_t struct mapnode_t { - short x,y,dx,dy; // partition line - short bbox[2][4]; // bounding box for each child + SWORD x,y,dx,dy; // partition line + SWORD bbox[2][4]; // bounding box for each child // If NF_SUBSECTOR is or'ed in, it's a subsector, // else it's a node of another subtree. - unsigned short children[2]; + WORD children[2]; }; @@ -256,23 +256,23 @@ struct mapnode_t // plus skill/visibility flags and attributes. struct mapthing_t { - short x; - short y; - short angle; - short type; - short options; + SWORD x; + SWORD y; + SWORD angle; + SWORD type; + SWORD options; }; // [RH] Hexen-compatible MapThing. struct mapthinghexen_t { - unsigned short thingid; - short x; - short y; - short z; - short angle; - short type; - short flags; + SWORD thingid; + SWORD x; + SWORD y; + SWORD z; + SWORD angle; + SWORD type; + SWORD flags; BYTE special; BYTE args[5]; }; From 6f9b035df83b5f3e23a32e278b1ed09586b0eecc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 3 Apr 2010 07:10:52 +0000 Subject: [PATCH 87/88] - Changed: The monster refiring functions should use the same sight checking mode as the code that triggers the attack. SVN r2266 (trunk) --- src/g_doom/a_possessed.cpp | 2 +- src/g_doom/a_spidermaster.cpp | 2 +- src/g_strife/a_sentinel.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_doom/a_possessed.cpp b/src/g_doom/a_possessed.cpp index e435bff14..c792a489d 100644 --- a/src/g_doom/a_possessed.cpp +++ b/src/g_doom/a_possessed.cpp @@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CPosRefire) if (!self->target || P_HitFriend (self) || self->target->health <= 0 - || !P_CheckSight (self, self->target, 0) ) + || !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES)) { self->SetState (self->SeeState); } diff --git a/src/g_doom/a_spidermaster.cpp b/src/g_doom/a_spidermaster.cpp index a29561b56..1e3628c69 100644 --- a/src/g_doom/a_spidermaster.cpp +++ b/src/g_doom/a_spidermaster.cpp @@ -22,7 +22,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpidRefire) if (!self->target || P_HitFriend (self) || self->target->health <= 0 - || !P_CheckSight (self, self->target, 0) ) + || !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES)) { self->SetState (self->SeeState); } diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp index 5f012cfb1..9f582dcd5 100644 --- a/src/g_strife/a_sentinel.cpp +++ b/src/g_strife/a_sentinel.cpp @@ -79,7 +79,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelRefire) { if (self->target == NULL || self->target->health <= 0 || - !P_CheckSight (self, self->target) || + !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) || P_HitFriend(self) || pr_sentinelrefire() < 40) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 095540caa..45038d83f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2847,7 +2847,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MonsterRefire) if (!self->target || P_HitFriend (self) || self->target->health <= 0 - || !P_CheckSight (self, self->target, 0) ) + || !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) ) { ACTION_JUMP(jump); } From d53fdb418b97fb6220a65c110db5de28a8ed273b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 4 Apr 2010 03:03:01 +0000 Subject: [PATCH 88/88] - Fixed: P_LookForMonsters() had not been updated for the new species check. SVN r2268 (trunk) --- src/p_enemy.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index c216baa00..558533742 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1178,8 +1178,7 @@ bool P_LookForMonsters (AActor *actor) { // Stop searching return false; } - if (mo->IsKindOf (RUNTIME_TYPE(actor)) || - actor->IsKindOf (RUNTIME_TYPE(mo))) + if (mo->GetSpecies() == actor->GetSpecies()) { // [RH] Don't go after same species continue; }