From dc504874329491363e905f72b1c69749905a95a5 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 11 Jul 2011 02:35:33 +0000 Subject: [PATCH 001/993] - Lets try using semaphores on Linux instead of sleeping to implement cl_capfps. SVN r3270 (trunk) --- src/CMakeLists.txt | 7 ------ src/sdl/i_system.cpp | 55 +++++++++++--------------------------------- 2 files changed, 13 insertions(+), 49 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0eef076d9..6f8eba214 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -444,13 +444,6 @@ if( NOT STRNICMP_EXISTS ) add_definitions( -Dstrnicmp=strncasecmp ) endif( NOT STRNICMP_EXISTS ) -if( NOT WIN32 ) - CHECK_FUNCTION_EXISTS( sigtimedwait SIGTIMEDWAIT_EXISTS ) - if( SIGTIMEDWAIT_EXISTS ) - add_definitions( -DHAVE_SIGTIMEDWAIT ) - endif( SIGTIMEDWAIT_EXISTS ) -endif( NOT WIN32) - if( NOT MSVC ) add_definitions( -D__forceinline=inline ) endif( NOT MSVC ) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 5a7d89e8a..0f0c7125f 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #ifndef NO_GTK #include #include @@ -124,10 +125,7 @@ static DWORD BaseTime; static int TicFrozen; // Signal based timer. -static struct timespec SignalTimeOut = { 0, 1000000/TICRATE }; -#ifdef HAVE_SIGTIMEDWAIT -static sigset_t SignalWaitSet; -#endif +static sem_t timerWait; static int tics; static DWORD sig_start, sig_next; @@ -175,11 +173,6 @@ int I_GetTimePolled (bool saveMS) int I_GetTimeSignaled (bool saveMS) { - if (TicFrozen != 0) - { - return TicFrozen; - } - if (saveMS) { TicStart = sig_start; @@ -203,15 +196,10 @@ int I_WaitForTicSignaled (int prevtic) { assert (TicFrozen == 0); -#ifdef HAVE_SIGTIMEDWAIT - while(sigtimedwait(&SignalWaitSet, NULL, &SignalTimeOut) == -1 && errno == EINTR) - ; -#else - while(nanosleep(&SignalTimeOut, NULL) == -1 && errno == EINTR) - ; -#endif + while(tics <= prevtic) + while(sem_wait(&timerWait) != 0); - return I_GetTimePolled(false); + return tics; } void I_FreezeTimeSelect (bool frozen) @@ -258,6 +246,7 @@ void I_HandleAlarm (int sig) tics++; sig_start = SDL_GetTicks(); sig_next = Scale((Scale (sig_start, TICRATE, 1000) + 1), 1000, TICRATE); + sem_post(&timerWait); } // @@ -267,41 +256,23 @@ void I_HandleAlarm (int sig) // void I_SelectTimer() { - struct sigaction act; + sem_init(&timerWait, 0, 0); + signal(SIGALRM, I_HandleAlarm); + struct itimerval itv; - - sigfillset (&act.sa_mask); - act.sa_flags = 0; - // [BL] This doesn't seem to be executed consistantly, I'm guessing the - // sleep functions are taking over the signal. So for now, lets just - // attach WaitForTic to signals in order to reduce CPU usage. - //act.sa_handler = I_HandleAlarm; - act.sa_handler = SIG_IGN; - - sigaction (SIGALRM, &act, NULL); - itv.it_interval.tv_sec = itv.it_value.tv_sec = 0; itv.it_interval.tv_usec = itv.it_value.tv_usec = 1000000/TICRATE; - // [BL] See above. - I_GetTime = I_GetTimePolled; - I_FreezeTime = I_FreezeTimePolled; - if (setitimer(ITIMER_REAL, &itv, NULL) != 0) { - //I_GetTime = I_GetTimePolled; - //I_FreezeTime = I_FreezeTimePolled; + I_GetTime = I_GetTimePolled; + I_FreezeTime = I_FreezeTimePolled; I_WaitForTic = I_WaitForTicPolled; } else { -#ifdef HAVE_SIGTIMEDWAIT - sigemptyset(&SignalWaitSet); - sigaddset(&SignalWaitSet, SIGALRM); -#endif - - //I_GetTime = I_GetTimeSignaled; - //I_FreezeTime = I_FreezeTimeSignaled; + I_GetTime = I_GetTimeSignaled; + I_FreezeTime = I_FreezeTimeSignaled; I_WaitForTic = I_WaitForTicSignaled; } } From c8b8cdd13bd6ffeab91d81e78eb7ad52123274d6 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 14 Jul 2011 09:31:39 +0000 Subject: [PATCH 002/993] - Fixed: SBarInfo string center alignment didn't work with non-monospace fonts. SVN r3271 (trunk) --- src/g_shared/sbarinfo_commands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index c320af1fd..f31a5f77b 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -781,7 +781,7 @@ class CommandDrawString : public SBarInfoCommand break; case ALIGN_CENTER: if(script->spacingCharacter == '\0') - x -= static_cast (font->StringWidth(str)+(spacing * str.Len()) / 2); + x -= static_cast ((font->StringWidth(str)+(spacing * str.Len())) / 2); else x -= static_cast ((font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing) * str.Len() / 2); break; From 080e769c768241d55ed8b847647637baaad09c0e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Jul 2011 13:26:36 +0000 Subject: [PATCH 003/993] - removed all asserts from the interpolation objects' Destroy methods. The condition will not be true after a failed savegame write occured. - fixed: D_ErrorCleanup must clear 'savegamerestore'. - fixed: Cleaning up when loading a savegame failed while restoring the thinker list did not work. There were two issues: * removed the asserts in GC::SweepList because they get triggered by thinkers that were not fully initialized during loading. * AActor::UnlinkFromWorld may not assume that the sector list has been initialized when this function is called. SVN r3274 (trunk) --- src/d_main.cpp | 1 + src/dobjgc.cpp | 6 ++++-- src/dthinker.cpp | 13 ++---------- src/p_maputl.cpp | 40 ++++++++++++++++++++---------------- src/r_data/r_interpolate.cpp | 6 ------ 5 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 62f58d5b3..a90a813f4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -912,6 +912,7 @@ void D_Display () void D_ErrorCleanup () { + savegamerestore = false; screen->Unlock (); bglobal.RemoveAllBots (true); D_QuitNetGame (); diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 6fae559c3..ba69f58f7 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -242,8 +242,10 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count) // be in a thinker list, then I need to add write barriers for every time a // thinker pointer is changed. This seems easier and perfectly reasonable, since // a live thinker that isn't on a thinker list isn't much of a thinker. - assert(!curr->IsKindOf(RUNTIME_CLASS(DThinker)) || (curr->ObjectFlags & OF_Sentinel)); - assert(!curr->IsKindOf(RUNTIME_CLASS(DInterpolation))); + + // However, this can happen during deletion of the thinker list while cleaning up + // from a savegame error so we can't assume that any thinker that gets here is an error. + curr->Destroy(); } curr->ObjectFlags |= OF_Cleanup; diff --git a/src/dthinker.cpp b/src/dthinker.cpp index a4f4db27e..85c5fb4bc 100644 --- a/src/dthinker.cpp +++ b/src/dthinker.cpp @@ -192,19 +192,10 @@ void DThinker::SerializeAll(FArchive &arc, bool hubLoad) statcount--; } } - catch (class CDoomError &err) + catch (class CDoomError &) { bSerialOverride = false; - - // DestroyAllThinkers cannot be called here. It will try to delete the corrupted - // object table left behind by the serializer and crash. - // Trying to continue is not an option here because the garbage collector will - // crash the next time it runs. - // Even making this a fatal error will crash but at least the message can be seen - // before the crash - which is not the case with all other options. - - //DestroyAllThinkers(); - I_FatalError("%s", err.GetMessage()); + DestroyAllThinkers(); throw; } bSerialOverride = false; diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 9cd2a34b8..91c0e1b7c 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -246,26 +246,30 @@ void AActor::UnlinkFromWorld () // pointers, allows head node pointers to be treated like everything else AActor **prev = sprev; AActor *next = snext; - if ((*prev = next)) // unlink from sector list - next->sprev = prev; - snext = NULL; - sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! - // phares 3/14/98 - // - // Save the sector list pointed to by touching_sectorlist. - // In P_SetThingPosition, we'll keep any nodes that represent - // sectors the Thing still touches. We'll add new ones then, and - // delete any nodes for sectors the Thing has vacated. Then we'll - // put it back into touching_sectorlist. It's done this way to - // avoid a lot of deleting/creating for nodes, when most of the - // time you just get back what you deleted anyway. - // - // If this Thing is being removed entirely, then the calling - // routine will clear out the nodes in sector_list. + if (prev != NULL) // prev will be NULL if this actor gets deleted due to cleaning up from a broken savegame + { + if ((*prev = next)) // unlink from sector list + next->sprev = prev; + snext = NULL; + sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! - sector_list = touching_sectorlist; - touching_sectorlist = NULL; //to be restored by P_SetThingPosition + // phares 3/14/98 + // + // Save the sector list pointed to by touching_sectorlist. + // In P_SetThingPosition, we'll keep any nodes that represent + // sectors the Thing still touches. We'll add new ones then, and + // delete any nodes for sectors the Thing has vacated. Then we'll + // put it back into touching_sectorlist. It's done this way to + // avoid a lot of deleting/creating for nodes, when most of the + // time you just get back what you deleted anyway. + // + // If this Thing is being removed entirely, then the calling + // routine will clear out the nodes in sector_list. + + sector_list = touching_sectorlist; + touching_sectorlist = NULL; //to be restored by P_SetThingPosition + } } if (!(flags & MF_NOBLOCKMAP)) diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 5655adf20..3ca3b557c 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -406,12 +406,10 @@ void DSectorPlaneInterpolation::Destroy() { if (ceiling) { - assert(sector->interpolations[sector_t::CeilingMove] == this); sector->interpolations[sector_t::CeilingMove] = NULL; } else { - assert(sector->interpolations[sector_t::FloorMove] == this); sector->interpolations[sector_t::FloorMove] = NULL; } @@ -570,12 +568,10 @@ void DSectorScrollInterpolation::Destroy() { if (ceiling) { - assert(sector->interpolations[sector_t::CeilingScroll] == this); sector->interpolations[sector_t::CeilingScroll] = NULL; } else { - assert(sector->interpolations[sector_t::FloorScroll] == this); sector->interpolations[sector_t::FloorScroll] = NULL; } Super::Destroy(); @@ -661,7 +657,6 @@ DWallScrollInterpolation::DWallScrollInterpolation(side_t *_side, int _part) void DWallScrollInterpolation::Destroy() { - assert(side->textures[part].interpolation == this); side->textures[part].interpolation = NULL; Super::Destroy(); } @@ -746,7 +741,6 @@ DPolyobjInterpolation::DPolyobjInterpolation(FPolyObj *po) void DPolyobjInterpolation::Destroy() { - assert(poly->interpolation == this); poly->interpolation = NULL; Super::Destroy(); } From bdbea0da32cd9b1d77dfdcdcfed6b61297e61fd0 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Mon, 1 Aug 2011 03:53:57 +0000 Subject: [PATCH 004/993] - Use kernel semaphores on Mac OS X since it doesn't support POSIX semaphores. SVN r3276 (trunk) --- src/sdl/i_system.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 0f0c7125f..ecaf1a26e 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -33,12 +33,19 @@ #include #include #include -#include #ifndef NO_GTK #include #include #endif +#ifdef __APPLE__ +#include +#include +#include +#else +#include +#endif + #include "doomerrors.h" #include @@ -125,7 +132,11 @@ static DWORD BaseTime; static int TicFrozen; // Signal based timer. +#ifdef __APPLE__ +static semaphore_t timerWait; +#else static sem_t timerWait; +#endif static int tics; static DWORD sig_start, sig_next; @@ -197,7 +208,14 @@ int I_WaitForTicSignaled (int prevtic) assert (TicFrozen == 0); while(tics <= prevtic) + { +#ifdef __APPLE__ + while(semaphore_wait(timerWait) != KERN_SUCCESS) + ; +#else while(sem_wait(&timerWait) != 0); +#endif + } return tics; } @@ -246,7 +264,11 @@ void I_HandleAlarm (int sig) tics++; sig_start = SDL_GetTicks(); sig_next = Scale((Scale (sig_start, TICRATE, 1000) + 1), 1000, TICRATE); +#ifdef __APPLE__ + semaphore_signal(timerWait); +#else sem_post(&timerWait); +#endif } // @@ -256,7 +278,11 @@ void I_HandleAlarm (int sig) // void I_SelectTimer() { +#ifdef __APPLE__ + semaphore_create(mach_task_self(), &timerWait, 0, 0); +#else sem_init(&timerWait, 0, 0); +#endif signal(SIGALRM, I_HandleAlarm); struct itimerval itv; From ba4630f0df038110a4a424900bca6734b2de9f5c Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 13 Aug 2011 20:30:59 +0000 Subject: [PATCH 005/993] - Added ammo1capacity and ammo2capacity to drawnumber. SVN r3277 (trunk) --- src/g_shared/sbarinfo_commands.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index f31a5f77b..8b62359f9 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -890,6 +890,10 @@ class CommandDrawNumber : public CommandDrawString value = AMMO1; else if(sc.Compare("ammo2")) value = AMMO2; + else if(sc.Compare("ammo1capacity")) + value = AMMO1CAPACITY; + else if(sc.Compare("ammo2capacity")) + value = AMMO2CAPACITY; else if(sc.Compare("score")) value = SCORE; else if(sc.Compare("ammo")) //request the next string to be an ammo type @@ -1124,6 +1128,24 @@ class CommandDrawNumber : public CommandDrawString num = 0; break; } + case AMMO1CAPACITY: + if(statusBar->ammo1 == NULL) //no ammo, do not draw + { + str = ""; + return; + } + else + num = statusBar->ammo1->MaxAmount; + break; + case AMMO2CAPACITY: + if(statusBar->ammo2 == NULL) //no ammo, do not draw + { + str = ""; + return; + } + else + num = statusBar->ammo2->MaxAmount; + break; case AMMOCAPACITY: { AInventory* item = statusBar->CPlayer->mo->FindInventory(inventoryItem); @@ -1283,6 +1305,8 @@ class CommandDrawNumber : public CommandDrawString AMMO1, AMMO2, AMMO, + AMMO1CAPACITY, + AMMO2CAPACITY, AMMOCAPACITY, FRAGS, INVENTORY, From f42358ad08370fecad167ca1bcebb5ee71aa625c Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 13 Aug 2011 21:11:09 +0000 Subject: [PATCH 006/993] - Backported FMOD Ex 4.34 fixes from gzdoom-macosx. (With changes to continue to allow compilation with 4.22-4.28.) SVN r3278 (trunk) --- specs/fmod_version.txt | 2 +- src/sound/fmodsound.cpp | 23 +++++++++++++++++++++-- wadsrc/static/menudef.txt | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/specs/fmod_version.txt b/specs/fmod_version.txt index c285c50b9..1016b9388 100644 --- a/specs/fmod_version.txt +++ b/specs/fmod_version.txt @@ -1,3 +1,3 @@ -This version of ZDoom must be compiled with any version between 4.22 and 4.28 inclusive. +This version of ZDoom must be compiled with any version between 4.22 and 4.28 inclusive or 4.34. Use of the latest 4.26 is recommended though due to technical issues with 4.28. diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 308e6db9e..e1a15bb24 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -75,6 +75,10 @@ extern HWND Window; #define SPECTRUM_SIZE 256 +#if FMOD_VERSION < 0x43400 +#define FMOD_OPENSTATE_PLAYING FMOD_OPENSTATE_STREAMING +#endif + // TYPES ------------------------------------------------------------------- struct FEnumList @@ -157,7 +161,9 @@ static const FEnumList OutputNames[] = { "Windows Multimedia", FMOD_OUTPUTTYPE_WINMM }, { "WinMM", FMOD_OUTPUTTYPE_WINMM }, { "WaveOut", FMOD_OUTPUTTYPE_WINMM }, +#if FMOD_VERSION < 0x43400 { "OpenAL", FMOD_OUTPUTTYPE_OPENAL }, +#endif { "WASAPI", FMOD_OUTPUTTYPE_WASAPI }, { "ASIO", FMOD_OUTPUTTYPE_ASIO }, @@ -165,6 +171,9 @@ static const FEnumList OutputNames[] = { "OSS", FMOD_OUTPUTTYPE_OSS }, { "ALSA", FMOD_OUTPUTTYPE_ALSA }, { "ESD", FMOD_OUTPUTTYPE_ESD }, +#if FMOD_VERSION >= 0x43400 + { "PulseAudio", FMOD_OUTPUTTYPE_PULSEAUDIO }, +#endif { "SDL", 666 }, // Mac @@ -388,12 +397,17 @@ public: bool is; FMOD_OPENSTATE openstate = FMOD_OPENSTATE_MAX; bool starving; + bool diskbusy; if (Stream == NULL) { return true; } +#if FMOD_VERSION < 0x43400 if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving)) +#else + if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving, &diskbusy)) +#endif { openstate = FMOD_OPENSTATE_ERROR; } @@ -436,7 +450,7 @@ public: Owner->Sys->setStreamBufferSize(16*1024, FMOD_TIMEUNIT_RAWBYTES); return result != FMOD_OK; } - if (JustStarted && openstate == FMOD_OPENSTATE_STREAMING) + if (JustStarted && openstate == FMOD_OPENSTATE_PLAYING) { JustStarted = false; } @@ -480,14 +494,19 @@ public: unsigned int percentbuffered; unsigned int position; bool starving; + bool diskbusy; float volume; float frequency; bool paused; bool isplaying; +#if FMOD_VERSION < 0x43400 if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving)) +#else + if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving, &diskbusy)) +#endif { - stats = (openstate <= FMOD_OPENSTATE_STREAMING ? OpenStateNames[openstate] : "Unknown state"); + stats = (openstate <= FMOD_OPENSTATE_PLAYING ? OpenStateNames[openstate] : "Unknown state"); stats.AppendFormat(",%3d%% buffered, %s", percentbuffered, starving ? "Starving" : "Well-fed"); } if (Channel == NULL) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index f7e0b51b2..73928b8bd 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1266,6 +1266,7 @@ OptionString SoundOutputsUnix "ALSA", "ALSA" "SDL", "SDL" "ESD", "ESD" + "PulseAudio", "PulseAudio" "No sound", "No sound" } From 5c81cf20baf7a7a6c800dfc5d98559fe0c4b333c Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sun, 14 Aug 2011 23:53:20 +0000 Subject: [PATCH 007/993] - Merged r1236, r1237, and r1240 of GZDoom. SVN r3279 (trunk) --- src/dobjgc.cpp | 7 ++++++- src/r_utility.cpp | 5 +++-- src/sound/fmodsound.cpp | 4 ++++ src/v_palette.cpp | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index ba69f58f7..ebf61a698 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -533,7 +533,12 @@ void Barrier(DObject *pointing, DObject *pointed) void DelSoftRootHead() { - if (SoftRoots != NULL) delete SoftRoots; + if (SoftRoots != NULL) + { + // Don't let the destructor print a warning message + SoftRoots->ObjectFlags |= OF_YesReallyDelete; + delete SoftRoots; + } SoftRoots = NULL; } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 8a9e4fe11..29d008ca5 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -529,8 +529,9 @@ void R_Init () StartScreen->Progress(); V_InitFonts(); StartScreen->Progress(); - R_InitColormaps (); - StartScreen->Progress(); + // Colormap init moved back to InitPalette() + //R_InitColormaps (); + //StartScreen->Progress(); R_InitPointToAngle (); R_InitTables (); diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index e1a15bb24..4a5ab95a8 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -397,7 +397,9 @@ public: bool is; FMOD_OPENSTATE openstate = FMOD_OPENSTATE_MAX; bool starving; +#if FMOD_VERSION >= 0x43400 bool diskbusy; +#endif if (Stream == NULL) { @@ -494,7 +496,9 @@ public: unsigned int percentbuffered; unsigned int position; bool starving; +#if FMOD_VERSION >= 0x43400 bool diskbusy; +#endif float volume; float frequency; bool paused; diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 80ea75a6f..fa8ed4615 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -378,6 +378,10 @@ void InitPalette () GPalette.BaseColors[0].r, GPalette.BaseColors[0].g, GPalette.BaseColors[0].b, 1, 255); } } + + // Colormaps have to be initialized before actors are loaded, + // otherwise Powerup.Colormap will not work. + R_InitColormaps (); } extern "C" void STACK_ARGS DoBlending_MMX (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); From f6ddad95b7bb00d369c48c2c6cb32f8fde0e620a Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 16 Aug 2011 21:59:35 +0000 Subject: [PATCH 008/993] - Set the CMAKE_MODULE_DIR so that we can use find_package instead of include for FluidSynth. - Fixed: FadeTo() accepted parameters out of range. - Fixed: "Enable autosaves" menu option didn't handle all possible values of disableautosave. SVN r3280 (trunk) --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 2 +- src/p_acs.cpp | 2 +- wadsrc/static/menudef.txt | 9 ++++++++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b541a9c20..c67f73aee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ if( CMAKE_COMPILER_IS_GNUCXX ) set( PROFILE 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." ) endif( CMAKE_COMPILER_IS_GNUCXX ) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") + find_package( BZip2 ) find_package( JPEG ) find_package( ZLIB ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6f8eba214..da0653527 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -257,7 +257,7 @@ endif( FMOD_LIBRARY ) # Search for FluidSynth -include( ../FindFluidSynth.cmake ) +find_package( FluidSynth ) # Search for NASM diff --git a/src/p_acs.cpp b/src/p_acs.cpp index cc2a5630d..467bc4e32 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2399,7 +2399,7 @@ int DLevelScript::DoSpawnSpotFacing (int type, int spot, int tid, bool force) void DLevelScript::DoFadeTo (int r, int g, int b, int a, fixed_t time) { - DoFadeRange (0, 0, 0, -1, r, g, b, a, time); + DoFadeRange (0, 0, 0, -1, clamp(r, 0, 255), clamp(g, 0, 255), clamp(b, 0, 255), clamp(a, 0, FRACUNIT), time); } void DLevelScript::DoFadeRange (int r1, int g1, int b1, int a1, diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 73928b8bd..c7e9c6cd9 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -791,6 +791,13 @@ OptionMenu "AltHUDOptions" // //------------------------------------------------------------------------------------------- +OptionValue Autosave +{ + 0, "Always" + 1, "Scripts Only" + 2, "Never" +} + OptionMenu "MiscOptions" { Title "Miscellaneous Options" @@ -803,7 +810,7 @@ OptionMenu "MiscOptions" Option "Show IWAD selection dialog", "queryiwad", "OnOff" StaticText " " Option "Enable cheats from all games", "allcheats", "OnOff" - Option "Enable autosaves", "disableautosave", "OffOn" + Option "Enable autosaves", "disableautosave", "Autosave" Slider "Number of autosaves", "autosavecount", 1, 32, 1, 0 StaticText " " Option "Cache nodes", "gl_cachenodes", "OnOff" From c12b04c130cc62535797317cbc84e901ab980fb4 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 18 Aug 2011 21:40:03 +0000 Subject: [PATCH 009/993] - Fixed: autosave count has a maximum of 20 not 32. SVN r3282 (trunk) --- wadsrc/static/menudef.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index c7e9c6cd9..eb6f09dd5 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -811,7 +811,7 @@ OptionMenu "MiscOptions" StaticText " " Option "Enable cheats from all games", "allcheats", "OnOff" Option "Enable autosaves", "disableautosave", "Autosave" - Slider "Number of autosaves", "autosavecount", 1, 32, 1, 0 + Slider "Number of autosaves", "autosavecount", 1, 20, 1, 0 StaticText " " Option "Cache nodes", "gl_cachenodes", "OnOff" Slider "Time threshold for node caching", "gl_cachetime", 0.0, 2.0, 0.1 From edfc16906a0581397192c87a61a2ede7c174cca6 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 19 Aug 2011 07:56:43 +0000 Subject: [PATCH 010/993] - Disable the save game menu when not in a level. SVN r3283 (trunk) --- src/menu/menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 971110b56..dec0a4241 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -396,7 +396,7 @@ void M_SetMenu(FName menu, int param) return; case NAME_Savegamemenu: - if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer)) + if (!usergame || (players[consoleplayer].health <= 0 && !multiplayer) || gamestate != GS_LEVEL) { // cannot save outside the game. M_StartMessage (GStrings("SAVEDEAD"), 1); From eafb9da2c11126991a68dd994241ac21a5652871 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 23 Aug 2011 02:39:20 +0000 Subject: [PATCH 011/993] - Backported GZDoom r1246: * Fixed possible crash when texture for menu item patch cannot be loaded. (From Alexey's Mac OS X port.) * Fixed iwadinfo.txt definitions of Hexen and Freedoom demos (also from Alexey's port.) * Added missing LOF_NOJUMP definition. SVN r3284 (trunk) --- src/menu/listmenu.cpp | 6 ++++-- wadsrc/static/actors/constants.txt | 1 + wadsrc/static/iwadinfo.txt | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 2f14ee5e1..5e9fc13d1 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -553,7 +553,9 @@ void FListMenuItemPatch::Drawer(bool selected) } int FListMenuItemPatch::GetWidth() -{ - return TexMan[mTexture]->GetScaledWidth(); +{ + return mTexture.isValid() + ? TexMan[mTexture]->GetScaledWidth() + : 0; } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index fb391ee91..fa8f37e95 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -61,6 +61,7 @@ const int LOF_NOSOUNDCHECK = 2; const int LOF_DONTCHASEGOAL = 4; const int LOF_NOSEESOUND = 8; const int LOF_FULLVOLSEESOUND = 16; +const int LOF_NOJUMP = 32; // Flags for A_Respawn const int RSF_FOG = 1; diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index efdf836a5..1d4c9c65c 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -115,7 +115,7 @@ IWad Name = "Hexen: Demo Version" Game = "Hexen" Config = "Hexen" - Mapinfo = "mapinfo/doom2.txt" + Mapinfo = "mapinfo/hexen.txt" Compatibility = "Shareware" MustContain = "TITLE", "MAP01", "WINNOWR" BannerColors = "f0 f0 f0", "6b 3c 18" @@ -205,7 +205,7 @@ IWad Autoname = "Freedoom1" Game = "Doom" Config = "Doom" - Mapinfo = "mapinfo/doom2.txt" + Mapinfo = "mapinfo/doom1.txt" MustContain = "E1M1", "FREEDOOM" BannerColors = "32 54 43", "c6 dc d1" } From f2a457206ce1b3684c2367b2235216bffd2ca953 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 30 Aug 2011 15:34:40 +0000 Subject: [PATCH 012/993] - fixed some potential NULL pointer accesses. SVN r3285 (trunk) --- src/g_doom/a_bossbrain.cpp | 2 +- src/g_doom/a_doomweaps.cpp | 2 +- src/g_hexen/a_hexenspecialdecs.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_doom/a_bossbrain.cpp b/src/g_doom/a_bossbrain.cpp index d0fb03cbc..f7bc68080 100644 --- a/src/g_doom/a_bossbrain.cpp +++ b/src/g_doom/a_bossbrain.cpp @@ -120,10 +120,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BrainSpit) // Boss cubes should move freely to their destination so it's // probably best to disable all collision detection for them. - if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION; if (spit != NULL) { + if (spit->flags & MF_NOCLIP) spit->flags5 |= MF5_NOINTERACTION; spit->target = targ; spit->master = self; // [RH] Do this correctly for any trajectory. Doom would divide by 0 diff --git a/src/g_doom/a_doomweaps.cpp b/src/g_doom/a_doomweaps.cpp index f5bf1a800..23496b99b 100644 --- a/src/g_doom/a_doomweaps.cpp +++ b/src/g_doom/a_doomweaps.cpp @@ -586,7 +586,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray) damage += (pr_bfgspray() & 7) + 1; thingToHit = linetarget; - P_DamageMobj (thingToHit, self->target, self->target, damage, spray->DamageType); + P_DamageMobj (thingToHit, self->target, self->target, damage, spray != NULL? FName(spray->DamageType) : FName(NAME_BFGSplash)); P_TraceBleed (damage, thingToHit, self->target); } } diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp index 9c1fc398d..afca4f190 100644 --- a/src/g_hexen/a_hexenspecialdecs.cpp +++ b/src/g_hexen/a_hexenspecialdecs.cpp @@ -61,9 +61,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_PotteryExplode) for(i = (pr_pottery()&3)+3; i; i--) { mo = Spawn ("PotteryBit", self->x, self->y, self->z, ALLOW_REPLACE); - mo->SetState (mo->SpawnState + (pr_pottery()%5)); if (mo) { + mo->SetState (mo->SpawnState + (pr_pottery()%5)); mo->velz = ((pr_pottery()&7)+5)*(3*FRACUNIT/4); mo->velx = (pr_pottery.Random2())<<(FRACBITS-6); mo->vely = (pr_pottery.Random2())<<(FRACBITS-6); From 5747406776a530798491df7bdcb7c1bdb69dc2b1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 31 Aug 2011 06:14:28 +0000 Subject: [PATCH 013/993] - fixed some more potential NULL pointer accesses. SVN r3286 (trunk) --- src/g_shared/a_action.cpp | 39 ++++++++++++++++++++------------------ src/g_shared/a_pickups.cpp | 4 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp index 1a7c83b89..c283b5720 100644 --- a/src/g_shared/a_action.cpp +++ b/src/g_shared/a_action.cpp @@ -266,9 +266,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) self->x + (((pr_freeze()-128)*self->radius)>>7), self->y + (((pr_freeze()-128)*self->radius)>>7), self->z + (pr_freeze()*self->height/255), ALLOW_REPLACE); - mo->SetState (mo->SpawnState + (pr_freeze()%3)); if (mo) { + mo->SetState (mo->SpawnState + (pr_freeze()%3)); mo->velz = FixedDiv(mo->z - self->z, self->height)<<2; mo->velx = pr_freeze.Random2 () << (FRACBITS-7); mo->vely = pr_freeze.Random2 () << (FRACBITS-7); @@ -281,24 +281,27 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks) { // attach the player's view to a chunk of ice AActor *head = Spawn("IceChunkHead", self->x, self->y, self->z + self->player->mo->ViewHeight, ALLOW_REPLACE); - head->velz = FixedDiv(head->z - self->z, self->height)<<2; - head->velx = pr_freeze.Random2 () << (FRACBITS-7); - head->vely = pr_freeze.Random2 () << (FRACBITS-7); - head->health = self->health; - head->angle = self->angle; - if (head->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + if (head != NULL) { - head->player = self->player; - head->player->mo = static_cast(head); - self->player = NULL; - head->ObtainInventory (self); - } - head->pitch = 0; - head->RenderStyle = self->RenderStyle; - head->alpha = self->alpha; - if (head->player->camera == self) - { - head->player->camera = head; + head->velz = FixedDiv(head->z - self->z, self->height)<<2; + head->velx = pr_freeze.Random2 () << (FRACBITS-7); + head->vely = pr_freeze.Random2 () << (FRACBITS-7); + head->health = self->health; + head->angle = self->angle; + if (head->IsKindOf(RUNTIME_CLASS(APlayerPawn))) + { + head->player = self->player; + head->player->mo = static_cast(head); + self->player = NULL; + head->ObtainInventory (self); + } + head->pitch = 0; + head->RenderStyle = self->RenderStyle; + head->alpha = self->alpha; + if (head->player->camera == self) + { + head->player->camera = head; + } } } diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index d37869a68..207c35cec 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -647,10 +647,10 @@ AInventory *AInventory::CreateTossable () { copy->MaxAmount = MaxAmount; copy->Amount = 1; + copy->DropTime = 30; + copy->flags &= ~(MF_SPECIAL|MF_SOLID); Amount--; } - copy->DropTime = 30; - copy->flags &= ~(MF_SPECIAL|MF_SOLID); return copy; } From f8bc459a2133f4629418910cd09780638ecad781 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 31 Aug 2011 22:49:24 +0000 Subject: [PATCH 014/993] - fix uninitialized string buffer in bot code. SVN r3287 (trunk) --- src/b_game.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/b_game.cpp b/src/b_game.cpp index 7d8e94ffe..e97253c53 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -474,6 +474,7 @@ static void appendinfo (char *&front, const char *back) { size_t newlen = strlen (back) + 2; newstr = new char[newlen]; + newstr[0] = 0; } strcat (newstr, "\\"); strcat (newstr, back); From 7714ee3ffdf5fe549515208d7477d0b52f9df6d1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 1 Sep 2011 22:57:49 +0000 Subject: [PATCH 015/993] - Fix more errors found with static code analysis. SVN r3288 (trunk) --- src/fragglescript/t_load.cpp | 2 +- src/p_glnodes.cpp | 6 +- src/p_setup.cpp | 1 - src/po_man.cpp | 14 +- zdoom.vcproj | 750 +++++++++++++++++------------------ 5 files changed, 388 insertions(+), 385 deletions(-) diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 2d1e49fa5..850d61769 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -316,7 +316,7 @@ bool FScriptLoader::ParseInfo(MapData * map) } - delete lump; + delete[] lump; return HasScripts; } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 8f623486d..26bd4b1df 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1234,7 +1234,7 @@ static bool CheckCachedNodes(MapData *map) BYTE md5[16]; BYTE md5map[16]; DWORD numlin; - DWORD *verts; + DWORD *verts = NULL; FString path = CreateCacheName(map, false); FILE *f = fopen(path, "rb"); @@ -1298,6 +1298,10 @@ static bool CheckCachedNodes(MapData *map) return true; errorout: + if (verts != NULL) + { + delete[] verts; + } fclose(f); return false; } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 3ddd2e259..340b6df63 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3098,7 +3098,6 @@ static void P_GroupLines (bool buildmap) // set the soundorg to the middle of the bounding box sector->soundorg[0] = bbox.Right()/2 + bbox.Left()/2; sector->soundorg[1] = bbox.Top()/2 + bbox.Bottom()/2; - sector->soundorg[2] = sector->floorplane.ZatPoint (sector->soundorg[0], sector->soundorg[1]); } delete[] linesDoneInEachSector; times[3].Unclock(); diff --git a/src/po_man.cpp b/src/po_man.cpp index b27021810..856ff9341 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -445,7 +445,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle, Printf ("EV_RotatePoly: Invalid polyobj num: %d\n", polyNum); break; } - if (poly && poly->specialdata && !overRide) + if (poly->specialdata && !overRide) { // mirroring poly is already in motion break; } @@ -555,8 +555,8 @@ bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle, while ( (mirror = poly->GetMirror()) ) { poly = PO_GetPolyobj(mirror); - if (poly && poly->specialdata && !overRide) - { // mirroring poly is already in motion + if (poly == NULL || (poly->specialdata != NULL && !overRide)) + { // mirroring poly does not exist or is already in motion break; } pe = new DMovePoly (mirror); @@ -655,8 +655,8 @@ bool EV_MovePolyTo(line_t *line, int polyNum, int speed, fixed_t targx, fixed_t while ( (mirror = poly->GetMirror()) ) { poly = PO_GetPolyobj(mirror); - if (poly && poly->specialdata && !overRide) - { // mirroring poly is already in motion + if (poly == NULL || (poly->specialdata != NULL && !overRide)) + { // mirroring poly does not exist or is already in motion break; } // reverse the direction @@ -841,8 +841,8 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, while ( (mirror = poly->GetMirror()) ) { poly = PO_GetPolyobj (mirror); - if (poly && poly->specialdata) - { // mirroring poly is already in motion + if (poly == NULL || poly->specialdata != NULL) + { // mirroring poly does not exist or is already in motion break; } pd = new DPolyDoor (mirror, type); diff --git a/zdoom.vcproj b/zdoom.vcproj index dff0e6cb2..4601991fa 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - @@ -1848,6 +1840,14 @@ Outputs="$(IntDir)/$(InputName).obj" /> + + + @@ -2037,6 +2037,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -2047,14 +2055,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - + + + @@ -2477,14 +2485,6 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> - - - @@ -2783,7 +2783,7 @@ /> + + + - - - Date: Thu, 8 Sep 2011 00:55:47 +0000 Subject: [PATCH 016/993] - Backported kgsws's weapon dropitem changes from Skulltag. SVN r3289 (trunk) --- src/p_user.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/p_user.cpp b/src/p_user.cpp index df8d88725..84a81d384 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1185,6 +1185,22 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor) { AInventory *item; + // kgDROP - start - modified copy from a_action.cpp + FDropItem *di = weap->GetDropItems(); + + if (di != NULL) + { + while (di != NULL) + { + if (di->Name != NAME_None) + { + const PClass *ti = PClass::FindClass(di->Name); + if (ti) P_DropItem (player->mo, ti, di->amount, di->probability); + } + di = di->Next; + } + } else + // kgDROP - end if (weap->SpawnState != NULL && weap->SpawnState != ::GetDefault()->SpawnState) { From c013e72caa348851eb3bed0f421d478ac9e8ba15 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 8 Sep 2011 01:28:26 +0000 Subject: [PATCH 017/993] - Backported VisibleToTeam and VisibleToPlayerClass from Skulltag with some modifications. SVN r3290 (trunk) --- src/actor.h | 9 +++++++++ src/p_mobj.cpp | 29 ++++++++++++++++++++++++++++ src/r_things.cpp | 3 ++- src/thingdef/thingdef_properties.cpp | 18 +++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/actor.h b/src/actor.h index e7dece16b..713fc0139 100644 --- a/src/actor.h +++ b/src/actor.h @@ -763,6 +763,8 @@ public: return bloodcls; } + bool IsVisibleToPlayer() const; + // Calculate amount of missile damage virtual int GetMissileDamage(int mask, int add); @@ -814,6 +816,13 @@ public: DWORD flags4; // [RH] Even more flags! DWORD flags5; // OMG! We need another one. DWORD flags6; // Shit! Where did all the flags go? + + // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. + DWORD VisibleToTeam; + + // [BB] If NAME_None, all players can see the actor, else only players whose playerclass name is VisibleToPlayerClass can see it. + FNameNoInit VisibleToPlayerClass; + int special1; // Special info int special2; // Special info int health; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 36339ffee..814fb1e42 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -310,6 +310,7 @@ void AActor::Serialize (FArchive &arc) << smokecounter << BlockingMobj << BlockingLine + << VisibleToTeam // [BB] << pushfactor << Species << Score; @@ -871,6 +872,34 @@ bool AActor::CheckLocalView (int playernum) const return false; } +//============================================================================ +// +// AActor :: IsVisibleToPlayer +// +// Returns true if this actor should be seen by the console player. +// +//============================================================================ + +bool AActor::IsVisibleToPlayer() const +{ + // [BB] Safety check. This should never be NULL. Nevertheless, we return true to leave the default ZDoom behavior unaltered. + if ( players[consoleplayer].camera == NULL ) + return true; + + if ( VisibleToTeam != 0 && teamplay && + VisibleToTeam-1 != players[consoleplayer].userinfo.team ) + return false; + + const player_t* pPlayer = players[consoleplayer].camera->player; + + if ( ( VisibleToPlayerClass != NAME_None ) + && pPlayer && pPlayer->mo && ( VisibleToPlayerClass != pPlayer->mo->GetClass()->TypeName ) ) + return false; + + // [BB] Passed all checks. + return true; +} + //============================================================================ // // AActor :: ConversationAnimation diff --git a/src/r_things.cpp b/src/r_things.cpp index f604549c6..ec8ec89f1 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -495,7 +495,8 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor // Don't waste time projecting sprites that are definitely not visible. if (thing == NULL || (thing->renderflags & RF_INVISIBLE) || - !thing->RenderStyle.IsVisible(thing->alpha)) + !thing->RenderStyle.IsVisible(thing->alpha) || + !thing->IsVisibleToPlayer()) { return; } diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 558caa6c1..04ffd9d28 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1234,6 +1234,24 @@ DEFINE_PROPERTY(designatedteam, I, Actor) defaults->DesignatedTeam = val; } +//========================================================================== +// [BB] +//========================================================================== +DEFINE_PROPERTY(visibletoteam, I, Actor) +{ + PROP_INT_PARM(i, 0); + defaults->VisibleToTeam=i+1; +} + +//========================================================================== +// [BB] +//========================================================================== +DEFINE_PROPERTY(visibletoplayerclass, S, Actor) +{ + PROP_STRING_PARM(n, 0); + defaults->VisibleToPlayerClass = n; +} + //========================================================================== // // Special inventory properties From faa122ede3af7128fd452b66d9ccea0b1accbbd5 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 10 Sep 2011 04:24:40 +0000 Subject: [PATCH 018/993] - Adjust VisibleToPlayerClass to accept multiple classes as well as work with inheritance. SVN r3291 (trunk) --- src/actor.h | 3 --- src/info.h | 1 + src/p_mobj.cpp | 18 +++++++++++++++--- src/thingdef/thingdef_properties.cpp | 9 ++++++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/actor.h b/src/actor.h index 713fc0139..374dc9b89 100644 --- a/src/actor.h +++ b/src/actor.h @@ -820,9 +820,6 @@ public: // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. DWORD VisibleToTeam; - // [BB] If NAME_None, all players can see the actor, else only players whose playerclass name is VisibleToPlayerClass can see it. - FNameNoInit VisibleToPlayerClass; - int special1; // Special info int special2; // Special info int health; diff --git a/src/info.h b/src/info.h index 66d564606..0ac7a0fed 100644 --- a/src/info.h +++ b/src/info.h @@ -210,6 +210,7 @@ struct FActorInfo PainChanceList *PainChances; PainFlashList *PainFlashes; FPlayerColorSetMap *ColorSets; + TArray VisibleToPlayerClass; }; class FDoomEdMap diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 814fb1e42..73a4cd49b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -892,9 +892,21 @@ bool AActor::IsVisibleToPlayer() const const player_t* pPlayer = players[consoleplayer].camera->player; - if ( ( VisibleToPlayerClass != NAME_None ) - && pPlayer && pPlayer->mo && ( VisibleToPlayerClass != pPlayer->mo->GetClass()->TypeName ) ) - return false; + if(pPlayer && pPlayer->mo && GetClass()->ActorInfo->VisibleToPlayerClass.Size() > 0) + { + bool visible = false; + for(unsigned int i = 0;i < GetClass()->ActorInfo->VisibleToPlayerClass.Size();++i) + { + const PClass *cls = GetClass()->ActorInfo->VisibleToPlayerClass[i]; + if(cls && pPlayer->mo->GetClass()->IsDescendantOf(cls)) + { + visible = true; + break; + } + } + if(!visible) + return false; + } // [BB] Passed all checks. return true; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 04ffd9d28..22264b683 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1246,10 +1246,13 @@ DEFINE_PROPERTY(visibletoteam, I, Actor) //========================================================================== // [BB] //========================================================================== -DEFINE_PROPERTY(visibletoplayerclass, S, Actor) +DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) { - PROP_STRING_PARM(n, 0); - defaults->VisibleToPlayerClass = n; + for(unsigned int i = 0;i < PROP_PARM_COUNT;++i) + { + PROP_STRING_PARM(n, i); + info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + } } //========================================================================== From d6b6a73fee71e98bd71580d1f485239c065f05b5 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 13 Sep 2011 20:13:26 +0000 Subject: [PATCH 019/993] - Fixed MSVC warning. SVN r3292 (trunk) --- src/thingdef/thingdef_properties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 22264b683..3cb22e778 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1248,7 +1248,7 @@ DEFINE_PROPERTY(visibletoteam, I, Actor) //========================================================================== DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) { - for(unsigned int i = 0;i < PROP_PARM_COUNT;++i) + for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); From de8bf651f2155d007ca7320e94722fe3b716bb70 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 14 Sep 2011 23:24:32 +0000 Subject: [PATCH 020/993] - Fix warnings reported by gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) SVN r3293 (trunk) --- src/p_teleport.cpp | 4 +- src/r_data/voxels.cpp | 5 +- src/resourcefiles/file_directory.cpp | 10 ++-- src/sdl/i_main.cpp | 19 ++++++- src/sdl/i_system.cpp | 76 ++++++++++++++++++++++++++++ src/thingdef/thingdef_codeptr.cpp | 2 +- 6 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 59359a981..6d3969234 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -513,9 +513,9 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO while (P_PointOnLineSide(x, y, l) != side && --fudge >= 0) { if (abs(l->dx) > abs(l->dy)) - y -= l->dx < 0 != side ? -1 : 1; + y -= (l->dx < 0) != side ? -1 : 1; else - x += l->dy < 0 != side ? -1 : 1; + x += (l->dy < 0) != side ? -1 : 1; } // Adjust z position to be same height above ground as before. diff --git a/src/r_data/voxels.cpp b/src/r_data/voxels.cpp index bbfe706e8..50705c5cc 100644 --- a/src/r_data/voxels.cpp +++ b/src/r_data/voxels.cpp @@ -417,8 +417,6 @@ void FVoxel::Remap() static bool VOX_ReadSpriteNames(FScanner &sc, TArray &vsprites) { - unsigned int i; - vsprites.Clear(); while (sc.GetString()) { @@ -442,8 +440,7 @@ static bool VOX_ReadSpriteNames(FScanner &sc, TArray &vsprites) else { int frame = (sc.StringLen == 4) ? 255 : sc.String[4] - 'A'; - - i = GetSpriteIndex(sc.String, false); + int i = GetSpriteIndex(sc.String, false); if (i != -1) { vsprites.Push((frame << 24) | i); diff --git a/src/resourcefiles/file_directory.cpp b/src/resourcefiles/file_directory.cpp index 89fb2be9c..420b7dde3 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -186,7 +186,7 @@ int FDirectory::AddDirectory(const char *dirpath) { if (strstr(fileinfo.name, ".orig") || strstr(fileinfo.name, ".bak")) { - // We shuuldn't add backup files to the lump directory + // We shouldn't add backup files to the lump directory continue; } @@ -211,8 +211,8 @@ int FDirectory::AddDirectory(const char *dirpath) DIR* directory = opendir(scanDirectories[i].GetChars()); if (directory == NULL) { - Printf("Could not ready directory: %s\n", strerror(errno)); - return NULL; + Printf("Could not read directory: %s\n", strerror(errno)); + return 0; } struct dirent *file; @@ -250,7 +250,7 @@ int FDirectory::AddDirectory(const char *dirpath) int FDirectory::AddDirectory(const char *dirpath) { - char *argv [2] = {NULL, NULL }; + char *argv [2] = { NULL, NULL }; argv[0] = new char[strlen(dirpath)+1]; strcpy(argv[0], dirpath); FTS *fts; @@ -261,7 +261,7 @@ int FDirectory::AddDirectory(const char *dirpath) if (fts == NULL) { Printf("Failed to start directory traversal: %s\n", strerror(errno)); - return NULL; + return 0; } while ((ent = fts_read(fts)) != NULL) { diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index d80d8a430..3b2de3c57 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -81,6 +81,10 @@ extern "C" int cc_install_handlers(int, char**, int, int*, const char*, int(*)(c // EXTERNAL DATA DECLARATIONS ---------------------------------------------- +#ifdef USE_XCURSOR +extern bool UseXCursor; +#endif + // PUBLIC DATA DEFINITIONS ------------------------------------------------- #ifndef NO_GTK @@ -256,7 +260,7 @@ int main (int argc, char **argv) cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo); } - printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n\n", + printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n", DOTVERSIONSTR_NOREV,SVN_REVISION_STRING,__DATE__); seteuid (getuid ()); @@ -279,6 +283,19 @@ int main (int argc, char **argv) } atterm (SDL_Quit); + { + char viddriver[80]; + + if (SDL_VideoDriverName(viddriver, sizeof(viddriver)) != NULL) + { + printf("Using video driver %s\n", viddriver); +#ifdef USE_XCURSOR + UseXCursor = (strcmp(viddriver, "x11") == 0); +#endif + } + printf("\n"); + } + SDL_WM_SetCaption (GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")", NULL); try diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index ecaf1a26e..55ba296b6 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -79,6 +79,13 @@ #include "m_fixed.h" #include "g_level.h" +#ifdef USE_XCURSOR +// Xlib has its own GC, so don't let it interfere. +#define GC XGC +#include +#undef GC +#endif + EXTERN_CVAR (String, language) extern "C" @@ -92,6 +99,11 @@ extern bool GtkAvailable; #elif defined(__APPLE__) int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad); #endif +#ifdef USE_XCURSOR +bool UseXCursor; +SDL_Cursor *X11Cursor; +SDL_Cursor *FirstCursor; +#endif DWORD LanguageIDs[4] = { @@ -830,6 +842,47 @@ unsigned int I_MakeRNGSeed() return seed; } +#ifdef USE_XCURSOR +// Hack! Hack! SDL does not provide a clean way to get the XDisplay. +// On the other hand, there are no more planned updates for SDL 1.2, +// so we should be fine making assumptions. +struct SDL_PrivateVideoData +{ + int local_X11; + Display *X11_Display; +}; + +struct SDL_VideoDevice +{ + const char *name; + int (*functions)()[9]; + SDL_VideoInfo info; + SDL_PixelFormat *displayformatalphapixel; + int (*morefuncs)()[9]; + Uint16 *gamma; + int (*somefuncs)()[9]; + unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack! + int is_32bit; + int (*itsafuncs)()[13]; + SDL_Surface *surfaces[3]; + SDL_Palette *physpal; + SDL_Color *gammacols; + char *wm_strings[2]; + int offsets[2]; + SDL_GrabMode input_grab; + int handles_any_size; + SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in? +}; + +extern SDL_VideDevice *current_video; +#define SDL_Display (current_video->hidden->X11_Display) + +SDL_Cursor *CreateColorCursor(FTexture *cursorpic) +{ + return NULL; +} +#endif + SDL_Surface *cursorSurface = NULL; SDL_Rect cursorBlit = {0, 0, 32, 32}; bool I_SetCursor(FTexture *cursorpic) @@ -842,6 +895,21 @@ bool I_SetCursor(FTexture *cursorpic) return false; } +#ifdef USE_XCURSOR + if (UseXCursor) + { + if (FirstCursor == NULL) + { + FirstCursor = SDL_GetCursor(); + } + X11Cursor = CreateColorCursor(cursorpic); + if (X11Cursor != NULL) + { + SDL_SetCursor(X11Cursor); + return true; + } + } +#endif if (cursorSurface == NULL) cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0)); @@ -863,6 +931,14 @@ bool I_SetCursor(FTexture *cursorpic) SDL_FreeSurface(cursorSurface); cursorSurface = NULL; } +#ifdef USE_XCURSOR + if (X11Cursor != NULL) + { + SDL_SetCursor(FirstCursor); + SDL_FreeCursor(X11Cursor); + X11Cursor = NULL; + } +#endif } return true; } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e1c5e1363..965d4de08 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3888,7 +3888,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack) if (dpuff->flags2 & MF2_THRUGHOST && self->target->flags3 & MF3_GHOST) damage = 0; - if (0 && dpuff->flags3 & MF3_PUFFONACTORS || !spawnblood) + if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood) { spawnblood = false; P_SpawnPuff(self, pufftype, dx, dy, dz, angle, 0); From c12538c346ebb10ee884afeb24839264f5809924 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 14 Sep 2011 23:34:28 +0000 Subject: [PATCH 021/993] - Fixed crash when trying to play a MIDI file with no notes. SVN r3294 (trunk) --- src/sound/music_midistream.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index f9c2d4f28..c8c8ab08e 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -339,6 +339,10 @@ void MIDIStreamer::Play(bool looping, int subsong) if (MIDI->Preprocess(this, looping)) { StartPlayback(); + if (MIDI == NULL) + { // The MIDI file had no content and has been automatically closed. + return; + } } if (0 != MIDI->Resume()) From a0bb1c25461c4380db0f1358c4efa33566a7b307 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 21 Sep 2011 19:39:12 +0000 Subject: [PATCH 022/993] - added Gez's patch for proper splash checks with 3D-floors. SVN r3295 (trunk) --- src/g_shared/a_fastprojectile.cpp | 3 + src/p_map.cpp | 23 ++++---- src/p_mobj.cpp | 11 +++- src/p_trace.cpp | 92 ++++++++++++++++++++++++------- src/p_trace.h | 5 +- 5 files changed, 101 insertions(+), 33 deletions(-) diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index d45a9f2a8..c019fcbf6 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -28,6 +28,7 @@ void AFastProjectile::Tick () PrevX = x; PrevY = y; PrevZ = z; + fixed_t oldz = z; PrevAngle = angle; if (!(flags5 & MF5_NOTIMEFREEZE)) @@ -99,6 +100,8 @@ void AFastProjectile::Tick () } } z += zfrac; + UpdateWaterLevel (oldz); + oldz = z; if (z <= floorz) { // Hit the floor diff --git a/src/p_map.cpp b/src/p_map.cpp index 9e927698b..b9e6dc125 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -64,7 +64,7 @@ CVAR (Int, sv_smartaim, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) static void CheckForPushSpecial (line_t *line, int side, AActor *mobj); static void SpawnShootDecal (AActor *t1, const FTraceResults &trace); static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz); + fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor = false); static FRandom pr_tracebleed ("TraceBleed"); static FRandom pr_checkthing ("CheckThing"); @@ -3555,7 +3555,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, *victim = trace.Actor; } } - if (trace.CrossedWater) + if (trace.Crossed3DWater || trace.CrossedWater) { if (puff == NULL) @@ -3563,7 +3563,7 @@ AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, puff = P_SpawnPuff (t1, pufftype, hitx, hity, hitz, angle - ANG180, 2, flags|PF_HITTHING|PF_TEMPORARY); killPuff = true; } - SpawnDeepSplash (t1, trace, puff, vx, vy, vz, shootz); + SpawnDeepSplash (t1, trace, puff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); } } if (killPuff && puff != NULL) @@ -3925,11 +3925,11 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color P_HitWater (thepuff, trace.Sector); } } - if (trace.CrossedWater) + if (trace.Crossed3DWater || trace.CrossedWater) { if (thepuff != NULL) { - SpawnDeepSplash (source, trace, thepuff, vx, vy, vz, shootz); + SpawnDeepSplash (source, trace, thepuff, vx, vy, vz, shootz, trace.Crossed3DWater != NULL); } } thepuff->Destroy (); @@ -5469,13 +5469,16 @@ void SpawnShootDecal (AActor *t1, const FTraceResults &trace) //========================================================================== static void SpawnDeepSplash (AActor *t1, const FTraceResults &trace, AActor *puff, - fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz) + fixed_t vx, fixed_t vy, fixed_t vz, fixed_t shootz, bool ffloor) { - if (!trace.CrossedWater->heightsec) return; - - fixed_t num, den, hitdist; - const secplane_t *plane = &trace.CrossedWater->heightsec->floorplane; + const secplane_t *plane; + if (ffloor && trace.Crossed3DWater) + plane = trace.Crossed3DWater->top.plane; + else if (trace.CrossedWater && trace.CrossedWater->heightsec) + plane = &trace.CrossedWater->heightsec->floorplane; + else return; + fixed_t num, den, hitdist; den = TMulScale16 (plane->a, vx, plane->b, vy, plane->c, vz); if (den != 0) { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 73a4cd49b..7eb2d39b9 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -4737,7 +4737,16 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z if (y == FIXED_MIN) y = thing->y; if (z == FIXED_MIN) z = thing->z; // don't splash above the object - if (checkabove && z > thing->z + (thing->height >> 1)) return false; + if (checkabove) + { + fixed_t compare_z = thing->z + (thing->height >> 1); + // Missiles are typically small and fast, so they might + // end up submerged by the move that calls P_HitWater. + if (thing->flags & MF_MISSILE) + compare_z -= thing->velz; + if (z > compare_z) + return false; + } #if 0 // needs some rethinking before activation diff --git a/src/p_trace.cpp b/src/p_trace.cpp index bd00da36f..59dbe08f9 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -59,7 +59,9 @@ struct FTraceInfo int sectorsel; bool TraceTraverse (int ptflags); + bool CheckPlane(const secplane_t &plane); bool CheckSectorPlane (const sector_t *sector, bool checkFloor); + bool Check3DFloorPlane(const F3DFloor *ffloor, bool checkBottom); }; static bool EditTraceResult (DWORD flags, FTraceResults &res); @@ -90,17 +92,18 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, inf.EnterDist = 0; inf.TraceCallback = callback; inf.TraceFlags = flags; - res.CrossedWater = NULL; inf.Results = &res; inf.inshootthrough = true; - - res.HitType = TRACE_HitNone; - - // Do a 3D floor check in the starting sector - memset(&res, 0, sizeof(res)); inf.sectorsel=0; + memset(&res, 0, sizeof(res)); + /* // Redundant with the memset + res.HitType = TRACE_HitNone; + res.CrossedWater = NULL; + res.Crossed3DWater = NULL; + */ #ifdef _3DFLOORS + // Do a 3D floor check in the starting sector TDeletingArray &ff = sector->e->XFloor.ffloors; if (ff.Size()) @@ -114,8 +117,16 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, for(unsigned int i=0;iflags&FF_EXISTS)) + continue; - if (!(rover->flags&FF_SHOOTTHROUGH) && rover->flags&FF_EXISTS) + if (rover->flags&FF_SWIMMABLE && res.Crossed3DWater == NULL) + { + if (inf.Check3DFloorPlane(rover, false)) + res.Crossed3DWater = rover; + } + + if (!(rover->flags&FF_SHOOTTHROUGH)) { fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y); fixed_t ff_top=rover->top.plane->ZatPoint(x, y); @@ -243,6 +254,26 @@ bool FTraceInfo::TraceTraverse (int ptflags) fixed_t hitx, hity, hitz; fixed_t dist; + // Deal with splashes in 3D floors +#ifdef _3DFLOORS + if (CurSector->e->XFloor.ffloors.Size()) + { + for(unsigned int i=0;ie->XFloor.ffloors.Size();i++) + { + F3DFloor * rover=CurSector->e->XFloor.ffloors[i]; + if (!(rover->flags&FF_EXISTS)) + continue; + + // Deal with splashy stuff + if (rover->flags&FF_SWIMMABLE && Results->Crossed3DWater == NULL) + { + if (Check3DFloorPlane(rover, false)) + Results->Crossed3DWater = rover; + } + } + } +#endif + if (in->isaline) { int lineside; @@ -287,7 +318,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) entersector = (lineside == 0) ? in->d.line->backsector : in->d.line->frontsector; // For backwards compatibility: Ignore lines with the same sector on both sides. - // This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15 need it. + // This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15) need it. if (i_compatflags & COMPATF_TRACE && in->d.line->backsector == in->d.line->frontsector) { // We must check special activation here because the code below is never reached. @@ -587,19 +618,8 @@ cont1: return true; } -bool FTraceInfo::CheckSectorPlane (const sector_t *sector, bool checkFloor) +bool FTraceInfo::CheckPlane (const secplane_t &plane) { - secplane_t plane; - - if (checkFloor) - { - plane = sector->floorplane; - } - else - { - plane = sector->ceilingplane; - } - fixed_t den = TMulScale16 (plane.a, Vx, plane.b, Vy, plane.c, Vz); if (den != 0) @@ -623,6 +643,38 @@ bool FTraceInfo::CheckSectorPlane (const sector_t *sector, bool checkFloor) return false; } +bool FTraceInfo::CheckSectorPlane (const sector_t *sector, bool checkFloor) +{ + secplane_t plane; + + if (checkFloor) + { + plane = sector->floorplane; + } + else + { + plane = sector->ceilingplane; + } + + return CheckPlane(plane); +} + +bool FTraceInfo::Check3DFloorPlane (const F3DFloor *ffloor, bool checkBottom) +{ + secplane_t plane; + + if (checkBottom) + { + plane = *(ffloor->bottom.plane); + } + else + { + plane = *(ffloor->top.plane); + } + + return CheckPlane(plane); +} + static bool EditTraceResult (DWORD flags, FTraceResults &res) { if (flags & TRACE_NoSky) diff --git a/src/p_trace.h b/src/p_trace.h index e13a7f905..8ce905da3 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -73,8 +73,9 @@ struct FTraceResults BYTE Side; BYTE Tier; ETraceResult HitType; - sector_t *CrossedWater; - F3DFloor * ffloor; + sector_t *CrossedWater; // For Boom-style, Transfer_Heights-based deep water + F3DFloor *Crossed3DWater; // For 3D floor-based deep water + F3DFloor *ffloor; }; enum From 3c47a30249c6278a8c4165bc2fa9e56ff1ab839c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Sep 2011 08:23:51 +0000 Subject: [PATCH 023/993] - added Gez's submission for inventory restrictions but changed the added checks to be in the main CallTryPickup function. SVN r3296 (trunk) --- src/g_hexen/a_clericholy.cpp | 38 --------- src/g_hexen/a_fighterplayer.cpp | 77 ------------------- src/g_hexen/a_fighterquietus.cpp | 37 --------- src/g_hexen/a_hexenglobal.h | 3 - src/g_hexen/a_magestaff.cpp | 38 --------- src/g_shared/a_pickups.cpp | 54 ++++++++++++- src/g_shared/a_pickups.h | 3 + src/g_shared/a_weaponpiece.cpp | 28 +++++++ src/g_shared/a_weaponpiece.h | 1 + src/g_shared/a_weapons.cpp | 24 ++++++ src/info.h | 2 + src/thingdef/thingdef.cpp | 5 ++ src/thingdef/thingdef_properties.cpp | 32 +++++++- wadsrc/static/actors/hexen/baseweapons.txt | 6 ++ wadsrc/static/actors/hexen/clericholy.txt | 3 +- wadsrc/static/actors/hexen/fighterquietus.txt | 3 +- wadsrc/static/actors/hexen/magestaff.txt | 3 +- 17 files changed, 158 insertions(+), 199 deletions(-) diff --git a/src/g_hexen/a_clericholy.cpp b/src/g_hexen/a_clericholy.cpp index 01d13931c..560c1d87c 100644 --- a/src/g_hexen/a_clericholy.cpp +++ b/src/g_hexen/a_clericholy.cpp @@ -25,44 +25,6 @@ static FRandom pr_wraithvergedrop ("WraithvergeDrop"); void SpawnSpiritTail (AActor *spirit); //========================================================================== - -class AClericWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AClericWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AClericWeaponPiece) - -bool AClericWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - // Cleric's Wraithverge (Holy Symbol?) -------------------------------------- class ACWeapWraithverge : public AClericWeapon diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 0867a86e4..ec1e1a827 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -11,87 +11,10 @@ #include "thingdef/thingdef.h" */ -// Fighter Weapon Base Class ------------------------------------------------ - IMPLEMENT_CLASS (AFighterWeapon) IMPLEMENT_CLASS (AClericWeapon) IMPLEMENT_CLASS (AMageWeapon) -bool AFighterWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - -// Cleric Weapon Base Class ------------------------------------------------- - -bool AClericWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - -// Mage Weapon Base Class --------------------------------------------------- - -bool AMageWeapon::TryPickup (AActor *&toucher) -{ - // The Doom and Hexen players are not excluded from pickup in case - // somebody wants to use these weapons with either of those games. - if (toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer)) || - toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer))) - { // Wrong class, but try to pick up for mana - if (ShouldStay()) - { // Can't pick up weapons for other classes in coop netplay - return false; - } - - bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); - gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } - return Super::TryPickup (toucher); -} - - - static FRandom pr_fpatk ("FPunchAttack"); //============================================================================ diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp index dc930a34f..8bc27751c 100644 --- a/src/g_hexen/a_fighterquietus.cpp +++ b/src/g_hexen/a_fighterquietus.cpp @@ -18,43 +18,6 @@ static FRandom pr_fswordflame ("FSwordFlame"); //========================================================================== -class AFighterWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AFighterWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AFighterWeaponPiece) - -bool AFighterWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_MagePlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - //============================================================================ // // A_DropQuietusPieces diff --git a/src/g_hexen/a_hexenglobal.h b/src/g_hexen/a_hexenglobal.h index a20827774..44ffc6d57 100644 --- a/src/g_hexen/a_hexenglobal.h +++ b/src/g_hexen/a_hexenglobal.h @@ -15,21 +15,18 @@ class AFighterWeapon : public AWeapon { DECLARE_CLASS (AFighterWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; class AClericWeapon : public AWeapon { DECLARE_CLASS (AClericWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; class AMageWeapon : public AWeapon { DECLARE_CLASS (AMageWeapon, AWeapon); public: - bool TryPickup (AActor *&toucher); }; #endif //__A_HEXENGLOBAL_H__ diff --git a/src/g_hexen/a_magestaff.cpp b/src/g_hexen/a_magestaff.cpp index 2316edde3..743a1b5f7 100644 --- a/src/g_hexen/a_magestaff.cpp +++ b/src/g_hexen/a_magestaff.cpp @@ -23,44 +23,6 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *); static divline_t BlockCheckLine; //========================================================================== - -class AMageWeaponPiece : public AWeaponPiece -{ - DECLARE_CLASS (AMageWeaponPiece, AWeaponPiece) -protected: - bool TryPickup (AActor *&toucher); -}; - -IMPLEMENT_CLASS (AMageWeaponPiece) - -bool AMageWeaponPiece::TryPickup (AActor *&toucher) -{ - if (!toucher->IsKindOf (PClass::FindClass(NAME_ClericPlayer)) && - !toucher->IsKindOf (PClass::FindClass(NAME_FighterPlayer))) - { - return Super::TryPickup(toucher); - } - else - { // Wrong class, but try to pick up for ammo - if (ShouldStay()) - { - // Can't pick up weapons for other classes in coop netplay - return false; - } - - AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); - - bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + - toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); - - if (gaveSome) - { - GoAwayAndDie (); - } - return gaveSome; - } -} - // The Mages's Staff (Bloodscourge) ----------------------------------------- class AMWeapBloodscourge : public AMageWeapon diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 207c35cec..7075aeb87 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1266,13 +1266,29 @@ bool AInventory::TryPickup (AActor *&toucher) //=========================================================================== // -// AInventory :: TryPickup +// AInventory :: TryPickupRestricted +// +//=========================================================================== + +bool AInventory::TryPickupRestricted (AActor *&toucher) +{ + return false; +} + +//=========================================================================== +// +// AInventory :: CallTryPickup // //=========================================================================== bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) { - bool res = TryPickup(toucher); + bool res; + if (CanPickup(toucher)) + res = TryPickup(toucher); + else + res = TryPickupRestricted(toucher); // let an item decide for itself how it will handle this + // Morph items can change the toucher so we need an option to return this info. if (toucher_return != NULL) *toucher_return = toucher; @@ -1288,6 +1304,40 @@ bool AInventory::CallTryPickup (AActor *toucher, AActor **toucher_return) } +//=========================================================================== +// +// AInventory :: CanPickup +// +//=========================================================================== + +bool AInventory::CanPickup (AActor *toucher) +{ + if (!toucher) + return false; + + FActorInfo *ai = GetClass()->ActorInfo; + // Is the item restricted to certain player classes? + if (ai->RestrictedToPlayerClass.Size() != 0) + { + for (unsigned i = 0; i < ai->RestrictedToPlayerClass.Size(); ++i) + { + if (toucher->IsKindOf(ai->RestrictedToPlayerClass[i])) + return true; + } + return false; + } + // Or is it forbidden to certain other classes? + else + { + for (unsigned i = 0; i < ai->ForbiddenToPlayerClass.Size(); ++i) + { + if (toucher->IsKindOf(ai->ForbiddenToPlayerClass[i])) + return false; + } + } + return true; +} + //=========================================================================== // // CCMD printinv diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index efc7a8c37..10572c9ce 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -198,6 +198,8 @@ public: protected: virtual bool TryPickup (AActor *&toucher); + virtual bool TryPickupRestricted (AActor *&toucher); + bool CanPickup(AActor * toucher); void GiveQuest(AActor * toucher); private: @@ -277,6 +279,7 @@ public: virtual AInventory *CreateCopy (AActor *other); virtual AInventory *CreateTossable (); virtual bool TryPickup (AActor *&toucher); + virtual bool TryPickupRestricted (AActor *&toucher); virtual bool PickupForAmmo (AWeapon *ownedWeapon); virtual bool Use (bool pickup); virtual void Destroy(); diff --git a/src/g_shared/a_weaponpiece.cpp b/src/g_shared/a_weaponpiece.cpp index 4d4729e37..a73b2511c 100644 --- a/src/g_shared/a_weaponpiece.cpp +++ b/src/g_shared/a_weaponpiece.cpp @@ -23,6 +23,34 @@ void AWeaponPiece::Serialize (FArchive &arc) arc << WeaponClass << FullWeapon << PieceValue; } +//========================================================================== +// +// TryPickupWeaponPiece +// +//========================================================================== + +bool AWeaponPiece::TryPickupRestricted (AActor *&toucher) +{ + // Wrong class, but try to pick up for ammo + if (ShouldStay()) + { + // Can't pick up weapons for other classes in coop netplay + return false; + } + + AWeapon * Defaults=(AWeapon*)GetDefaultByType(WeaponClass); + + bool gaveSome = !!(toucher->GiveAmmo (Defaults->AmmoType1, Defaults->AmmoGive1) + + toucher->GiveAmmo (Defaults->AmmoType2, Defaults->AmmoGive2)); + + if (gaveSome) + { + GoAwayAndDie (); + } + return gaveSome; +} + + //========================================================================== // // TryPickupWeaponPiece diff --git a/src/g_shared/a_weaponpiece.h b/src/g_shared/a_weaponpiece.h index b59c77f6e..c07f56f24 100644 --- a/src/g_shared/a_weaponpiece.h +++ b/src/g_shared/a_weaponpiece.h @@ -8,6 +8,7 @@ protected: public: void Serialize (FArchive &arc); bool TryPickup (AActor *&toucher); + bool TryPickupRestricted (AActor *&toucher); bool ShouldStay (); virtual const char *PickupMessage (); virtual void PlayPickupSound (AActor *toucher); diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 068756869..3095ecbe0 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -72,6 +72,30 @@ void AWeapon::Serialize (FArchive &arc) // //=========================================================================== +bool AWeapon::TryPickupRestricted (AActor *&toucher) +{ + // Wrong class, but try to pick up for ammo + if (ShouldStay()) + { // Can't pick up weapons for other classes in coop netplay + return false; + } + + bool gaveSome = (NULL != AddAmmo (toucher, AmmoType1, AmmoGive1)); + gaveSome |= (NULL != AddAmmo (toucher, AmmoType2, AmmoGive2)); + if (gaveSome) + { + GoAwayAndDie (); + } + return gaveSome; +} + + +//=========================================================================== +// +// AWeapon :: TryPickup +// +//=========================================================================== + bool AWeapon::TryPickup (AActor *&toucher) { FState * ReadyState = FindState(NAME_Ready); diff --git a/src/info.h b/src/info.h index 0ac7a0fed..39d73f4a7 100644 --- a/src/info.h +++ b/src/info.h @@ -211,6 +211,8 @@ struct FActorInfo PainFlashList *PainFlashes; FPlayerColorSetMap *ColorSets; TArray VisibleToPlayerClass; + TArray RestrictedToPlayerClass; + TArray ForbiddenToPlayerClass; }; class FDoomEdMap diff --git a/src/thingdef/thingdef.cpp b/src/thingdef/thingdef.cpp index ea067ae88..aba84b265 100644 --- a/src/thingdef/thingdef.cpp +++ b/src/thingdef/thingdef.cpp @@ -146,6 +146,11 @@ FActorInfo *CreateNewActor(const FScriptPosition &sc, FName typeName, FName pare info = ti->ActorInfo; } + // Copy class lists from parent + info->ForbiddenToPlayerClass = parent->ActorInfo->ForbiddenToPlayerClass; + info->RestrictedToPlayerClass = parent->ActorInfo->RestrictedToPlayerClass; + info->VisibleToPlayerClass = parent->ActorInfo->VisibleToPlayerClass; + if (parent->ActorInfo->DamageFactors != NULL) { // copy damage factors from parent diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 3cb22e778..0a3a6c9f3 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1248,10 +1248,12 @@ DEFINE_PROPERTY(visibletoteam, I, Actor) //========================================================================== DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) { + info->VisibleToPlayerClass.Clear(); for(int i = 0;i < PROP_PARM_COUNT;++i) { PROP_STRING_PARM(n, i); - info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + if (*n != 0) + info->VisibleToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); } } @@ -1261,6 +1263,34 @@ DEFINE_PROPERTY(visibletoplayerclass, S_s, Actor) // //========================================================================== +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(restrictedto, S_s, Inventory) +{ + info->RestrictedToPlayerClass.Clear(); + for(int i = 0;i < PROP_PARM_COUNT;++i) + { + PROP_STRING_PARM(n, i); + if (*n != 0) + info->RestrictedToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + } +} + +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(forbiddento, S_s, Inventory) +{ + info->ForbiddenToPlayerClass.Clear(); + for(int i = 0;i < PROP_PARM_COUNT;++i) + { + PROP_STRING_PARM(n, i); + if (*n != 0) + info->ForbiddenToPlayerClass.Push(FindClassTentative(n, "PlayerPawn")); + } +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/actors/hexen/baseweapons.txt b/wadsrc/static/actors/hexen/baseweapons.txt index 08bd2881f..5348e437d 100644 --- a/wadsrc/static/actors/hexen/baseweapons.txt +++ b/wadsrc/static/actors/hexen/baseweapons.txt @@ -1,14 +1,20 @@ +// The Doom and Heretic players are not excluded from pickup in case +// somebody wants to use these weapons with either of those games. + ACTOR FighterWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo ClericPlayer, MagePlayer } ACTOR ClericWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo FighterPlayer, MagePlayer } ACTOR MageWeapon : Weapon native { Weapon.Kickback 150 + Inventory.ForbiddenTo FighterPlayer, ClericPlayer } diff --git a/wadsrc/static/actors/hexen/clericholy.txt b/wadsrc/static/actors/hexen/clericholy.txt index 15673ab1b..e97be8b17 100644 --- a/wadsrc/static/actors/hexen/clericholy.txt +++ b/wadsrc/static/actors/hexen/clericholy.txt @@ -1,10 +1,11 @@ // Cleric Weapon Piece ------------------------------------------------------ -ACTOR ClericWeaponPiece : WeaponPiece native +ACTOR ClericWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_WRAITHVERGE_PIECE" + Inventory.ForbiddenTo FighterPlayer, MagePlayer WeaponPiece.Weapon CWeapWraithverge +FLOATBOB } diff --git a/wadsrc/static/actors/hexen/fighterquietus.txt b/wadsrc/static/actors/hexen/fighterquietus.txt index 034914d23..a77e851d8 100644 --- a/wadsrc/static/actors/hexen/fighterquietus.txt +++ b/wadsrc/static/actors/hexen/fighterquietus.txt @@ -1,10 +1,11 @@ // Fighter Weapon Piece ----------------------------------------------------- -ACTOR FighterWeaponPiece : WeaponPiece native +ACTOR FighterWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_QUIETUS_PIECE" + Inventory.ForbiddenTo ClericPlayer, MagePlayer WeaponPiece.Weapon FWeapQuietus +FLOATBOB } diff --git a/wadsrc/static/actors/hexen/magestaff.txt b/wadsrc/static/actors/hexen/magestaff.txt index 65c0ac893..aa75ed446 100644 --- a/wadsrc/static/actors/hexen/magestaff.txt +++ b/wadsrc/static/actors/hexen/magestaff.txt @@ -1,10 +1,11 @@ // Mage Weapon Piece -------------------------------------------------------- -ACTOR MageWeaponPiece : WeaponPiece native +ACTOR MageWeaponPiece : WeaponPiece { Inventory.PickupSound "misc/w_pkup" Inventory.PickupMessage "$TXT_BLOODSCOURGE_PIECE" + Inventory.ForbiddenTo FighterPlayer, ClericPlayer WeaponPiece.Weapon MWeapBloodscourge +FLOATBOB } From 9c8bb236ecbf6e725a5b392ad919a9785d858b9f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Tue, 27 Sep 2011 01:14:31 +0000 Subject: [PATCH 024/993] - Backport r1253 through r1256 and r1259 of GZDoom. * By pressing request, allow Linux users to build ZDoom with an FMOD version that doesn't give them 3D sound positioning. :p * Fixed severe copy-pasta portal copy bug. * 3D floors hidden by being moved above the ceiling or below the floor will no longer show in the automap. * Reject TEXTURES scale of 0. They'd do nothing but provoke a division by zero error. * Maybe fixed Linux compilation? SVN r3297 (trunk) --- src/CMakeLists.txt | 2 +- src/am_map.cpp | 11 ++++++++++- src/p_spec.cpp | 14 +++++++------- src/sdl/i_system.cpp | 10 +++++----- src/textures/multipatchtexture.cpp | 2 ++ 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da0653527..98860716b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,7 @@ set( MINOR_VERSIONS "50" "49" "48" "47" "46" "45" "44" "43" "42" "41" "27" "26" "25" "24" "23" "22" "21" "20" "21" "19" "18" "17" "16" "15" "14" "13" "12" "11" "10" "09" "08" "07" "06" "05" "04" "03" "02" "01" "00" ) -set( MAJOR_VERSIONS "30" "28" "26" "24" "22" "20" ) +set( MAJOR_VERSIONS "34" "28" "26" "24" "22" "20" ) set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "../fmod" ) foreach( majver ${MAJOR_VERSIONS} ) foreach( minver ${MINOR_VERSIONS} ) diff --git a/src/am_map.cpp b/src/am_map.cpp index a6b03446f..ec7e99859 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1670,6 +1670,7 @@ void AM_drawSubsectors() // (Make the comparison in floating point to avoid overflows and improve performance.) double secx; double secy; + double seczb, seczt; double cmpz = FIXED2DBL(viewz); if (players[consoleplayer].camera && sec == players[consoleplayer].camera->Sector) @@ -1683,6 +1684,8 @@ void AM_drawSubsectors() secx = FIXED2DBL(sec->soundorg[0]); secy = FIXED2DBL(sec->soundorg[1]); } + seczb = floorplane->ZatPoint(secx, secy); + seczt = sec->ceilingplane.ZatPoint(secx, secy); for (unsigned int i = 0; i < sec->e->XFloor.ffloors.Size(); ++i) { @@ -1690,7 +1693,13 @@ void AM_drawSubsectors() if (!(rover->flags & FF_EXISTS)) continue; if (rover->flags & FF_FOG) continue; if (rover->alpha == 0) continue; - if (rover->top.plane->ZatPoint(secx, secy) < cmpz) + double roverz = rover->top.plane->ZatPoint(secx, secy); + // Ignore 3D floors that are above or below the sector itself: + // they are hidden. Since 3D floors are sorted top to bottom, + // if we get below the sector floor, we can stop. + if (roverz > seczt) continue; + if (roverz < seczb) break; + if (roverz < cmpz) { maptex = *(rover->top.texture); floorplane = rover->top.plane; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index d73575bea..a60751aa2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1046,18 +1046,18 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha) { // Check if this portal needs to be copied to other sectors // This must be done here to ensure that it gets done only after the portal is set up - if (lines[i].special == Sector_SetPortal && - lines[i].args[1] == 1 && - lines[i].args[2] == plane && - lines[i].args[3] == sectortag) + if (lines[j].special == Sector_SetPortal && + lines[j].args[1] == 1 && + lines[j].args[2] == plane && + lines[j].args[3] == sectortag) { - if (lines[i].args[0] == 0) + if (lines[j].args[0] == 0) { - SetPortal(lines[i].frontsector, plane, reference, alpha); + SetPortal(lines[j].frontsector, plane, reference, alpha); } else { - for (int s=-1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;) + for (int s=-1; (s = P_FindSectorFromTag(lines[j].args[0],s)) >= 0;) { SetPortal(§ors[s], plane, reference, alpha); } diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 55ba296b6..bee304f4c 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -855,15 +855,15 @@ struct SDL_PrivateVideoData struct SDL_VideoDevice { const char *name; - int (*functions)()[9]; + int (*functions[9])(); SDL_VideoInfo info; SDL_PixelFormat *displayformatalphapixel; - int (*morefuncs)()[9]; + int (*morefuncs[9])(); Uint16 *gamma; - int (*somefuncs)()[9]; + int (*somefuncs[9])(); unsigned int texture; // Only here if SDL was compiled with OpenGL support. Ack! int is_32bit; - int (*itsafuncs)()[13]; + int (*itsafuncs[13])(); SDL_Surface *surfaces[3]; SDL_Palette *physpal; SDL_Color *gammacols; @@ -874,7 +874,7 @@ struct SDL_VideoDevice SDL_PrivateVideoData *hidden; // Why did they have to bury this so far in? }; -extern SDL_VideDevice *current_video; +extern SDL_VideoDevice *current_video; #define SDL_Display (current_video->hidden->X11_Display) SDL_Cursor *CreateColorCursor(FTexture *cursorpic) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 0bfb979a6..2013294a8 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1254,11 +1254,13 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype) { sc.MustGetFloat(); xScale = FLOAT2FIXED(sc.Float); + if (xScale == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name); } else if (sc.Compare("YScale")) { sc.MustGetFloat(); yScale = FLOAT2FIXED(sc.Float); + if (yScale == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name); } else if (sc.Compare("WorldPanning")) { From 3117f657c74c94f30978b516a30b021848561d1d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 3 Oct 2011 00:36:37 +0000 Subject: [PATCH 025/993] - Change UDMF lineflag 'transparent' to 'translucent' to match the spec. (Hopefully nobody used 'transparent'; it's not in the DoomBuilder configs, so that should be a safe assumption.) SVN r3298 (trunk) --- src/p_udmf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 97e537531..8968db07c 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -752,7 +752,7 @@ public: Flag(ld->flags, ML_BLOCK_FLOATERS, key); continue; - case NAME_Transparent: + case NAME_Translucent: CHECK_N(St | Zd | Zdt | Va) strifetrans = CheckBool(key); continue; From f51f4866e444201b97a740ff5b8c0c3837bb2aaa Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 3 Oct 2011 00:38:20 +0000 Subject: [PATCH 026/993] - Fix mapcolor for Strife's passcard. SVN r3299 (trunk) --- wadsrc/static/lockdefs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/lockdefs.txt b/wadsrc/static/lockdefs.txt index a6ddd74ba..c7ce76738 100644 --- a/wadsrc/static/lockdefs.txt +++ b/wadsrc/static/lockdefs.txt @@ -364,7 +364,7 @@ Lock 3 Strife Passcard RemoteMessage "$TXT_NEED_PASSCARD" Message "$TXT_NEED_PASSCARD_DOOR" - Mapcolor 128 266 150 + Mapcolor 128 166 150 } From 307050d38dada3e3a4da9b96672d5be695602e06 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 3 Oct 2011 00:56:01 +0000 Subject: [PATCH 027/993] - Remove the chasecam restriction that the player sprite must be visible. (When crushed, the real player is turned invisible, defeating the death/chasecam.) SVN r3300 (trunk) --- src/r_utility.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 29d008ca5..0f715e2bd 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -773,10 +773,7 @@ void R_SetupFrame (AActor *actor) } if (player != NULL && gamestate != GS_TITLELEVEL && - ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) && - (camera->RenderStyle.BlendOp != STYLEOP_None) && - !(camera->renderflags & RF_INVISIBLE) && - camera->sprite != SPR_TNT1) + ((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0))) { // [RH] Use chasecam view P_AimCamera (camera, iview->nviewx, iview->nviewy, iview->nviewz, viewsector); From b5cd69fe4c9ce463686cace3ef145b9c730455e2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2011 09:46:31 +0000 Subject: [PATCH 028/993] - fixed: Invalid intermission string references to the string table could cause a crash. SVN r3301 (trunk) --- src/intermission/intermission.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 1ef24689c..023dff655 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -291,7 +291,7 @@ void DIntermissionScreenText::Init(FIntermissionAction *desc, bool first) { Super::Init(desc, first); mText = static_cast(desc)->mText; - if (mText[0] == '$') mText = GStrings[&mText[1]]; + if (mText[0] == '$') mText = GStrings(&mText[1]); mTextSpeed = static_cast(desc)->mTextSpeed; mTextX = static_cast(desc)->mTextX; if (mTextX < 0) mTextX =gameinfo.TextScreenX; From 46cedffafb0b3f2e211866613d743ae29e66ca32 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Oct 2011 10:01:59 +0000 Subject: [PATCH 029/993] Fixed floor crushers in Strife. SVN r3302 (trunk) --- wadsrc/static/xlat/strife.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wadsrc/static/xlat/strife.txt b/wadsrc/static/xlat/strife.txt index b1e170037..93a97753f 100644 --- a/wadsrc/static/xlat/strife.txt +++ b/wadsrc/static/xlat/strife.txt @@ -113,7 +113,7 @@ RetailOnly = 121 52 = WALK|REP, ACS_ExecuteAlways (0, 0, 52, tag) 53 = WALK, Plat_PerpetualRaiseLip (tag, P_SLOW, PLATWAIT, 0) 54 = WALK, Plat_Stop (tag) - 56 = WALK, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 56 = WALK, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 57 = WALK, Ceiling_CrushStop (tag) 58 = WALK, Floor_RaiseByValue (tag, F_SLOW, 64) 59 = WALK, Floor_RaiseByValueTxTy (tag, F_SLOW, 24) @@ -164,7 +164,7 @@ RetailOnly = 121 91 = WALK|REP, Floor_RaiseToLowestCeiling (tag, F_SLOW) 92 = WALK|REP, Floor_RaiseByValue (tag, F_SLOW, 64) 93 = WALK|REP, Floor_RaiseByValueTxTy (tag, F_SLOW, 24) - 94 = WALK|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 94 = WALK|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 95 = WALK|REP, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 96 = WALK|REP, Floor_RaiseByTexture (tag, F_SLOW) 97 = WALK|REP|MONST, Teleport (0, tag) @@ -247,7 +247,7 @@ RetailOnly = 121 49 = USE, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) 50 = USE, Door_Close (tag, D_SLOW) 51 = USE, Teleport_EndGame (0) - 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 101 = USE, Floor_RaiseToLowestCeiling (tag, F_SLOW) 102 = USE, Floor_LowerToHighest (tag, F_SLOW, 128) 103 = USE, Door_Open (tag, D_SLOW) @@ -289,7 +289,7 @@ RetailOnly = 121 64 = USE|REP, Floor_RaiseToLowestCeiling (tag, F_SLOW) 66 = USE|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 3) 67 = USE|REP, Plat_UpByValueStayTx (tag, P_SLOW/2, 4) - 65 = USE|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10) + 65 = USE|REP, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) 68 = USE|REP, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 69 = USE|REP, Floor_RaiseToNearest (tag, F_SLOW) 70 = USE|REP, Floor_LowerToHighest (tag, F_FAST, 128) From 3d214602c4ae346b21e20828c8c80909ddaa0f15 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 27 Oct 2011 01:05:59 +0000 Subject: [PATCH 030/993] - Fixed: Strife line type 11 has the same Teleport_NewMap/Exit_Normal semantics as line type 52. SVN r3303 (trunk) --- wadsrc/static/xlat/strife.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/xlat/strife.txt b/wadsrc/static/xlat/strife.txt index 93a97753f..3d06cd7cd 100644 --- a/wadsrc/static/xlat/strife.txt +++ b/wadsrc/static/xlat/strife.txt @@ -278,7 +278,7 @@ RetailOnly = 121 235 = USE, ACS_ExecuteWithResult (0, 235, tag) // Buttons - 11 = USE|REP, Exit_Normal (0) + 11 = USE|REP, ACS_ExecuteWithResult (0, 52, tag) 42 = USE|REP, Door_Close (tag, D_SLOW) 43 = USE|REP, Ceiling_LowerToFloor (tag, C_SLOW) 45 = USE|REP, Floor_LowerToHighest (tag, F_SLOW, 128) From de956a9ab63222110987072f7a59ba14c9f9120b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 27 Oct 2011 01:35:30 +0000 Subject: [PATCH 031/993] - Added a fourth paremeter to Floor_LowerToHighest. Set it to 1 to always apply the offset to the target height. (This is Heretic's behavior.) SVN r3304 (trunk) --- src/actionspecials.h | 2 +- src/p_floor.cpp | 5 +++-- src/p_lnspec.cpp | 4 ++-- src/p_spec.h | 4 ++-- wadsrc/static/xlat/heretic.txt | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index 6e77bff7a..722742613 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -219,7 +219,7 @@ DEFINE_SPECIAL(Floor_RaiseToLowestCeiling, 238, 2, 2, 2) DEFINE_SPECIAL(Floor_RaiseByValueTxTy, 239, 3, 3, 3) DEFINE_SPECIAL(Floor_RaiseByTexture, 240, 2, 2, 2) DEFINE_SPECIAL(Floor_LowerToLowestTxTy, 241, 2, 2, 2) -DEFINE_SPECIAL(Floor_LowerToHighest, 242, 3, 3, 3) +DEFINE_SPECIAL(Floor_LowerToHighest, 242, 3, 4, 4) DEFINE_SPECIAL(Exit_Normal, 243, 1, 1, 1) DEFINE_SPECIAL(Exit_Secret, 244, 1, 1, 1) DEFINE_SPECIAL(Elevator_RaiseToNearest, 245, 2, 2, 2) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index d18a908b6..e0381e733 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -272,11 +272,12 @@ DFloor::DFloor (sector_t *sec) // // HANDLE FLOOR TYPES // [RH] Added tag, speed, height, crush, change params. +// This functions starts too many different things. // //========================================================================== bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush) + fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower) { int secnum; bool rtn; @@ -332,7 +333,7 @@ manual_floor: floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); // [RH] DOOM's turboLower type did this. I've just extended it // to be applicable to all LowerToHighest types. - if (floor->m_FloorDestDist != sec->floorplane.d) + if (hereticlower || floor->m_FloorDestDist != sec->floorplane.d) floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight+height); break; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index eb1c2b1c0..96c9ac465 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -275,9 +275,9 @@ FUNC(LS_Floor_LowerToLowest) } FUNC(LS_Floor_LowerToHighest) -// Floor_LowerToHighest (tag, speed, adjust) +// Floor_LowerToHighest (tag, speed, adjust, hereticlower) { - return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, 0, 0, false, arg3==1); } FUNC(LS_Floor_LowerToNearest) diff --git a/src/p_spec.h b/src/p_spec.h index 19de4ce8a..547154c19 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -755,7 +755,7 @@ protected: fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, int usespecials); friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush); + fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false); friend bool EV_FloorCrushStop (int tag); friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); private: @@ -766,7 +766,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line, fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt, int usespecials); bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, - fixed_t speed, fixed_t height, int crush, int change, bool hexencrush); + fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower); bool EV_FloorCrushStop (int tag); bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed); diff --git a/wadsrc/static/xlat/heretic.txt b/wadsrc/static/xlat/heretic.txt index 8a2b696bc..2ed3748b3 100644 --- a/wadsrc/static/xlat/heretic.txt +++ b/wadsrc/static/xlat/heretic.txt @@ -3,6 +3,7 @@ include "xlat/base.txt" 7 = USE, Stairs_BuildUpDoom (tag, F_SLOW, 8) 8 = WALK, Stairs_BuildUpDoom (tag, F_SLOW, 8) 10 = WALK, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) + 36 = WALK, Floor_LowerToHighest (tag, F_FAST, 136, 1) 88 = WALK|REP, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 99 = 0, Scroll_Texture_Right (SCROLL_UNIT) 100 = WALK|REP, Door_Raise (tag, D_SLOW*3, VDOORWAIT) From 3401d9f2bb71ba52219ee3c36befba88f7c1129a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 1 Nov 2011 01:41:01 +0000 Subject: [PATCH 032/993] - Fix incorrect line arg count for Ceiling_Waggle. SVN r3306 (trunk) --- src/actionspecials.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index 722742613..7bd89cbfb 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -36,7 +36,7 @@ DEFINE_SPECIAL(ClearForceField, 34, 1, 1, 1) // [RH] Remove Strife's forcefie DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 3, 3) DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 3, 3) DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 4) -DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 4) // [RH] Complement of Floor_Waggle +DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 5) // [RH] Complement of Floor_Waggle DEFINE_SPECIAL(Teleport_ZombieChanger, 39, 2, 2, 2) // [RH] Needed for Strife DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 3, 3) DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 3, 3) From c23b918596494b8eee920ea0a85cc603a1af5e68 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 1 Nov 2011 01:59:47 +0000 Subject: [PATCH 033/993] - Fixed: restart ccmd did not reset the palette. SVN r3307 (trunk) --- src/v_video.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 314ae22f8..db0be3696 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1539,7 +1539,14 @@ void V_Init (bool restart) } screen = new DDummyFrameBuffer (width, height); } - + // Update screen palette when restarting + else + { + PalEntry *palette = screen->GetPalette (); + for (int i = 0; i < 256; ++i) + *palette++ = GPalette.BaseColors[i]; + screen->UpdatePalette(); + } BuildTransTable (GPalette.BaseColors); } From e121bd7d9287d8baf5f721d725f55a7cc27f1a22 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 1 Nov 2011 02:58:52 +0000 Subject: [PATCH 034/993] - Added compat_badangles to simulate Doom's incorrect sine table: Player spawning and teleporting will be offset by one fineangle so they cannot face directly in one of the cardinal directions. SVN r3308 (trunk) --- src/compatibility.cpp | 108 +++++++++++++++++++++++++----------------- src/compatibility.h | 3 +- src/d_main.cpp | 86 +++++++++++++++++++-------------- src/doomdef.h | 2 + src/doomstat.h | 3 +- src/g_level.cpp | 2 + src/g_level.h | 5 +- src/g_mapinfo.cpp | 18 +++++-- src/p_mobj.cpp | 5 ++ src/p_teleport.cpp | 7 ++- 10 files changed, 149 insertions(+), 90 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 57d2b3f72..80532c788 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -59,7 +59,14 @@ struct FCompatOption { const char *Name; int CompatFlags; - int BCompatFlags; + int WhichSlot; +}; + +enum +{ + SLOT_COMPAT, + SLOT_COMPAT2, + SLOT_BCOMPAT }; enum @@ -86,41 +93,43 @@ TMap BCompatMap; static FCompatOption Options[] = { - { "setslopeoverflow", 0, BCOMPATF_SETSLOPEOVERFLOW }, - { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, - { "vileghosts", 0, BCOMPATF_VILEGHOSTS }, - { "ignoreteleporttags", 0, BCOMPATF_BADTELEPORTERS }, + { "setslopeoverflow", BCOMPATF_SETSLOPEOVERFLOW, SLOT_BCOMPAT }, + { "resetplayerspeed", BCOMPATF_RESETPLAYERSPEED, SLOT_BCOMPAT }, + { "vileghosts", BCOMPATF_VILEGHOSTS, SLOT_BCOMPAT }, + { "ignoreteleporttags", BCOMPATF_BADTELEPORTERS, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp - { "shorttex", COMPATF_SHORTTEX, 0 }, - { "stairs", COMPATF_STAIRINDEX, 0 }, - { "limitpain", COMPATF_LIMITPAIN, 0 }, - { "nopassover", COMPATF_NO_PASSMOBJ, 0 }, - { "notossdrops", COMPATF_NOTOSSDROPS, 0 }, - { "useblocking", COMPATF_USEBLOCKING, 0 }, - { "nodoorlight", COMPATF_NODOORLIGHT, 0 }, - { "ravenscroll", COMPATF_RAVENSCROLL, 0 }, - { "soundtarget", COMPATF_SOUNDTARGET, 0 }, - { "dehhealth", COMPATF_DEHHEALTH, 0 }, - { "trace", COMPATF_TRACE, 0 }, - { "dropoff", COMPATF_DROPOFF, 0 }, - { "boomscroll", COMPATF_BOOMSCROLL, 0 }, - { "invisibility", COMPATF_INVISIBILITY, 0 }, - { "silentinstantfloors", COMPATF_SILENT_INSTANT_FLOORS, 0 }, - { "sectorsounds", COMPATF_SECTORSOUNDS, 0 }, - { "missileclip", COMPATF_MISSILECLIP, 0 }, - { "crossdropoff", COMPATF_CROSSDROPOFF, 0 }, - { "wallrun", COMPATF_WALLRUN, 0 }, // [GZ] Added for CC MAP29 - { "anybossdeath", COMPATF_ANYBOSSDEATH, 0}, // [GZ] Added for UAC_DEAD - { "mushroom", COMPATF_MUSHROOM, 0}, - { "mbfmonstermove", COMPATF_MBFMONSTERMOVE, 0 }, - { "corpsegibs", COMPATF_CORPSEGIBS, 0 }, - { "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 }, - { "spritesort", COMPATF_SPRITESORT, 0 }, - { "hitscan", COMPATF_HITSCAN, 0 }, - { "lightlevel", COMPATF_LIGHT, 0 }, - { "polyobj", COMPATF_POLYOBJ, 0 }, - { "maskedmidtex", COMPATF_MASKEDMIDTEX, 0 }, + { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, + { "stairs", COMPATF_STAIRINDEX, SLOT_COMPAT }, + { "limitpain", COMPATF_LIMITPAIN, SLOT_COMPAT }, + { "nopassover", COMPATF_NO_PASSMOBJ, SLOT_COMPAT }, + { "notossdrops", COMPATF_NOTOSSDROPS, SLOT_COMPAT }, + { "useblocking", COMPATF_USEBLOCKING, SLOT_COMPAT }, + { "nodoorlight", COMPATF_NODOORLIGHT, SLOT_COMPAT }, + { "ravenscroll", COMPATF_RAVENSCROLL, SLOT_COMPAT }, + { "soundtarget", COMPATF_SOUNDTARGET, SLOT_COMPAT }, + { "dehhealth", COMPATF_DEHHEALTH, SLOT_COMPAT }, + { "trace", COMPATF_TRACE, SLOT_COMPAT }, + { "dropoff", COMPATF_DROPOFF, SLOT_COMPAT }, + { "boomscroll", COMPATF_BOOMSCROLL, SLOT_COMPAT }, + { "invisibility", COMPATF_INVISIBILITY, SLOT_COMPAT }, + { "silentinstantfloors", COMPATF_SILENT_INSTANT_FLOORS, SLOT_COMPAT }, + { "sectorsounds", COMPATF_SECTORSOUNDS, SLOT_COMPAT }, + { "missileclip", COMPATF_MISSILECLIP, SLOT_COMPAT }, + { "crossdropoff", COMPATF_CROSSDROPOFF, SLOT_COMPAT }, + { "wallrun", COMPATF_WALLRUN, SLOT_COMPAT }, // [GZ] Added for CC MAP29 + { "anybossdeath", COMPATF_ANYBOSSDEATH, SLOT_COMPAT },// [GZ] Added for UAC_DEAD + { "mushroom", COMPATF_MUSHROOM, SLOT_COMPAT }, + { "mbfmonstermove", COMPATF_MBFMONSTERMOVE, SLOT_COMPAT }, + { "corpsegibs", COMPATF_CORPSEGIBS, SLOT_COMPAT }, + { "noblockfriends", COMPATF_NOBLOCKFRIENDS, SLOT_COMPAT }, + { "spritesort", COMPATF_SPRITESORT, SLOT_COMPAT }, + { "hitscan", COMPATF_HITSCAN, SLOT_COMPAT }, + { "lightlevel", COMPATF_LIGHT, SLOT_COMPAT }, + { "polyobj", COMPATF_POLYOBJ, SLOT_COMPAT }, + { "maskedmidtex", COMPATF_MASKEDMIDTEX, SLOT_COMPAT }, + { "badangles", COMPATF2_BADANGLES, SLOT_COMPAT2 }, + { NULL, 0, 0 } }; @@ -189,15 +198,13 @@ void ParseCompatibility() md5array.Push(md5); sc.MustGetString(); } while (!sc.Compare("{")); - flags.CompatFlags = 0; - flags.BCompatFlags = 0; + memset(flags.CompatFlags, 0, sizeof(flags.CompatFlags)); flags.ExtCommandIndex = ~0u; while (sc.GetString()) { if ((i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0) { - flags.CompatFlags |= Options[i].CompatFlags; - flags.BCompatFlags |= Options[i].BCompatFlags; + flags.CompatFlags[Options[i].WhichSlot] |= Options[i].CompatFlags; } else if (sc.Compare("clearlineflags")) { @@ -226,7 +233,7 @@ void ParseCompatibility() sc.MustGetString(); CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL)); - for(int i=0;i<5;i++) + for (int i = 0; i < 5; i++) { sc.MustGetNumber(); CompatParams.Push(sc.Number); @@ -269,18 +276,21 @@ void CheckCompatibility(MapData *map) { ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT; if (gameinfo.flags & GI_COMPATSTAIRS) ii_compatflags |= COMPATF_STAIRINDEX; + ii_compatflags2 = 0; ib_compatflags = 0; ii_compatparams = -1; } else if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATPOLY1) && Wads.CheckLumpName(map->lumpnum, "MAP36")) { ii_compatflags = COMPATF_POLYOBJ; + ii_compatflags2 = 0; ib_compatflags = 0; ii_compatparams = -1; } else if (Wads.GetLumpFile(map->lumpnum) == 2 && (gameinfo.flags & GI_COMPATPOLY2) && Wads.CheckLumpName(map->lumpnum, "MAP47")) { ii_compatflags = COMPATF_POLYOBJ; + ii_compatflags2 = 0; ib_compatflags = 0; ii_compatparams = -1; } @@ -297,25 +307,35 @@ void CheckCompatibility(MapData *map) { Printf("%02X", md5.Bytes[j]); } - if (flags != NULL) Printf(", cflags = %08x, bflags = %08x\n", flags->CompatFlags, flags->BCompatFlags); - else Printf("\n"); + if (flags != NULL) + { + Printf(", cflags = %08x, cflags2 = %08x, bflags = %08x\n", + flags->CompatFlags[SLOT_COMPAT], flags->CompatFlags[SLOT_COMPAT2], flags->CompatFlags[SLOT_BCOMPAT]); + } + else + { + Printf("\n"); + } } if (flags != NULL) { - ii_compatflags = flags->CompatFlags; - ib_compatflags = flags->BCompatFlags; + ii_compatflags = flags->CompatFlags[SLOT_COMPAT]; + ii_compatflags2 = flags->CompatFlags[SLOT_COMPAT2]; + ib_compatflags = flags->CompatFlags[SLOT_BCOMPAT]; ii_compatparams = flags->ExtCommandIndex; } else { ii_compatflags = 0; + ii_compatflags2 = 0; ib_compatflags = 0; ii_compatparams = -1; } } // Reset i_compatflags compatflags.Callback(); + compatflags2.Callback(); } //========================================================================== @@ -416,5 +436,5 @@ CCMD (mapchecksum) CCMD (hiddencompatflags) { - Printf("%08x %08x\n", ii_compatflags, ib_compatflags); + Printf("%08x %08x %08x\n", ii_compatflags, ii_compatflags2, ib_compatflags); } diff --git a/src/compatibility.h b/src/compatibility.h index 5726955b5..cf4dce2f7 100644 --- a/src/compatibility.h +++ b/src/compatibility.h @@ -14,8 +14,7 @@ union FMD5Holder struct FCompatValues { - int CompatFlags; - int BCompatFlags; + int CompatFlags[3]; unsigned int ExtCommandIndex; }; diff --git a/src/d_main.cpp b/src/d_main.cpp index a90a813f4..072ee03d0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -515,8 +515,8 @@ CVAR (Flag, sv_nocountendmonst, dmflags2, DF2_NOCOUNTENDMONST); // //========================================================================== -int i_compatflags; // internal compatflags composed from the compatflags CVAR and MAPINFO settings -int ii_compatflags, ib_compatflags; +int i_compatflags, i_compatflags2; // internal compatflags composed from the compatflags CVAR and MAPINFO settings +int ii_compatflags, ii_compatflags2, ib_compatflags; EXTERN_CVAR(Int, compatmode) @@ -526,19 +526,30 @@ static int GetCompatibility(int mask) else return (mask & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask); } +static int GetCompatibility2(int mask) +{ + return (level.info == NULL) ? mask + : (mask & ~level.info->compatmask2) | (level.info->compatflags2 & level.info->compatmask2); +} + CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) { int old = i_compatflags; i_compatflags = GetCompatibility(self) | ii_compatflags; - if ((old ^i_compatflags) & COMPATF_POLYOBJ) + if ((old ^ i_compatflags) & COMPATF_POLYOBJ) { FPolyObj::ClearAllSubsectorLinks(); } } +CUSTOM_CVAR (Int, compatflags2, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) +{ + i_compatflags2 = GetCompatibility2(self) | ii_compatflags2; +} + CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) { - int v; + int v, w = 0; switch (self) { @@ -558,6 +569,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN| COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT|COMPATF_MASKEDMIDTEX; + w = COMPATF2_BADANGLES; break; case 3: // Boom compat mode @@ -580,40 +592,42 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) } compatflags = v; + compatflags2 = w; } -CVAR (Flag, compat_shortTex, compatflags, COMPATF_SHORTTEX); -CVAR (Flag, compat_stairs, compatflags, COMPATF_STAIRINDEX); -CVAR (Flag, compat_limitpain, compatflags, COMPATF_LIMITPAIN); -CVAR (Flag, compat_silentpickup,compatflags, COMPATF_SILENTPICKUP); -CVAR (Flag, compat_nopassover, compatflags, COMPATF_NO_PASSMOBJ); -CVAR (Flag, compat_soundslots, compatflags, COMPATF_MAGICSILENCE); -CVAR (Flag, compat_wallrun, compatflags, COMPATF_WALLRUN); -CVAR (Flag, compat_notossdrops, compatflags, COMPATF_NOTOSSDROPS); -CVAR (Flag, compat_useblocking, compatflags, COMPATF_USEBLOCKING); -CVAR (Flag, compat_nodoorlight, compatflags, COMPATF_NODOORLIGHT); -CVAR (Flag, compat_ravenscroll, compatflags, COMPATF_RAVENSCROLL); -CVAR (Flag, compat_soundtarget, compatflags, COMPATF_SOUNDTARGET); -CVAR (Flag, compat_dehhealth, compatflags, COMPATF_DEHHEALTH); -CVAR (Flag, compat_trace, compatflags, COMPATF_TRACE); -CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF); -CVAR (Flag, compat_boomscroll, compatflags, COMPATF_BOOMSCROLL); -CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY); -CVAR (Flag, compat_silentinstantfloors,compatflags, COMPATF_SILENT_INSTANT_FLOORS); -CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS); -CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP); -CVAR (Flag, compat_crossdropoff,compatflags, COMPATF_CROSSDROPOFF); -CVAR (Flag, compat_anybossdeath,compatflags, COMPATF_ANYBOSSDEATH); -CVAR (Flag, compat_minotaur, compatflags, COMPATF_MINOTAUR); -CVAR (Flag, compat_mushroom, compatflags, COMPATF_MUSHROOM); -CVAR (Flag, compat_mbfmonstermove,compatflags, COMPATF_MBFMONSTERMOVE); -CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS); -CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS); -CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT); -CVAR (Flag, compat_hitscan, compatflags,COMPATF_HITSCAN); -CVAR (Flag, compat_light, compatflags,COMPATF_LIGHT); -CVAR (Flag, compat_polyobj, compatflags,COMPATF_POLYOBJ); -CVAR (Flag, compat_maskedmidtex,compatflags,COMPATF_MASKEDMIDTEX); +CVAR (Flag, compat_shortTex, compatflags, COMPATF_SHORTTEX); +CVAR (Flag, compat_stairs, compatflags, COMPATF_STAIRINDEX); +CVAR (Flag, compat_limitpain, compatflags, COMPATF_LIMITPAIN); +CVAR (Flag, compat_silentpickup, compatflags, COMPATF_SILENTPICKUP); +CVAR (Flag, compat_nopassover, compatflags, COMPATF_NO_PASSMOBJ); +CVAR (Flag, compat_soundslots, compatflags, COMPATF_MAGICSILENCE); +CVAR (Flag, compat_wallrun, compatflags, COMPATF_WALLRUN); +CVAR (Flag, compat_notossdrops, compatflags, COMPATF_NOTOSSDROPS); +CVAR (Flag, compat_useblocking, compatflags, COMPATF_USEBLOCKING); +CVAR (Flag, compat_nodoorlight, compatflags, COMPATF_NODOORLIGHT); +CVAR (Flag, compat_ravenscroll, compatflags, COMPATF_RAVENSCROLL); +CVAR (Flag, compat_soundtarget, compatflags, COMPATF_SOUNDTARGET); +CVAR (Flag, compat_dehhealth, compatflags, COMPATF_DEHHEALTH); +CVAR (Flag, compat_trace, compatflags, COMPATF_TRACE); +CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF); +CVAR (Flag, compat_boomscroll, compatflags, COMPATF_BOOMSCROLL); +CVAR (Flag, compat_invisibility, compatflags, COMPATF_INVISIBILITY); +CVAR (Flag, compat_silentinstantfloors, compatflags, COMPATF_SILENT_INSTANT_FLOORS); +CVAR (Flag, compat_sectorsounds, compatflags, COMPATF_SECTORSOUNDS); +CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP); +CVAR (Flag, compat_crossdropoff, compatflags, COMPATF_CROSSDROPOFF); +CVAR (Flag, compat_anybossdeath, compatflags, COMPATF_ANYBOSSDEATH); +CVAR (Flag, compat_minotaur, compatflags, COMPATF_MINOTAUR); +CVAR (Flag, compat_mushroom, compatflags, COMPATF_MUSHROOM); +CVAR (Flag, compat_mbfmonstermove, compatflags, COMPATF_MBFMONSTERMOVE); +CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS); +CVAR (Flag, compat_noblockfriends, compatflags, COMPATF_NOBLOCKFRIENDS); +CVAR (Flag, compat_spritesort, compatflags, COMPATF_SPRITESORT); +CVAR (Flag, compat_hitscan, compatflags, COMPATF_HITSCAN); +CVAR (Flag, compat_light, compatflags, COMPATF_LIGHT); +CVAR (Flag, compat_polyobj, compatflags, COMPATF_POLYOBJ); +CVAR (Flag, compat_maskedmidtex, compatflags, COMPATF_MASKEDMIDTEX); +CVAR (Flag, compat_badangles, compatflags2, COMPATF2_BADANGLES); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 03de866ef..538f084d7 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -334,6 +334,8 @@ enum COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom COMPATF_POLYOBJ = 1 << 30, // Draw polyobjects the old fashioned way COMPATF_MASKEDMIDTEX = 1 << 31, // Ignore compositing when drawing masked midtextures + + COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/doomstat.h b/src/doomstat.h index 826c31990..0daa8d6b9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -240,6 +240,7 @@ EXTERN_CVAR (Int, dmflags); EXTERN_CVAR (Int, dmflags2); // [BC] EXTERN_CVAR (Int, compatflags); -extern int i_compatflags, ii_compatflags, ib_compatflags; +EXTERN_CVAR (Int, compatflags2); +extern int i_compatflags, i_compatflags2, ii_compatflags, ii_compatflags2, ib_compatflags; #endif diff --git a/src/g_level.cpp b/src/g_level.cpp index 0b89dafa8..95b11f4a9 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -664,6 +664,7 @@ void G_DoCompleted (void) } else { + level_info_t *nextinfo = FindLevelInfo (nextlevel); wminfo.next = nextinfo->mapname; wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->pname, FTexture::TEX_MiscPatch)]; @@ -1253,6 +1254,7 @@ void G_InitLevelLocals () level.skypic2[8] = 0; compatflags.Callback(); + compatflags2.Callback(); NormalLight.ChangeFade (level.fadeto); diff --git a/src/g_level.h b/src/g_level.h index 8e0477f41..336b47105 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -299,8 +299,8 @@ struct level_info_t float aircontrol; int WarpTrans; int airsupply; - DWORD compatflags; - DWORD compatmask; + DWORD compatflags, compatflags2; + DWORD compatmask, compatmask2; FString Translator; // for converting Doom-format linedef and sector types. int DefaultEnvironment; // Default sound environment for the map. FName Intermission; @@ -561,6 +561,7 @@ struct FSkillInfo bool FastMonsters; bool DisableCheats; bool AutoUseHealth; + bool EasyBossBrain; int RespawnCounter; int RespawnLimit; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index ea1c0d7c0..3b6e6eb92 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -254,8 +254,8 @@ void level_info_t::Reset() aircontrol = 0.f; WarpTrans = 0; airsupply = 20; - compatflags = 0; - compatmask = 0; + compatflags = compatflags2 = 0; + compatmask = compatmask2 = 0; Translator = ""; RedirectType = 0; RedirectMap[0] = 0; @@ -1272,6 +1272,7 @@ MapFlagHandlers[] = { "compat_light", MITYPE_COMPATFLAG, COMPATF_LIGHT, 0 }, { "compat_polyobj", MITYPE_COMPATFLAG, COMPATF_POLYOBJ, 0 }, { "compat_maskedmidtex", MITYPE_COMPATFLAG, COMPATF_MASKEDMIDTEX, 0 }, + { "compat_badangles", MITYPE_COMPATFLAG, 0, COMPATF2_BADANGLES }, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, @@ -1353,9 +1354,18 @@ void FMapInfoParser::ParseMapDefinition(level_info_t &info) if (sc.CheckNumber()) set = sc.Number; } - if (set) info.compatflags |= handler->data1; - else info.compatflags &= ~handler->data1; + if (set) + { + info.compatflags |= handler->data1; + info.compatflags2 |= handler->data2; + } + else + { + info.compatflags &= ~handler->data1; + info.compatflags2 &= ~handler->data2; + } info.compatmask |= handler->data1; + info.compatmask2 |= handler->data2; } break; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7eb2d39b9..c77128a22 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1871,6 +1871,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) goto explode; } + // Reflect the missile along angle mo->angle = angle; angle >>= ANGLETOFINESHIFT; @@ -3950,6 +3951,10 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) { spawn_angle = ANG45 * (mthing->angle / 45); } + if (i_compatflags2 & COMPATF2_BADANGLES) + { + spawn_angle += 1 << ANGLETOFINESHIFT; + } } mobj = static_cast diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 6d3969234..d46df1005 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -322,6 +322,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool angle_t angle = 0; fixed_t s = 0, c = 0; fixed_t velx = 0, vely = 0; + angle_t badangle = 0; if (thing == NULL) { // Teleport function called with an invalid actor @@ -367,7 +368,11 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool { z = ONFLOORZ; } - if (P_Teleport (thing, searcher->x, searcher->y, z, searcher->angle, fog, sourceFog, keepOrientation, haltVelocity)) + if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL)) + { + badangle = 1 << ANGLETOFINESHIFT; + } + if (P_Teleport (thing, searcher->x, searcher->y, z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (!fog && line && keepOrientation) From 4816b3182b0995204065bf826d729ccc3d43834c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 2 Nov 2011 02:44:01 +0000 Subject: [PATCH 035/993] - Add compat_badangles to the menu. SVN r3309 (trunk) --- src/menu/optionmenu.cpp | 2 +- wadsrc/static/compatibility.txt | 7 +++++++ wadsrc/static/menudef.txt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index 12294a36c..4c5b2ef62 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -584,7 +584,7 @@ public: Super::Drawer(); char text[64]; - mysnprintf(text, 64, "compatflags = %d", *compatflags); + mysnprintf(text, 64, "compatflags = %d compatflags2 = %d", *compatflags, *compatflags2); screen->DrawText (SmallFont, OptionSettings.mFontColorValue, (screen->GetWidth() - SmallFont->StringWidth (text) * CleanXfac_1) / 2, 0, text, DTA_CleanNoMove_1, true, TAG_DONE); diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 4bfa156e6..de05766cf 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -141,3 +141,10 @@ DCE862393CAAA6FF1294FB7056B53057 // UAC Ultra map07: Contains a scroller dependi { ignoreteleporttags } + +8FF30D57F6CE64F085A6567EC302842A // Enjay's test map for this flag +9D7893D09FEE55C31B73C670DF850962 // Memento Mori II, map12 +{ + badangles +} + diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index eb6f09dd5..03f0baeac 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1201,6 +1201,7 @@ OptionMenu "CompatibilityOptions" Option "Cripple sound for silent BFG trick", "compat_soundslots", "YesNo" Option "Draw polyobjects like Hexen", "compat_POLYOBJ", "YesNo" Option "Ignore Y offsets on masked midtextures", "compat_MASKEDMIDTEX", "YesNo" + Option "Cannot travel straight NSEW", "compat_badangles", "YesNo" Class "CompatibilityMenu" } From e68d9562082437961e761927d2d505afed03bb7f Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 3 Nov 2011 21:08:39 +0000 Subject: [PATCH 036/993] - Fixed: 2048 should be a valid height for a Doom patch. SVN r3310 (trunk) --- src/textures/patchtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/patchtexture.cpp b/src/textures/patchtexture.cpp index eb9487bc2..e476cbad8 100644 --- a/src/textures/patchtexture.cpp +++ b/src/textures/patchtexture.cpp @@ -94,7 +94,7 @@ static bool CheckIfPatch(FileReader & file) int height = LittleShort(foo->height); int width = LittleShort(foo->width); - if (height > 0 && height < 2048 && width > 0 && width <= 2048 && width < file.GetLength()/4) + if (height > 0 && height <= 2048 && width > 0 && width <= 2048 && width < file.GetLength()/4) { // The dimensions seem like they might be valid for a patch, so // check the column directory for extra security. At least one From 9acf65b9a457b7ffdc52bfaed43e463bf1e9179d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 4 Nov 2011 01:12:53 +0000 Subject: [PATCH 037/993] - Added support for a PALVERS lump. This specifies replacement textures to be used when for walls and floors when the renderer is paletted. The format is very simple: rgbtex1 paltex1 rgbtex2 paltex2 ... The first texture is the one to be used normally, and the second is the one to be used in paletted modes. The vid_nopalsubstitutions cvar can be used to ignore this lump. SVN r3311 (trunk) --- src/r_plane.cpp | 10 +++--- src/r_segs.cpp | 41 ++++++++++++------------ src/textures/texturemanager.cpp | 56 ++++++++++++++++++++++++++++++++- src/textures/textures.h | 17 ++++++++-- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 9e754853f..0652121f7 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1080,7 +1080,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske } else { // regular flat - FTexture *tex = TexMan(pl->picnum); + FTexture *tex = TexMan(pl->picnum, true); if (tex->UseType == FTexture::TEX_Null) { @@ -1368,9 +1368,9 @@ void R_DrawSkyPlane (visplane_t *pl) if (!(pl->sky & PL_SKYFLAT)) { // use sky1 sky1: - frontskytex = TexMan(sky1tex); + frontskytex = TexMan(sky1tex, true); if (level.flags & LEVEL_DOUBLESKY) - backskytex = TexMan(sky2tex); + backskytex = TexMan(sky2tex, true); else backskytex = NULL; skyflip = 0; @@ -1381,7 +1381,7 @@ void R_DrawSkyPlane (visplane_t *pl) } else if (pl->sky == PL_SKYFLAT) { // use sky2 - frontskytex = TexMan(sky2tex); + frontskytex = TexMan(sky2tex, true); backskytex = NULL; frontcyl = sky2cyl; skyflip = 0; @@ -1407,7 +1407,7 @@ void R_DrawSkyPlane (visplane_t *pl) pos = side_t::top; } - frontskytex = TexMan(s->GetTexture(pos)); + frontskytex = TexMan(s->GetTexture(pos), true); if (frontskytex == NULL || frontskytex->UseType == FTexture::TEX_Null) { // [RH] The blank texture: Use normal sky instead. goto sky1; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 7e69190e5..525052328 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -240,7 +240,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) frontsector = curline->frontsector; backsector = curline->backsector; - tex = TexMan(curline->sidedef->GetTexture(side_t::mid)); + tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); if (i_compatflags & COMPATF_MASKEDMIDTEX) { tex = tex->GetRawTexture(); @@ -705,15 +705,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) } else if(fover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if(fover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -764,15 +764,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) fover = NULL; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if(rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } } // correct colors now @@ -881,15 +881,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) } else if (fover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (fover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -937,15 +937,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) fover = NULL; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } } // correct colors now @@ -1799,7 +1799,7 @@ void R_NewWall (bool needlights) // [RH] Horizon lines do not need to be textured if (linedef->special != Line_Horizon) { - midtexture = TexMan(sidedef->GetTexture(side_t::mid)); + midtexture = TexMan(sidedef->GetTexture(side_t::mid), true); rw_offset_mid = sidedef->GetTextureXOffset(side_t::mid); rowoffset = sidedef->GetTextureYOffset(side_t::mid); rw_midtexturescalex = sidedef->GetTextureXScale(side_t::mid); @@ -1943,7 +1943,7 @@ void R_NewWall (bool needlights) if (rw_havehigh) { // top texture - toptexture = TexMan(sidedef->GetTexture(side_t::top)); + toptexture = TexMan(sidedef->GetTexture(side_t::top), true); rw_offset_top = sidedef->GetTextureXOffset(side_t::top); rowoffset = sidedef->GetTextureYOffset(side_t::top); @@ -1973,7 +1973,7 @@ void R_NewWall (bool needlights) } if (rw_havelow) { // bottom texture - bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom)); + bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom), true); rw_offset_bottom = sidedef->GetTextureXOffset(side_t::bottom); rowoffset = sidedef->GetTextureYOffset(side_t::bottom); @@ -2016,7 +2016,7 @@ void R_NewWall (bool needlights) markceiling = false; } - FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid)); + FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid), true); segtextured = midtex != NULL || toptexture != NULL || bottomtexture != NULL; @@ -2218,7 +2218,7 @@ void R_StoreWallRange (int start, int stop) if(!ds_p->fake) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. - if ((TexMan(sidedef->GetTexture(side_t::mid))->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && + if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && (WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= TOO_CLOSE_Z)) @@ -2244,7 +2244,7 @@ void R_StoreWallRange (int start, int stop) lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); swal = (fixed_t *)(openings + ds_p->swall); - FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid)); + FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); fixed_t yrepeat = FixedMul(pic->yScale, sidedef->GetTextureYScale(side_t::mid)); fixed_t xoffset = sidedef->GetTextureXOffset(side_t::mid); @@ -2550,6 +2550,7 @@ int WallMost (short *mostbuf, const secplane_t &plane) { clearbufshort (&mostbuf[ix1], ix2-ix1, viewheight); return bad; + } if (bad&3) @@ -2759,7 +2760,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, xscale = decal->ScaleX; yscale = decal->ScaleY; - WallSpriteTile = TexMan(decal->PicNum); + WallSpriteTile = TexMan(decal->PicNum, true); flipx = (BYTE)(decal->RenderFlags & RF_XFLIP); if (WallSpriteTile == NULL || WallSpriteTile->UseType == FTexture::TEX_Null) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 622d92f75..1abbab29f 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -55,6 +55,8 @@ FTextureManager TexMan; +CVAR(Bool, vid_nopalsubstitutions, false, CVAR_ARCHIVE) + //========================================================================== // // FTextureManager :: FTextureManager @@ -749,7 +751,7 @@ void FTextureManager::AddPatches (int lumpnum) { file->Read (name, 8); - if (CheckForTexture (name, FTexture::TEX_WallPatch, false) == -1) + if (CheckForTexture (name, FTexture::TEX_WallPatch, 0) == -1) { CreateTexture (Wads.CheckNumForName (name, ns_patches), FTexture::TEX_WallPatch); } @@ -1001,6 +1003,57 @@ void FTextureManager::Init() InitAnimDefs(); FixAnimations(); InitSwitchList(); + InitPalettedVersions(); +} + +//========================================================================== +// +// FTextureManager :: InitPalettedVersions +// +//========================================================================== + +void FTextureManager::InitPalettedVersions() +{ + int lump, lastlump = 0; + + PalettedVersions.Clear(); + while ((lump = Wads.FindLump("PALVERS", &lastlump)) != -1) + { + FScanner sc(lump); + + while (sc.GetString()) + { + FTextureID pic1 = CheckForTexture(sc.String, FTexture::TEX_Any); + if (!pic1.isValid()) + { + sc.ScriptMessage("Unknown texture %s to replace"); + } + sc.MustGetString(); + FTextureID pic2 = CheckForTexture(sc.String, FTexture::TEX_Any); + if (!pic2.isValid()) + { + sc.ScriptMessage("Unknown texture %s to use as replacement"); + } + if (pic1.isValid() && pic2.isValid()) + { + PalettedVersions[pic1.GetIndex()] = pic2.GetIndex(); + } + } + } +} + +//========================================================================== +// +// FTextureManager :: PalCheck +// +//========================================================================== + +FTextureID FTextureManager::PalCheck(FTextureID tex) +{ + if (vid_nopalsubstitutions) return tex; + int *newtex = PalettedVersions.CheckKey(tex.GetIndex()); + if (newtex == NULL || *newtex == 0) return tex; + return *newtex; } //========================================================================== @@ -1152,6 +1205,7 @@ int FTextureManager::CountLumpTextures (int lumpnum) // // R_PrecacheLevel // + // Preloads all relevant graphics for the level. // //=========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index a35c911ad..6c1b8f717 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -332,15 +332,20 @@ public: FTexture *FindTexture(const char *texname, int usetype = FTexture::TEX_MiscPatch, BITFIELD flags = TEXMAN_TryAny); // Get texture with translation - FTexture *operator() (FTextureID texnum) + FTexture *operator() (FTextureID texnum, bool withpalcheck=false) { if ((size_t)texnum.texnum >= Textures.Size()) return NULL; - return Textures[Translation[texnum.texnum]].Texture; + int picnum = Translation[texnum.texnum]; + if (withpalcheck) + { + picnum = PalCheck(picnum).GetIndex(); + } + return Textures[picnum].Texture; } FTexture *operator() (const char *texname) { FTextureID texnum = GetTexture (texname, FTexture::TEX_MiscPatch); - if (texnum.texnum==-1) return NULL; + if (texnum.texnum == -1) return NULL; return Textures[Translation[texnum.texnum]].Texture; } @@ -350,6 +355,8 @@ public: return Textures[Translation[i]].Texture; } + FTextureID PalCheck(FTextureID tex); + enum { TEXMAN_TryAny = 1, @@ -434,6 +441,8 @@ private: void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); void ParseAnimatedDoor(FScanner &sc); + void InitPalettedVersions(); + // Switches void InitSwitchList (); @@ -452,6 +461,7 @@ private: int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; TArray FirstTextureForFile; + TMap PalettedVersions; // maps from normal -> paletted version TArray mAnimations; TArray mSwitchDefs; @@ -529,6 +539,7 @@ public: void MakeTexture (); protected: + DSimpleCanvas *Canvas; BYTE *Pixels; Span DummySpans[2]; From e6e15be7e00173ee62d0564f5e10e0b3a8cc12c7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 5 Nov 2011 22:45:58 +0000 Subject: [PATCH 038/993] - fixed: p_floor.cpp had some checks for 0-tags wrong (thanks to FDARI for the fix) SVN r3312 (trunk) --- src/p_floor.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index e0381e733..443ec01be 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -283,7 +283,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, bool rtn; sector_t* sec; DFloor* floor; - bool manual = false; + //bool manual = false; tag == 0 and manual == true constitutes the same evidence [fdari] fixed_t ceilingheight; fixed_t newheight; vertex_t *spot, *spot2; @@ -296,12 +296,12 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag, if (!line || !(sec = line->backsector)) return rtn; secnum = (int)(sec-sectors); - manual = true; + //manual = true; goto manual_floor; } secnum = -1; - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sec = §ors[secnum]; @@ -309,12 +309,15 @@ manual_floor: // ALREADY MOVING? IF SO, KEEP GOING... if (sec->PlaneMoving(sector_t::floor)) { - if (manual) - continue; - else - return false; + // There was a test for 0/non-0 here, supposed to prevent 0-tags from executing "continue" and searching for unrelated sectors + // Unfortunately, the condition had been reversed, so that searches for tag-0 would continue, + // while numbered tags would abort (return false, even if some floors have been successfully triggered) + + // All occurences of the condition (faulty or not) have been replaced by a looping condition: Looping only occurs if we're looking for a non-0 tag. + continue; } + // new floor thinker rtn = true; floor = new DFloor (sec); @@ -525,8 +528,6 @@ manual_floor: floor->SetFloorChangeType (line->frontsector, change); } } - if (manual) - return rtn; } return rtn; } @@ -806,7 +807,7 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) DFloor* floor; vertex_t* spot; fixed_t height; - bool manual = false; + // bool manual = false; Instead of breaking when manual is true, fail to (re)enter loop when tag is false (0). secnum = -1; rtn = false; @@ -815,18 +816,18 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed) { if (!line || !(s1 = line->backsector)) return rtn; - manual = true; + //manual = true; goto manual_donut; } - while ((secnum = P_FindSectorFromTag(tag,secnum)) >= 0) + while (tag && (secnum = P_FindSectorFromTag(tag,secnum)) >= 0) { s1 = §ors[secnum]; // s1 is pillar's sector manual_donut: // ALREADY MOVING? IF SO, KEEP GOING... if (s1->PlaneMoving(sector_t::floor)) - continue; + continue; // safe now, because we check that tag is non-0 in the looping condition [fdari] rtn = true; s2 = getNextSector (s1->lines[0], s1); // s2 is pool's sector @@ -870,7 +871,6 @@ manual_donut: floor->StartFloorSound (); break; } - if (manual) break; } return rtn; } @@ -1034,7 +1034,6 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, fixed_t floorheight, ceilingheight; fixed_t newheight; vertex_t* spot; - bool manual = false; if (!line && (elevtype == DElevator::elevateCurrent)) return false; @@ -1046,19 +1045,18 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype, { if (!line || !(sec = line->backsector)) return rtn; - manual = true; goto manual_elevator; } // act on all sectors with the same tag as the triggering linedef - while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) + while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) // never loop for a non-0 tag (condition moved to beginning of loop) [FDARI] { sec = §ors[secnum]; manual_elevator: // If either floor or ceiling is already activated, skip it if (sec->PlaneMoving(sector_t::floor) || sec->ceilingdata) //jff 2/22/98 - continue; + continue; // the loop used to break at the end if tag were 0, but would miss that step if "continue" occured [FDARI] // create and initialize new elevator thinker rtn = true; @@ -1116,7 +1114,6 @@ manual_elevator: elevator->m_CeilingDestDist = sec->ceilingplane.PointToDist (sec->soundorg[0], sec->soundorg[1], ceilingheight - height); break; } - if (manual) break; } return rtn; } @@ -1379,7 +1376,7 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset, sector_t *sector; DWaggleBase *waggle; bool retCode; - bool manual = false; + //bool manual = false; retCode = false; sectorIndex = -1; @@ -1388,12 +1385,12 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset, { if (!line || !(sector = line->backsector)) return retCode; - manual = true; + //manual = true; goto manual_waggle; } - while ((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + while (tag && (sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { sector = §ors[sectorIndex]; manual_waggle: @@ -1421,7 +1418,6 @@ manual_waggle: /(TICRATE+((3*TICRATE)*height)/255); waggle->m_Ticker = timer ? timer*TICRATE : -1; waggle->m_State = WGLSTATE_EXPAND; - if (manual) break; } return retCode; } From 66f86add059778c16a96096ff9a4918656808357 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 7 Nov 2011 00:31:17 +0000 Subject: [PATCH 039/993] - Fixed: Starting in a sector with a musinfo thing would not trigger the thing. SVN r3313 (trunk) --- src/g_level.cpp | 6 ++++++ src/g_level.h | 1 + src/s_advsound.cpp | 54 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 95b11f4a9..d552a3140 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -665,6 +665,7 @@ void G_DoCompleted (void) else { + level_info_t *nextinfo = FindLevelInfo (nextlevel); wminfo.next = nextinfo->mapname; wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->pname, FTexture::TEX_MiscPatch)]; @@ -1366,6 +1367,11 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) << level.maptime << i; + if (SaveVersion >= 3313) + { + arc << level.nextmusic; + } + // Hub transitions must keep the current total time if (!hubLoad) level.totaltime = i; diff --git a/src/g_level.h b/src/g_level.h index 336b47105..4b70f595a 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -401,6 +401,7 @@ struct FLevelLocals int musicorder; int cdtrack; unsigned int cdid; + int nextmusic; // For MUSINFO purposes char skypic1[9]; char skypic2[9]; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 2dd815f1b..58102ce4c 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -293,6 +293,7 @@ float S_GetMusicVolume (const char *music) } //========================================================================== + // // S_HashSounds // @@ -2248,6 +2249,8 @@ class AMusicChanger : public ASectorAction DECLARE_CLASS (AMusicChanger, ASectorAction) public: virtual bool TriggerAction (AActor *triggerer, int activationType); + virtual void Tick(); + virtual void PostBeginPlay(); }; IMPLEMENT_CLASS(AMusicChanger) @@ -2256,19 +2259,46 @@ bool AMusicChanger::TriggerAction (AActor *triggerer, int activationType) { if (activationType & SECSPAC_Enter) { - if (args[0] != 0) - { - FName *music = level.info->MusicMap.CheckKey(args[0]); - - if (music != NULL) - { - S_ChangeMusic(music->GetChars(), args[1]); - } - } - else - { - S_ChangeMusic("*"); + if (args[0] == 0 || level.info->MusicMap.CheckKey(args[0])) + { + level.nextmusic = args[0]; + reactiontime = 30; } } return Super::TriggerAction (triggerer, activationType); } + +void AMusicChanger::Tick() +{ + Super::Tick(); + if (reactiontime > -1 && --reactiontime == 0) + { + // Is it our music that's queued for being played? + if (level.nextmusic == args[0]) + { + if (args[0] != 0) + { + FName *music = level.info->MusicMap.CheckKey(args[0]); + + if (music != NULL) + { + S_ChangeMusic(music->GetChars(), args[1]); + } + } + else + { + S_ChangeMusic("*"); + } + } + } + } + +void AMusicChanger::PostBeginPlay() +{ + // The music changer should consider itself activated if the player + // spawns in its sector as well as if it enters the sector during a P_TryMove. + if (players[consoleplayer].mo && players[consoleplayer].mo->Sector == this->Sector) + { + TriggerAction(players[consoleplayer].mo, SECSPAC_Enter); + } +} From f00f5d23044b770d7cebaa51c8af8bea416eabb7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 7 Nov 2011 00:43:41 +0000 Subject: [PATCH 040/993] - Allow subclasses when checking for PowerWeaponLevel2. SVN r3314 (trunk) --- src/g_shared/a_morph.cpp | 3 ++- src/g_shared/a_weapons.cpp | 2 +- src/m_cheat.cpp | 2 +- src/p_lnspec.cpp | 2 +- src/p_pspr.cpp | 2 +- src/p_user.cpp | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index e8042ac85..26fe9fd8c 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -235,7 +235,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, player->MorphStyle = 0; player->MorphExitFlash = NULL; player->viewheight = mo->ViewHeight; - AInventory *level2 = mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); + AInventory *level2 = mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true); if (level2 != NULL) { level2->Destroy (); @@ -273,6 +273,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, if ((unsigned int)player->userinfo.skin >= PlayerClasses.Size () && (size_t)player->userinfo.skin < numskins) { + skinindex = player->userinfo.skin; } else if (PlayerClasses.Size () > 1) diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 3095ecbe0..6f89154bc 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -126,7 +126,7 @@ bool AWeapon::Use (bool pickup) // weapon, if one exists. if (SisterWeapon != NULL && SisterWeapon->WeaponFlags & WIF_POWERED_UP && - Owner->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2))) + Owner->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true)) { useweap = SisterWeapon; } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 0bb699f88..cf7c844b6 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -181,7 +181,7 @@ void cht_DoCheat (player_t *player, int cheat) case CHT_POWER: if (player->mo != NULL && player->health >= 0) { - item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); + item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true); if (item != NULL) { item->Destroy (); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 96c9ac465..430f29bb7 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2656,7 +2656,7 @@ FUNC(LS_SetPlayerProperty) { // Take power from activator if (power != 4) { - AInventory *item = it->FindInventory (powers[power]); + AInventory *item = it->FindInventory (powers[power], true); if (item != NULL) { item->Destroy (); diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 2bd844788..25b23ca92 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -155,7 +155,7 @@ void P_BringUpWeapon (player_t *player) if (weapon != NULL && weapon->SisterWeapon && weapon->SisterWeapon->WeaponFlags & WIF_POWERED_UP && - player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2))) + player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true)) { weapon = weapon->SisterWeapon; } diff --git a/src/p_user.cpp b/src/p_user.cpp index 84a81d384..4c438b3da 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -672,7 +672,7 @@ AWeapon *APlayerPawn::BestWeapon (const PClass *ammotype) int bestOrder = INT_MAX; AInventory *item; AWeapon *weap; - bool tomed = NULL != FindInventory (RUNTIME_CLASS(APowerWeaponLevel2)); + bool tomed = NULL != FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true); // Find the best weapon the player has. for (item = Inventory; item != NULL; item = item->Inventory) From 48c7423fbf153fd352cb4fa2658169397067a6f6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 7 Nov 2011 01:23:23 +0000 Subject: [PATCH 041/993] - Added flag ALF_NOFRIENDS and a friend-basis pointer to P_AimLineAttack(). A_DeathBallImpact uses these to avoid aiming at friends when the death ball bounces. (The pointer is needed because the missile itself does the aiming, not the player that shot it, and missiles are nobody's friends.) SVN r3315 (trunk) --- src/g_heretic/a_hereticweaps.cpp | 3 ++- src/p_local.h | 3 ++- src/p_map.cpp | 18 ++++++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index d7c083be3..d287b01b7 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -657,7 +657,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DeathBallImpact) angle = 0; for (i = 0; i < 16; i++) { - P_AimLineAttack (self, angle, 10*64*FRACUNIT, &linetarget); + P_AimLineAttack (self, angle, 10*64*FRACUNIT, &linetarget, 0, ALF_NOFRIENDS, NULL, self->target); if (linetarget && self->target != linetarget) { self->tracer = linetarget; @@ -1277,6 +1277,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2) AActor *mo; angle_t angle; fixed_t x, y, z; + fixed_t slope; FSoundID soundid; player_t *player; diff --git a/src/p_local.h b/src/p_local.h index bc357c68a..3c3040e66 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -410,7 +410,7 @@ 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, int flags = 0, 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, AActor *friender=NULL); enum { @@ -418,6 +418,7 @@ enum ALF_CHECK3D = 2, ALF_CHECKNONSHOOTABLE = 4, ALF_CHECKCONVERSATION = 8, + ALF_NOFRIENDS = 16, }; AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, bool ismelee = false, AActor **victim = NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index b9e6dc125..35ab352ce 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -330,7 +330,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr FBlockLinesIterator it(box); line_t *ld; - // P_LineOpening requires the thing's z to be the destination ín order to work. + // P_LineOpening requires the thing's z to be the destination ú‹ order to work. fixed_t savedz = thing->z; thing->z = z; while ((ld = it.Next())) @@ -2848,6 +2848,7 @@ struct aim_t fixed_t attackrange; fixed_t shootz; // Height if not aiming up or down AActor* shootthing; + AActor* friender; // actor to check friendliness again fixed_t toppitch, bottompitch; AActor * linetarget; @@ -3147,11 +3148,15 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e } } - if (sv_smartaim != 0 && !(flags & ALF_FORCENOSMART)) + if ((flags & ALF_NOFRIENDS) && th->IsFriend(friender)) + { + continue; + } + else 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. - if (th->IsFriend(shootthing)) + // In particular avoid autoaiming at friends and barrels. + if (th->IsFriend(friender)) { if (sv_smartaim < 2) { @@ -3160,7 +3165,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e pitch_friend = thingpitch; } } - else if (!(th->flags3&MF3_ISMONSTER) && th->player == NULL) + else if (!(th->flags3 & MF3_ISMONSTER) && th->player == NULL) { if (sv_smartaim < 3) { @@ -3192,7 +3197,7 @@ 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, - int flags, AActor *target) + int flags, AActor *target, AActor *friender) { fixed_t x2; fixed_t y2; @@ -3201,6 +3206,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p angle >>= ANGLETOFINESHIFT; aim.flags = flags; aim.shootthing = t1; + aim.friender = (friender == NULL) ? t1 : friender; x2 = t1->x + (distance>>FRACBITS)*finecosine[angle]; y2 = t1->y + (distance>>FRACBITS)*finesine[angle]; From 4d46655de65e5a89a0a034063e34f01e23f7595d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 17 Nov 2011 02:33:26 +0000 Subject: [PATCH 042/993] - Fix: Use correct pickup flash color. SVN r3316 (trunk) --- wadsrc/static/mapinfo/chex.txt | 2 +- wadsrc/static/mapinfo/doomcommon.txt | 2 +- wadsrc/static/mapinfo/heretic.txt | 2 +- wadsrc/static/mapinfo/hexen.txt | 2 +- wadsrc/static/mapinfo/strife.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index acc4462b1..edc5b4f29 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -43,7 +43,7 @@ gameinfo endoom = "ENDOOM" player5start = 4001 drawreadthis = true - pickupcolor = "d6 ba 45" + pickupcolor = "d7 ba 45" quitmessages = "$QUITMSG", "$QUITMSG23", "$QUITMSG24", "$QUITMSG25", "$QUITMSG26", "$QUITMSG27", "$QUITMSG28", "$QUITMSG29" menufontcolor_title = "GREEN" menufontcolor_label = "UNTRANSLATED" diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index f152aa730..9e3665533 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -42,7 +42,7 @@ gameinfo defaultdropstyle = 1 endoom = "ENDOOM" player5start = 4001 - pickupcolor = "d6 ba 45" + pickupcolor = "d7 ba 45" quitmessages = "$QUITMSG", "$QUITMSG1", "$QUITMSG2", "$QUITMSG3", "$QUITMSG4", "$QUITMSG5", "$QUITMSG6", "$QUITMSG7", "$QUITMSG8", "$QUITMSG9", "$QUITMSG10", "$QUITMSG11", "$QUITMSG12", "$QUITMSG13", "$QUITMSG14" diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 33ab58190..84dd4552d 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -42,7 +42,7 @@ gameinfo defaultdropstyle = 1 endoom = "ENDTEXT" player5start = 4001 - pickupcolor = "d6 ba 45" + pickupcolor = "d7 ba 45" quitmessages = "$*RAVENQUITMSG" menufontcolor_title = "UNTRANSLATED" menufontcolor_label = "GREEN" diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index 83202485b..631c6d1e9 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -40,7 +40,7 @@ gameinfo defaultrespawntime = 12 defaultdropstyle = 1 player5start = 9100 - pickupcolor = "d6 ba 45" + pickupcolor = "d7 ba 45" quitmessages = "$*RAVENQUITMSG" menufontcolor_title = "UNTRANSLATED" menufontcolor_label = "RED" diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 7791d7369..83c2285e6 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -43,7 +43,7 @@ gameinfo defaultdropstyle = 2 endoom = "ENDSTRF" player5start = 5 - pickupcolor = "d6 ba 45" + pickupcolor = "d7 ba 45" quitmessages = "$QUITMSG", "$QUITMSG15", "$QUITMSG16", "$QUITMSG17", "$QUITMSG18", "$QUITMSG19", "$QUITMSG20", "$QUITMSG21", "$QUITMSG22" menufontcolor_title = "UNTRANSLATED" menufontcolor_label = "UNTRANSLATED" From 04387a692416b7d67360f93e27cb421652344a29 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 24 Nov 2011 03:59:02 +0000 Subject: [PATCH 043/993] - Initialize all parameters when converting MBF_PlaySound to A_PlaySound, because volume was being passed as 0 to A_PlaySound. SVN r3317 (trunk) --- src/d_dehacked.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 16dc5b516..5f93be98e 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -691,8 +691,11 @@ void SetDehParams(FState * state, int codepointer) if (value2) StateParams.Set(ParamIndex+1, new FxConstant(SoundMap[value2-1], *pos)); // hit sound break; case MBF_PlaySound: - StateParams.Set(ParamIndex+0, new FxConstant(SoundMap[value1-1], *pos)); // soundid - StateParams.Set(ParamIndex+4, new FxConstant((value2?ATTN_NONE:ATTN_NORM), *pos)); // attenuation + StateParams.Set(ParamIndex+0, new FxConstant(SoundMap[value1-1], *pos)); // soundid + StateParams.Set(ParamIndex+1, new FxConstant(CHAN_BODY, *pos)); // channel + StateParams.Set(ParamIndex+2, new FxConstant(1.0, *pos)); // volume + StateParams.Set(ParamIndex+3, new FxConstant(false, *pos)); // looping + StateParams.Set(ParamIndex+4, new FxConstant((value2 ? ATTN_NONE : ATTN_NORM), *pos)); // attenuation break; case MBF_RandomJump: StateParams.Set(ParamIndex+0, new FxConstant(2, *pos)); // count From 7d502e77892d2d05dc6e906463f8092161678894 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 24 Nov 2011 04:27:47 +0000 Subject: [PATCH 044/993] - Added SMF_CURSPEED flag for A_SeekerMissile to cause it to use the missile's current speed rather than its Speed property. SVN r3318 (trunk) --- src/p_local.h | 2 +- src/p_mobj.cpp | 18 +++++++++++------- src/thingdef/thingdef_codeptr.cpp | 3 ++- wadsrc/static/actors/constants.txt | 1 + 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 3c3040e66..879a876ad 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -97,7 +97,7 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer=false); void P_ThrustMobj (AActor *mo, angle_t angle, fixed_t move); int P_FaceMobj (AActor *source, AActor *target, angle_t *delta); -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false); +bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise = false, bool usecurspeed=false); enum EPuffFlags { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c77128a22..105772621 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1468,16 +1468,18 @@ bool AActor::CanSeek(AActor *target) const // //---------------------------------------------------------------------------- -bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise) +bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool precise, bool usecurspeed) { int dir; int dist; angle_t delta; angle_t angle; AActor *target; + fixed_t speed; + speed = !usecurspeed ? actor->Speed : xs_CRoundToInt(TVector3(actor->velx, actor->vely, actor->velz).Length()); target = actor->tracer; - if (target == NULL || actor->Speed == 0 || !actor->CanSeek(target)) + if (target == NULL || speed == 0 || !actor->CanSeek(target)) { return false; } @@ -1507,8 +1509,8 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci if (!precise) { - actor->velx = FixedMul (actor->Speed, finecosine[angle]); - actor->vely = FixedMul (actor->Speed, finesine[angle]); + actor->velx = FixedMul (speed, finecosine[angle]); + actor->vely = FixedMul (speed, finesine[angle]); if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) { @@ -1516,7 +1518,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci target->z + target->height < actor->z) { // Need to seek vertically dist = P_AproxDistance (target->x - actor->x, target->y - actor->y); - dist = dist / actor->Speed; + dist = dist / speed; if (dist < 1) { dist = 1; @@ -1541,8 +1543,8 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci pitch >>= ANGLETOFINESHIFT; } - fixed_t xyscale = FixedMul(actor->Speed, finecosine[pitch]); - actor->velz = FixedMul(actor->Speed, finesine[pitch]); + fixed_t xyscale = FixedMul(speed, finecosine[pitch]); + actor->velz = FixedMul(speed, finesine[pitch]); actor->velx = FixedMul(xyscale, finecosine[angle]); actor->vely = FixedMul(xyscale, finesine[angle]); } @@ -1872,6 +1874,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) } + // Reflect the missile along angle mo->angle = angle; angle >>= ANGLETOFINESHIFT; @@ -2468,6 +2471,7 @@ void P_NightmareRespawn (AActor *mobj) z = mo->z; + // inherit attributes from deceased one mo->SpawnPoint[0] = mobj->SpawnPoint[0]; mo->SpawnPoint[1] = mobj->SpawnPoint[1]; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 965d4de08..c26510727 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -487,6 +487,7 @@ enum { SMF_LOOK = 1, SMF_PRECISE = 2, + SMF_CURSPEED = 4, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile) { @@ -501,7 +502,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SeekerMissile) { self->tracer = P_RoughMonsterSearch (self, distance); } - P_SeekerMissile(self, clamp(ang1, 0, 90) * ANGLE_1, clamp(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE)); + P_SeekerMissile(self, clamp(ang1, 0, 90) * ANGLE_1, clamp(ang2, 0, 90) * ANGLE_1, !!(flags & SMF_PRECISE), !!(flags & SMF_CURSPEED)); } //========================================================================== diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index fa8f37e95..fe84014e2 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -124,6 +124,7 @@ const int BF_AFFECTBOSSES = 4; // Flags for A_SeekerMissile const int SMF_LOOK = 1; const int SMF_PRECISE = 2; +const int SMF_CURSPEED = 4; // Flags for A_CustomPunch const int CPF_USEAMMO = 1; From 17ba09c88201f3cf6afdc22e9456c3137f459a8b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 24 Nov 2011 04:36:36 +0000 Subject: [PATCH 045/993] - Fixed: Cht_ChangeLevel cheats should not check for disabled cheats. SVN r3319 (trunk) --- src/st_stuff.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/st_stuff.cpp b/src/st_stuff.cpp index 08e6f0be4..bbfad744a 100644 --- a/src/st_stuff.cpp +++ b/src/st_stuff.cpp @@ -193,7 +193,7 @@ static cheatseq_t DoomCheats[] = { CheatPowerup[4], 0, 0, 0, {CHT_BEHOLDA,0}, Cht_Generic }, { CheatPowerup[5], 0, 0, 0, {CHT_BEHOLDL,0}, Cht_Generic }, { CheatChoppers, 0, 0, 0, {CHT_CHAINSAW,0}, Cht_Generic }, - { CheatClev, 0, 0, 0, {0,0}, Cht_ChangeLevel } + { CheatClev, 0, 1, 0, {0,0}, Cht_ChangeLevel } }; static cheatseq_t HereticCheats[] = @@ -211,7 +211,7 @@ static cheatseq_t HereticCheats[] = { CheatAmmo, 0, 0, 0, {CHT_TAKEWEAPS,0}, Cht_Generic }, { CheatGod, 0, 0, 0, {CHT_NOWUDIE,0}, Cht_Generic }, { CheatMassacre, 0, 0, 0, {CHT_MASSACRE,0}, Cht_Generic }, - { CheatEngage, 0, 0, 0, {0,0}, Cht_ChangeLevel }, + { CheatEngage, 0, 1, 0, {0,0}, Cht_ChangeLevel }, { CheatPowerup1[0], 0, 0, 0, {CHT_GIMMIEA,0}, Cht_Generic }, { CheatPowerup1[1], 0, 0, 0, {CHT_GIMMIEB,0}, Cht_Generic }, { CheatPowerup1[2], 0, 0, 0, {CHT_GIMMIEC,0}, Cht_Generic }, @@ -262,7 +262,7 @@ static cheatseq_t StrifeCheats[] = { CheatPowerup2[4], 0, 0, 0, {CHT_PUMPUPP,0}, Cht_Generic }, { CheatPowerup2[5], 0, 0, 0, {CHT_PUMPUPS,0}, Cht_Generic }, { CheatPowerup2[6], 0, 0, 0, {CHT_PUMPUPT,0}, Cht_Generic }, - { CheatRift, 0, 0, 0, {0,0}, Cht_ChangeLevel }, + { CheatRift, 0, 1, 0, {0,0}, Cht_ChangeLevel }, { CheatDonnyTrump, 0, 0, 0, {CHT_DONNYTRUMP,0},Cht_Generic }, { CheatScoot, 0, 0, 0, {0,0}, Cht_ChangeStartSpot }, { CheatLego, 0, 0, 0, {CHT_LEGO,0}, Cht_Generic }, @@ -284,7 +284,7 @@ static cheatseq_t ChexCheats[] = { CheatDigitalCafe, 0, 0, 0, {CHT_BEHOLDA,0}, Cht_Generic }, { CheatJoshuaStorms, 0, 0, 0, {CHT_BEHOLDL,0}, Cht_Generic }, { CheatJoelKoenigs, 0, 0, 0, {CHT_CHAINSAW,0}, Cht_Generic }, - { CheatLeeSnyder, 0, 0, 0, {0,0}, Cht_ChangeLevel } + { CheatLeeSnyder, 0, 1, 0, {0,0}, Cht_ChangeLevel } }; static cheatseq_t SpecialCheats[] = From cffae9c33cdb2119841c060bbbdd6fb4920ac10e Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Fri, 25 Nov 2011 21:49:03 +0000 Subject: [PATCH 046/993] - Applied Thomas's patch to fix physics with non-solid polyobjs, but adjusted it to work with 3D mid textures as well (at least as well as I could). SVN r3320 (trunk) --- src/po_man.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/po_man.cpp b/src/po_man.cpp index 856ff9341..8a18269e4 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -21,6 +21,7 @@ #include "tables.h" #include "s_sndseq.h" #include "a_sharedglobal.h" +#include "p_3dmidtex.h" #include "p_lnspec.h" #include "r_data/r_interpolate.h" #include "g_level.h" @@ -1291,6 +1292,22 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) checker.Push (mobj); if ((mobj->flags&MF_SOLID) && !(mobj->flags&MF_NOCLIP)) { + fixed_t top = -INT_MAX, bottom = INT_MAX; + bool above; + // [TN] Check wether this actor gets blocked by the line. + if(!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) + && !(ld->flags & ML_BLOCK_PLAYERS && mobj->player) + && !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER) + && !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS)) + && (!(ld->flags & ML_3DMIDTEX) || + (!P_LineOpening_3dMidtex(mobj, ld, bottom, top, &above) && + (mobj->z + mobj->height < bottom) + ) || (above && mobj->z > mobj->floorz)) + ) + { + continue; + } + FBoundingBox box(mobj->x, mobj->y, mobj->radius); if (box.Right() <= ld->bbox[BOXLEFT] From 7d348e71488b3f68b9fdf68496d3325922ff8862 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Sat, 26 Nov 2011 06:59:35 +0000 Subject: [PATCH 047/993] - Fixed: The scanner triggered an assertion failure on empty strings. SVN r3321 (trunk) --- src/sc_man.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 3860105dd..148f00637 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -239,7 +239,7 @@ void FScanner::PrepareScript () { // If the last character in the buffer is a null character, change // it to a newline. Otherwise, append a newline to the end. - if (ScriptBuffer[ScriptBuffer.Len() - 1] == '\0') + if (ScriptBuffer.Len() > 0 && ScriptBuffer[ScriptBuffer.Len() - 1] == '\0') { ScriptBuffer.LockBuffer()[ScriptBuffer.Len() - 1] = '\n'; ScriptBuffer.UnlockBuffer(); From 0897a593c7f0c6716dc09a54f9b4d739b495d243 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 28 Nov 2011 00:10:04 +0000 Subject: [PATCH 048/993] - When a missile teleports, maintain velocity on the other end. SVN r3322 (trunk) --- src/p_teleport.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index d46df1005..12497590a 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -110,6 +110,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, sector_t *destsect; bool resetpitch = false; fixed_t floorheight, ceilingheight; + fixed_t missilespeed; oldx = thing->x; oldy = thing->y; @@ -122,6 +123,10 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, player = NULL; floorheight = destsect->floorplane.ZatPoint (x, y); ceilingheight = destsect->ceilingplane.ZatPoint (x, y); + if (thing->flags & MF_MISSILE) + { // We don't measure z velocity, because it doesn't change. + missilespeed = xs_CRoundToInt(TVector2(thing->velx, thing->vely).Length()); + } if (z == ONFLOORZ) { if (player) @@ -206,8 +211,8 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, if (thing->flags & MF_MISSILE) { angle >>= ANGLETOFINESHIFT; - thing->velx = FixedMul (thing->Speed, finecosine[angle]); - thing->vely = FixedMul (thing->Speed, finesine[angle]); + thing->velx = FixedMul (missilespeed, finecosine[angle]); + thing->vely = FixedMul (missilespeed, finesine[angle]); } // [BC] && bHaltVelocity. else if (!keepOrientation && bHaltVelocity) // no fog doesn't alter the player's momentum From b41dbf8a5291aec63bdd6778e6d9eae5eddf30c1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 6 Dec 2011 01:25:37 +0000 Subject: [PATCH 049/993] - A_SetPitch now clamps the player's pitch within the valid range. It can be made to clamp other actors' pitches to within the range (-90,+90) degrees with the SPF_FORCECLAMP flag. - Transmit the local viewpitch limits to the other players. SVN r3323 (trunk) --- src/d_net.cpp | 8 ++++++++ src/d_player.h | 10 +++++++--- src/d_protocol.h | 1 + src/p_mobj.cpp | 2 ++ src/p_user.cpp | 12 ++++++++++-- src/r_renderer.h | 2 +- src/r_swrenderer.cpp | 2 +- src/r_utility.cpp | 8 ++++---- src/thingdef/thingdef_codeptr.cpp | 26 +++++++++++++++++++++++++- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 3 +++ 11 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 50d524cd2..1532c0a35 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2450,6 +2450,11 @@ void Net_DoCommand (int type, BYTE **stream, int player) } break; + case DEM_SETPITCHLIMIT: + players[player].MinPitch = ReadByte(stream) * -ANGLE_1; // up + players[player].MaxPitch = ReadByte(stream) * ANGLE_1; // down + break; + default: I_Error ("Unknown net command: %d", type); break; @@ -2570,6 +2575,9 @@ void Net_SkipCommand (int type, BYTE **stream) skip = 2 + ((*stream)[1] >> 7); break; + case DEM_SETPITCHLIMIT: + skip = 2; + break; default: return; diff --git a/src/d_player.h b/src/d_player.h index d3f2feb95..95604f0bd 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -282,6 +282,7 @@ public: bool centering; BYTE turnticks; + bool attackdown; bool usedown; DWORD oldbuttons; @@ -342,9 +343,9 @@ public: TObjPtr enemy; // The dead meat. - TObjPtr missile; // A threathing missile that got to be avoided. - TObjPtr mate; // Friend (used for grouping in templay or coop. - TObjPtr last_mate; // If bots mate dissapeared (not if died) that mate is + TObjPtr missile; // A threatening missile that needs to be avoided. + TObjPtr mate; // Friend (used for grouping in teamplay or coop). + TObjPtr last_mate; // If bots mate disappeared (not if died) that mate is // pointed to by this. Allows bot to roam to it if // necessary. @@ -380,6 +381,9 @@ public: FString LogText; // [RH] Log for Strife + int MinPitch; // Viewpitch limits (negative is up, positive is down) + int MaxPitch; + SBYTE crouching; SBYTE crouchdir; fixed_t crouchfactor; diff --git a/src/d_protocol.h b/src/d_protocol.h index b96c94e06..f00526555 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -159,6 +159,7 @@ enum EDemoCommand DEM_CONVCLOSE, // 60 DEM_CONVNULL, // 61 DEM_RUNSPECIAL, // 62 Byte: Special number, Byte: Arg count, Ints: Args + DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees) }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 105772621..559b2e477 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2783,6 +2783,7 @@ void AActor::Tick () static const BYTE HereticScrollDirs[4] = { 6, 9, 1, 4 }; static const BYTE HereticSpeedMuls[5] = { 5, 10, 25, 30, 35 }; + AActor *onmo; int i; @@ -4027,6 +4028,7 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) p->BlendR = p->BlendG = p->BlendB = p->BlendA = 0.f; p->mo->ResetAirSupply(false); p->Uncrouch(); + p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0. diff --git a/src/p_user.cpp b/src/p_user.cpp index 4c438b3da..236f4d319 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -522,6 +522,14 @@ void APlayerPawn::PostBeginPlay() P_FindFloorCeiling(this, true); z = floorz; } + else if (player - players == consoleplayer) + { + // Ask the local player's renderer what pitch restrictions + // should be imposed and let everybody know. + Net_WriteByte(DEM_SETPITCHLIMIT); + Net_WriteByte(Renderer->GetMaxViewPitch(false)); // up + Net_WriteByte(Renderer->GetMaxViewPitch(true)); // down + } } //=========================================================================== @@ -2213,11 +2221,11 @@ void P_PlayerThink (player_t *player) player->mo->pitch -= look; if (look > 0) { // look up - player->mo->pitch = MAX(player->mo->pitch, Renderer->GetMaxViewPitch(false)); + player->mo->pitch = MAX(player->mo->pitch, player->MinPitch); } else { // look down - player->mo->pitch = MIN(player->mo->pitch, Renderer->GetMaxViewPitch(true)); + player->mo->pitch = MIN(player->mo->pitch, player->MaxPitch); } } } diff --git a/src/r_renderer.h b/src/r_renderer.h index c9de1278a..bc464c031 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -49,7 +49,7 @@ struct FRenderer virtual void StartSerialize(FArchive &arc) {} virtual void EndSerialize(FArchive &arc) {} - virtual int GetMaxViewPitch(bool down) = 0; + virtual int GetMaxViewPitch(bool down) = 0; // return value is in plain degrees virtual void OnModeSet () {} virtual void ErrorCleanup () {} diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index c518abf90..56f816d6f 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -173,7 +173,7 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites() int FSoftwareRenderer::GetMaxViewPitch(bool down) { - return down? MAX_DN_ANGLE*ANGLE_1 : -MAX_UP_ANGLE*ANGLE_1; + return down ? MAX_DN_ANGLE : MAX_UP_ANGLE; } //========================================================================== diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 0f715e2bd..858cbbba7 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -601,11 +601,11 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi // Avoid overflowing viewpitch (can happen when a netgame is stalled) if (viewpitch + delta <= viewpitch) { - viewpitch = Renderer->GetMaxViewPitch(true); + viewpitch = player->MaxPitch; } else { - viewpitch = MIN(viewpitch + delta, Renderer->GetMaxViewPitch(true)); + viewpitch = MIN(viewpitch + delta, player->MaxPitch); } } else if (delta < 0) @@ -613,11 +613,11 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi // Avoid overflowing viewpitch (can happen when a netgame is stalled) if (viewpitch + delta >= viewpitch) { - viewpitch = Renderer->GetMaxViewPitch(false); + viewpitch = player->MinPitch; } else { - viewpitch = MAX(viewpitch + delta, Renderer->GetMaxViewPitch(false)); + viewpitch = MAX(viewpitch + delta, player->MinPitch); } } } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c26510727..b801b3e4f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3416,10 +3416,34 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle) // //=========================================================================== +enum +{ + SPF_FORCECLAMP = 1, // players always clamp +}; + DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) { - ACTION_PARAM_START(1); + ACTION_PARAM_START(2); ACTION_PARAM_ANGLE(pitch, 0); + ACTION_PARAM_INT(flags, 1); + + if (self->player != NULL || (flags & SPF_FORCECLAMP)) + { // clamp the pitch we set + int min, max; + + if (self->player != NULL) + { + min = self->player->MinPitch; + max = self->player->MaxPitch; + } + else + { + min = -ANGLE_90 + (1 << ANGLETOFINESHIFT); + max = ANGLE_90 - (1 << ANGLETOFINESHIFT); + } + pitch = clamp(pitch, min, max); + } + self->pitch = pitch; } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 29b265ac6..0d51bf4e8 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -278,7 +278,7 @@ ACTOR Actor native //: Thinker action native A_PigPain (); action native A_MonsterRefire(int chance, state label); action native A_SetAngle(float angle = 0); - action native A_SetPitch(float pitch); + action native A_SetPitch(float pitch, int flags = 0); action native A_ScaleVelocity(float scale); action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0); action native A_SetArg(int pos, int value); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index fe84014e2..42dca0e3e 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -257,5 +257,8 @@ Const Int WARPF_STOP = 0x80; Const Int WARPF_TOFLOOR = 0x100; Const Int WARPF_TESTONLY = 0x200; +// flags for A_SetPitch +const int SPF_FORCECLAMP = 1; + // This is only here to provide one global variable for testing. native int testglobalvar; From 43fed9dc892fe6999f4056c0b3c4b5486ae8bd97 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 6 Dec 2011 01:30:48 +0000 Subject: [PATCH 050/993] - Need to bump demo/gameversion due to DEM_SETPITCHLIMIT. MINDEMOVERSION also needs to be touched, since the default limits are now 0. SVN r3325 (trunk) --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index bb2e096ac..4c35f5a95 100644 --- a/src/version.h +++ b/src/version.h @@ -54,7 +54,7 @@ // Version identifier for network games. // Bump it every time you do a release unless you're certain you // didn't change anything that will affect sync. -#define NETGAMEVERSION 224 +#define NETGAMEVERSION 225 // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to @@ -64,11 +64,11 @@ // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x214 +#define DEMOGAMEVERSION 0x215 // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. -#define MINDEMOVERSION 0x213 +#define MINDEMOVERSION 0x215 // SAVEVER is the version of the information stored in level snapshots. // Note that SAVEVER is not directly comparable to VERSION. From 5284ab968879265203e4807cc8296423e4623a8a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 6 Dec 2011 01:50:38 +0000 Subject: [PATCH 051/993] - Do nothing in D_DoAdvanceDemo if gameaction is not ga_nothing. SVN r3326 (trunk) --- src/d_main.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 072ee03d0..26095d93a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1225,12 +1225,17 @@ void D_DoAdvanceDemo (void) static int pagecount; const char *pagename = NULL; + advancedemo = false; + + if (gameaction != ga_nothing) + { + return; + } + V_SetBlend (0,0,0,0); players[consoleplayer].playerstate = PST_LIVE; // not reborn - advancedemo = false; usergame = false; // no save / end game here paused = 0; - gameaction = ga_nothing; // [RH] If you want something more dynamic for your title, create a map // and name it TITLEMAP. That map will be loaded and used as the title. From 2f8d6beb1e2599d1765a7c1efb21b0ef0410d961 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 6 Dec 2011 01:52:07 +0000 Subject: [PATCH 052/993] - Be less verbose when attempting to play non-ZDoom demos. SVN r3327 (trunk) --- src/g_game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 9ff2d4225..ee8092b72 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2534,7 +2534,7 @@ void G_DoPlayDemo (void) if (ReadLong (&demo_p) != FORM_ID) { - const char *eek = "Cannot play non-ZDoom demos.\n(They would go out of sync badly.)\n"; + const char *eek = "Cannot play non-ZDoom demos.\n"; C_ForgetCVars(); M_Free(demobuffer); From 8e8331d44c3f51ce4a1e1ce3f7478f005fa81ef5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 6 Dec 2011 02:51:32 +0000 Subject: [PATCH 053/993] - Fixed: Pressing a key to advance an intermission screen only worked on the local computer. SVN r3328 (trunk) --- src/d_net.cpp | 6 ++++++ src/d_protocol.h | 1 + src/intermission/intermission.cpp | 26 +++++++++++++++++++++++++- src/intermission/intermission.h | 5 ++++- src/version.h | 2 +- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 1532c0a35..3ee20b8b6 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -59,6 +59,7 @@ #include "m_argv.h" #include "p_lnspec.h" #include "v_video.h" +#include "intermission/intermission.h" int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backSide, int arg0, int arg1, int arg2, int always, bool wantResultCode, bool net); @@ -748,6 +749,7 @@ void GetPackets (void) } if (netbuffer[0] & NCMD_QUITTERS) + { numplayers = netbuffer[k++]; for (int i = 0; i < numplayers; ++i) @@ -2455,6 +2457,10 @@ void Net_DoCommand (int type, BYTE **stream, int player) players[player].MaxPitch = ReadByte(stream) * ANGLE_1; // down break; + case DEM_ADVANCEINTER: + F_AdvanceIntermission(); + break; + default: I_Error ("Unknown net command: %d", type); break; diff --git a/src/d_protocol.h b/src/d_protocol.h index f00526555..79de464b1 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -160,6 +160,7 @@ enum EDemoCommand DEM_CONVNULL, // 61 DEM_RUNSPECIAL, // 62 Byte: Special number, Byte: Arg count, Ints: Args DEM_SETPITCHLIMIT, // 63 Byte: Up limit, Byte: Down limit (in degrees) + DEM_ADVANCEINTER, // 64 Advance intermission screen state }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 023dff655..cb533bda8 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -50,6 +50,7 @@ #include "g_level.h" #include "p_conversation.h" #include "menu/menu.h" +#include "d_net.h" FIntermissionDescriptorList IntermissionDescriptors; @@ -769,7 +770,11 @@ bool DIntermissionController::Responder (event_t *ev) if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing int res = mScreen->Responder(ev); - mAdvance = (res == -1); + if (res == -1 && !mSentAdvance) + { + Net_WriteByte(DEM_ADVANCEINTER); + mSentAdvance = true; + } return !!res; } return false; @@ -777,6 +782,10 @@ bool DIntermissionController::Responder (event_t *ev) void DIntermissionController::Ticker () { + if (mAdvance) + { + mSentAdvance = false; + } if (mScreen != NULL) { mAdvance |= (mScreen->Ticker() == -1); @@ -926,3 +935,18 @@ void F_EndFinale () DIntermissionController::CurrentIntermission = NULL; } } + +//========================================================================== +// +// Called by net loop. +// +//========================================================================== + +void F_AdvanceIntermission() +{ + if (DIntermissionController::CurrentIntermission != NULL) + { + DIntermissionController::CurrentIntermission->mAdvance = true; + } +} + diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index ee316c349..dc562c4c5 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -288,7 +288,7 @@ class DIntermissionController : public DObject TObjPtr mScreen; bool mDeleteDesc; bool mFirst; - bool mAdvance; + bool mAdvance, mSentAdvance; BYTE mGameState; int mIndex; @@ -302,6 +302,8 @@ public: void Ticker (); void Drawer (); void Destroy(); + + friend void F_AdvanceIntermission(); }; @@ -312,6 +314,7 @@ void F_Drawer (); void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, BYTE state); void F_StartIntermission(FName desc, BYTE state); void F_EndFinale (); +void F_AdvanceIntermission(); // Create an intermission from old cluster data void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat, diff --git a/src/version.h b/src/version.h index 4c35f5a95..d4ee01b13 100644 --- a/src/version.h +++ b/src/version.h @@ -64,7 +64,7 @@ // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x215 +#define DEMOGAMEVERSION 0x216 // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands. From 893455ef6166f50e4bc83946528ff15abbf5cc0a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 6 Dec 2011 08:36:28 +0000 Subject: [PATCH 054/993] - sync source with latest GZDoom: Includes: - Made the move tried from checking missile spawns ignore drop off height. This solves the Voodoo Gun ghostly civilian issue. - Fixed: the NOTELEPORT flag is removed from Dehacked missiles which lose the MISSILE flag. This caused problems with certain special effects based on dehacked spawn cubes. - Fixed: all Boom silent teleporters preserve relative height. - support for palette independent particle colors if the renderer can handle them. SVN r3329 (trunk) --- src/actionspecials.h | 2 +- src/d_dehacked.cpp | 9 + src/d_main.cpp | 2 +- src/p_effect.cpp | 19 +- src/p_glnodes.cpp | 2 +- src/p_lnspec.cpp | 4 +- src/p_local.h | 2 +- src/p_map.cpp | 8 +- src/p_mobj.cpp | 2 +- src/p_spec.h | 4 +- src/p_teleport.cpp | 12 +- src/p_udmf.cpp | 8 + src/r_things.cpp | 2 +- src/sdl/crashcatcher.c | 2 + src/sdl/i_main.cpp | 22 ++ src/sdl/i_system.cpp | 19 +- src/stats.cpp | 9 + src/stats.h | 73 ++++ wadsrc/static/xlat/base.txt | 12 +- zdoom.vcproj | 750 ++++++++++++++++++------------------ 20 files changed, 556 insertions(+), 407 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index 7bd89cbfb..eee1c9589 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -69,7 +69,7 @@ DEFINE_SPECIAL(Floor_RaiseInstant, 67, 3, 3, 3) DEFINE_SPECIAL(Floor_MoveToValueTimes8, 68, 4, 4, 4) DEFINE_SPECIAL(Ceiling_MoveToValueTimes8, 69, 4, 4, 4) DEFINE_SPECIAL(Teleport, 70, 1, 3, 3) -DEFINE_SPECIAL(Teleport_NoFog, 71, 1, 3, 3) +DEFINE_SPECIAL(Teleport_NoFog, 71, 1, 4, 4) DEFINE_SPECIAL(ThrustThing, 72, 2, 4, 4) DEFINE_SPECIAL(DamageThing, 73, 1, 2, 2) DEFINE_SPECIAL(Teleport_NewMap, 74, 2, 3, 3) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 5f93be98e..5ea9d6644 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1090,6 +1090,15 @@ static int PatchThing (int thingy) value[0] &= ~MF_TRANSLUCENT; // clean the slot vchanged[2] = true; value[2] |= 2; // let the TRANSLUCxx code below handle it } + if ((info->flags & MF_MISSILE) && (info->flags2 & MF2_NOTELEPORT) + && !(value[0] & MF_MISSILE)) + { + // ZDoom gives missiles flags that did not exist in Doom: MF2_NOTELEPORT, + // MF2_IMPACT, and MF2_PCROSS. The NOTELEPORT one can be a problem since + // some projectile actors (those new to Doom II) were not excluded from + // triggering line effects and can teleport when the missile flag is removed. + info->flags2 &= ~MF2_NOTELEPORT; + } info->flags = value[0]; } if (vchanged[1]) diff --git a/src/d_main.cpp b/src/d_main.cpp index 26095d93a..1b1d94a56 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -585,7 +585,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS; break; - case 6: // Boom with some added settings to reenable spme 'broken' behavior + case 6: // Boom with some added settings to reenable some 'broken' behavior v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ| COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS; break; diff --git a/src/p_effect.cpp b/src/p_effect.cpp index 5e6532001..48fb5ffa1 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -215,13 +215,15 @@ void P_InitEffects () P_InitParticles(); while (color->color) { - *(color->color) = ColorMatcher.Pick (color->r, color->g, color->b); + *(color->color) = (MAKERGB(color->r, color->g, color->b) + | (ColorMatcher.Pick (color->r, color->g, color->b) << 24)); color++; } int kind = gameinfo.defaultbloodparticlecolor; - blood1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind)); - blood2 = ColorMatcher.Pick(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3); + int kind3 = MAKERGB(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3); + blood1 = kind | (ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind)) << 24); + blood2 = kind3 | (ColorMatcher.Pick(RPART(kind3), GPART(kind3), BPART(kind3)) << 24); } @@ -520,8 +522,9 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i color2 = grey1; break; default: // colorized blood - color1 = ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind)); - color2 = ColorMatcher.Pick(RPART(kind)>>1, GPART(kind)>>1, BPART(kind)>>1); + color1 = kind | (ColorMatcher.Pick(RPART(kind), GPART(kind), BPART(kind)) << 24); + color2 = MAKERGB((kind)>>1, GPART(kind)>>1, BPART(kind)>>1) + | (ColorMatcher.Pick(RPART(kind)>>1, GPART(kind)>>1, BPART(kind)>>1) << 24); break; } @@ -598,7 +601,7 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end { // Only consider sound in 2D (for now, anyway) - // [BB] You have to devide by lengthsquared here, not multiply with it. + // [BB] You have to divide by lengthsquared here, not multiply with it. r = ((start.Y - FIXED2FLOAT(mo->y)) * (-dir.Y) - (start.X - FIXED2FLOAT(mo->x)) * (dir.X)) / lengthsquared; r = clamp(r, 0., 1.); @@ -646,7 +649,7 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end FVector3 spiral_step = step * r_rail_spiralsparsity; int spiral_steps = steps * r_rail_spiralsparsity; - color1 = color1 == 0 ? -1 : ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1)); + color1 = color1 == 0 ? -1 : color1 | (ColorMatcher.Pick(RPART(color1), GPART(color1), BPART(color1)) <<24); pos = start; deg = FAngle(270); for (i = spiral_steps; i; i--) @@ -699,7 +702,7 @@ void P_DrawRailTrail (AActor *source, const FVector3 &start, const FVector3 &end FVector3 trail_step = step * r_rail_trailsparsity; int trail_steps = steps * r_rail_trailsparsity; - color2 = color2 == 0 ? -1 : ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2)); + color2 = color2 == 0 ? -1 : color2 | (ColorMatcher.Pick(RPART(color2), GPART(color2), BPART(color2)) <<24); FVector3 diff(0, 0, 0); pos = start; diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 26bd4b1df..3ca7fc6d3 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1078,7 +1078,7 @@ static FString GetCachePath() FSRef folder; if (noErr == FSFindFolder(kLocalDomain, kApplicationSupportFolderType, kCreateFolder, &folder) && - noErr == FSRefMakePath(&folder, (UInt8*)path.GetChars(), PATH_MAX)) + noErr == FSRefMakePath(&folder, (UInt8*)pathstr, PATH_MAX)) { path = pathstr; } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 430f29bb7..8cbeec335 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -855,9 +855,9 @@ FUNC( LS_Teleport_NoStop ) } FUNC(LS_Teleport_NoFog) -// Teleport_NoFog (tid, useang, sectortag) +// Teleport_NoFog (tid, useang, sectortag, keepheight) { - return EV_Teleport (arg0, arg2, ln, backSide, it, false, false, !arg1); + return EV_Teleport (arg0, arg2, ln, backSide, it, false, false, !arg1, true, !!arg3); } FUNC(LS_Teleport_ZombieChanger) diff --git a/src/p_local.h b/src/p_local.h index 879a876ad..0b6474baa 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -383,7 +383,7 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm); bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y); AActor *P_CheckOnmobj (AActor *thing); void P_FakeZMovement (AActor *mo); -bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm); +bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false); bool P_TryMove (AActor* thing, fixed_t x, fixed_t y, int dropoff, const secplane_t * onfloor = NULL); bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y); void P_ApplyTorque(AActor *mo); diff --git a/src/p_map.cpp b/src/p_map.cpp index 35ab352ce..605f0bbc3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1646,7 +1646,8 @@ static void CheckForPushSpecial (line_t *line, int side, AActor *mobj) bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, int dropoff, // killough 3/15/98: allow dropoff as option const secplane_t *onfloor, // [RH] Let P_TryMove keep the thing on the floor - FCheckPosition &tm) + FCheckPosition &tm, + bool missileCheck) // [GZ] Fired missiles ignore the drop-off test { fixed_t oldx; fixed_t oldy; @@ -1777,7 +1778,7 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, if (dropoff==2 && // large jump down (e.g. dogs) (tm.floorz-tm.dropoffz > 128*FRACUNIT || thing->target == NULL || thing->target->z >tm.dropoffz)) { - dropoff = false; + dropoff = false; } @@ -1795,8 +1796,9 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y, } if (floorz - tm.dropoffz > thing->MaxDropOffHeight && - !(thing->flags2 & MF2_BLASTED)) + !(thing->flags2 & MF2_BLASTED) && !missileCheck) { // Can't move over a dropoff unless it's been blasted + // [GZ] Or missile-spawned thing->z = oldz; return false; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 559b2e477..7f8e9b3f9 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5017,7 +5017,7 @@ bool P_CheckMissileSpawn (AActor* th) bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF)); // killough 3/15/98: no dropoff (really = don't care for missiles) - if (!(P_TryMove (th, th->x, th->y, false, NULL, tm))) + if (!(P_TryMove (th, th->x, th->y, false, NULL, tm, true))) { // [RH] Don't explode ripping missiles that spawn inside something if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) diff --git a/src/p_spec.h b/src/p_spec.h index 547154c19..96bd4c8ee 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -876,8 +876,8 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag); // // P_TELEPT // -bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true); -bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation, bool haltVelocity = true); +bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false); +bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false); bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse); bool EV_TeleportOther (int other_tid, int dest_tid, bool fog); bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog); diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 12497590a..cc31358a8 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -99,7 +99,7 @@ void P_SpawnTeleportFog(fixed_t x, fixed_t y, fixed_t z, int spawnid) // bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, - bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity) + bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight) { fixed_t oldx; fixed_t oldy; @@ -127,7 +127,11 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, { // We don't measure z velocity, because it doesn't change. missilespeed = xs_CRoundToInt(TVector2(thing->velx, thing->vely).Length()); } - if (z == ONFLOORZ) + if (keepHeight) + { + z = floorheight + aboveFloor; + } + else if (z == ONFLOORZ) { if (player) { @@ -320,7 +324,7 @@ static AActor *SelectTeleDest (int tid, int tag) } bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, - bool sourceFog, bool keepOrientation, bool haltVelocity) + bool sourceFog, bool keepOrientation, bool haltVelocity, bool keepHeight) { AActor *searcher; fixed_t z; @@ -377,7 +381,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool { badangle = 1 << ANGLETOFINESHIFT; } - if (P_Teleport (thing, searcher->x, searcher->y, z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity)) + if (P_Teleport (thing, searcher->x, searcher->y, z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity, keepHeight)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (!fog && line && keepOrientation) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 8968db07c..e1e0f371a 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1452,6 +1452,8 @@ public: char *buffer = new char[map->Size(ML_TEXTMAP)]; isTranslated = true; + isExtended = false; + floordrop = false; map->Read(ML_TEXTMAP, buffer); sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), buffer, map->Size(ML_TEXTMAP)); @@ -1570,6 +1572,12 @@ public: } } + // Catch bogus maps here rather than during nodebuilding + if (ParsedVertices.Size() == 0) I_Error("Map has no vertices.\n"); + if (ParsedSectors.Size() == 0) I_Error("Map has no sectors. \n"); + if (ParsedLines.Size() == 0) I_Error("Map has no linedefs.\n"); + if (ParsedSides.Size() == 0) I_Error("Map has no sidedefs.\n"); + // Create the real vertices numvertexes = ParsedVertices.Size(); vertexes = new vertex_t[numvertexes]; diff --git a/src/r_things.cpp b/src/r_things.cpp index ec8ec89f1..a2d257563 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2112,7 +2112,7 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis->x1 = x1; vis->x2 = x2; vis->Translation = 0; - vis->startfrac = particle->color; + vis->startfrac = 255 & (particle->color >>24); vis->pic = NULL; vis->bIsVoxel = false; vis->renderflags = particle->trans; diff --git a/src/sdl/crashcatcher.c b/src/sdl/crashcatcher.c index 73fa4b036..863f97680 100644 --- a/src/sdl/crashcatcher.c +++ b/src/sdl/crashcatcher.c @@ -14,6 +14,8 @@ #ifndef PR_SET_PTRACER #define PR_SET_PTRACER 0x59616d61 #endif +#else if defined (__APPLE__) +#include #endif diff --git a/src/sdl/i_main.cpp b/src/sdl/i_main.cpp index 3b2de3c57..cda8d54e2 100644 --- a/src/sdl/i_main.cpp +++ b/src/sdl/i_main.cpp @@ -255,10 +255,12 @@ void I_ShutdownJoysticks(); int main (int argc, char **argv) { +#if !defined (__APPLE__) { int s[4] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS }; cc_install_handlers(argc, argv, 4, s, "zdoom-crash.log", DoomSpecificInfo); } +#endif // !__APPLE__ printf(GAMENAME" v%s - SVN revision %s - SDL version\nCompiled on %s\n", DOTVERSIONSTR_NOREV,SVN_REVISION_STRING,__DATE__); @@ -297,6 +299,26 @@ int main (int argc, char **argv) } SDL_WM_SetCaption (GAMESIG " " DOTVERSIONSTR " (" __DATE__ ")", NULL); + +#ifdef __APPLE__ + + const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); + if ( NULL != videoInfo ) + { + EXTERN_CVAR( Int, vid_defwidth ) + EXTERN_CVAR( Int, vid_defheight ) + EXTERN_CVAR( Int, vid_defbits ) + EXTERN_CVAR( Bool, vid_vsync ) + EXTERN_CVAR( Bool, fullscreen ) + + vid_defwidth = videoInfo->current_w; + vid_defheight = videoInfo->current_h; + vid_defbits = videoInfo->vfmt->BitsPerPixel; + vid_vsync = True; + fullscreen = True; + } + +#endif // __APPLE__ try { diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index bee304f4c..6c88a173b 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -39,6 +39,7 @@ #endif #ifdef __APPLE__ +#include #include #include #include @@ -393,9 +394,25 @@ void STACK_ARGS I_FatalError (const char *error, ...) int index; va_list argptr; va_start (argptr, error); - index = vsprintf (errortext, error, argptr); + index = vsnprintf (errortext, MAX_ERRORTEXT, error, argptr); va_end (argptr); +#ifdef __APPLE__ + // Close window or exit fullscreen and release mouse capture + SDL_Quit(); + + const CFStringRef errorString = CFStringCreateWithCStringNoCopy( kCFAllocatorDefault, + errortext, kCFStringEncodingASCII, kCFAllocatorNull ); + if ( NULL != errorString ) + { + CFOptionFlags dummy; + + CFUserNotificationDisplayAlert( 0, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, + CFSTR( "Error" ), errorString, CFSTR( "Exit" ), NULL, NULL, &dummy ); + CFRelease( errorString ); + } +#endif // __APPLE__ + // Record error to log (if logging) if (Logfile) { diff --git a/src/stats.cpp b/src/stats.cpp index dba058caa..76fe36c26 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -42,6 +42,15 @@ #include "m_swap.h" #include "sbar.h" + +#if defined (__APPLE__) + +mach_timebase_info_data_t cycle_t::s_info; +bool cycle_t::s_initialized; + +#endif // __APPLE__ + + FStat *FStat::FirstStat; FStat::FStat (const char *name) diff --git a/src/stats.h b/src/stats.h index 65eb73926..ed493188b 100644 --- a/src/stats.h +++ b/src/stats.h @@ -38,6 +38,77 @@ #ifndef _WIN32 +#if defined (__APPLE__) + + +#include + + +class cycle_t +{ +public: + cycle_t() + { + if ( !s_initialized ) + { + mach_timebase_info( &s_info ); + s_initialized = true; + } + + Reset(); + } + + cycle_t &operator=( const cycle_t &other ) + { + if ( &other != this ) + { + m_seconds = other.m_seconds; + + } + + return *this; + } + + void Reset() + { + m_seconds = 0; + } + + void Clock() + { + m_seconds -= Nanoseconds() * 1e-9; + } + + void Unclock() + { + m_seconds += Nanoseconds() * 1e-9; + } + + double Time() + { + return m_seconds; + } + + double TimeMS() + { + return m_seconds * 1e3; + } + +private: + double m_seconds; + + static mach_timebase_info_data_t s_info; + static bool s_initialized; + + uint64_t Nanoseconds() const + { + return mach_absolute_time() * s_info.numer / s_info.denom; + } + +}; + +#else // !__APPLE__ + #ifdef NO_CLOCK_GETTIME class cycle_t { @@ -100,6 +171,8 @@ private: #endif +#endif // __APPLE__ + #else // Windows diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index f9c9e0125..c5c7d7105 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -209,10 +209,10 @@ include "xlat/defines.i" 204 = USE, Ceiling_LowerToHighestFloor (tag, C_SLOW) 205 = USE|REP, Ceiling_LowerToLowest (tag, C_SLOW) 206 = USE|REP, Ceiling_LowerToHighestFloor (tag, C_SLOW) -207 = WALK|MONST, Teleport_NoFog (0, 0, tag) -208 = WALK|REP|MONST, Teleport_NoFog (0, 0, tag) -209 = USE|MONST, Teleport_NoFog (0, 0, tag) -210 = USE|REP|MONST, Teleport_NoFog (0, 0, tag) +207 = WALK|MONST, Teleport_NoFog (0, 0, tag, 1) +208 = WALK|REP|MONST, Teleport_NoFog (0, 0, tag, 1) +209 = USE|MONST, Teleport_NoFog (0, 0, tag, 1) +210 = USE|REP|MONST, Teleport_NoFog (0, 0, tag, 1) 211 = USE|REP, Plat_ToggleCeiling (tag) 212 = WALK|REP, Plat_ToggleCeiling (tag) 213 = 0, Transfer_FloorLight (tag) @@ -270,8 +270,8 @@ include "xlat/defines.i" 265 = MONWALK|REP, Teleport_Line (tag, tag, 1) 266 = MONWALK, Teleport_Line (tag, tag, 0) 267 = MONWALK|REP, Teleport_Line (tag, tag, 0) -268 = MONWALK, Teleport_NoFog (0, 0, tag) -269 = MONWALK|REP, Teleport_NoFog (0, 0, tag) +268 = MONWALK, Teleport_NoFog (0, 0, tag, 1) +269 = MONWALK|REP, Teleport_NoFog (0, 0, tag, 1) /****** MBF linetypes ******/ diff --git a/zdoom.vcproj b/zdoom.vcproj index 4601991fa..dff0e6cb2 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -1840,14 +1848,6 @@ Outputs="$(IntDir)/$(InputName).obj" /> - - - @@ -2037,14 +2037,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -2055,6 +2047,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + - - - @@ -2485,6 +2477,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -2783,7 +2783,7 @@ /> - - - + + + Date: Fri, 9 Dec 2011 00:59:38 +0000 Subject: [PATCH 055/993] - Fixed: levellump for drawstring should be all uppercase for consistency. SVN r3330 (trunk) --- src/g_shared/sbarinfo_commands.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 8b62359f9..2c44c09f3 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -695,6 +695,7 @@ class CommandDrawString : public SBarInfoCommand { cache = level.lumpnum; str = level.mapname; + str.ToUpper(); RealignString(); } break; From b1905c16ef5c93bb148453577f0de64e37283a85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 12 Dec 2011 16:07:32 +0000 Subject: [PATCH 056/993] - added UDMF LOcknumber property, submitted by Nightfall. SVN r3331 (trunk) --- src/am_map.cpp | 62 ++++++++++++++++++++++++++++---------------------- src/namedef.h | 13 ++++++----- src/p_spec.cpp | 27 ++++++++++++---------- src/p_udmf.cpp | 17 +++++++++----- src/r_defs.h | 13 ++++++----- 5 files changed, 75 insertions(+), 57 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index ec7e99859..d2046f33e 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1913,12 +1913,13 @@ bool AM_Check3DFloors(line_t *line) //============================================================================= void AM_drawWalls (bool allmap) -{ - int i; - static mline_t l; - - for (i = 0; i < numlines; i++) - { +{ + int i; + static mline_t l; + int lock, color; + + for (i = 0; i < numlines; i++) + { l.a.x = lines[i].v1->x >> FRACTOMAPBITS; l.a.y = lines[i].v1->y >> FRACTOMAPBITS; l.b.x = lines[i].v2->x >> FRACTOMAPBITS; @@ -1948,14 +1949,22 @@ void AM_drawWalls (bool allmap) else if (lines[i].flags & ML_SECRET) { // secret door if (am_cheat != 0 && lines[i].backsector != NULL) - AM_drawMline(&l, SecretWallColor); - else - AM_drawMline(&l, WallColor); - } - else if ((lines[i].special == Teleport || - lines[i].special == Teleport_NoFog || - lines[i].special == Teleport_ZombieChanger || - lines[i].special == Teleport_Line) && + AM_drawMline(&l, SecretWallColor); + else + AM_drawMline(&l, WallColor); + } else if (lines[i].locknumber > 0) { // [Dusk] specials w/ locknumbers + lock = lines[i].locknumber; + color = P_GetMapColorForLock(lock); + + AMColor c; + if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); + else c = LockedColor; + + AM_drawMline (&l, c); + } else if ((lines[i].special == Teleport || + lines[i].special == Teleport_NoFog || + lines[i].special == Teleport_ZombieChanger || + lines[i].special == Teleport_Line) && (lines[i].activation & SPAC_PlayerActivate) && am_colorset == 0) { // intra-level teleporters @@ -1975,19 +1984,18 @@ void AM_drawWalls (bool allmap) (lines[i].special == Door_Animated && lines[i].args[3] != 0) || (lines[i].special == Generic_Door && lines[i].args[4] != 0)) { - if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors - { - int P_GetMapColorForLock(int lock); - int lock; - - if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated) - lock=lines[i].args[3]; - else lock=lines[i].args[4]; - - int color = P_GetMapColorForLock(lock); - - AMColor c; - + if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors + { + int P_GetMapColorForLock(int lock); + + if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated) + lock=lines[i].args[3]; + else lock=lines[i].args[4]; + + color = P_GetMapColorForLock(lock); + + AMColor c; + if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); else c = LockedColor; diff --git a/src/namedef.h b/src/namedef.h index a98de3692..6cf7f322c 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -379,12 +379,13 @@ xx(Midtex3d) xx(Checkswitchrange) xx(Firstsideonly) xx(Transparent) -xx(Passuse) -xx(Repeatspecial) -xx(Conversation) - -xx(Playercross) -xx(Playeruse) +xx(Passuse) +xx(Repeatspecial) +xx(Conversation) +xx(Locknumber) + +xx(Playercross) +xx(Playeruse) xx(Playeruseback) xx(Monstercross) xx(Impact) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index a60751aa2..d0c28bc89 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -57,12 +57,13 @@ #include "gi.h" #include "statnums.h" #include "g_level.h" -#include "v_font.h" -#include "a_sharedglobal.h" -#include "farchive.h" - -// State. -#include "r_state.h" +#include "v_font.h" +#include "a_sharedglobal.h" +#include "farchive.h" +#include "a_keys.h" + +// State. +#include "r_state.h" #include "c_console.h" @@ -232,12 +233,14 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) BYTE special; if (!P_TestActivateLine (line, mo, side, activationType)) - { - return false; - } - lineActivation = line->activation; - repeat = line->flags & ML_REPEAT_SPECIAL; - buttonSuccess = false; + { + return false; + } + int remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); + if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; + lineActivation = line->activation; + repeat = line->flags & ML_REPEAT_SPECIAL; + buttonSuccess = false; buttonSuccess = P_ExecuteSpecial(line->special, line, mo, side == 1, line->args[0], line->args[1], line->args[2], diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index e1e0f371a..20ef4ffd2 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -877,12 +877,17 @@ public: Flag(ld->flags, ML_BLOCKUSE, key); continue; - case NAME_blocksight: - Flag(ld->flags, ML_BLOCKSIGHT, key); - continue; - - default: - break; + case NAME_blocksight: + Flag(ld->flags, ML_BLOCKSIGHT, key); + continue; + + // [Dusk] lock number + case NAME_Locknumber: + ld->locknumber = CheckInt(key); + continue; + + default: + break; } if (!strnicmp("user_", key.GetChars(), 5)) diff --git a/src/r_defs.h b/src/r_defs.h index 7af5eabde..03c2290c2 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -907,12 +907,13 @@ struct line_t side_t *sidedef[2]; //DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided fixed_t bbox[4]; // bounding box, for the extent of the LineDef. - slopetype_t slopetype; // To aid move clipping. - sector_t *frontsector, *backsector; - int validcount; // if == validcount, already checked -}; - -// phares 3/14/98 + slopetype_t slopetype; // To aid move clipping. + sector_t *frontsector, *backsector; + int validcount; // if == validcount, already checked + int locknumber; // [Dusk] lock number for special +}; + +// phares 3/14/98 // // Sector list node showing all sectors an object appears in. // From 7279e2ad62cf0294ba931489e9a1c6e91ea6d137 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 14 Dec 2011 00:16:19 +0000 Subject: [PATCH 057/993] - Fixed: Player pitch limits were reset to 0 when changing levels and loading saved games. SVN r3332 (trunk) --- src/d_player.h | 2 ++ src/g_level.cpp | 2 ++ src/p_saveg.cpp | 2 ++ src/p_user.cpp | 29 +++++++++++++++++++++++------ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 95604f0bd..abd463590 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -256,6 +256,7 @@ public: void SetLogNumber (int num); void SetLogText (const char *text); + void SendPitchLimits() const; APlayerPawn *mo; BYTE playerstate; @@ -283,6 +284,7 @@ public: bool centering; BYTE turnticks; + bool attackdown; bool usedown; DWORD oldbuttons; diff --git a/src/g_level.cpp b/src/g_level.cpp index d552a3140..97061852e 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -666,6 +666,7 @@ void G_DoCompleted (void) { + level_info_t *nextinfo = FindLevelInfo (nextlevel); wminfo.next = nextinfo->mapname; wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->pname, FTexture::TEX_MiscPatch)]; @@ -1148,6 +1149,7 @@ void G_FinishTravel () pawn->LinkToWorld (); pawn->AddToHash (); pawn->SetState(pawn->SpawnState); + pawn->player->SendPitchLimits(); for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 741887cab..785bacf9c 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -112,6 +112,8 @@ void P_SerializePlayers (FArchive &arc, bool skipload) { SpawnExtraPlayers (); } + // Redo pitch limits, since the spawned player has them at 0. + players[consoleplayer].SendPitchLimits(); } } diff --git a/src/p_user.cpp b/src/p_user.cpp index 236f4d319..49495c19f 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -408,6 +408,26 @@ int player_t::GetSpawnClass() return static_cast(GetDefaultByType(type))->SpawnMask; } +//=========================================================================== +// +// player_t :: SendPitchLimits +// +// Ask the local player's renderer what pitch restrictions should be imposed +// and let everybody know. Only sends data for the consoleplayer, since the +// local player is the only one our data is valid for. +// +//=========================================================================== + +void player_t::SendPitchLimits() const +{ + if (this - players == consoleplayer) + { + Net_WriteByte(DEM_SETPITCHLIMIT); + Net_WriteByte(Renderer->GetMaxViewPitch(false)); // up + Net_WriteByte(Renderer->GetMaxViewPitch(true)); // down + } +} + //=========================================================================== // // APlayerPawn @@ -522,13 +542,9 @@ void APlayerPawn::PostBeginPlay() P_FindFloorCeiling(this, true); z = floorz; } - else if (player - players == consoleplayer) + else { - // Ask the local player's renderer what pitch restrictions - // should be imposed and let everybody know. - Net_WriteByte(DEM_SETPITCHLIMIT); - Net_WriteByte(Renderer->GetMaxViewPitch(false)); // up - Net_WriteByte(Renderer->GetMaxViewPitch(true)); // down + player->SendPitchLimits(); } } @@ -2505,6 +2521,7 @@ void P_UnPredictPlayer () { player_t *player = &players[consoleplayer]; + if (player->cheats & CF_PREDICTING) { AActor *act = player->mo; From 8e636b8abf4af42cde98aa2bf607f947b2f59ca5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 14 Dec 2011 00:36:47 +0000 Subject: [PATCH 058/993] - Fixed: Must not try to draw null flats in the textured automap. SVN r3333 (trunk) --- src/am_map.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index d2046f33e..11ecf74af 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1728,15 +1728,19 @@ void AM_drawSubsectors() } // Draw the polygon. - screen->FillSimplePoly(TexMan(maptex), - &points[0], points.Size(), - originx, originy, - scale / (FIXED2FLOAT(sec->GetXScale(sector_t::floor)) * float(1 << MAPBITS)), - scale / (FIXED2FLOAT(sec->GetYScale(sector_t::floor)) * float(1 << MAPBITS)), - rotation, - colormap, - floorlight - ); + FTexture *pic = TexMan(maptex); + if (pic != NULL && pic->UseType != FTexture::TEX_Null) + { + screen->FillSimplePoly(TexMan(maptex), + &points[0], points.Size(), + originx, originy, + scale / (FIXED2FLOAT(sec->GetXScale(sector_t::floor)) * float(1 << MAPBITS)), + scale / (FIXED2FLOAT(sec->GetYScale(sector_t::floor)) * float(1 << MAPBITS)), + rotation, + colormap, + floorlight + ); + } } } From 038d3cc820c158c7ecffd9863c934c8dd937ab0f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 25 Dec 2011 22:45:12 +0000 Subject: [PATCH 059/993] - Initialize mSentAdvance to false. SVN r3334 (trunk) --- src/intermission/intermission.cpp | 39 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index cb533bda8..7e82ff65b 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -328,7 +328,7 @@ void DIntermissionScreenText::Drawer () size_t count; int c; const FRemapTable *range; - + // draw some of the text onto the screen int rowheight = SmallFont->GetHeight () + (gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1); bool scale = (CleanXfac != 1 || CleanYfac != 1); @@ -336,7 +336,7 @@ void DIntermissionScreenText::Drawer () int cx = mTextX; int cy = mTextY; const char *ch = mText; - + count = (mTicker - mTextDelay) / mTextSpeed; range = SmallFont->GetColorTranslation (mTextColor); @@ -392,7 +392,7 @@ void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) mName = static_cast(desc)->mName; mClass = PClass::FindClass(static_cast(desc)->mCastClass); if (mClass != NULL) mDefaults = GetDefaultByType(mClass); - else + else { mDefaults = NULL; caststate = NULL; @@ -489,7 +489,7 @@ int DIntermissionScreenCast::Ticker () if (--casttics > 0 && caststate != NULL) return 0; // not time to change state yet - + if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL || (caststate->GetNextState() == caststate && castdeath)) { @@ -506,7 +506,7 @@ int DIntermissionScreenCast::Ticker () PlayAttackSound(); castframes++; } - + if (castframes == 12 && !castdeath) { // go into attack frame @@ -533,7 +533,7 @@ int DIntermissionScreenCast::Ticker () } PlayAttackSound(); } - + if (castattacking) { if (castframes == 24 || caststate == mDefaults->SeeState ) @@ -544,7 +544,7 @@ int DIntermissionScreenCast::Ticker () caststate = mDefaults->SeeState; } } - + casttics = caststate->GetTics(); if (casttics == -1) casttics = 15; @@ -555,7 +555,7 @@ void DIntermissionScreenCast::Drawer () { spriteframe_t* sprframe; FTexture* pic; - + Super::Drawer(); const char *name = mName; @@ -568,13 +568,13 @@ void DIntermissionScreenCast::Drawer () name, DTA_CleanNoMove, true, TAG_DONE); } - + // draw the current frame in the middle of the screen if (caststate != NULL) { int castsprite; - if (!(mDefaults->flags4 & MF4_NOSKIN) && + if (!(mDefaults->flags4 & MF4_NOSKIN) && mDefaults->SpawnState != NULL && caststate->sprite == mDefaults->SpawnState->sprite && mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)) && skins != NULL) @@ -695,6 +695,7 @@ DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, mDeleteDesc = DeleteDesc; mIndex = 0; mAdvance = false; + mSentAdvance = false; mScreen = NULL; mFirst = true; mGameState = state; @@ -712,7 +713,7 @@ bool DIntermissionController::NextPage () return false; } - if (mScreen != NULL) + if (mScreen != NULL) { bg = mScreen->GetBackground(&fill); mScreen->Destroy(); @@ -765,7 +766,7 @@ bool DIntermissionController::Responder (event_t *ev) const char *cmd = Bindings.GetBind (ev->data1); if (cmd != NULL && !stricmp (cmd, "toggleconsole")) - return false; + return false; } if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing @@ -883,11 +884,11 @@ void F_StartIntermission(FName seq, BYTE state) // //========================================================================== -bool F_Responder (event_t* ev) -{ +bool F_Responder (event_t* ev) +{ if (DIntermissionController::CurrentIntermission != NULL) { - return DIntermissionController::CurrentIntermission->Responder(ev); + return DIntermissionController::CurrentIntermission->Responder(ev); } return false; } @@ -898,11 +899,11 @@ bool F_Responder (event_t* ev) // //========================================================================== -void F_Ticker () +void F_Ticker () { if (DIntermissionController::CurrentIntermission != NULL) { - DIntermissionController::CurrentIntermission->Ticker(); + DIntermissionController::CurrentIntermission->Ticker(); } } @@ -916,7 +917,7 @@ void F_Drawer () { if (DIntermissionController::CurrentIntermission != NULL) { - DIntermissionController::CurrentIntermission->Drawer(); + DIntermissionController::CurrentIntermission->Drawer(); } } @@ -931,7 +932,7 @@ void F_EndFinale () { if (DIntermissionController::CurrentIntermission != NULL) { - DIntermissionController::CurrentIntermission->Destroy(); + DIntermissionController::CurrentIntermission->Destroy(); DIntermissionController::CurrentIntermission = NULL; } } From 243197bfd4cee3296f162e9b2b3ed5ee2c0b93f7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jan 2012 23:16:35 +0000 Subject: [PATCH 060/993] - Fixed: Setting an actor's score with ACS also modified its nametag. SVN r3335 (trunk) --- src/p_acs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 467bc4e32..a1354e51e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -2771,6 +2771,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) case APROP_Score: actor->Score = value; + break; case APROP_NameTag: actor->SetTag(FBehavior::StaticLookupString(value)); From 83fc6cf53aeb5d2fc9d8de66283a4cb1606737f5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jan 2012 23:47:13 +0000 Subject: [PATCH 061/993] - Fixed: Hexen's ACS implementation truncates all line specials to bytes, so we need to do the same for maps defined with Hexen-style MAPINFOs. SVN r3336 (trunk) --- src/p_acs.cpp | 53 +++++++++++++++++++++++++++++++++++++------------- src/p_spec.cpp | 30 ++++++++++++++-------------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index a1354e51e..639f70313 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3676,6 +3676,9 @@ int DLevelScript::RunScript () FRemapTable *translation = 0; int resultValue = 1; + // Hexen truncates all special arguments to bytes. + const int specialargmask = (level.flags2 & LEVEL2_HEXENHACK) ? 255 : ~0; + switch (state) { case SCRIPT_Delayed: @@ -3845,78 +3848,100 @@ int DLevelScript::RunScript () case PCD_LSPEC1: P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(1), 0, 0, 0, 0); + STACK(1) & specialargmask, 0, 0, 0, 0); sp -= 1; break; case PCD_LSPEC2: P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(2), STACK(1), 0, 0, 0); + STACK(2) & specialargmask, + STACK(1) & specialargmask, 0, 0, 0); sp -= 2; break; case PCD_LSPEC3: P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(3), STACK(2), STACK(1), 0, 0); + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask, 0, 0); sp -= 3; break; case PCD_LSPEC4: P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(4), STACK(3), STACK(2), - STACK(1), 0); + STACK(4) & specialargmask, + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask, 0); sp -= 4; break; case PCD_LSPEC5: P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(5), STACK(4), STACK(3), - STACK(2), STACK(1)); + STACK(5) & specialargmask, + STACK(4) & specialargmask, + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask); sp -= 5; break; case PCD_LSPEC5RESULT: STACK(5) = P_ExecuteSpecial(NEXTBYTE, activationline, activator, backSide, - STACK(5), STACK(4), STACK(3), - STACK(2), STACK(1)); + STACK(5) & specialargmask, + STACK(4) & specialargmask, + STACK(3) & specialargmask, + STACK(2) & specialargmask, + STACK(1) & specialargmask); sp -= 4; break; case PCD_LSPEC1DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, - uallong(pc[0]), 0, 0, 0, 0); + uallong(pc[0]) & specialargmask ,0, 0, 0, 0); pc += 1; break; case PCD_LSPEC2DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, - uallong(pc[0]), uallong(pc[1]), 0, 0, 0); + uallong(pc[0]) & specialargmask, + uallong(pc[1]) & specialargmask, 0, 0, 0); pc += 2; break; case PCD_LSPEC3DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, - uallong(pc[0]), uallong(pc[1]), uallong(pc[2]), 0, 0); + uallong(pc[0]) & specialargmask, + uallong(pc[1]) & specialargmask, + uallong(pc[2]) & specialargmask, 0, 0); pc += 3; break; case PCD_LSPEC4DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, - uallong(pc[0]), uallong(pc[1]), uallong(pc[2]), uallong(pc[3]), 0); + uallong(pc[0]) & specialargmask, + uallong(pc[1]) & specialargmask, + uallong(pc[2]) & specialargmask, + uallong(pc[3]) & specialargmask, 0); pc += 4; break; case PCD_LSPEC5DIRECT: temp = NEXTBYTE; P_ExecuteSpecial(temp, activationline, activator, backSide, - uallong(pc[0]), uallong(pc[1]), uallong(pc[2]), uallong(pc[3]), uallong(pc[4])); + uallong(pc[0]) & specialargmask, + uallong(pc[1]) & specialargmask, + uallong(pc[2]) & specialargmask, + uallong(pc[3]) & specialargmask, + uallong(pc[4]) & specialargmask); pc += 5; break; + // Parameters for PCD_LSPEC?DIRECTB are by definition bytes so never need and-ing. case PCD_LSPEC1DIRECTB: P_ExecuteSpecial(((BYTE *)pc)[0], activationline, activator, backSide, ((BYTE *)pc)[1], 0, 0, 0, 0); diff --git a/src/p_spec.cpp b/src/p_spec.cpp index d0c28bc89..e763719d2 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -57,13 +57,13 @@ #include "gi.h" #include "statnums.h" #include "g_level.h" -#include "v_font.h" -#include "a_sharedglobal.h" -#include "farchive.h" -#include "a_keys.h" - -// State. -#include "r_state.h" +#include "v_font.h" +#include "a_sharedglobal.h" +#include "farchive.h" +#include "a_keys.h" + +// State. +#include "r_state.h" #include "c_console.h" @@ -233,14 +233,14 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) BYTE special; if (!P_TestActivateLine (line, mo, side, activationType)) - { - return false; - } - int remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); - if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; - lineActivation = line->activation; - repeat = line->flags & ML_REPEAT_SPECIAL; - buttonSuccess = false; + { + return false; + } + int remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); + if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; + lineActivation = line->activation; + repeat = line->flags & ML_REPEAT_SPECIAL; + buttonSuccess = false; buttonSuccess = P_ExecuteSpecial(line->special, line, mo, side == 1, line->args[0], line->args[1], line->args[2], From a408a913bc48d3cd8f2f0d35875b2945a17f7975 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jan 2012 23:48:46 +0000 Subject: [PATCH 062/993] - Added missing newline characters to [BSP rebuilding] messages in p_glnodes.cpp. SVN r3337 (trunk) --- src/p_glnodes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 3ca7fc6d3..7203b775a 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -208,7 +208,7 @@ bool P_CheckForGLNodes() int missing = CheckForMissingSegs(); if (missing > 0) { - Printf("%d missing segs counted\nThe BSP needs to be rebuilt", missing); + Printf("%d missing segs counted\nThe BSP needs to be rebuilt.\n", missing); } return missing == 0; } @@ -718,7 +718,7 @@ static bool DoLoadGLNodes(FileReader * f, wadlump_t * lumps) int missing = CheckForMissingSegs(); if (missing > 0) { - Printf("%d missing segs counted in GL nodes.\nThe BSP has to be rebuilt", missing); + Printf("%d missing segs counted in GL nodes.\nThe BSP has to be rebuilt.\n", missing); } return missing == 0; } From 1bdbfb360e1fb950549c094d40c0510187ece576 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 21 Jan 2012 23:51:24 +0000 Subject: [PATCH 063/993] - Remove an int->bool conversion warning. SVN r3338 (trunk) --- src/p_spec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index e763719d2..5a863eb6b 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -236,7 +236,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType) { return false; } - int remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); + bool remote = (line->special != 7 && line->special != 8 && (line->special < 11 || line->special > 14)); if (line->locknumber > 0 && !P_CheckKeys (mo, line->locknumber, remote)) return false; lineActivation = line->activation; repeat = line->flags & ML_REPEAT_SPECIAL; From 2faf92858a0061fa05aa85d8caaee4855194bc61 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jan 2012 00:14:02 +0000 Subject: [PATCH 064/993] - Fixed: LIGHT2SHADE would overflow with light values larger than 10 bits. SVN r3339 (trunk) --- src/r_defs.h | 14 +++++++------- src/r_main.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 03c2290c2..849b8db16 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -907,13 +907,13 @@ struct line_t side_t *sidedef[2]; //DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided fixed_t bbox[4]; // bounding box, for the extent of the LineDef. - slopetype_t slopetype; // To aid move clipping. - sector_t *frontsector, *backsector; - int validcount; // if == validcount, already checked - int locknumber; // [Dusk] lock number for special -}; - -// phares 3/14/98 + slopetype_t slopetype; // To aid move clipping. + sector_t *frontsector, *backsector; + int validcount; // if == validcount, already checked + int locknumber; // [Dusk] lock number for special +}; + +// phares 3/14/98 // // Sector list node showing all sectors an object appears in. // diff --git a/src/r_main.h b/src/r_main.h index 776d1b162..0126d3906 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -74,7 +74,7 @@ extern bool r_dontmaplines; // Convert a light level into an unbounded colormap index (shade). Result is // fixed point. Why the +12? I wish I knew, but experimentation indicates it // is necessary in order to best reproduce Doom's original lighting. -#define LIGHT2SHADE(l) ((NUMCOLORMAPS*2*FRACUNIT)-(((l)+12)*FRACUNIT*NUMCOLORMAPS/128)) +#define LIGHT2SHADE(l) ((NUMCOLORMAPS*2*FRACUNIT)-(((l)+12)*(FRACUNIT*NUMCOLORMAPS/128))) // MAXLIGHTSCALE from original DOOM, divided by 2. #define MAXLIGHTVIS (24*FRACUNIT) From 00d3e1975fc4994bbd4532a43860cba86409a241 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jan 2012 00:18:13 +0000 Subject: [PATCH 065/993] - Play "misc/secret" as a UI sound. SVN r3340 (trunk) --- src/p_spec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 5a863eb6b..5b9c40b6e 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -603,7 +603,7 @@ void P_GiveSecret(AActor *actor, bool printmessage, bool playsound) if (actor->CheckLocalView (consoleplayer)) { if (printmessage) C_MidPrint (SmallFont, secretmessage); - if (playsound) S_Sound (CHAN_AUTO, "misc/secret", 1, ATTN_NORM); + if (playsound) S_Sound (CHAN_AUTO | CHAN_UI, "misc/secret", 1, ATTN_NORM); } } level.found_secrets++; From d9713669f1d9d62717bc99c8a02137039105b8ca Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jan 2012 00:31:42 +0000 Subject: [PATCH 066/993] - Fixed: Totally freezing a player did not ignore crouch toggling. SVN r3341 (trunk) --- src/d_net.cpp | 5 +++-- src/d_player.h | 2 ++ src/p_user.cpp | 11 ++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 3ee20b8b6..0af22bf7b 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2353,9 +2353,10 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_CROUCH: if (gamestate == GS_LEVEL && players[player].mo != NULL && - players[player].health > 0 && !(players[player].oldbuttons & BT_JUMP)) + players[player].health > 0 && !(players[player].oldbuttons & BT_JUMP) && + !P_IsPlayerTotallyFrozen(&players[player])) { - players[player].crouching = players[player].crouchdir<0? 1 : -1; + players[player].crouching = players[player].crouchdir < 0 ? 1 : -1; } break; diff --git a/src/d_player.h b/src/d_player.h index abd463590..2b9c7b2f2 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -426,6 +426,8 @@ void P_CheckPlayerSprites(); #define CROUCHSPEED (FRACUNIT/12) +bool P_IsPlayerTotallyFrozen(const player_t *player); + // [GRB] Custom player classes enum { diff --git a/src/p_user.cpp b/src/p_user.cpp index 49495c19f..28250f9dd 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2126,9 +2126,7 @@ void P_PlayerThink (player_t *player) player->mo->flags &= ~MF_JUSTATTACKED; } - bool totallyfrozen = (player->cheats & CF_TOTALLYFROZEN || gamestate == GS_TITLELEVEL || - (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE ))) - ); + bool totallyfrozen = P_IsPlayerTotallyFrozen(player); // [RH] Being totally frozen zeros out most input parameters. if (totallyfrozen) @@ -2723,3 +2721,10 @@ void P_EnumPlayerColorSets(FName classname, TArray *out) } } +bool P_IsPlayerTotallyFrozen(const player_t *player) +{ + return + gamestate == GS_TITLELEVEL || + player->cheats & CF_TOTALLYFROZEN || + ((level.flags2 & LEVEL2_FROZEN) && !(player->cheats & CF_TIMEFREEZE)); +} From f28393263b0689160cdbb8b041c8406ce2af4266 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 22 Jan 2012 22:55:20 +0000 Subject: [PATCH 067/993] - Improve tag support for xlat: Any combination of arguments can now be tags, and you can add (or subtract) a constant to them. If you do wish to add a constant, tag must come first. e.g. tag+3 is good, but 3+tag will not work. (As a bonus, the parser is simpler, too.) SVN r3342 (trunk) --- src/p_xlat.cpp | 36 ++---- src/xlat/parse_xlat.cpp | 7 ++ src/xlat/xlat.h | 10 +- src/xlat/xlat_parser.y | 265 ++++++++-------------------------------- 4 files changed, 72 insertions(+), 246 deletions(-) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index e61dcd52f..7824adf2c 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -118,11 +118,6 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) if (linetrans != NULL && linetrans->special != 0) { ld->special = linetrans->special; - ld->args[0] = linetrans->args[0]; - ld->args[1] = linetrans->args[1]; - ld->args[2] = linetrans->args[2]; - ld->args[3] = linetrans->args[3]; - ld->args[4] = linetrans->args[4]; ld->flags = flags | ((linetrans->flags & 0x1f) << 9); if (linetrans->flags & 0x20) ld->flags |= ML_FIRSTSIDEONLY; @@ -134,30 +129,17 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) { ld->activation = SPAC_UseThrough; } - switch (linetrans->flags & LINETRANS_TAGMASK) + // Set special arguments. + for (int t = 0; t < LINETRANS_MAXARGS; ++t) { - case LINETRANS_HAS2TAGS: // First two arguments are tags - ld->args[1] = tag; - case LINETRANS_HASTAGAT1: // First argument is a tag - ld->args[0] = tag; - break; - - case LINETRANS_HASTAGAT2: // Second argument is a tag - ld->args[1] = tag; - break; - - case LINETRANS_HASTAGAT3: // Third argument is a tag - ld->args[2] = tag; - break; - - case LINETRANS_HASTAGAT4: // Fourth argument is a tag - ld->args[3] = tag; - break; - - case LINETRANS_HASTAGAT5: // Fifth argument is a tag - ld->args[4] = tag; - break; + ld->args[t] = linetrans->args[t]; + // Arguments that are tags have the tag's value added to them. + if (linetrans->flags & (1 << (LINETRANS_TAGSHIFT+t))) + { + ld->args[t] += tag; + } } + if ((ld->flags & ML_SECRET) && ld->activation & (SPAC_Use|SPAC_UseThrough)) { ld->flags &= ~ML_MONSTERSCANACTIVATE; diff --git a/src/xlat/parse_xlat.cpp b/src/xlat/parse_xlat.cpp index 5edcde581..e5d277265 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/xlat/parse_xlat.cpp @@ -67,9 +67,16 @@ FLineFlagTrans LineFlagTranslations[16]; struct SpecialArgs { int addflags; + int argcount; int args[5]; }; +struct SpecialArg +{ + int arg; + bool bIsTag; +}; + struct ListFilter { WORD filter; diff --git a/src/xlat/xlat.h b/src/xlat/xlat.h index 018a2639e..0d020e75e 100644 --- a/src/xlat/xlat.h +++ b/src/xlat/xlat.h @@ -6,14 +6,8 @@ enum { - LINETRANS_HASTAGAT1 = (1<<6), // (tag, x, x, x, x) - LINETRANS_HASTAGAT2 = (2<<6), // (x, tag, x, x, x) - LINETRANS_HASTAGAT3 = (3<<6), // (x, x, tag, x, x) - LINETRANS_HASTAGAT4 = (4<<6), // (x, x, x, tag, x) - LINETRANS_HASTAGAT5 = (5<<6), // (x, x, x, x, tag) - - LINETRANS_HAS2TAGS = (7<<6), // (tag, tag, x, x, x) - LINETRANS_TAGMASK = (7<<6) + LINETRANS_TAGSHIFT = 24, + LINETRANS_MAXARGS = 5 }; struct FLineTrans diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index d6f71b6a3..046a950c9 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -99,228 +99,71 @@ linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. Printf ("%s, line %d: %s is undefined\n", context->SourceFile, context->SourceLine, S.sym); } +%type special_arg {SpecialArg} + +special_arg(Z) ::= exp(A). +{ + Z.arg = A; + Z.bIsTag = false; +} +special_arg(Z) ::= TAG. +{ + Z.arg = 0; + Z.bIsTag = true; +} +special_arg(Z) ::= TAG PLUS exp(A). +{ + Z.arg = A; + Z.bIsTag = true; +} +special_arg(Z) ::= TAG MINUS exp(A). +{ + Z.arg = -A; + Z.bIsTag = true; +} + +%type multi_special_arg {SpecialArgs} + +multi_special_arg(Z) ::= special_arg(A). +{ + Z.addflags = A.bIsTag << LINETRANS_TAGSHIFT; + Z.argcount = 1; + Z.args[0] = A.arg; + Z.args[1] = 0; + Z.args[2] = 0; + Z.args[3] = 0; + Z.args[4] = 0; +} +multi_special_arg(Z) ::= multi_special_arg(A) COMMA special_arg(B). +{ + Z = A; + if (Z.argcount < LINETRANS_MAXARGS) + { + Z.addflags |= B.bIsTag << (LINETRANS_TAGSHIFT + Z.argcount); + Z.args[Z.argcount] = B.arg; + Z.argcount++; + } + else if (Z.argcount++ == LINETRANS_MAXARGS) + { + context->PrintError("Line special has too many arguments\n"); + } +} + %type special_args {SpecialArgs} special_args(Z) ::= . /* empty */ { Z.addflags = 0; + Z.argcount = 0; Z.args[0] = 0; Z.args[1] = 0; Z.args[2] = 0; Z.args[3] = 0; Z.args[4] = 0; } -special_args(Z) ::= TAG. +special_args(Z) ::= multi_special_arg(A). { - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT1; - Z.args[0] = 0; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= TAG COMMA TAG. -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= TAG COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HAS2TAGS; - Z.args[0] = Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = 0; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA TAG COMMA exp(C) COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT2; - Z.args[0] = A; - Z.args[1] = 0; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D). -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = D; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA TAG COMMA exp(D) COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT3; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = 0; - Z.args[3] = D; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT4; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = 0; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA TAG COMMA exp(E). -{ - Z.addflags = LINETRANS_HASTAGAT4; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = 0; - Z.args[4] = E; -} -special_args(Z) ::= exp(A) COMMA exp(B) COMMA exp(C) COMMA exp(D) COMMA TAG. -{ - Z.addflags = LINETRANS_HASTAGAT5; - Z.args[0] = A; - Z.args[1] = B; - Z.args[2] = C; - Z.args[3] = D; - Z.args[4] = 0; + Z = A; } //========================================================================== @@ -463,7 +306,7 @@ list_val(A) ::= exp(B) COLON exp(C). maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON. { // Just kill all specials higher than the max. - // If the translator wants to redefine some later, just let it.s + // If the translator wants to redefine some later, just let it. SimpleLineTranslations.Resize(mx+1); } From b21062c39aee9f3c1d06cef6de941820a630083e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 23 Jan 2012 00:24:42 +0000 Subject: [PATCH 068/993] - Added more tag operators for xlat: * / & | ^ SVN r3343 (trunk) --- src/p_xlat.cpp | 13 +++++++++--- src/xlat/parse_xlat.cpp | 2 +- src/xlat/xlat.h | 18 ++++++++++++++-- src/xlat/xlat_parser.y | 46 ++++++++++++++++++++++++++++++++++------- 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 7824adf2c..28792ff7a 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -133,10 +133,17 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) for (int t = 0; t < LINETRANS_MAXARGS; ++t) { ld->args[t] = linetrans->args[t]; - // Arguments that are tags have the tag's value added to them. - if (linetrans->flags & (1 << (LINETRANS_TAGSHIFT+t))) + // Apply tag modifications, if needed. + int tagop = (linetrans->flags >> (LINETRANS_TAGSHIFT + t*TAGOP_NUMBITS)) & TAGOP_MASK; + switch (tagop) { - ld->args[t] += tag; + case TAGOP_None: default: break; + case TAGOP_Add: ld->args[t] += tag; break; + case TAGOP_Mul: ld->args[t] *= tag; break; + case TAGOP_Div: ld->args[t] /= tag; break; + case TAGOP_And: ld->args[t] &= tag; break; + case TAGOP_Or: ld->args[t] |= tag; break; + case TAGOP_Xor: ld->args[t] ^= tag; break; } } diff --git a/src/xlat/parse_xlat.cpp b/src/xlat/parse_xlat.cpp index e5d277265..17cd42d21 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/xlat/parse_xlat.cpp @@ -74,7 +74,7 @@ struct SpecialArgs struct SpecialArg { int arg; - bool bIsTag; + ELineTransTagOp tagop; }; struct ListFilter diff --git a/src/xlat/xlat.h b/src/xlat/xlat.h index 0d020e75e..0653d4ab6 100644 --- a/src/xlat/xlat.h +++ b/src/xlat/xlat.h @@ -4,10 +4,24 @@ #include "doomtype.h" #include "tarray.h" +enum ELineTransTagOp +{ + TAGOP_None, + TAGOP_Add, + TAGOP_Mul, + TAGOP_Div, + TAGOP_And, + TAGOP_Or, + TAGOP_Xor, + + TAGOP_NUMBITS = 3, + TAGOP_MASK = (1 << TAGOP_NUMBITS) - 1 +}; + enum { - LINETRANS_TAGSHIFT = 24, - LINETRANS_MAXARGS = 5 + LINETRANS_MAXARGS = 5, + LINETRANS_TAGSHIFT = 30 - LINETRANS_MAXARGS * TAGOP_NUMBITS, }; struct FLineTrans diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index 046a950c9..1f14409c4 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -27,7 +27,7 @@ external_declaration ::= NOP. %left XOR. %left AND. %left MINUS PLUS. -%left MULTIPLY DIVIDE. +%left MULTIPLY DIVIDE MODULUS. %left NEG. %type exp {int} @@ -35,7 +35,7 @@ exp(A) ::= NUM(B). { A = B.val; } exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } -exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by Zero"); } +exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } exp(A) ::= exp(B) OR exp(C). { A = B | C; } exp(A) ::= exp(B) AND exp(C). { A = B & C; } exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } @@ -104,29 +104,59 @@ linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. special_arg(Z) ::= exp(A). { Z.arg = A; - Z.bIsTag = false; + Z.tagop = TAGOP_None; } special_arg(Z) ::= TAG. { Z.arg = 0; - Z.bIsTag = true; + Z.tagop = TAGOP_Add; } special_arg(Z) ::= TAG PLUS exp(A). { Z.arg = A; - Z.bIsTag = true; + Z.tagop = TAGOP_Add; } special_arg(Z) ::= TAG MINUS exp(A). { Z.arg = -A; - Z.bIsTag = true; + Z.tagop = TAGOP_Add; } +special_arg(Z) ::= TAG MULTIPLY exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_Mul; +} +special_arg(Z) ::= TAG DIVIDE exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_Div; + if (A == 0) + { + context->PrintError("Division by zero"); + } +} +special_arg(Z) ::= TAG OR exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_Or; +} +special_arg(Z) ::= TAG AND exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_And; +} +special_arg(Z) ::= TAG XOR exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_Xor; +} + %type multi_special_arg {SpecialArgs} multi_special_arg(Z) ::= special_arg(A). { - Z.addflags = A.bIsTag << LINETRANS_TAGSHIFT; + Z.addflags = A.tagop << LINETRANS_TAGSHIFT; Z.argcount = 1; Z.args[0] = A.arg; Z.args[1] = 0; @@ -139,7 +169,7 @@ multi_special_arg(Z) ::= multi_special_arg(A) COMMA special_arg(B). Z = A; if (Z.argcount < LINETRANS_MAXARGS) { - Z.addflags |= B.bIsTag << (LINETRANS_TAGSHIFT + Z.argcount); + Z.addflags |= B.tagop << (LINETRANS_TAGSHIFT + Z.argcount * TAGOP_NUMBITS); Z.args[Z.argcount] = B.arg; Z.argcount++; } From 4b2ae689ed8a6e7597382c87f817f95d556a54c2 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 23 Jan 2012 02:47:51 +0000 Subject: [PATCH 069/993] - Added modulus to FParseContext/xlat. - Fixed: Division of tag arguments for xlat was in the wrong order. SVN r3344 (trunk) --- src/p_xlat.cpp | 15 ++++++++------- src/parsecontext.cpp | 1 + src/parsecontext.h | 2 ++ src/xlat/xlat.h | 1 + src/xlat/xlat_parser.y | 10 ++++++++++ 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 28792ff7a..07828ac50 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -137,13 +137,14 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) int tagop = (linetrans->flags >> (LINETRANS_TAGSHIFT + t*TAGOP_NUMBITS)) & TAGOP_MASK; switch (tagop) { - case TAGOP_None: default: break; - case TAGOP_Add: ld->args[t] += tag; break; - case TAGOP_Mul: ld->args[t] *= tag; break; - case TAGOP_Div: ld->args[t] /= tag; break; - case TAGOP_And: ld->args[t] &= tag; break; - case TAGOP_Or: ld->args[t] |= tag; break; - case TAGOP_Xor: ld->args[t] ^= tag; break; + case TAGOP_None: default: break; + case TAGOP_Add: ld->args[t] += tag; break; + case TAGOP_Mul: ld->args[t] *= tag; break; + case TAGOP_Div: ld->args[t] = tag / ld->args[t]; break; + case TAGOP_Mod: ld->args[t] = tag % ld->args[t]; break; + case TAGOP_And: ld->args[t] &= tag; break; + case TAGOP_Or: ld->args[t] |= tag; break; + case TAGOP_Xor: ld->args[t] ^= tag; break; } } diff --git a/src/parsecontext.cpp b/src/parsecontext.cpp index 5b764d954..6fa36b2a8 100644 --- a/src/parsecontext.cpp +++ b/src/parsecontext.cpp @@ -267,6 +267,7 @@ loop: case '-': return TokenTrans[MINUS]; case '+': return TokenTrans[PLUS]; case '*': return TokenTrans[MULTIPLY]; + case '%': return TokenTrans[MODULUS]; case '(': return TokenTrans[LPAREN]; case ')': return TokenTrans[RPAREN]; case ',': return TokenTrans[COMMA]; diff --git a/src/parsecontext.h b/src/parsecontext.h index 020fc7e03..bafeaa888 100644 --- a/src/parsecontext.h +++ b/src/parsecontext.h @@ -47,6 +47,7 @@ enum PLUS , MULTIPLY , DIVIDE , + MODULUS , NUM , FLOATVAL , LPAREN , @@ -78,6 +79,7 @@ enum prefix##PLUS, \ prefix##MULTIPLY, \ prefix##DIVIDE, \ + prefix##MODULUS, \ prefix##NUM, \ prefix##FLOATVAL, \ prefix##LPAREN, \ diff --git a/src/xlat/xlat.h b/src/xlat/xlat.h index 0653d4ab6..765b9fd78 100644 --- a/src/xlat/xlat.h +++ b/src/xlat/xlat.h @@ -10,6 +10,7 @@ enum ELineTransTagOp TAGOP_Add, TAGOP_Mul, TAGOP_Div, + TAGOP_Mod, TAGOP_And, TAGOP_Or, TAGOP_Xor, diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index 1f14409c4..0fc702f74 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -36,6 +36,7 @@ exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } exp(A) ::= exp(B) DIVIDE exp(C). { if (C != 0) A = B / C; else context->PrintError("Division by zero"); } +exp(A) ::= exp(B) MODULUS exp(C). { if (C != 0) A = B % C; else context->PrintError("Division by zero"); } exp(A) ::= exp(B) OR exp(C). { A = B | C; } exp(A) ::= exp(B) AND exp(C). { A = B & C; } exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } @@ -135,6 +136,15 @@ special_arg(Z) ::= TAG DIVIDE exp(A). context->PrintError("Division by zero"); } } +special_arg(Z) ::= TAG MODULUS exp(A). +{ + Z.arg = A; + Z.tagop = TAGOP_Mod; + if (A == 0) + { + context->PrintError("Division by zero"); + } +} special_arg(Z) ::= TAG OR exp(A). { Z.arg = A; From ef88515ddadc74f3fb395d2a945ca724bf0b8afe Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 23 Jan 2012 04:18:37 +0000 Subject: [PATCH 070/993] =?UTF-8?q?-=20Remove=20all=20restrictions=20on=20?= =?UTF-8?q?what=20you=20can=20do=20with=20tags=20as=20line=20special=20arg?= =?UTF-8?q?uments=20in=20xlat.=20=20=20Something=20like=20=E3=80=8C(tag=20?= =?UTF-8?q?&=205)=20+=20(tag=20&=202)=20/=202=E3=80=8D=20is=20now=20a=20va?= =?UTF-8?q?lid=20argument=20for=20a=20standard=20line=20=20=20translation.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SVN r3345 (trunk) --- src/p_xlat.cpp | 165 +++++++++++++++++++++++++++++++++++++--- src/xlat/parse_xlat.cpp | 7 +- src/xlat/xlat.h | 41 +++++++--- src/xlat/xlat_parser.y | 121 ++++++++++++++--------------- 4 files changed, 251 insertions(+), 83 deletions(-) diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index 07828ac50..6023b1892 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -130,21 +130,33 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld) ld->activation = SPAC_UseThrough; } // Set special arguments. + FXlatExprState state; + state.tag = tag; + state.linetype = special; for (int t = 0; t < LINETRANS_MAXARGS; ++t) { - ld->args[t] = linetrans->args[t]; - // Apply tag modifications, if needed. - int tagop = (linetrans->flags >> (LINETRANS_TAGSHIFT + t*TAGOP_NUMBITS)) & TAGOP_MASK; - switch (tagop) + int arg = linetrans->args[t]; + int argop = (linetrans->flags >> (LINETRANS_TAGSHIFT + t*TAGOP_NUMBITS)) & TAGOP_MASK; + + switch (argop) { - case TAGOP_None: default: break; - case TAGOP_Add: ld->args[t] += tag; break; - case TAGOP_Mul: ld->args[t] *= tag; break; - case TAGOP_Div: ld->args[t] = tag / ld->args[t]; break; - case TAGOP_Mod: ld->args[t] = tag % ld->args[t]; break; - case TAGOP_And: ld->args[t] &= tag; break; - case TAGOP_Or: ld->args[t] |= tag; break; - case TAGOP_Xor: ld->args[t] ^= tag; break; + case ARGOP_Const: + ld->args[t] = arg; + break; + case ARGOP_Tag: + ld->args[t] = tag; + break; + case ARGOP_Expr: + { + int *xnode = &XlatExpressions[arg]; + state.bIsConstant = true; + XlatExprEval[*xnode](&ld->args[t], xnode, &state); + } + break; + default: + assert(0); + ld->args[t] = 0; + break; } } @@ -349,3 +361,132 @@ int P_TranslateSectorSpecial (int special) return special | mask; } +static const int *Expr_Const(int *dest, const int *xnode, FXlatExprState *state) +{ + *dest = xnode[-1]; + return xnode - 2; +} + +static const int *Expr_Tag(int *dest, const int *xnode, FXlatExprState *state) +{ + *dest = state->tag; + state->bIsConstant = false; + return xnode - 1; +} + +static const int *Expr_Add(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 + op2; + return xnode; +} + +static const int *Expr_Sub(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 - op2; + return xnode; +} + +static const int *Expr_Mul(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 * op2; + return xnode; +} + +static void Div0Check(int &op1, int &op2, const FXlatExprState *state) +{ + if (op2 == 0) + { + Printf("Xlat: Division by 0 for line type %d\n", state->linetype); + // Set some safe values + op1 = 0; + op2 = 1; + } +} + +static const int *Expr_Div(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + Div0Check(op1, op2, state); + *dest = op1 / op2; + return xnode; +} + +static const int *Expr_Mod(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + Div0Check(op1, op2, state); + *dest = op1 % op2; + return xnode; +} + +static const int *Expr_And(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 & op2; + return xnode; +} + +static const int *Expr_Or(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 | op2; + return xnode; +} + +static const int *Expr_Xor(int *dest, const int *xnode, FXlatExprState *state) +{ + int op1, op2; + + xnode = XlatExprEval[xnode[-1]](&op2, xnode-1, state); + xnode = XlatExprEval[xnode[0]](&op1, xnode, state); + *dest = op1 ^ op2; + return xnode; +} + +static const int *Expr_Neg(int *dest, const int *xnode, FXlatExprState *state) +{ + int op; + + xnode = XlatExprEval[xnode[-1]](&op, xnode-1, state); + *dest = -op; + return xnode; +} + +const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state) = +{ + Expr_Const, + Expr_Tag, + Expr_Add, + Expr_Sub, + Expr_Mul, + Expr_Div, + Expr_Mod, + Expr_And, + Expr_Or, + Expr_Xor, + Expr_Neg +}; \ No newline at end of file diff --git a/src/xlat/parse_xlat.cpp b/src/xlat/parse_xlat.cpp index 17cd42d21..0b5c36235 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/xlat/parse_xlat.cpp @@ -57,6 +57,7 @@ DEFINE_TOKEN_TRANS(XLAT_) static FString LastTranslator; TAutoGrowArray SimpleLineTranslations; +TArray XlatExpressions; FBoomTranslator Boomish[MAX_BOOMISH]; int NumBoomish; TAutoGrowArray SectorTranslations; @@ -74,7 +75,7 @@ struct SpecialArgs struct SpecialArg { int arg; - ELineTransTagOp tagop; + ELineTransArgOp argop; }; struct ListFilter @@ -108,6 +109,7 @@ struct XlatParseContext : public FParseContext XlatParseContext(void *parser, ParseFunc parse, int *tt) : FParseContext(parser, parse, tt) { + DefiningLineType = -1; } //========================================================================== @@ -152,6 +154,8 @@ struct XlatParseContext : public FParseContext } return false; } + + int DefiningLineType; }; #include "xlat_parser.c" @@ -166,6 +170,7 @@ struct XlatParseContext : public FParseContext void P_ClearTranslator() { SimpleLineTranslations.Clear(); + XlatExpressions.Clear(); NumBoomish = 0; SectorTranslations.Clear(); SectorMasks.Clear(); diff --git a/src/xlat/xlat.h b/src/xlat/xlat.h index 765b9fd78..c5471ac8e 100644 --- a/src/xlat/xlat.h +++ b/src/xlat/xlat.h @@ -4,18 +4,13 @@ #include "doomtype.h" #include "tarray.h" -enum ELineTransTagOp +enum ELineTransArgOp { - TAGOP_None, - TAGOP_Add, - TAGOP_Mul, - TAGOP_Div, - TAGOP_Mod, - TAGOP_And, - TAGOP_Or, - TAGOP_Xor, + ARGOP_Const, + ARGOP_Tag, + ARGOP_Expr, - TAGOP_NUMBITS = 3, + TAGOP_NUMBITS = 2, TAGOP_MASK = (1 << TAGOP_NUMBITS) - 1 }; @@ -25,6 +20,23 @@ enum LINETRANS_TAGSHIFT = 30 - LINETRANS_MAXARGS * TAGOP_NUMBITS, }; +enum +{ + XEXP_Const, + XEXP_Tag, + XEXP_Add, + XEXP_Sub, + XEXP_Mul, + XEXP_Div, + XEXP_Mod, + XEXP_And, + XEXP_Or, + XEXP_Xor, + XEXP_Neg, + + XEXP_COUNT +}; + struct FLineTrans { int special; @@ -95,12 +107,21 @@ struct FLineFlagTrans bool ismask; }; +struct FXlatExprState +{ + int linetype; + int tag; + bool bIsConstant; +}; + extern TAutoGrowArray SimpleLineTranslations; +extern TArray XlatExpressions; extern FBoomTranslator Boomish[MAX_BOOMISH]; extern int NumBoomish; extern TAutoGrowArray SectorTranslations; extern TArray SectorMasks; extern FLineFlagTrans LineFlagTranslations[16]; +extern const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state); #endif diff --git a/src/xlat/xlat_parser.y b/src/xlat/xlat_parser.y index 0fc702f74..084e25160 100644 --- a/src/xlat/xlat_parser.y +++ b/src/xlat/xlat_parser.y @@ -89,84 +89,85 @@ single_enum ::= SYM(A) EQUALS exp(B). // //========================================================================== -linetype_declaration ::= exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. +%type linetype_exp {int} +linetype_exp(Z) ::= exp(A). +{ + Z = static_cast(context)->DefiningLineType = A; +} + +linetype_declaration ::= linetype_exp(linetype) EQUALS exp(flags) COMMA exp(special) LPAREN special_args(arg) RPAREN. { SimpleLineTranslations.SetVal(linetype, FLineTrans(special&0xffff, flags+arg.addflags, arg.args[0], arg.args[1], arg.args[2], arg.args[3], arg.args[4])); + static_cast(context)->DefiningLineType = -1; } -linetype_declaration ::= exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. +linetype_declaration ::= linetype_exp EQUALS exp COMMA SYM(S) LPAREN special_args RPAREN. { Printf ("%s, line %d: %s is undefined\n", context->SourceFile, context->SourceLine, S.sym); + static_cast(context)->DefiningLineType = -1; } +%type exp_with_tag {int} +exp_with_tag(A) ::= NUM(B). { XlatExpressions.Push(B.val); A = XlatExpressions.Push(XEXP_Const); } +exp_with_tag(A) ::= TAG. { A = XlatExpressions.Push(XEXP_Tag); } +exp_with_tag(A) ::= exp_with_tag PLUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Add); } +exp_with_tag(A) ::= exp_with_tag MINUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Sub); } +exp_with_tag(A) ::= exp_with_tag MULTIPLY exp_with_tag. { A = XlatExpressions.Push(XEXP_Mul); } +exp_with_tag(A) ::= exp_with_tag DIVIDE exp_with_tag. { A = XlatExpressions.Push(XEXP_Div); } +exp_with_tag(A) ::= exp_with_tag MODULUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Mod); } +exp_with_tag(A) ::= exp_with_tag OR exp_with_tag. { A = XlatExpressions.Push(XEXP_Or); } +exp_with_tag(A) ::= exp_with_tag AND exp_with_tag. { A = XlatExpressions.Push(XEXP_And); } +exp_with_tag(A) ::= exp_with_tag XOR exp_with_tag. { A = XlatExpressions.Push(XEXP_Xor); } +exp_with_tag(A) ::= MINUS exp_with_tag. [NEG] { A = XlatExpressions.Push(XEXP_Neg); } +exp_with_tag(A) ::= LPAREN exp_with_tag(B) RPAREN. { A = B; } + + %type special_arg {SpecialArg} -special_arg(Z) ::= exp(A). +special_arg(Z) ::= exp_with_tag(A). { - Z.arg = A; - Z.tagop = TAGOP_None; -} -special_arg(Z) ::= TAG. -{ - Z.arg = 0; - Z.tagop = TAGOP_Add; -} -special_arg(Z) ::= TAG PLUS exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Add; -} -special_arg(Z) ::= TAG MINUS exp(A). -{ - Z.arg = -A; - Z.tagop = TAGOP_Add; -} -special_arg(Z) ::= TAG MULTIPLY exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Mul; -} -special_arg(Z) ::= TAG DIVIDE exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Div; - if (A == 0) - { - context->PrintError("Division by zero"); + if (XlatExpressions[A] == XEXP_Tag) + { // Store tags directly + Z.arg = 0; + Z.argop = ARGOP_Tag; + XlatExpressions.Delete(A); + } + else + { // Try and evaluate it. If it's a constant, store it and erase the + // expression. Otherwise, store the index to the expression. We make + // no attempt to simplify non-constant expressions. + FXlatExprState state; + int val; + const int *endpt; + int *xnode; + + state.linetype = static_cast(context)->DefiningLineType; + state.tag = 0; + state.bIsConstant = true; + xnode = &XlatExpressions[A]; + endpt = XlatExprEval[*xnode](&val, xnode, &state); + if (state.bIsConstant) + { + Z.arg = val; + Z.argop = ARGOP_Const; + endpt++; + assert(endpt >= &XlatExpressions[0]); + XlatExpressions.Resize((unsigned)(endpt - &XlatExpressions[0])); + } + else + { + Z.arg = A; + Z.argop = ARGOP_Expr; + } } } -special_arg(Z) ::= TAG MODULUS exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Mod; - if (A == 0) - { - context->PrintError("Division by zero"); - } -} -special_arg(Z) ::= TAG OR exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Or; -} -special_arg(Z) ::= TAG AND exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_And; -} -special_arg(Z) ::= TAG XOR exp(A). -{ - Z.arg = A; - Z.tagop = TAGOP_Xor; -} - %type multi_special_arg {SpecialArgs} multi_special_arg(Z) ::= special_arg(A). { - Z.addflags = A.tagop << LINETRANS_TAGSHIFT; + Z.addflags = A.argop << LINETRANS_TAGSHIFT; Z.argcount = 1; Z.args[0] = A.arg; Z.args[1] = 0; @@ -179,7 +180,7 @@ multi_special_arg(Z) ::= multi_special_arg(A) COMMA special_arg(B). Z = A; if (Z.argcount < LINETRANS_MAXARGS) { - Z.addflags |= B.tagop << (LINETRANS_TAGSHIFT + Z.argcount * TAGOP_NUMBITS); + Z.addflags |= B.argop << (LINETRANS_TAGSHIFT + Z.argcount * TAGOP_NUMBITS); Z.args[Z.argcount] = B.arg; Z.argcount++; } From 9d67dc36e896498382fe8ec3e813abf8eeeddd45 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 24 Jan 2012 03:16:24 +0000 Subject: [PATCH 071/993] - Fixed: Episodes with NoSkillMenu defined had their own idea of default skill that differed from episodes with skill menus (and completely ignored whichever skill is explicitly defined as the default skill). SVN r3346 (trunk) --- src/menu/menu.h | 1 + src/menu/menudef.cpp | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/menu/menu.h b/src/menu/menu.h index 8a484b7ba..55884ab84 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -671,6 +671,7 @@ void M_ActivateMenu(DMenu *menu); void M_ClearMenus (); void M_ParseMenuDefs(); void M_StartupSkillMenu(FGameStartup *gs); +int M_GetDefaultSkill(); void M_StartControlPanel (bool makeSound); void M_SetMenu(FName menu, int param = -1); void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index f413a9475..4390f1675 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -1235,7 +1235,7 @@ void M_CreateMenus() //============================================================================= // -// THe skill menu must be refeshed each time it starts up +// The skill menu must be refeshed each time it starts up // //============================================================================= extern int restart; @@ -1345,7 +1345,7 @@ void M_StartupSkillMenu(FGameStartup *gs) } if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) { - ld->mAutoselect = firstitem + MIN(2u, AllSkills.Size()-1); + ld->mAutoselect = firstitem + M_GetDefaultSkill(); } else { @@ -1400,12 +1400,23 @@ fail: if (!done) { done = true; - int defskill = DefaultSkill; - if ((unsigned int)defskill >= AllSkills.Size()) - { - defskill = (AllSkills.Size() - 1) / 2; - } - od->mSelectedItem = defskill; + od->mSelectedItem = M_GetDefaultSkill(); } } } + +//============================================================================= +// +// Returns the default skill level. +// +//============================================================================= + +int M_GetDefaultSkill() +{ + int defskill = DefaultSkill; + if ((unsigned int)defskill >= AllSkills.Size()) + { + defskill = (AllSkills.Size() - 1) / 2; + } + return defskill; +} From ddd5fe753547d113c0c3ec2696154de2855e54d8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 24 Jan 2012 03:25:06 +0000 Subject: [PATCH 072/993] - Fixed: If an episode skips the skill menu, it should also skip the confirm skill menu if the default skill requests confirmation. SVN r3347 (trunk) --- src/menu/menudef.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 4390f1675..25d859ea6 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -1320,8 +1320,8 @@ void M_StartupSkillMenu(FGameStartup *gs) FSkillInfo &skill = AllSkills[i]; FListMenuItem *li; // Using a different name for skills that must be confirmed makes handling this easier. - FName action = skill.MustConfirm? NAME_StartgameConfirm : NAME_Startgame; - + FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + NAME_StartgameConfirm : NAME_Startgame; FString *pItemText = NULL; if (gs->PlayerClass != NULL) { @@ -1388,7 +1388,8 @@ fail: FSkillInfo &skill = AllSkills[i]; FOptionMenuItem *li; // Using a different name for skills that must be confirmed makes handling this easier. - const char *action = skill.MustConfirm? "StartgameConfirm" : "Startgame"; + const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? + "StartgameConfirm" : "Startgame"; FString *pItemText = NULL; if (gs->PlayerClass != NULL) From 5d7ee4dbfdad96b4ed086802a7f898edfd40d298 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 9 Feb 2012 19:59:32 +0000 Subject: [PATCH 073/993] - fixed: Line type 49 was wrong for all games. Fixed by adding a new Ceiling_CrushAndRaiseDist special. (thanks to Gez for the patch) SVN r3348 (trunk) --- src/actionspecials.h | 1 + src/p_ceiling.cpp | 8 ++++++-- src/p_lnspec.cpp | 20 +++++++++++++------- src/p_spec.h | 1 + wadsrc/static/xlat/base.txt | 2 +- wadsrc/static/xlat/heretic.txt | 1 + wadsrc/static/xlat/strife.txt | 2 +- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index eee1c9589..a1d34a54f 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -146,6 +146,7 @@ DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1, 5) DEFINE_SPECIAL(Sector_SetContents, 161, -1, -1, 3) // [RH] Begin new specials for ZDoom +DEFINE_SPECIAL(Ceiling_CrushAndRaiseDist, 168, 3, 5, 5) DEFINE_SPECIAL(Generic_Crusher2, 169, 5, 5, 5) DEFINE_SPECIAL(Sector_SetCeilingScale2, 170, 3, 3, 3) DEFINE_SPECIAL(Sector_SetFloorScale2, 171, 3, 3, 3) diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index fdac779ac..426bdf507 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -133,6 +133,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: m_Direction = -1; m_Speed = m_Speed1; if (!SN_IsMakingLoopingSound (m_Sector)) @@ -164,6 +165,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilCrushRaiseAndStay: m_Speed = m_Speed2; m_Direction = 1; @@ -193,6 +195,7 @@ void DCeiling::Tick () switch (m_Type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilLowerAndCrush: case ceilLowerAndCrushDist: if (m_Speed1 == FRACUNIT && m_Speed2 == FRACUNIT) @@ -254,6 +257,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, switch (type) { case ceilCrushAndRaise: + case ceilCrushAndRaiseDist: case ceilCrushRaiseAndStay: ceiling->m_TopHeight = sec->ceilingplane.d; case ceilLowerAndCrush: @@ -263,7 +267,7 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, { targheight += 8*FRACUNIT; } - else if (type == ceilLowerAndCrushDist) + else if (type == ceilLowerAndCrushDist || type == ceilCrushAndRaiseDist) { targheight += height; } @@ -505,7 +509,7 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, // Reactivate in-stasis ceilings...for certain types. // This restarts a crusher after it has been stopped - if (type == DCeiling::ceilCrushAndRaise) + if (type == DCeiling::ceilCrushAndRaise || type == DCeiling::ceilCrushAndRaiseDist) { P_ActivateInStasisCeiling (tag); } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 8cbeec335..dd66fdb0f 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -616,6 +616,12 @@ FUNC(LS_Ceiling_CrushAndRaiseA) return EV_DoCeiling (DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), SPEED(arg2), 0, arg3, 0, 0, CRUSHTYPE(arg4)); } +FUNC(LS_Ceiling_CrushAndRaiseDist) +// Ceiling_CrushAndRaiseDist (tag, dist, speed, damage, crushtype) +{ + return EV_DoCeiling (DCeiling::ceilCrushAndRaiseDist, ln, arg0, SPEED(arg2), SPEED(arg2), arg1*FRACUNIT, arg3, 0, 0, CRUSHTYPE(arg4)); +} + FUNC(LS_Ceiling_CrushAndRaiseSilentA) // Ceiling_CrushAndRaiseSilentA (tag, dnspeed, upspeed, damage, crushtype) { @@ -3248,13 +3254,13 @@ lnSpecFunc LineSpecials[256] = /* 159 */ LS_NOP, // Sector_SetPlaneReflection in GZDoom /* 160 */ LS_NOP, // Sector_Set3DFloor in GZDoom and Vavoom /* 161 */ LS_NOP, // Sector_SetContents in GZDoom and Vavoom - /* 162 */ LS_NOP, - /* 163 */ LS_NOP, - /* 164 */ LS_NOP, - /* 165 */ LS_NOP, - /* 166 */ LS_NOP, - /* 167 */ LS_NOP, - /* 168 */ LS_NOP, + /* 162 */ LS_NOP, // Reserved Doom64 branch + /* 163 */ LS_NOP, // Reserved Doom64 branch + /* 164 */ LS_NOP, // Reserved Doom64 branch + /* 165 */ LS_NOP, // Reserved Doom64 branch + /* 166 */ LS_NOP, // Reserved Doom64 branch + /* 167 */ LS_NOP, // Reserved Doom64 branch + /* 168 */ LS_Ceiling_CrushAndRaiseDist, /* 169 */ LS_Generic_Crusher2, /* 170 */ LS_Sector_SetCeilingScale2, /* 171 */ LS_Sector_SetFloorScale2, diff --git a/src/p_spec.h b/src/p_spec.h index 96bd4c8ee..b1a0048f4 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -603,6 +603,7 @@ public: ceilLowerInstant, ceilRaiseInstant, ceilCrushAndRaise, + ceilCrushAndRaiseDist, ceilLowerAndCrush, ceilLowerAndCrushDist, ceilCrushRaiseAndStay, diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index c5c7d7105..93bb0cc1f 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -48,7 +48,7 @@ include "xlat/defines.i" 46 = SHOOT|REP|MONST, Door_Open (tag, D_SLOW) 47 = SHOOT, Plat_RaiseAndStayTx0 (tag, P_SLOW/2) 48 = 0, Scroll_Texture_Left (SCROLL_UNIT) - 49 = USE, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) + 49 = USE, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 10) 50 = USE, Door_Close (tag, D_SLOW) 51 = USE, Exit_Secret (0) 52 = WALK, Exit_Normal (0) diff --git a/wadsrc/static/xlat/heretic.txt b/wadsrc/static/xlat/heretic.txt index 2ed3748b3..8fe344f5b 100644 --- a/wadsrc/static/xlat/heretic.txt +++ b/wadsrc/static/xlat/heretic.txt @@ -4,6 +4,7 @@ include "xlat/base.txt" 8 = WALK, Stairs_BuildUpDoom (tag, F_SLOW, 8) 10 = WALK, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 36 = WALK, Floor_LowerToHighest (tag, F_FAST, 136, 1) + 49 = USE, Ceiling_LowerAndCrush (tag, C_SLOW, 0, 2) 88 = WALK|REP, Plat_DownWaitUpStayLip (tag, P_FAST, PLATWAIT, 0) 99 = 0, Scroll_Texture_Right (SCROLL_UNIT) 100 = WALK|REP, Door_Raise (tag, D_SLOW*3, VDOORWAIT) diff --git a/wadsrc/static/xlat/strife.txt b/wadsrc/static/xlat/strife.txt index 3d06cd7cd..f0320f04e 100644 --- a/wadsrc/static/xlat/strife.txt +++ b/wadsrc/static/xlat/strife.txt @@ -244,7 +244,7 @@ RetailOnly = 121 189 = USE, ACS_LockedExecute (0, 0, 189, tag, 13) 41 = USE, Ceiling_LowerToFloor (tag, C_SLOW) 71 = USE, Floor_LowerToHighest (tag, F_FAST, 128) - 49 = USE, Ceiling_CrushAndRaiseA (tag, C_SLOW, C_SLOW, 10) + 49 = USE, Ceiling_CrushAndRaiseDist (tag, 8, C_SLOW, 0, 2) 50 = USE, Door_Close (tag, D_SLOW) 51 = USE, Teleport_EndGame (0) 55 = USE, Floor_RaiseAndCrush (tag, F_SLOW, 10, 2) From 68fbd7589760e8561a7ccdc5b3e92c402d6497ae Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 10 Feb 2012 00:53:50 +0000 Subject: [PATCH 074/993] - Fixed compilation with FMOD 4.38+. The removal of hardware voices and EAX was a fairly major change, so I'm making no provisions for using older FMOD DLLs when compiled with the 4.38 API. However, sound positioning is still broken like in 4.28, so you are recommended to continue building with 4.26. Also, the Freeverb-based DSP unit is no longer present in FMOD, so the underwater effect is currently unavailable when using 4.38 until I can figure out how to make it work with the SFX Reverb unit instead. (And on that topic, the Freeverb DSP was officially only for stereo outputs, so I really shouldn't have been using it in the first place.) - Since I would like to eventually figure out the sound positioning issues with the newer FMODs, the following have been added: * snd_drawoutput now labels its outputs with the speakers they represent. * DCanvas::DrawTextA was added as an alias for DrawText, since the Windows headers #define DrawText to a Unicode/non-Unicode variant. * The loopsound console command was added to spawn an actor at the player's location and have it loop a sound infinitely. Hopefully I can figure it out. FMOD's 3D example works, so I assume the problem lies with my code, though I don't really know where to begin looking for the problem. SVN r3350 (trunk) --- src/r_polymost.cpp | 2 +- src/s_sound.cpp | 39 +- src/sound/fmodsound.cpp | 177 +++-- src/sound/fmodsound.h | 5 + src/v_text.cpp | 45 +- src/v_video.h | 6 +- wadsrc/static/actors/shared/sharedmisc.txt | 25 +- wadsrc/static/sprites/spkra0.png | Bin 0 -> 525 bytes zdoom.vcproj | 750 ++++++++++----------- 9 files changed, 613 insertions(+), 436 deletions(-) create mode 100644 wadsrc/static/sprites/spkra0.png diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp index 0075d6ca0..92cec1a6e 100644 --- a/src/r_polymost.cpp +++ b/src/r_polymost.cpp @@ -671,7 +671,7 @@ void drawquad(float x0, float y0, float x1, float y1, float x2, float y2, float void printnum(int x, int y, int num) { char foo[16]; mysnprintf (foo, countof(foo), "%d", num); - RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo); + RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo, TAG_DONE); } void drawpolymosttest() diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 5c171af0d..4af92f46e 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2591,7 +2591,44 @@ CCMD (playsound) { if (argv.argc() > 1) { - S_Sound (CHAN_AUTO | CHAN_UI, argv[1], 1.f, ATTN_NONE); + FSoundID id = argv[1]; + if (id == 0) + { + Printf("'%s' is not a sound\n", argv[1]); + } + else + { + S_Sound (CHAN_AUTO | CHAN_UI, id, 1.f, ATTN_NONE); + } + } +} + +//========================================================================== +// +// CCMD loopsound +// +//========================================================================== + +CCMD (loopsound) +{ + if (players[consoleplayer].mo != NULL && !netgame && argv.argc() > 1) + { + FSoundID id = argv[1]; + if (id == 0) + { + Printf("'%s' is not a sound\n", argv[1]); + } + else + { + AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->x, + players[consoleplayer].mo->y, + players[consoleplayer].mo->z + 32*FRACUNIT, + ALLOW_REPLACE); + if (icon != NULL) + { + S_Sound(icon, CHAN_BODY | CHAN_LOOP, id, 1.f, ATTN_IDLE); + } + } } } diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 4a5ab95a8..5af94a340 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -63,6 +63,10 @@ extern HWND Window; #include "cmdlib.h" #include "s_sound.h" +#if FMOD_VERSION > 0x42899 && FMOD_VERSION < 0x43800 +#error You are trying to compile with an unsupported version of FMOD. +#endif + // MACROS ------------------------------------------------------------------ // killough 2/21/98: optionally use varying pitched sounds @@ -173,12 +177,12 @@ static const FEnumList OutputNames[] = { "ESD", FMOD_OUTPUTTYPE_ESD }, #if FMOD_VERSION >= 0x43400 { "PulseAudio", FMOD_OUTPUTTYPE_PULSEAUDIO }, + { "Pulse", FMOD_OUTPUTTYPE_PULSEAUDIO }, #endif { "SDL", 666 }, // Mac #if FMOD_VERSION < 0x43000 - // Sound Manager support was removed sometime in the 4.29 line. { "Sound Manager", FMOD_OUTPUTTYPE_SOUNDMANAGER }, #endif { "Core Audio", FMOD_OUTPUTTYPE_COREAUDIO }, @@ -238,6 +242,9 @@ static const char *OpenStateNames[] = "Streaming" }; +const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNames4[4] = { "L", "R", "BL", "BR" }; +const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNamesMore[8] = { "L", "R", "C", "LFE", "BL", "BR", "SL", "SR" }; + // CODE -------------------------------------------------------------------- //========================================================================== @@ -348,7 +355,7 @@ public: Channel->setSpeakerMix(1, 1, 1, 1, 1, 1, 1, 1); Channel->setVolume(volume); // Ensure reverb is disabled. - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == Channel->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -704,7 +711,11 @@ bool FMODSoundRenderer::Init() } const char *wrongver = NULL; +#if FMOD_VERSION >= 0x43800 + if (version < 0x43800) +#else if (version < 0x42000) +#endif { wrongver = "an old"; } @@ -842,7 +853,14 @@ bool FMODSoundRenderer::Init() result = Sys->setDriver(driver); } result = Sys->getDriver(&driver); +#if FMOD_VERSION >= 0x43700 + // We were built with an FMOD that only returns the control panel frequency + result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &speakermode); + Driver_MaxFrequency = Driver_MinFrequency; +#else + // We were built with an FMOD that returns a frequency range result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &Driver_MaxFrequency, &speakermode); +#endif if (result != FMOD_OK) { Printf(TEXTCOLOR_BLUE"Could not ascertain driver capabilities. Some things may be weird. (Error %d)\n", result); @@ -871,7 +889,9 @@ bool FMODSoundRenderer::Init() format = eval >= 0 ? FMOD_SOUND_FORMAT(eval) : FMOD_SOUND_FORMAT_PCM16; eval = Enum_NumForName(ResamplerNames, snd_resampler); resampler = eval >= 0 ? FMOD_DSP_RESAMPLER(eval) : FMOD_DSP_RESAMPLER_LINEAR; - samplerate = clamp(snd_samplerate, Driver_MinFrequency, Driver_MaxFrequency); + // These represented the frequency limits for hardware channels, which we never used anyway. +// samplerate = clamp(snd_samplerate, Driver_MinFrequency, Driver_MaxFrequency); + samplerate = snd_samplerate; if (samplerate == 0 || snd_samplerate == 0) { // Creative's ASIO drivers report the only supported frequency as 0! if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL, NULL, NULL, NULL)) @@ -922,7 +942,12 @@ bool FMODSoundRenderer::Init() initflags = FMOD_INIT_NORMAL; if (snd_hrtf) { + // These flags are the same thing, just with different names. +#ifdef FMOD_INIT_SOFTWARE_HRTF initflags |= FMOD_INIT_SOFTWARE_HRTF; +#else + initflags |= FMOD_INIT_HRTF_LOWPASS; +#endif } if (snd_profile) { @@ -1007,6 +1032,7 @@ bool FMODSoundRenderer::Init() } // Create DSP units for underwater effect +#if FMOD_VERSION < 0x43701 result = Sys->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &WaterLP); if (result != FMOD_OK) { @@ -1020,6 +1046,9 @@ bool FMODSoundRenderer::Init() Printf(TEXTCOLOR_BLUE" Could not create underwater reverb unit. (Error %d)\n", result); } } +#else + result = FMOD_ERR_UNSUPPORTED; +#endif // Connect underwater DSP unit between PausableSFX and SFX groups, while // retaining the connection established by SfxGroup->addGroup(). @@ -1066,6 +1095,7 @@ bool FMODSoundRenderer::Init() WaterLP->setActive(false); WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); WaterLP->setParameter(FMOD_DSP_LOWPASS_RESONANCE, 2); +#if FMOD_VERSION < 0x43701 if (WaterReverb != NULL) { FMOD::DSPConnection *dry; @@ -1090,6 +1120,7 @@ bool FMODSoundRenderer::Init() } } else +#endif { result = sfx_head->addInput(WaterLP, NULL); } @@ -1209,7 +1240,6 @@ void FMODSoundRenderer::PrintStatus() int driver; int samplerate; int numoutputchannels; - int num2d, num3d, total; unsigned int bufferlength; int numbuffers; @@ -1233,12 +1263,6 @@ void FMODSoundRenderer::PrintStatus() Printf ("Driver: "TEXTCOLOR_GREEN"%d"TEXTCOLOR_NORMAL" ("TEXTCOLOR_ORANGE"%s"TEXTCOLOR_NORMAL")\n", driver, name); DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency); } - if (FMOD_OK == Sys->getHardwareChannels(&num2d, &num3d, &total)) - { - Printf (TEXTCOLOR_YELLOW "Hardware 2D channels: "TEXTCOLOR_GREEN"%d\n", num2d); - Printf (TEXTCOLOR_YELLOW "Hardware 3D channels: "TEXTCOLOR_GREEN"%d\n", num3d); - Printf (TEXTCOLOR_YELLOW "Total hardware channels: "TEXTCOLOR_GREEN"%d\n", total); - } if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) { Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: "TEXTCOLOR_GREEN"%d\n", samplerate); @@ -1276,15 +1300,6 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max { Printf("\n"); } - if (caps & FMOD_CAPS_REVERB_EAX2) Printf(TEXTCOLOR_OLIVE " EAX2"); - if (caps & FMOD_CAPS_REVERB_EAX3) Printf(TEXTCOLOR_OLIVE " EAX3"); - if (caps & FMOD_CAPS_REVERB_EAX4) Printf(TEXTCOLOR_OLIVE " EAX4"); - if (caps & FMOD_CAPS_REVERB_EAX5) Printf(TEXTCOLOR_OLIVE " EAX5"); - if (caps & FMOD_CAPS_REVERB_I3DL2) Printf(TEXTCOLOR_OLIVE " I3DL2"); - if (caps & (FMOD_CAPS_REVERB_EAX2 | FMOD_CAPS_REVERB_EAX3 | FMOD_CAPS_REVERB_EAX4 | FMOD_CAPS_REVERB_EAX5 | FMOD_CAPS_REVERB_I3DL2)) - { - Printf("\n"); - } if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n"); } @@ -1689,7 +1704,7 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi } if (flags & SNDF_NOREVERB) { - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -1809,7 +1824,7 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * } if (flags & SNDF_NOREVERB) { - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; if (FMOD_OK == chan->getReverbProperties(&reverb)) { reverb.Room = -10000; @@ -2180,7 +2195,7 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener) { DPrintf ("Reverb Environment %s\n", env->Name); const_cast(env)->Modified = false; - Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties)); + SetSystemReverbProperties(&env->Properties); PrevEnvironment = env; if (!SfxReverbHooked) @@ -2567,23 +2582,60 @@ void FMODSoundRenderer::DrawWaveDebug(int mode) const int window_height = 100; int window_size; int numoutchans; - int y; + int y, yy; + const spk *labels; + int labelcount; if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans, NULL, NULL, NULL)) { return; } + // Decide on which set of labels to use. + labels = (numoutchans == 4) ? SpeakerNames4 : SpeakerNamesMore; + labelcount = MIN(numoutchans, countof(SpeakerNamesMore)); + // Scale all the channel windows so one group fits completely on one row, with // 16 pixels of padding between each window. window_size = (screen->GetWidth() - 16) / numoutchans - 16; float *wavearray = (float*)alloca(MAX(SPECTRUM_SIZE,window_size)*sizeof(float)); - y = 16; - y = DrawChannelGroupOutput(SfxGroup, wavearray, window_size, window_height, y, mode); - y = DrawChannelGroupOutput(MusicGroup, wavearray, window_size, window_height, y, mode >> 2); - y = DrawSystemOutput(wavearray, window_size, window_height, y, mode >> 4); + + yy = DrawChannelGroupOutput(SfxGroup, wavearray, window_size, window_height, y, mode); + if (y != yy) + { + DrawSpeakerLabels(labels, yy-14, window_size, labelcount); + } + y = DrawChannelGroupOutput(MusicGroup, wavearray, window_size, window_height, yy, mode >> 2); + if (y != yy) + { + DrawSpeakerLabels(labels, y-14, window_size, labelcount); + } + yy = DrawSystemOutput(wavearray, window_size, window_height, y, mode >> 4); + if (y != yy) + { + DrawSpeakerLabels(labels, yy-14, window_size, labelcount); + } +} + +//========================================================================== +// +// FMODSoundRenderer :: DrawSpeakerLabels +// +//========================================================================== + +void FMODSoundRenderer::DrawSpeakerLabels(const spk *labels, int y, int width, int count) +{ + if (labels == NULL) + { + return; + } + for (int i = 0, x = 16; i < count; ++i) + { + screen->DrawText(SmallFont, CR_LIGHTBLUE, x, y, labels[i], TAG_DONE); + x += width + 16; + } } //========================================================================== @@ -2716,7 +2768,7 @@ void FMODSoundRenderer::DrawWave(float *wavearray, int x, int y, int width, int // Draw a box around the oscilloscope. screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width + 1, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); + screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); @@ -2823,7 +2875,7 @@ void FMODSoundRenderer::DrawSpectrum(float *spectrumarray, int x, int y, int wid // Draw a border and dark background for the spectrum. screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width + 1, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); + screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); screen->Dim(MAKERGB(0,0,0), 0.3f, x, y, width, height); @@ -2912,17 +2964,60 @@ short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizeby void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const { -#if FMOD_VERSION >= 0x42600 - if (ActiveFMODVersion < 0x42600) - { - // This parameter was added for 4.26.00, and trying to pass it to older - // DLLs will fail. - exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem); - } - else + memset(exinfo, 0, sizeof(*exinfo)); +#if FMOD_VERSION >= 0x42600 && FMOD_VERSION < 0x43800 + if (ActiveFMODVersion < 0x42600) + { + // This parameter was added for 4.26.00, and trying to pass it to older + // DLLs will fail. + exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem); + } + else #endif - { - exinfo->cbsize = sizeof(*exinfo); - } - memset((BYTE *)exinfo + sizeof(exinfo->cbsize), 0, exinfo->cbsize - sizeof(exinfo->cbsize)); + { + exinfo->cbsize = sizeof(*exinfo); + } } + +//========================================================================== +// +// FMODSoundRenderer :: SetSystemReverbProperties +// +// Set the global reverb properties. +// +//========================================================================== + +FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES *props) +{ +#if FMOD_VERSION < 0x43800 + return Sys->setReverbProperties((const FMOD_REVERB_PROPERTIES *)props); +#else + // The reverb format changed when hardware mixing support was dropped, because + // all EAX-only properties were removed from the structure. + FMOD_REVERB_PROPERTIES fr; + + fr.Instance = props->Instance; + fr.Environment = props->Environment; + fr.EnvDiffusion = props->EnvDiffusion; + fr.Room = props->Room; + fr.RoomHF = props->RoomHF; + fr.RoomLF = props->RoomLF; + fr.DecayTime = props->DecayTime; + fr.DecayHFRatio = props->DecayHFRatio; + fr.DecayLFRatio = props->DecayLFRatio; + fr.Reflections = props->Reflections; + fr.ReflectionsDelay = props->ReflectionsDelay; + fr.Reverb = props->Reverb; + fr.ReverbDelay = props->ReverbDelay; + fr.ModulationTime = props->ModulationTime; + fr.ModulationDepth = props->ModulationDepth; + fr.HFReference = props->HFReference; + fr.LFReference = props->LFReference; + fr.Diffusion = props->Diffusion; + fr.Density = props->Density; + fr.Flags = props->Flags; + + return Sys->setReverbProperties(&fr); +#endif +} + diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h index 8e28d0743..e00b2ed27 100644 --- a/src/sound/fmodsound.h +++ b/src/sound/fmodsound.h @@ -81,6 +81,7 @@ private: bool ReconnectSFXReverbUnit(); void InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const; + FMOD_RESULT SetSystemReverbProperties(const REVERB_PROPERTIES *props); bool Init (); void Shutdown (); @@ -97,6 +98,10 @@ private: int DrawSystemSpectrum(float *wavearray, int width, int height, int y, bool skip); void DrawSpectrum(float *spectrumarray, int x, int y, int width, int height); + typedef char spk[4]; + static const spk SpeakerNames4[4], SpeakerNamesMore[8]; + void DrawSpeakerLabels(const spk *labels, int y, int width, int count); + FMOD::System *Sys; FMOD::ChannelGroup *SfxGroup, *PausableSfx; FMOD::ChannelGroup *MusicGroup; diff --git a/src/v_text.cpp b/src/v_text.cpp index 55dbcc774..b4d1e5334 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -78,11 +78,11 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B // // Write a string using the given font // -void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...) +void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag1, va_list taglist) { - va_list tags; - DWORD tag; INTBOOL boolval; + va_list tags; + uint32 tag; int maxstrlen = INT_MAX; int w, maxwidth; @@ -117,8 +117,12 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c maxwidth = Width; scalex = scaley = 1; - va_start (tags, string); - tag = va_arg (tags, DWORD); +#ifndef NO_VA_COPY + va_copy(tags, taglist); +#else + tags = taglist; +#endif + tag = tag1; while (tag != TAG_DONE) { @@ -203,7 +207,7 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c height = va_arg (tags, int); break; } - tag = va_arg (tags, DWORD); + tag = va_arg (tags, uint32); } height *= scaley; @@ -233,8 +237,12 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c if (NULL != (pic = font->GetChar (c, &w))) { - va_list taglist; - va_start (taglist, string); +#ifndef NO_VA_COPY + va_copy(tags, taglist); +#else + tags = taglist; +#endif + tag = tag1; if (forcedwidth) { w = forcedwidth; @@ -242,20 +250,35 @@ void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, c DTA_Translation, range, DTA_DestWidth, forcedwidth, DTA_DestHeight, height, - TAG_MORE, &taglist); + TAG_MORE, &tags); } else { DrawTexture (pic, cx, cy, DTA_Translation, range, - TAG_MORE, &taglist); + TAG_MORE, &tags); } - va_end (taglist); + va_end (tags); } cx += (w + kerning) * scalex; } } +void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +{ + va_list tags; + va_start(tags, tag); + DrawTextV(font, normalcolor, x, y, string, tag, tags); +} + +// A synonym so that this can still be used in files that #include Windows headers +void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +{ + va_list tags; + va_start(tags, tag); + DrawTextV(font, normalcolor, x, y, string, tag, tags); +} + // // Find string width using this font // diff --git a/src/v_video.h b/src/v_video.h index da184cba3..50a81f132 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -214,7 +214,11 @@ public: void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const; // 2D Text drawing - void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...); + void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); +#ifndef DrawText // See WinUser.h for the definition of DrawText as a macro + void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); +#endif + void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, va_list tags); void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...); struct DrawParms diff --git a/wadsrc/static/actors/shared/sharedmisc.txt b/wadsrc/static/actors/shared/sharedmisc.txt index 33aa25591..6a71025d2 100644 --- a/wadsrc/static/actors/shared/sharedmisc.txt +++ b/wadsrc/static/actors/shared/sharedmisc.txt @@ -68,7 +68,7 @@ ACTOR MapSpotGravity : MapSpot 9013 -NOGRAVITY } -// Point Pushers --------------------------------------------------- +// Point Pushers ----------------------------------------------------------- ACTOR PointPusher 5001 { @@ -110,7 +110,7 @@ ACTOR Gibs : RealGibs 24 ClearFlags } -// Needed for loading Build maps --------------------------------------- +// Needed for loading Build maps ------------------------------------------- ACTOR CustomSprite 9988 native { @@ -124,7 +124,7 @@ ACTOR CustomSprite 9988 native } } -// SwitchableDecoration: Activate and Deactivate change state --------------- +// SwitchableDecoration: Activate and Deactivate change state -------------- ACTOR SwitchableDecoration native { @@ -135,7 +135,7 @@ ACTOR SwitchingDecoration : SwitchableDecoration native { } -// Random spawner ----------------------------------------------------------- +// Random spawner ---------------------------------------------------------- ACTOR RandomSpawner native { @@ -145,14 +145,14 @@ ACTOR RandomSpawner native +THRUACTORS } -// Fast projectiles ----------------------------------------------------------- +// Fast projectiles -------------------------------------------------------- ACTOR FastProjectile native { Projectile } -// Sector flag setter ----------------------------------------------------------- +// Sector flag setter ------------------------------------------------------ ACTOR SectorFlagSetter 9041 native { @@ -161,3 +161,16 @@ ACTOR SectorFlagSetter 9041 native +DONTSPLASH RenderStyle None } + +// Marker for sounds ------------------------------------------------------- + +ACTOR SpeakerIcon : Unknown +{ + States + { + Spawn: + SPKR A -1 BRIGHT + Stop + } + Scale 0.125 +} diff --git a/wadsrc/static/sprites/spkra0.png b/wadsrc/static/sprites/spkra0.png new file mode 100644 index 0000000000000000000000000000000000000000..9af2d4d8379d36be6c2dc1b047964324f619e756 GIT binary patch literal 525 zcmV+o0`mQdP)_!uO(f<-uhgaIl^c?Sst zu4K=By*^gJhl_o^g?~Yy*wstY!2Tut02dqBPU(zzen8U42x$Y6)A|^3Qh|wCz2>;s z;v2ZK2p`S>6j3oLDFkfF zBs>9TP3%Ji=0NPjj390|H~^RfTu8%MOBU`#uB5KLHePRbjb* zeNg8dHxar~9^_wWFjpPV0}w zL#wSEy3FuTb1EO^=5sq^08k46jEvYv28K)n7)yPOY9C}KHi)$7>wuFAzOx@PoSt}H zt3L>2^B!Iz973NW=lPiEs>Q*Q=A)<;1;fk5faC6dleB8T4@k;Y%p`sQ+#KmBmV(^< P00000NkvXXu0mjfql(+x literal 0 HcmV?d00001 diff --git a/zdoom.vcproj b/zdoom.vcproj index dff0e6cb2..4601991fa 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - @@ -1848,6 +1840,14 @@ Outputs="$(IntDir)/$(InputName).obj" /> + + + @@ -2037,6 +2037,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -2047,14 +2055,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - + + + @@ -2477,14 +2485,6 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> - - - @@ -2783,7 +2783,7 @@ /> + + + - - - Date: Sat, 11 Feb 2012 00:15:03 +0000 Subject: [PATCH 075/993] - Fixed: DCanvas::DrawTextV needs to accept the entire tag list in one parameter. Otherwise, it can't pass it to DrawTexture with a simple TAG_MORE. (Not sure why I thought the initial tag needed to be separate, though it did catch one case where it wasn't provided.) SVN r3351 (trunk) --- src/v_text.cpp | 19 ++++++++++--------- src/v_video.h | 6 +++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/v_text.cpp b/src/v_text.cpp index b4d1e5334..c5208be36 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -78,7 +78,7 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B // // Write a string using the given font // -void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag1, va_list taglist) +void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, va_list taglist) { INTBOOL boolval; va_list tags; @@ -122,7 +122,7 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * #else tags = taglist; #endif - tag = tag1; + tag = va_arg(tags, uint32); while (tag != TAG_DONE) { @@ -209,6 +209,7 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * } tag = va_arg (tags, uint32); } + va_end(tags); height *= scaley; @@ -242,7 +243,6 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * #else tags = taglist; #endif - tag = tag1; if (forcedwidth) { w = forcedwidth; @@ -262,21 +262,22 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char * } cx += (w + kerning) * scalex; } + va_end(taglist); } -void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...) { va_list tags; - va_start(tags, tag); - DrawTextV(font, normalcolor, x, y, string, tag, tags); + va_start(tags, string); + DrawTextV(font, normalcolor, x, y, string, tags); } // A synonym so that this can still be used in files that #include Windows headers -void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...) +void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...) { va_list tags; - va_start(tags, tag); - DrawTextV(font, normalcolor, x, y, string, tag, tags); + va_start(tags, string); + DrawTextV(font, normalcolor, x, y, string, tags); } // diff --git a/src/v_video.h b/src/v_video.h index 50a81f132..6d97256f9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -214,11 +214,11 @@ public: void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const; // 2D Text drawing - void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); + void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...); #ifndef DrawText // See WinUser.h for the definition of DrawText as a macro - void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, ...); + void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...); #endif - void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, uint32 tag, va_list tags); + void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, va_list tags); void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...); struct DrawParms From cd150bd170eb290d12de5e587dcab1cff5bd94cc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 11 Feb 2012 01:04:42 +0000 Subject: [PATCH 076/993] - Fixed: Forgot to divide the length of the SVCT chunks in ACS objects by 4 to get the actual number of scripts to set VarCount for. SVN r3352 (trunk) --- src/p_acs.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 639f70313..d24da1275 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1529,11 +1529,11 @@ void FBehavior::LoadScriptsDirectory () } } - // Load script var counts + // Load script var counts. (Only recorded for scripts that use more than LOCAL_SIZE variables.) scripts.b = FindChunk (MAKE_ID('S','V','C','T')); if (scripts.dw != NULL) { - max = scripts.dw[1]; + max = scripts.dw[1] / 4; scripts.dw += 2; for (i = max; i > 0; --i, scripts.w += 2) { @@ -6999,6 +6999,7 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr new DACSThinker; script = num; + assert(code->VarCount >= code->ArgCount); numlocalvars = code->VarCount; localvars = new SDWORD[code->VarCount]; if (code->VarCount > 0) From d2c8a86bb4cea45d7e5c280f25ea06d2fd5f457c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 11 Feb 2012 01:17:09 +0000 Subject: [PATCH 077/993] - Fixed: CheckMobjBlocking() did not consider one-sided lines without the ML_BLOCKING flag to be blocking. SVN r3353 (trunk) --- src/po_man.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/po_man.cpp b/src/po_man.cpp index 8a18269e4..d5219e51c 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1295,7 +1295,8 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) fixed_t top = -INT_MAX, bottom = INT_MAX; bool above; // [TN] Check wether this actor gets blocked by the line. - if(!(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) + if (ld->backsector != NULL && + !(ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) && !(ld->flags & ML_BLOCK_PLAYERS && mobj->player) && !(ld->flags & ML_BLOCKMONSTERS && mobj->flags3 & MF3_ISMONSTER) && !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS)) From 033b3964f17cbd87dd42a73b3f4adb46e83d5de8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 11 Feb 2012 01:44:56 +0000 Subject: [PATCH 078/993] - Fixed: C_DoKey() must disable all doublebind processing if it isn't passed any doublebindings. This is because the automap calls it with its own bindings, which effectively cancelled all doublebindings while the automap was open. SVN r3354 (trunk) --- src/am_map.cpp | 70 +++++++++++++++++++++++++------------------------- src/c_bind.cpp | 12 +++++---- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 11ecf74af..1c5415a99 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1917,13 +1917,13 @@ bool AM_Check3DFloors(line_t *line) //============================================================================= void AM_drawWalls (bool allmap) -{ - int i; - static mline_t l; - int lock, color; - - for (i = 0; i < numlines; i++) - { +{ + int i; + static mline_t l; + int lock, color; + + for (i = 0; i < numlines; i++) + { l.a.x = lines[i].v1->x >> FRACTOMAPBITS; l.a.y = lines[i].v1->y >> FRACTOMAPBITS; l.b.x = lines[i].v2->x >> FRACTOMAPBITS; @@ -1953,22 +1953,22 @@ void AM_drawWalls (bool allmap) else if (lines[i].flags & ML_SECRET) { // secret door if (am_cheat != 0 && lines[i].backsector != NULL) - AM_drawMline(&l, SecretWallColor); - else - AM_drawMline(&l, WallColor); - } else if (lines[i].locknumber > 0) { // [Dusk] specials w/ locknumbers - lock = lines[i].locknumber; - color = P_GetMapColorForLock(lock); - - AMColor c; - if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); - else c = LockedColor; - - AM_drawMline (&l, c); - } else if ((lines[i].special == Teleport || - lines[i].special == Teleport_NoFog || - lines[i].special == Teleport_ZombieChanger || - lines[i].special == Teleport_Line) && + AM_drawMline(&l, SecretWallColor); + else + AM_drawMline(&l, WallColor); + } else if (lines[i].locknumber > 0) { // [Dusk] specials w/ locknumbers + lock = lines[i].locknumber; + color = P_GetMapColorForLock(lock); + + AMColor c; + if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); + else c = LockedColor; + + AM_drawMline (&l, c); + } else if ((lines[i].special == Teleport || + lines[i].special == Teleport_NoFog || + lines[i].special == Teleport_ZombieChanger || + lines[i].special == Teleport_Line) && (lines[i].activation & SPAC_PlayerActivate) && am_colorset == 0) { // intra-level teleporters @@ -1988,18 +1988,18 @@ void AM_drawWalls (bool allmap) (lines[i].special == Door_Animated && lines[i].args[3] != 0) || (lines[i].special == Generic_Door && lines[i].args[4] != 0)) { - if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors - { - int P_GetMapColorForLock(int lock); - - if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated) - lock=lines[i].args[3]; - else lock=lines[i].args[4]; - - color = P_GetMapColorForLock(lock); - - AMColor c; - + if (am_colorset == 0 || am_colorset == 3) // Raven games show door colors + { + int P_GetMapColorForLock(int lock); + + if (lines[i].special==Door_LockedRaise || lines[i].special==Door_Animated) + lock=lines[i].args[3]; + else lock=lines[i].args[4]; + + color = P_GetMapColorForLock(lock); + + AMColor c; + if (color >= 0) c.FromRGB(RPART(color), GPART(color), BPART(color)); else c = LockedColor; diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 0aa8ddc19..0744efeee 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -829,6 +829,7 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) bool dclick; int dclickspot; BYTE dclickmask; + unsigned int nowtime; if (ev->type != EV_KeyDown && ev->type != EV_KeyUp) return false; @@ -841,10 +842,11 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) dclick = false; // This used level.time which didn't work outside a level. - if (DClickTime[ev->data1] > I_MSTime() && ev->type == EV_KeyDown) + nowtime = I_MSTime(); + if (doublebinds != NULL && DClickTime[ev->data1] > nowtime && ev->type == EV_KeyDown) { // Key pressed for a double click - if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1); + binding = doublebinds->GetBinding(ev->data1); DClicked[dclickspot] |= dclickmask; dclick = true; } @@ -853,11 +855,11 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) if (ev->type == EV_KeyDown) { // Key pressed for a normal press binding = binds->GetBinding(ev->data1); - DClickTime[ev->data1] = I_MSTime() + 571; + DClickTime[ev->data1] = nowtime + 571; } - else if (DClicked[dclickspot] & dclickmask) + else if (doublebinds != NULL && DClicked[dclickspot] & dclickmask) { // Key released from a double click - if (doublebinds != NULL) binding = doublebinds->GetBinding(ev->data1); + binding = doublebinds->GetBinding(ev->data1); DClicked[dclickspot] &= ~dclickmask; DClickTime[ev->data1] = 0; dclick = true; From 540473cbe0c40aeca66259014b0c883ef3544abb Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Feb 2012 02:41:55 +0000 Subject: [PATCH 079/993] - Fixed: Sound limiting applied even to sounds that were already playing on the same actor+channel. Since in this case, it's really just restarting the sound, it shouldn't limit it. (Since it's already playing, we know the limit wasn't exceeded when it started playing, so it shouldn't be exceeded if we restart it now.) SVN r3355 (trunk) --- src/s_sound.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 4af92f46e..726d71ef4 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -101,7 +101,7 @@ extern float S_GetMusicVolume (const char *music); // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- -static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range); +static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range, AActor *actor, int channel); static bool S_IsChannelUsed(AActor *actor, int channel, int *seen); static void S_ActivatePlayList(bool goBack); static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel); @@ -952,7 +952,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO // If this sound doesn't like playing near itself, don't play it if // that's what would happen. - if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit, limit_range)) + if (near_limit > 0 && S_CheckSoundLimit(sfx, pos, near_limit, limit_range, actor, channel)) { chanflags |= CHAN_EVICTED; } @@ -1157,7 +1157,7 @@ void S_RestartSound(FSoundChan *chan) // If this sound doesn't like playing near itself, don't play it if // that's what would happen. - if (chan->NearLimit > 0 && S_CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange)) + if (chan->NearLimit > 0 && S_CheckSoundLimit(&S_sfx[chan->SoundID], pos, chan->NearLimit, chan->LimitRange, NULL, 0)) { return; } @@ -1389,12 +1389,19 @@ bool S_CheckSingular(int sound_id) // // Limits the number of nearby copies of a sound that can play near // each other. If there are NearLimit instances of this sound already -// playing within 256 units of the new sound, the new sound will not -// start. +// playing within sqrt(limit_range) (typically 256 units) of the new sound, the +// new sound will not start. +// +// If an actor is specified, and it is already playing the same sound on +// the same channel, this sound will not be limited. In this case, we're +// restarting an already playing sound, so there's no need to limit it. +// +// Returns true if the sound should not play. // //========================================================================== -bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range) +bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, float limit_range, + AActor *actor, int channel) { FSoundChan *chan; int count; @@ -1405,6 +1412,12 @@ bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limit, floa { FVector3 chanorigin; + if (actor != NULL && chan->EntChannel == channel && + chan->SourceType == SOURCE_Actor && chan->Actor == actor) + { // We are restarting a playing sound. Always let it play. + return false; + } + CalcPosVel(chan, &chanorigin, NULL); if ((chanorigin - pos).LengthSquared() <= limit_range) { From 5a95c997d19552ee8d9ab568890621b9856977f6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 12 Feb 2012 02:45:48 +0000 Subject: [PATCH 080/993] - Added keys on the automap for Heretic in easy mode, courtesy of Gez. SVN r3356 (trunk) --- src/am_map.cpp | 55 +++++++++++++++++++++++++++- src/g_level.h | 4 +- src/g_skill.cpp | 9 +++++ wadsrc/static/maparrows/ravenkey.txt | 9 +++++ wadsrc/static/mapinfo/heretic.txt | 1 + 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 wadsrc/static/maparrows/ravenkey.txt diff --git a/src/am_map.cpp b/src/am_map.cpp index 1c5415a99..44b6da619 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -308,6 +308,7 @@ struct islope_t static TArray MapArrow; static TArray CheatMapArrow; static TArray CheatKey; +static TArray EasyKey; #define R (MAPUNIT) // [RH] Avoid lots of warnings without compiler-specific #pragmas @@ -536,10 +537,12 @@ void AM_StaticInit() MapArrow.Clear(); CheatMapArrow.Clear(); CheatKey.Clear(); + EasyKey.Clear(); if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow); if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow); AM_ParseArrow(CheatKey, "maparrows/key.txt"); + AM_ParseArrow(EasyKey, "maparrows/ravenkey.txt"); if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); char namebuf[9]; @@ -2261,6 +2264,49 @@ void AM_drawPlayers () // //============================================================================= +void AM_drawKeys () +{ + AMColor color; + mpoint_t p; + angle_t angle; + + TThinkerIterator it; + AKey *key; + + while ((key = it.Next()) != NULL) + { + p.x = key->x >> FRACTOMAPBITS; + p.y = key->y >> FRACTOMAPBITS; + angle = key->angle; + + if (am_rotate == 1 || (am_rotate == 2 && viewactive)) + { + AM_rotatePoint (&p.x, &p.y); + angle += ANG90 - players[consoleplayer].camera->angle; + } + + color = ThingColor; + if (key->flags & MF_SPECIAL) + { + // Find the key's own color. + // Only works correctly if single-key locks have lower numbers than any-key locks. + // That is the case for all default keys, however. + int P_GetMapColorForKey (AInventory * key); + int c = P_GetMapColorForKey(key); + + if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); + else color = ThingColor_CountItem; + AM_drawLineCharacter(&EasyKey[0], EasyKey.Size(), 0, 0, color, p.x, p.y); + } + } +} + +//============================================================================= +// +// +// +//============================================================================= + void AM_drawThings () { AMColor color; @@ -2299,7 +2345,12 @@ void AM_drawThings () // That is the case for all default keys, however. if (t->IsKindOf(RUNTIME_CLASS(AKey))) { - if (am_showkeys) + if (G_SkillProperty(SKILLP_EasyKey)) + { + // Already drawn by AM_drawKeys(), so don't draw again + color.Index = -1; + } + else if (am_showkeys) { int P_GetMapColorForKey (AInventory * key); int c = P_GetMapColorForKey(static_cast(t)); @@ -2521,6 +2572,8 @@ void AM_Drawer () AM_drawWalls(allmap); AM_drawPlayers(); + if (G_SkillProperty(SKILLP_EasyKey)) + AM_drawKeys(); if (am_cheat >= 2 || allthings) AM_drawThings(); diff --git a/src/g_level.h b/src/g_level.h index 4b70f595a..10dc15eb8 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -545,7 +545,8 @@ enum ESkillProperty SKILLP_MonsterHealth, SKILLP_FriendlyHealth, SKILLP_NoPain, - SKILLP_ArmorFactor + SKILLP_ArmorFactor, + SKILLP_EasyKey, }; int G_SkillProperty(ESkillProperty prop); const char * G_SkillName(); @@ -564,6 +565,7 @@ struct FSkillInfo bool AutoUseHealth; bool EasyBossBrain; + bool EasyKey; int RespawnCounter; int RespawnLimit; fixed_t Aggressiveness; diff --git a/src/g_skill.cpp b/src/g_skill.cpp index cac38563a..46b9a1702 100644 --- a/src/g_skill.cpp +++ b/src/g_skill.cpp @@ -66,6 +66,7 @@ void FMapInfoParser::ParseSkill () skill.FastMonsters = false; skill.DisableCheats = false; skill.EasyBossBrain = false; + skill.EasyKey = false; skill.AutoUseHealth = false; skill.RespawnCounter = 0; skill.RespawnLimit = 0; @@ -125,6 +126,10 @@ void FMapInfoParser::ParseSkill () { skill.EasyBossBrain = true; } + else if (sc.Compare ("easykey")) + { + skill.EasyKey = true; + } else if (sc.Compare("autousehealth")) { skill.AutoUseHealth = true; @@ -351,6 +356,9 @@ int G_SkillProperty(ESkillProperty prop) case SKILLP_EasyBossBrain: return AllSkills[gameskill].EasyBossBrain; + case SKILLP_EasyKey: + return AllSkills[gameskill].EasyKey; + case SKILLP_SpawnFilter: return AllSkills[gameskill].SpawnFilter; @@ -428,6 +436,7 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other) DisableCheats = other.DisableCheats; AutoUseHealth = other.AutoUseHealth; EasyBossBrain = other.EasyBossBrain; + EasyKey = other.EasyKey; RespawnCounter= other.RespawnCounter; RespawnLimit= other.RespawnLimit; Aggressiveness= other.Aggressiveness; diff --git a/wadsrc/static/maparrows/ravenkey.txt b/wadsrc/static/maparrows/ravenkey.txt new file mode 100644 index 000000000..d66a64345 --- /dev/null +++ b/wadsrc/static/maparrows/ravenkey.txt @@ -0,0 +1,9 @@ +( 0, 0 ), ( 0.25, -0.5 ) +( 0.25, -0.5 ), ( 0.5, -0.5 ) +( 0.5, -0.5 ), ( 0.5, 0.5 ) +( 0.5, 0.5 ), ( 0.25, 0.5 ) +( 0.25, 0.5 ), ( 0, 0 ) // handle part type thing +( 0, 0 ), ( -1, 0 ) // stem +( -1, 0 ), ( -1, -0.5 ) // end lockpick part +( -0.75, 0 ), ( -0.75, -0.25 ) + diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 84dd4552d..196e81c50 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -75,6 +75,7 @@ skill baby EasyBossBrain SpawnFilter = Baby Name = "$MNU_WETNURSE" + EasyKey } skill easy From ebd115e7ca0c7cdf9893f63ebe106c73b1d04750 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 14 Feb 2012 03:15:13 +0000 Subject: [PATCH 081/993] - Removed snd_3dspread, because it totally does not do what I want. I was using it to preserve some of the stereoness of stereo sounds played in 3D. My testing was done only with stereo speakers, however, and I did not realize that it was moving the perceived physical location of the sound itself (because it sounded fine with my two speakers). So when 3D spread started working with mono sounds as well in FMOD 4.28, sound positioning was completely broken for everything when outputting to more than two speakers, because sounds were being spread across a 180 degree arc. Whoops! Stereo sounds are now completely mono when not played by you, the listener. SVN r3357 (trunk) --- src/sound/fmodsound.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 5af94a340..8c62e3b5e 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -1725,8 +1725,6 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi // //========================================================================== -CVAR(Float, snd_3dspread, 180, 0) - FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, @@ -1811,7 +1809,6 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener * if (mode & FMOD_3D) { chan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]); - chan->set3DSpread(snd_3dspread); } if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq)) { From 9ffb4c40ac6c87ec658e1e35366152fbb1f6f8c5 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 15 Feb 2012 02:18:30 +0000 Subject: [PATCH 082/993] - Added support for loading named ACS scripts. You can't run them directly at the moment, but you can still use them for automatically executed script types (like open and enter). - Change the DACSThinker::RunningScripts array into a TMap so that it can catalog the new range of ACS scripts (up to 32767). SVN r3359 (trunk) --- src/p_acs.cpp | 128 ++++++++++++++++++++++++++++++++++++++++---------- src/p_acs.h | 9 ++-- 2 files changed, 109 insertions(+), 28 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index d24da1275..5c0a5aa6e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1544,6 +1544,27 @@ void FBehavior::LoadScriptsDirectory () } } } + + // Load script names (if any) + scripts.b = FindChunk(MAKE_ID('S','N','A','M')); + if (scripts.dw != NULL) + { + for (i = 0; i < NumScripts; ++i) + { + // ACC stores script names as an index into the SNAM chunk, with the first index as + // -1 and counting down from there. We convert this from an index into SNAM into + // a negative index into the global name table. + if (Scripts[i].Number < 0) + { + const char *str = (const char *)(scripts.b + 8 + scripts.dw[3 + (-Scripts[i].Number - 1)]); + FName name(str); + Scripts[i].Number = -name; + } + } + // We need to resort scripts, because the new numbers for named scripts likely + // do not match the order they were originally in. + qsort (Scripts, NumScripts, sizeof(ScriptPtr), SortScripts); + } } int STACK_ARGS FBehavior::SortScripts (const void *a, const void *b) @@ -1621,8 +1642,8 @@ bool FBehavior::IsGood () const ScriptPtr *FBehavior::FindScript (int script) const { - const ScriptPtr *ptr = BinarySearch - ((ScriptPtr *)Scripts, NumScripts, &ScriptPtr::Number, (WORD)script); + const ScriptPtr *ptr = BinarySearch + ((ScriptPtr *)Scripts, NumScripts, &ScriptPtr::Number, script); // If the preceding script has the same number, return it instead. // See the note by the script sorting above for why. @@ -1859,6 +1880,50 @@ void FBehavior::StaticStopMyScripts (AActor *actor) } } +//========================================================================== +// +// SerializeScriptNumber +// +// Serializes a script number. If it's negative, it's really a name, so +// that will get serialized after it. +// +//========================================================================== + +static void SerializeScriptNumber(FArchive &arc, int &scriptnum, bool was2byte) +{ + if (SaveVersion < 3359) + { + if (was2byte) + { + WORD oldver; + arc << oldver; + scriptnum = oldver; + } + else + { + arc << scriptnum; + } + } + else + { + arc << scriptnum; + // If the script number is negative, then it's really a name. + // So read/store the name after it. + if (scriptnum < 0) + { + if (arc.IsStoring()) + { + arc.WriteName(FName(ENamedName(-scriptnum)).GetChars()); + } + else + { + const char *nam = arc.ReadName(); + scriptnum = -FName(nam); + } + } + } +} + //---- The ACS Interpreter ----// IMPLEMENT_POINTY_CLASS (DACSThinker) @@ -1880,8 +1945,7 @@ DACSThinker::DACSThinker () ActiveThinker = this; Scripts = NULL; LastScript = NULL; - for (int i = 0; i < 1000; i++) - RunningScripts[i] = NULL; + RunningScripts.Clear(); } } @@ -1893,27 +1957,34 @@ DACSThinker::~DACSThinker () void DACSThinker::Serialize (FArchive &arc) { + int scriptnum; + Super::Serialize (arc); arc << Scripts << LastScript; if (arc.IsStoring ()) { - WORD i; - for (i = 0; i < 1000; i++) + ScriptMap::Iterator it(RunningScripts); + ScriptMap::Pair *pair; + + while (it.NextPair(pair)) { - if (RunningScripts[i]) - arc << RunningScripts[i] << i; + assert(pair->Value != NULL); + arc << pair->Value; + scriptnum = pair->Key; + SerializeScriptNumber(arc, scriptnum, true); } DLevelScript *nilptr = NULL; arc << nilptr; } - else + else // Loading { - WORD scriptnum; DLevelScript *script = NULL; + RunningScripts.Clear(); + arc << script; while (script) { - arc << scriptnum; + SerializeScriptNumber(arc, scriptnum, true); RunningScripts[scriptnum] = script; arc << script; } @@ -1975,8 +2046,9 @@ void DLevelScript::Serialize (FArchive &arc) DWORD i; Super::Serialize (arc); - arc << next << prev - << script; + arc << next << prev; + + SerializeScriptNumber(arc, script, false); arc << state << statedata @@ -3713,13 +3785,13 @@ int DLevelScript::RunScript () case SCRIPT_ScriptWaitPre: // Wait for a script to start running, then enter state scriptwait - if (controller->RunningScripts[statedata]) + if (controller->RunningScripts.CheckKey(statedata) != NULL) state = SCRIPT_ScriptWait; break; case SCRIPT_ScriptWait: // Wait for a script to stop running, then enter state running - if (controller->RunningScripts[statedata]) + if (controller->RunningScripts.CheckKey(statedata) != NULL) return resultValue; state = SCRIPT_Running; @@ -5016,7 +5088,7 @@ int DLevelScript::RunScript () case PCD_SCRIPTWAIT: statedata = STACK(1); - if (controller->RunningScripts[statedata]) + if (controller->RunningScripts.CheckKey(statedata) != NULL) state = SCRIPT_ScriptWait; else state = SCRIPT_ScriptWaitPre; @@ -6960,8 +7032,12 @@ int DLevelScript::RunScript () if (state == SCRIPT_PleaseRemove) { Unlink (); - if (controller->RunningScripts[script] == this) - controller->RunningScripts[script] = NULL; + DLevelScript **running; + if ((running = controller->RunningScripts.CheckKey(script)) != NULL && + *running == this) + { + controller->RunningScripts.Remove(script); + } } else { @@ -6977,13 +7053,14 @@ static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, cons bool backSide, int arg0, int arg1, int arg2, int always) { DACSThinker *controller = DACSThinker::ActiveThinker; + DLevelScript **running; - if (controller && !always && controller->RunningScripts[num]) + if (controller && !always && (running = controller->RunningScripts.CheckKey(num)) != NULL) { - if (controller->RunningScripts[num]->GetState () == DLevelScript::SCRIPT_Suspended) + if ((*running)->GetState() == DLevelScript::SCRIPT_Suspended) { - controller->RunningScripts[num]->SetState (DLevelScript::SCRIPT_Running); - return controller->RunningScripts[num]; + (*running)->SetState(DLevelScript::SCRIPT_Running); + return *running; } return NULL; } @@ -7044,9 +7121,12 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr static void SetScriptState (int script, DLevelScript::EScriptState state) { DACSThinker *controller = DACSThinker::ActiveThinker; + DLevelScript **running; - if (controller != NULL && controller->RunningScripts[script]) - controller->RunningScripts[script]->SetState (state); + if (controller != NULL && (running = controller->RunningScripts.CheckKey(script)) != NULL) + { + (*running)->SetState (state); + } } void P_DoDeferedScripts () diff --git a/src/p_acs.h b/src/p_acs.h index 245d90c40..737501a74 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -76,18 +76,18 @@ void P_ClearACSVars(bool); // The in-memory version struct ScriptPtr { - WORD Number; + int Number; + DWORD Address; BYTE Type; BYTE ArgCount; WORD VarCount; WORD Flags; - DWORD Address; }; // The present ZDoom version struct ScriptPtr3 { - WORD Number; + SWORD Number; BYTE Type; BYTE ArgCount; DWORD Address; @@ -747,7 +747,8 @@ public: void Serialize (FArchive &arc); void Tick (); - DLevelScript *RunningScripts[1000]; // Array of all synchronous scripts + typedef TMap ScriptMap; + ScriptMap RunningScripts; // Array of all synchronous scripts static TObjPtr ActiveThinker; void DumpScriptStatus(); From 25b73ac0238cb3f17fc1e6e51e7a5721397b8586 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 16 Feb 2012 04:21:43 +0000 Subject: [PATCH 083/993] - Added ability to use a constant for the maximum comparator for health and armor drawbars. SVN r3360 (trunk) --- src/g_shared/sbarinfo_commands.cpp | 100 ++++++++++++++++++----------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 2c44c09f3..0f77151c3 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -2235,8 +2235,8 @@ class CommandDrawBar : public SBarInfoCommand { public: CommandDrawBar(SBarInfo *script) : SBarInfoCommand(script), - border(0), horizontal(false), reverse(false), foreground(-1), background(-1), - type(HEALTH), inventoryItem(NULL), interpolationSpeed(0), drawValue(0) + border(0), horizontal(false), reverse(false), foreground(-1), + background(-1), type(HEALTH), interpolationSpeed(0), drawValue(0) { } @@ -2297,28 +2297,12 @@ class CommandDrawBar : public SBarInfoCommand if(sc.Compare("health")) { type = HEALTH; - if(sc.CheckToken(TK_Identifier)) //comparing reference - { - inventoryItem = PClass::FindClass(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) //must be a kind of inventory - { - sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); - inventoryItem = RUNTIME_CLASS(AInventory); - } - } + ParseComparator(sc); } else if(sc.Compare("armor")) { type = ARMOR; - if(sc.CheckToken(TK_Identifier)) - { - inventoryItem = PClass::FindClass(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) //must be a kind of inventory - { - sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); - inventoryItem = RUNTIME_CLASS(AInventory); - } - } + ParseComparator(sc); } else if(sc.Compare("ammo1")) type = AMMO1; @@ -2328,11 +2312,11 @@ class CommandDrawBar : public SBarInfoCommand { sc.MustGetToken(TK_Identifier); type = AMMO; - inventoryItem = PClass::FindClass(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(inventoryItem)) //must be a kind of ammo + data.inventoryItem = PClass::FindClass(sc.String); + if(data.inventoryItem == NULL || !RUNTIME_CLASS(AAmmo)->IsAncestorOf(data.inventoryItem)) //must be a kind of ammo { sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); - inventoryItem = RUNTIME_CLASS(AAmmo); + data.inventoryItem = RUNTIME_CLASS(AAmmo); } } else if(sc.Compare("frags")) @@ -2351,21 +2335,21 @@ class CommandDrawBar : public SBarInfoCommand { type = POWERUPTIME; sc.MustGetToken(TK_Identifier); - inventoryItem = PClass::FindClass(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(inventoryItem)) + data.inventoryItem = PClass::FindClass(sc.String); + if(data.inventoryItem == NULL || !RUNTIME_CLASS(APowerupGiver)->IsAncestorOf(data.inventoryItem)) { sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String); - inventoryItem = RUNTIME_CLASS(APowerupGiver); + data.inventoryItem = RUNTIME_CLASS(APowerupGiver); } } else { type = INVENTORY; - inventoryItem = PClass::FindClass(sc.String); - if(inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(inventoryItem)) + data.inventoryItem = PClass::FindClass(sc.String); + if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem)) { sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); - inventoryItem = RUNTIME_CLASS(AInventory); + data.inventoryItem = RUNTIME_CLASS(AInventory); } } sc.MustGetToken(','); @@ -2423,9 +2407,11 @@ class CommandDrawBar : public SBarInfoCommand if(value < 0) //health shouldn't display negatives value = 0; - if(inventoryItem != NULL) + if(data.useMaximumConstant) + max = data.value; + else if(data.inventoryItem != NULL) { - AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem); //max comparer + AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem); //max comparer if(item != NULL) max = item->Amount; else @@ -2436,9 +2422,11 @@ class CommandDrawBar : public SBarInfoCommand break; case ARMOR: value = statusBar->armor != NULL ? statusBar->armor->Amount : 0; - if(inventoryItem != NULL) + if(data.useMaximumConstant) + max = data.value; + else if(data.inventoryItem != NULL) { - AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem); + AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem); if(item != NULL) max = item->Amount; else @@ -2469,7 +2457,7 @@ class CommandDrawBar : public SBarInfoCommand break; case AMMO: { - AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem); + AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem); if(item != NULL) { value = item->Amount; @@ -2497,7 +2485,7 @@ class CommandDrawBar : public SBarInfoCommand break; case INVENTORY: { - AInventory *item = statusBar->CPlayer->mo->FindInventory(inventoryItem); + AInventory *item = statusBar->CPlayer->mo->FindInventory(data.inventoryItem); if(item != NULL) { value = item->Amount; @@ -2514,7 +2502,7 @@ class CommandDrawBar : public SBarInfoCommand case POWERUPTIME: { //Get the PowerupType and check to see if the player has any in inventory. - APowerupGiver *powerupGiver = (APowerupGiver*) GetDefaultByType(inventoryItem); + APowerupGiver *powerupGiver = (APowerupGiver*) GetDefaultByType(data.inventoryItem); const PClass *powerupType = powerupGiver->PowerupType; APowerup *powerup = (APowerup*) statusBar->CPlayer->mo->FindInventory(powerupType); if(powerup != NULL && powerupType != NULL && powerupGiver != NULL) @@ -2566,6 +2554,29 @@ class CommandDrawBar : public SBarInfoCommand drawValue = value; } protected: + void ParseComparator(FScanner &sc) + { + bool extendedSyntax = sc.CheckToken('('); + + if(sc.CheckToken(TK_Identifier)) //comparing reference + { + data.inventoryItem = PClass::FindClass(sc.String); + if(data.inventoryItem == NULL || !RUNTIME_CLASS(AInventory)->IsAncestorOf(data.inventoryItem)) //must be a kind of inventory + { + sc.ScriptMessage("'%s' is not a type of inventory item.", sc.String); + data.inventoryItem = RUNTIME_CLASS(AInventory); + } + } + else if(extendedSyntax && sc.CheckToken(TK_IntConst)) + { + data.useMaximumConstant = true; + data.value = sc.Number; + } + + if(extendedSyntax) + sc.MustGetToken(')'); + } + enum ValueType { HEALTH, @@ -2584,13 +2595,28 @@ class CommandDrawBar : public SBarInfoCommand SAVEPERCENT }; + struct AdditionalData + { + public: + AdditionalData() : useMaximumConstant(false) + { + } + + bool useMaximumConstant; + union + { + const PClass *inventoryItem; + int value; + }; + }; + unsigned int border; bool horizontal; bool reverse; int foreground; int background; ValueType type; - const PClass *inventoryItem; + AdditionalData data; SBarInfoCoordinate x; SBarInfoCoordinate y; From da974c34442ba9a703219192d5514935f2401eae Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 16 Feb 2012 05:01:17 +0000 Subject: [PATCH 084/993] - Allow any parameterized SBarInfo value to use parentheses to help make the syntax a little more consistent. SVN r3361 (trunk) --- src/g_shared/sbarinfo_commands.cpp | 37 ++++++++++++++++++++++++++++++ wadsrc/static/sbarinfo/doom.txt | 16 ++++++------- wadsrc/static/sbarinfo/hexen.txt | 24 +++++++++---------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 0f77151c3..6a295237a 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -65,6 +65,7 @@ class CommandDrawImage : public SBarInfoCommand } void Parse(FScanner &sc, bool fullScreenOffsets) { + bool parenthesized = false; bool getImage = true; if(sc.CheckToken(TK_Identifier)) { @@ -83,6 +84,8 @@ class CommandDrawImage : public SBarInfoCommand type = SIGIL; else if(sc.Compare("hexenarmor")) { + parenthesized = sc.CheckToken('('); + sc.MustGetToken(TK_Identifier); if(sc.Compare("armor")) type = HEXENARMOR_ARMOR; @@ -125,6 +128,8 @@ class CommandDrawImage : public SBarInfoCommand sc.MustGetToken(TK_StringConst); image = script->newImage(sc.String); sprite.SetInvalid(); + + if(parenthesized) sc.MustGetToken(')'); } sc.MustGetToken(','); GetCoordinates(sc, fullScreenOffsets, imgx, imgy); @@ -636,19 +641,27 @@ class CommandDrawString : public SBarInfoCommand strValue = LOGTEXT; else if(sc.Compare("globalvar")) { + bool parenthesized = sc.CheckToken('('); + strValue = GLOBALVAR; sc.MustGetToken(TK_IntConst); if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) sc.ScriptError("Global variable number out of range: %d", sc.Number); valueArgument = sc.Number; + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("globalarray")) { + bool parenthesized = sc.CheckToken('('); + strValue = GLOBALARRAY; sc.MustGetToken(TK_IntConst); if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) sc.ScriptError("Global variable number out of range: %d", sc.Number); valueArgument = sc.Number; + + if(parenthesized) sc.MustGetToken(')'); } else sc.ScriptError("Unknown string '%s'.", sc.String); @@ -899,6 +912,8 @@ class CommandDrawNumber : public CommandDrawString value = SCORE; else if(sc.Compare("ammo")) //request the next string to be an ammo type { + bool parenthesized = sc.CheckToken('('); + value = AMMO; sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindClass(sc.String); @@ -907,9 +922,13 @@ class CommandDrawNumber : public CommandDrawString sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); inventoryItem = RUNTIME_CLASS(AAmmo); } + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("ammocapacity")) { + bool parenthesized = sc.CheckToken('('); + value = AMMOCAPACITY; sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindClass(sc.String); @@ -918,6 +937,8 @@ class CommandDrawNumber : public CommandDrawString sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); inventoryItem = RUNTIME_CLASS(AAmmo); } + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("frags")) value = FRAGS; @@ -947,22 +968,32 @@ class CommandDrawNumber : public CommandDrawString value = KEYS; else if(sc.Compare("globalvar")) { + bool parenthesized = sc.CheckToken('('); + value = GLOBALVAR; sc.MustGetToken(TK_IntConst); if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) sc.ScriptError("Global variable number out of range: %d", sc.Number); valueArgument = sc.Number; + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("globalarray")) //acts like variable[playernumber()] { + bool parenthesized = sc.CheckToken('('); + value = GLOBALARRAY; sc.MustGetToken(TK_IntConst); if(sc.Number < 0 || sc.Number >= NUM_GLOBALVARS) sc.ScriptError("Global variable number out of range: %d", sc.Number); valueArgument = sc.Number; + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("poweruptime")) { + bool parenthesized = sc.CheckToken('('); + value = POWERUPTIME; sc.MustGetToken(TK_Identifier); inventoryItem = PClass::FindClass(sc.String); @@ -971,6 +1002,8 @@ class CommandDrawNumber : public CommandDrawString sc.ScriptMessage("'%s' is not a type of PowerupGiver.", sc.String); inventoryItem = RUNTIME_CLASS(APowerupGiver); } + + if(parenthesized) sc.MustGetToken(')'); } else { @@ -2310,6 +2343,8 @@ class CommandDrawBar : public SBarInfoCommand type = AMMO2; else if(sc.Compare("ammo")) //request the next string to be an ammo type { + bool parenthesized = sc.CheckToken('('); + sc.MustGetToken(TK_Identifier); type = AMMO; data.inventoryItem = PClass::FindClass(sc.String); @@ -2318,6 +2353,8 @@ class CommandDrawBar : public SBarInfoCommand sc.ScriptMessage("'%s' is not a type of ammo.", sc.String); data.inventoryItem = RUNTIME_CLASS(AAmmo); } + + if(parenthesized) sc.MustGetToken(')'); } else if(sc.Compare("frags")) type = FRAGS; diff --git a/wadsrc/static/sbarinfo/doom.txt b/wadsrc/static/sbarinfo/doom.txt index d80d0390b..08e81f6ca 100644 --- a/wadsrc/static/sbarinfo/doom.txt +++ b/wadsrc/static/sbarinfo/doom.txt @@ -79,15 +79,15 @@ statusbar normal // Standard Doom Status bar drawswitchableimage keyslot 3 && 6, "nullimage", "STKEYS1", "STKEYS4", "STKEYS7", 239, 181; drawswitchableimage keyslot 1 && 4, "nullimage", "STKEYS2", "STKEYS5", "STKEYS8", 239, 191; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammo Clip, 288, 173; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammo Shell, 288, 179; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammo RocketAmmo, 288, 185; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammo Cell, 288, 191; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammo(Clip), 288, 173; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammo(Shell), 288, 179; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammo(RocketAmmo), 288, 185; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammo(Cell), 288, 191; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity Clip, 314, 173; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity Shell, 314, 179; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity RocketAmmo, 314, 185; - drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity Cell, 314, 191; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity(Clip), 314, 173; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity(Shell), 314, 179; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity(RocketAmmo), 314, 185; + drawnumber 3, INDEXFONT_DOOM, untranslated, ammocapacity(Cell), 314, 191; gamemode deathmatch, teamgame { drawnumber 2, HUDFONT_DOOM, untranslated, frags, 138, 171; diff --git a/wadsrc/static/sbarinfo/hexen.txt b/wadsrc/static/sbarinfo/hexen.txt index e7a4c6c40..6450fac58 100755 --- a/wadsrc/static/sbarinfo/hexen.txt +++ b/wadsrc/static/sbarinfo/hexen.txt @@ -44,8 +44,8 @@ statusbar fullscreen, fullscreenoffsets drawimage "MANABRT2", -17, -15; else drawimage "MANADIM2", -17, -15; - drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo Mana1, drawshadow(1, 1), -21, -30, 1; - drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo Mana2, drawshadow(1, 1), -21, -15, 1; + drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo(Mana1), drawshadow(1, 1), -21, -30, 1; + drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo(Mana2), drawshadow(1, 1), -21, -15, 1; } } @@ -73,25 +73,25 @@ statusbar Normal weaponammo Mana1 { drawimage "MANABRT1", 77, 164; - drawbar "MANAVL1", "nullimage", ammo Mana1, vertical, 94, 164, 1; + drawbar "MANAVL1", "nullimage", ammo(Mana1), vertical, 94, 164, 1; } else { drawimage "MANADIM1", 77, 164; - drawbar "MANAVL1D", "nullimage", ammo Mana1, vertical, 94, 164, 1; + drawbar "MANAVL1D", "nullimage", ammo(Mana1), vertical, 94, 164, 1; } weaponammo Mana2 { drawimage "MANABRT2", 110, 164; - drawbar "MANAVL2", "nullimage", ammo Mana2, vertical, 102, 164, 1; + drawbar "MANAVL2", "nullimage", ammo(Mana2), vertical, 102, 164, 1; } else { drawimage "MANADIM2", 110, 164; - drawbar "MANAVL2D", "nullimage", ammo Mana2, vertical, 102, 164, 1; + drawbar "MANAVL2D", "nullimage", ammo(Mana2), vertical, 102, 164, 1; } - drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo Mana1, 91, 181; - drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo Mana2, 123, 181; + drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo(Mana1), 91, 181; + drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo(Mana2), 123, 181; } else //Weapon doesn't use ammo draw an alternative { @@ -207,10 +207,10 @@ statusbar Automap drawimage "H2BAR", 0, 135; drawimage "KEYBAR", 38, 162; drawkeybar 5, horizontal, 20, 46, 164; - drawimage hexenarmor armor, "ARMSLOT1", 150, 164; - drawimage hexenarmor shield, "ARMSLOT2", 181, 164; - drawimage hexenarmor helm, "ARMSLOT3", 212, 164; - drawimage hexenarmor amulet, "ARMSLOT4", 243, 164; + drawimage hexenarmor(armor, "ARMSLOT1"), 150, 164; + drawimage hexenarmor(shield, "ARMSLOT2"), 181, 164; + drawimage hexenarmor(helm, "ARMSLOT3"), 212, 164; + drawimage hexenarmor(amulet, "ARMSLOT4"), 243, 164; // Also draw the life gem here playertype FighterPlayer From 6f17e0f51b5d92dc8930d4182ef45988e8a66bd4 Mon Sep 17 00:00:00 2001 From: Braden Obrzut Date: Thu, 16 Feb 2012 20:18:46 +0000 Subject: [PATCH 085/993] - Fixed: Mac universal binary build. (I actually just realized that my DRDTeam build script ended up just working because of this modification.) SVN r3362 (trunk) --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98860716b..1d3d1067e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -359,7 +359,7 @@ endif( NOT NO_ASM ) set( SSE_MATTERS NO ) # SSE only matters on 32-bit targets. We check compiler flags to know if we can do it. -if( CMAKE_SIZEOF_VOID_P MATCHES "4" ) +if( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) CHECK_CXX_COMPILER_FLAG( "-msse2 -mfpmath=sse" CAN_DO_MFPMATH ) CHECK_CXX_COMPILER_FLAG( -arch:SSE2 CAN_DO_ARCHSSE2 ) if( CAN_DO_MFPMATH ) @@ -371,7 +371,7 @@ if( CMAKE_SIZEOF_VOID_P MATCHES "4" ) set( SSE2_ENABLE -arch:SSE2 ) set( SSE_MATTERS YES ) endif( CAN_DO_MFPMATH ) -endif( CMAKE_SIZEOF_VOID_P MATCHES "4" ) +endif( CMAKE_SIZEOF_VOID_P MATCHES "4" AND NOT CMAKE_OSX_ARCHITECTURES MATCHES ppc ) if( SSE_MATTERS ) if( WIN32 ) From 419599302334922ccd343fffb67c708676c07737 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 16 Feb 2012 21:23:03 +0000 Subject: [PATCH 086/993] - Make deferred scripts work with named scripts. - Added ACS_Named* function variants of the ACS_* specials that take script names instead of numbers. As these are functions and not specials, they can only be used from inside ACS. SVN r3363 (trunk) --- src/p_acs.cpp | 37 ++++++++++++++++++++++++++++++++----- src/p_lnspec.cpp | 13 +++++++++++++ src/p_lnspec.h | 2 ++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 5c0a5aa6e..02543313d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3,7 +3,7 @@ ** General BEHAVIOR management and ACS execution environment ** **--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit +** Copyright 1998-2012 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -3198,6 +3198,13 @@ enum EACSFunctions ACSF_SpawnForced, ACSF_AnnouncerSound, // Skulltag ACSF_SetPointer, + ACSF_ACS_NamedExecute, + ACSF_ACS_NamedSuspend, + ACSF_ACS_NamedTerminate, + ACSF_ACS_NamedLockedExecute, + ACSF_ACS_NamedLockedExecuteDoor, + ACSF_ACS_NamedExecuteWithResult, + ACSF_ACS_NamedExecuteAlways, }; int DLevelScript::SideFromID(int id, int side) @@ -3691,6 +3698,25 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args) case ACSF_SpawnForced: return DoSpawn(args[0], args[1], args[2], args[3], args[4], args[5], true); + case ACSF_ACS_NamedExecute: + case ACSF_ACS_NamedSuspend: + case ACSF_ACS_NamedTerminate: + case ACSF_ACS_NamedLockedExecute: + case ACSF_ACS_NamedLockedExecuteDoor: + case ACSF_ACS_NamedExecuteWithResult: + case ACSF_ACS_NamedExecuteAlways: + { + int scriptnum = -FName(FBehavior::StaticLookupString(args[0])); + int arg1 = argCount > 1 ? args[1] : 0; + int arg2 = argCount > 2 ? args[2] : 0; + int arg3 = argCount > 3 ? args[3] : 0; + int arg4 = argCount > 4 ? args[4] : 0; + return P_ExecuteSpecial(NamedACSToNormalACS[funcIndex - ACSF_ACS_NamedExecute], + activationline, activator, backSide, + scriptnum, arg1, arg2, arg3, arg4); + } + break; + default: break; } @@ -7283,8 +7309,9 @@ FArchive &operator<< (FArchive &arc, acsdefered_t *&defertop) BYTE type; arc << more; type = (BYTE)defer->type; - arc << type << defer->script << defer->playernum - << defer->arg0 << defer->arg1 << defer->arg2; + arc << type; + SerializeScriptNumber(arc, defer->script, false); + arc << defer->playernum << defer->arg0 << defer->arg1 << defer->arg2; defer = defer->next; } more = 0; @@ -7300,8 +7327,8 @@ FArchive &operator<< (FArchive &arc, acsdefered_t *&defertop) *defer = new acsdefered_t; arc << more; (*defer)->type = (acsdefered_t::EType)more; - arc << (*defer)->script << (*defer)->playernum - << (*defer)->arg0 << (*defer)->arg1 << (*defer)->arg2; + SerializeScriptNumber(arc, (*defer)->script, false); + arc << (*defer)->playernum << (*defer)->arg0 << (*defer)->arg1 << (*defer)->arg2; defer = &((*defer)->next); arc << more; } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index dd66fdb0f..746db932d 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -69,6 +69,19 @@ static FRandom pr_glass ("GlassBreak"); +// There are aliases for the ACS specials that take names instead of numbers. +// This table maps them onto the real number-based specials. +BYTE NamedACSToNormalACS[7] = +{ + ACS_Execute, + ACS_Suspend, + ACS_Terminate, + ACS_LockedExecute, + ACS_LockedExecuteDoor, + ACS_ExecuteWithResult, + ACS_ExecuteAlways, +}; + FName MODtoDamageType (int mod) { switch (mod) diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 1b842d29f..1d6a21bd9 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -197,6 +197,8 @@ typedef int (*lnSpecFunc)(struct line_t *line, extern lnSpecFunc LineSpecials[256]; +extern BYTE NamedACSToNormalACS[7]; + int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL); bool P_ActivateThingSpecial(AActor * thing, AActor * trigger, bool death=false); int P_ExecuteSpecial(int num, From 7561beb21219098722e0c424509e402540f9da8c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 16 Feb 2012 21:49:09 +0000 Subject: [PATCH 087/993] - Added action functions that work with script names instead of script numbers. They are named the same as their ACS function equivalents. e.g. From DECORATE, you can now use ACS_NamedExecuteAlways to run a script with a name. SVN r3364 (trunk) --- src/thingdef/thingdef_codeptr.cpp | 109 +++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 8 ++ wadsrc/static/actors/doom/doomplayer.txt | 7 +- 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b801b3e4f..18700c166 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4099,3 +4099,112 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) } } + +//========================================================================== +// +// ACS_Named* stuff +// +// These are exactly like their un-named line special equivalents, except +// they take strings instead of integers to indicate which script to run. +// Some of these probably aren't very useful, but they are included for +// the sake of completeness. +// +//========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedExecuteWithResult) +{ + ACTION_PARAM_START(4); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(arg1, 2); + ACTION_PARAM_INT(arg2, 3); + ACTION_PARAM_INT(arg3, 4); + + bool res = !!P_ExecuteSpecial(ACS_ExecuteWithResult, NULL, self, false, -scriptname, arg1, arg2, arg3, 0); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedExecute) +{ + ACTION_PARAM_START(5); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + ACTION_PARAM_INT(arg1, 2); + ACTION_PARAM_INT(arg2, 3); + ACTION_PARAM_INT(arg3, 4); + + bool res = !!P_ExecuteSpecial(ACS_Execute, NULL, self, false, -scriptname, mapnum, arg1, arg2, arg3); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedExecuteAlways) +{ + ACTION_PARAM_START(5); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + ACTION_PARAM_INT(arg1, 2); + ACTION_PARAM_INT(arg2, 3); + ACTION_PARAM_INT(arg3, 4); + + bool res = !!P_ExecuteSpecial(ACS_ExecuteAlways, NULL, self, false, -scriptname, mapnum, arg1, arg2, arg3); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedLockedExecute) +{ + ACTION_PARAM_START(5); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + ACTION_PARAM_INT(arg1, 2); + ACTION_PARAM_INT(arg2, 3); + ACTION_PARAM_INT(lock, 4); + + bool res = !!P_ExecuteSpecial(ACS_LockedExecute, NULL, self, false, -scriptname, mapnum, arg1, arg2, lock); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedLockedExecuteDoor) +{ + ACTION_PARAM_START(5); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + ACTION_PARAM_INT(arg1, 2); + ACTION_PARAM_INT(arg2, 3); + ACTION_PARAM_INT(lock, 4); + + bool res = !!P_ExecuteSpecial(ACS_LockedExecuteDoor, NULL, self, false, -scriptname, mapnum, arg1, arg2, lock); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedSuspend) +{ + ACTION_PARAM_START(2); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + + bool res = !!P_ExecuteSpecial(ACS_Suspend, NULL, self, false, -scriptname, mapnum, 0, 0, 0); + + ACTION_SET_RESULT(res); +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, ACS_NamedTerminate) +{ + ACTION_PARAM_START(2); + + ACTION_PARAM_NAME(scriptname, 0); + ACTION_PARAM_INT(mapnum, 1); + + bool res = !!P_ExecuteSpecial(ACS_Terminate, NULL, self, false, -scriptname, mapnum, 0, 0, 0); + + ACTION_SET_RESULT(res); +} diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 0d51bf4e8..1876ebb61 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -293,6 +293,14 @@ ACTOR Actor native //: Thinker action native A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); action native A_CopyFriendliness(int ptr_source = AAPTR_MASTER); + action native ACS_NamedExecute(string script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0); + action native ACS_NamedSuspend(string script, int mapnum=0); + action native ACS_NamedTerminate(string script, int mapnum=0); + action native ACS_NamedLockedExecute(string script, int mapnum=0, int arg1=0, int arg2=0, int lock=0); + action native ACS_NamedLockedExecuteDoor(string script, int mapnum=0, int arg1=0, int arg2=0, int lock=0); + action native ACS_NamedExecuteWithResult(string script, int arg1=0, int arg2=0, int arg3=0); + action native ACS_NamedExecuteAlways(string script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0); + States { Spawn: diff --git a/wadsrc/static/actors/doom/doomplayer.txt b/wadsrc/static/actors/doom/doomplayer.txt index 3f81eaaca..08cbeaaea 100644 --- a/wadsrc/static/actors/doom/doomplayer.txt +++ b/wadsrc/static/actors/doom/doomplayer.txt @@ -41,16 +41,16 @@ ACTOR DoomPlayer : PlayerPawn PLAY A -1 Loop See: - PLAY ABCD 4 + PLAY ABCD 4 Loop Missile: - PLAY E 12 + PLAY E 12 Goto Spawn Melee: PLAY F 6 BRIGHT Goto Missile Pain: - PLAY G 4 + PLAY G 4 PLAY G 4 A_Pain Goto Spawn Death: @@ -88,4 +88,3 @@ ACTOR DoomPlayer : PlayerPawn Stop } } - From 8f516a10078becfd60ad5f813e9de0ff23f0edd2 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 16 Feb 2012 22:13:46 +0000 Subject: [PATCH 088/993] - Added pukename console command. This is mostly the same as puke, except the scripts are named, and to run a script using ACS_ExecuteAlways, you need to add "always" after the script name but before any arguments. e.g.: pukename "A Script" 1 Will run the script "A Script" with a single argument of 1, provided the script is not already running. pukename "A Script" always 1 Will always run the script "A Script" with a single argument of 1. SVN r3365 (trunk) --- src/c_cmds.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/d_net.cpp | 47 +++++++++++++++++++++++++++++++++++------------ src/d_protocol.h | 1 + src/version.h | 4 ++-- 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 993b4677f..da8131027 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -489,6 +489,44 @@ CCMD (puke) } } +CCMD (pukename) +{ + int argc = argv.argc(); + + if (argc < 2 || argc > 6) + { + Printf ("Usage: pukename \"