diff --git a/bzip2/CMakeLists.txt b/bzip2/CMakeLists.txt index e819f4cde..5c1255604 100644 --- a/bzip2/CMakeLists.txt +++ b/bzip2/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) if( CMAKE_COMPILER_IS_GNUC ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fomit-frame-pointer" ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( CMAKE_COMPILER_IS_GNUC ) add_definitions( -DBZ_NO_STDIO ) diff --git a/game-music-emu/CMakeLists.txt b/game-music-emu/CMakeLists.txt index 0f1355336..7905f847a 100644 --- a/game-music-emu/CMakeLists.txt +++ b/game-music-emu/CMakeLists.txt @@ -7,7 +7,7 @@ if( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) endif( NOT CMAKE_BUILD_TYPE MATCHES "Release" ) if( CMAKE_COMPILER_IS_GNUCXX ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) if( NOT PROFILE ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer" ) endif( NOT PROFILE ) diff --git a/game-music-emu/gme/Gbs_Emu.cpp b/game-music-emu/gme/Gbs_Emu.cpp index a2b1d613f..83aefb424 100644 --- a/game-music-emu/gme/Gbs_Emu.cpp +++ b/game-music-emu/gme/Gbs_Emu.cpp @@ -18,8 +18,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "blargg_source.h" -Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000 }; -Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300 }; +Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000, 0, 0, 0, 0, 0, 0, 0, 0 }; +Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300, 0, 0, 0, 0, 0, 0, 0, 0 }; Gbs_Emu::Gbs_Emu() { @@ -39,7 +39,7 @@ Gbs_Emu::Gbs_Emu() set_max_initial_silence( 21 ); set_gain( 1.2 ); - static equalizer_t const eq = { -1.0, 120 }; + static equalizer_t const eq = { -1.0, 120, 0, 0, 0, 0, 0, 0, 0, 0 }; set_equalizer( eq ); } diff --git a/game-music-emu/gme/Music_Emu.cpp b/game-music-emu/gme/Music_Emu.cpp index f01024ce3..b0f3f71d5 100644 --- a/game-music-emu/gme/Music_Emu.cpp +++ b/game-music-emu/gme/Music_Emu.cpp @@ -24,7 +24,7 @@ int const silence_threshold = 0x10; long const fade_block_size = 512; int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift) -Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180 }; +Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180, 0, 0, 0, 0, 0, 0, 0, 0 }; void Music_Emu::clear_track_vars() { diff --git a/game-music-emu/gme/Nsf_Emu.cpp b/game-music-emu/gme/Nsf_Emu.cpp index 15f9e0b46..59d9b98cf 100644 --- a/game-music-emu/gme/Nsf_Emu.cpp +++ b/game-music-emu/gme/Nsf_Emu.cpp @@ -31,8 +31,8 @@ int const fme7_flag = 0x20; long const clock_divisor = 12; -Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80 }; -Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80 }; +Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; +Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr ) { diff --git a/game-music-emu/gme/Vgm_Emu.cpp b/game-music-emu/gme/Vgm_Emu.cpp index fc5394480..fe4be10a5 100644 --- a/game-music-emu/gme/Vgm_Emu.cpp +++ b/game-music-emu/gme/Vgm_Emu.cpp @@ -36,7 +36,7 @@ Vgm_Emu::Vgm_Emu() set_silence_lookahead( 1 ); // tracks should already be trimmed - static equalizer_t const eq = { -14.0, 80 }; + static equalizer_t const eq = { -14.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 }; set_equalizer( eq ); } diff --git a/game-music-emu/gme/gme.cpp b/game-music-emu/gme/gme.cpp index 23e7198d3..c9154c7a4 100644 --- a/game-music-emu/gme/gme.cpp +++ b/game-music-emu/gme/gme.cpp @@ -337,7 +337,7 @@ void GMEAPI gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq ) void GMEAPI gme_equalizer( Music_Emu const* me, gme_equalizer_t* out ) { - gme_equalizer_t e = { }; + gme_equalizer_t e = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; e.treble = me->equalizer().treble; e.bass = me->equalizer().bass; *out = e; diff --git a/gdtoa/CMakeLists.txt b/gdtoa/CMakeLists.txt index 9ef4b9c3e..6fc394d8d 100644 --- a/gdtoa/CMakeLists.txt +++ b/gdtoa/CMakeLists.txt @@ -8,8 +8,8 @@ if( MSVC ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4554 /wd4102" ) endif( MSVC ) -if( CMAKE_COMPILER_IS_GNUCXX ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) +if( CMAKE_COMPILER_IS_GNUCXX ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra" ) endif( CMAKE_COMPILER_IS_GNUCXX ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/jpeg-6b/CMakeLists.txt b/jpeg-6b/CMakeLists.txt index 665e99d4a..c3a5f458c 100644 --- a/jpeg-6b/CMakeLists.txt +++ b/jpeg-6b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) if( CMAKE_COMPILER_IS_GNUC ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fomit-frame-pointer" ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( CMAKE_COMPILER_IS_GNUC ) add_library( jpeg diff --git a/lzma/CMakeLists.txt b/lzma/CMakeLists.txt index b9b4bc047..6a2561c68 100644 --- a/lzma/CMakeLists.txt +++ b/lzma/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 2.4 ) if( CMAKE_COMPILER_IS_GNUC ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fomit-frame-pointer" ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" ) endif( CMAKE_COMPILER_IS_GNUC ) set( LZMA_FILES diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index fe6897d9f..f61096f69 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -1,5 +1,5 @@ =============================================================================== -Universal Doom Map Format ZDoom extensions v1.10 - 25.04.2010 +Universal Doom Map Format ZDoom extensions v1.15 - 14.12.2010 Copyright (c) 2008 Christoph Oelckers. @@ -84,6 +84,12 @@ field to 'strifeally', even for the 'Doom' namespace. In addition to the standard fields, ZDoom defines the following: Note: All fields default to false unless mentioned otherwise. + vertex + { + zfloor = ; // Floor height at this vertex. Only applies to triangular sectors + zceiling = ; // Ceiling height at this vertex. Only applies to triangular sectors + } + linedef { alpha = ; // Translucency of this line, default is 1.0 @@ -106,6 +112,7 @@ Note: All fields default to false unless mentioned otherwise. checkswitchrange = ;// Switches can only be activated when vertically reachable. blockprojectiles = ;// Line blocks all projectiles blockuse = ; // Line blocks all use actions + blocksight = ; // Line blocks monster line of sight } @@ -153,9 +160,15 @@ Note: All fields default to false unless mentioned otherwise. // relative to the owning sector's light level. lightceilingabsolute = ; // true = 'lightceiling' is an absolute value. Default is // relative to the owning sector's light level. + alphafloor = ; // translucency of floor plane (only has meaning with Sector_SetPortal) Default is 1.0. + alphaceiling = ; // translucency of ceiling plane (only has meaning with Sector_SetPortal) Default is 1.0. + renderstylefloor = ; // floor plane renderstyle (only has meaning with Sector_SetPortal); not implemented yet in software renderer + // can be "translucent" or "add", default is "translucent". + renderstyleceiling = ; // ceiling plane renderstyle (only has meaning with Sector_SetPortal); not implemented yet in software renderer + // can be "translucent" or "add", default is "translucent". gravity = ; // Sector's gravity. Default is 1.0. - lightcolor = ; // Sector'S light color as RRGGBB value, default = 0xffffff. - fadecolor = ; // Sector'S fog color as RRGGBB value, default = 0x000000. + lightcolor = ; // Sector's light color as RRGGBB value, default = 0xffffff. + fadecolor = ; // Sector's fog color as RRGGBB value, default = 0x000000. desaturation = ; // Color desaturation factor. 0 = none, 1 = full, default = 0. silent = ; // Actors in this sector make no sound, nofallingdamage = ; // Falling damage is disabled in this sector @@ -167,7 +180,7 @@ Note: All fields default to false unless mentioned otherwise. * Note about dropactors - The spec requires this to be false by default. Currently, however ZDoom assumes this to be true + The spec requires this to be false by default. Currently, however, ZDoom assumes this to be true for Doom format maps so any map converter converting to the ZDoomTranslated namespace should set this flag for each tagged sector. @@ -175,14 +188,11 @@ Note: All fields default to false unless mentioned otherwise. thing { - skill# = // Unlike the base spec, # can range from 1-8. - // 8 is the maximum amount of skills the skill - // menu can display. - class# = // Unlike the base spec, # can range from 1-8. - // 8 is the maximum amount of classes the class - // menu can display. + skill# = // Unlike the base spec, # can range from 1-16. + class# = // Unlike the base spec, # can range from 1-16. conversation = // Assigns a conversation dialogue to this thing. // Parameter is the conversation ID, 0 meaning none. + countsecret = ; // Picking up this actor counts as a secret. } @@ -202,6 +212,7 @@ Note: All fields default to false unless mentioned otherwise. 181: Plane_Align, arg2 215: Teleport_Line, arg0 222: Scroll_Texture_Model, arg0 (arg0 must be preserved) + 160: Sector_3DFloor, arg4 (both uses as high-byte of tag and line ID are not supported in UDMF and must be remapped) Some specials also allow setting the extended flags. These must also be converted to explicitly setting the flags through the defined map fields. @@ -269,7 +280,7 @@ Changed node specifications to deprecate compression of node lump. Added 'playeruseback' line trigger flag. 1.11 07.08.2010 -Added 'soundsequnce' sector property. +Added 'soundsequence' sector property. 1.12 22.08.2010 Added 'conversation' thing property. @@ -277,6 +288,21 @@ Added 'conversation' thing property. 1.13 29.08.2010 Added 'hidden' sector property. +1.14 19.09.2010 +Added 'countsecret' actor property. + +1.15 14.12.2010 +Added vertex floor and ceiling height properties + +1.16 23.01.2011 +Added alphaceiling and alphafloor sector properties +Added blocksight linedef flag +Removed remarks of 8 being the maximum number of player classes/skill levels the menu can handle so the spec now properly lists 16 as limit. + +1.17 12.02.2011 +Added renderstyleceiling and renderstylefloor sector properties +Added Sector_Set3DFloor to list of specials that need to be handled for line ID remapping + =============================================================================== EOF =============================================================================== diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 11df8be43..fbba7aa60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -298,6 +298,19 @@ else( WIN32 ) set( WITH_GSTREAMER ON ) endif( GSTREAMER_FOUND ) endif( NOT OPENAL_FOUND ) + + # Check for Xcursor library and header files + find_library( XCURSOR_LIB Xcursor ) + if( XCURSOR_LIB ) + find_file( XCURSOR_HEADER "X11/Xcursor/Xcursor.h" ) + if( XCURSOR_HEADER ) + add_definitions( -DUSE_XCURSOR=1 ) + message( STATUS "Found Xcursor at ${XCURSOR_LIB}" ) + set( ZDOOM_LIBS ${ZDOOM_LIBS} ${XCURSOR_LIB} ) + else( XCURSOR_HEADER ) + unset( XCURSOR_LIB ) + endif( XCURSOR_HEADER ) + endif( XCURSOR_LIB ) endif( APPLE ) set( NASM_NAMES nasm ) @@ -524,8 +537,7 @@ endif( SSE_MATTERS ) if( CMAKE_COMPILER_IS_GNUCXX ) if( PROFILE ) - set( CMAKE_C_FLinclude( FindFluidSynth.cmake ) -AGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) + set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pg" ) set( CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -pg" ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg" ) @@ -539,7 +551,7 @@ AGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg" ) set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_CXX_FLAGS}" ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_CXX_FLAGS}" ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused" ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused -Wextra -Wno-missing-field-initializers" ) # Remove extra warnings when using the official DirectX headers. # Also, TDM-GCC 4.4.0 no longer accepts glibc-style printf formats as valid, @@ -682,6 +694,7 @@ else( WIN32 ) sdl/hardware.cpp sdl/i_cd.cpp sdl/i_input.cpp + sdl/i_joystick.cpp sdl/i_main.cpp sdl/i_movie.cpp sdl/i_system.cpp @@ -747,6 +760,7 @@ add_executable( zdoom WIN32 ${SYSTEM_SOURCES} ${X86_SOURCES} x86.cpp + actorptrselect.cpp am_map.cpp b_bot.cpp b_func.cpp @@ -779,7 +793,6 @@ add_executable( zdoom WIN32 doomstat.cpp dsectoreffect.cpp dthinker.cpp - f_finale.cpp f_wipe.cpp farchive.cpp files.cpp @@ -803,6 +816,7 @@ add_executable( zdoom WIN32 m_misc.cpp m_png.cpp m_random.cpp + memarena.cpp md5.cpp name.cpp nodebuild.cpp @@ -852,19 +866,18 @@ add_executable( zdoom WIN32 p_xlat.cpp parsecontext.cpp po_man.cpp - r_anim.cpp + r_swrenderer.cpp + r_utility.cpp + r_3dfloors.cpp r_bsp.cpp - r_data.cpp r_draw.cpp r_drawt.cpp - r_interpolate.cpp r_main.cpp r_plane.cpp r_polymost.cpp r_segs.cpp r_sky.cpp r_things.cpp - r_translate.cpp s_advsound.cpp s_environment.cpp s_playlist.cpp @@ -872,8 +885,10 @@ add_executable( zdoom WIN32 s_sound.cpp sc_man.cpp st_stuff.cpp + statistics.cpp stats.cpp stringtable.cpp + strnatcmp.c tables.cpp teaminfo.cpp tempfiles.cpp @@ -931,6 +946,8 @@ add_executable( zdoom WIN32 g_shared/sbar_mugshot.cpp g_shared/shared_hud.cpp g_shared/shared_sbar.cpp + intermission/intermission.cpp + intermission/intermission_parse.cpp menu/colorpickermenu.cpp menu/joystickmenu.cpp menu/listmenu.cpp @@ -970,6 +987,7 @@ add_executable( zdoom WIN32 sound/music_mus_midiout.cpp sound/music_smf_midiout.cpp sound/music_hmi_midiout.cpp + sound/music_xmi_midiout.cpp sound/music_midistream.cpp sound/music_midi_base.cpp sound/music_midi_timidity.cpp @@ -980,6 +998,9 @@ add_executable( zdoom WIN32 sound/music_timidity_mididevice.cpp sound/music_win_mididevice.cpp sound/oalsound.cpp + sound/music_pseudo_mididevice.cpp + textures/animations.cpp + textures/anim_switches.cpp textures/automaptexture.cpp textures/bitmap.cpp textures/buildtexture.cpp @@ -1017,7 +1038,24 @@ add_executable( zdoom WIN32 timidity/resample.cpp timidity/timidity.cpp xlat/parse_xlat.cpp - autozend.cpp ) + fragglescript/t_fspic.cpp + fragglescript/t_func.cpp + fragglescript/t_load.cpp + fragglescript/t_oper.cpp + fragglescript/t_parse.cpp + fragglescript/t_prepro.cpp + fragglescript/t_script.cpp + fragglescript/t_spec.cpp + fragglescript/t_variable.cpp + fragglescript/t_cmd.cpp + r_data/colormaps.cpp + r_data/sprites.cpp + r_data/voxels.cpp + r_data/renderstyle.cpp + r_data/r_interpolate.cpp + r_data/r_translate.cpp + autozend.cpp +) set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) diff --git a/src/actionspecials.h b/src/actionspecials.h index c735c7a9d..6e77bff7a 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -95,6 +95,8 @@ DEFINE_SPECIAL(Polyobj_OR_MoveTimes8, 93, 4, 4, 4) DEFINE_SPECIAL(Pillar_BuildAndCrush, 94, 4, 5, 5) DEFINE_SPECIAL(FloorAndCeiling_LowerByValue, 95, 3, 3, 3) DEFINE_SPECIAL(FloorAndCeiling_RaiseByValue, 96, 3, 3, 3) +DEFINE_SPECIAL(Ceiling_LowerAndCrushDist, 97, 3, 5, 5) +DEFINE_SPECIAL(Sector_SetTranslucent, 98, 3, 4, 4) DEFINE_SPECIAL(Scroll_Texture_Left, 100, -1, -1, 2) DEFINE_SPECIAL(Scroll_Texture_Right, 101, -1, -1, 2) @@ -123,7 +125,7 @@ DEFINE_SPECIAL(UsePuzzleItem, 129, 2, 5, 5) DEFINE_SPECIAL(Thing_Activate, 130, 1, 1, 1) DEFINE_SPECIAL(Thing_Deactivate, 131, 1, 1, 1) DEFINE_SPECIAL(Thing_Remove, 132, 1, 1, 1) -DEFINE_SPECIAL(Thing_Destroy, 133, 1, 2, 2) +DEFINE_SPECIAL(Thing_Destroy, 133, 1, 3, 3) DEFINE_SPECIAL(Thing_Projectile, 134, 5, 5, 5) DEFINE_SPECIAL(Thing_Spawn, 135, 3, 4, 4) DEFINE_SPECIAL(Thing_ProjectileGravity, 136, 5, 5, 5) @@ -226,7 +228,7 @@ DEFINE_SPECIAL(Elevator_LowerToNearest, 247, 2, 2, 2) DEFINE_SPECIAL(HealThing, 248, 1, 2, 2) DEFINE_SPECIAL(Door_CloseWaitOpen, 249, 3, 4, 4) DEFINE_SPECIAL(Floor_Donut, 250, 3, 3, 3) -DEFINE_SPECIAL(FloorAndCeiling_LowerRaise, 251, 3, 3, 3) +DEFINE_SPECIAL(FloorAndCeiling_LowerRaise, 251, 3, 3, 4) DEFINE_SPECIAL(Ceiling_RaiseToNearest, 252, 2, 2, 2) DEFINE_SPECIAL(Ceiling_LowerToLowest, 253, 2, 2, 2) DEFINE_SPECIAL(Ceiling_LowerToFloor, 254, 2, 2, 2) diff --git a/src/actor.h b/src/actor.h index 2a8921b56..e7dece16b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -37,8 +37,9 @@ #include "doomdef.h" #include "textures/textures.h" -#include "r_blend.h" +#include "r_data/renderstyle.h" #include "s_sound.h" +#include "memarena.h" struct subsector_t; // @@ -269,7 +270,7 @@ enum MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on. MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. /* = 0x00000008, */ - /* = 0x00000010, */ + MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage MF5_CHASEGOAL = 0x00000080, // Walks to goal instead of target if a valid goal is set. @@ -289,7 +290,7 @@ enum MF5_NOINTERACTION = 0x00200000, // Thing is completely excluded from any gameplay related checks MF5_NOTIMEFREEZE = 0x00400000, // Actor is not affected by time freezer MF5_PUFFGETSOWNER = 0x00800000, // [BB] Sets the owner of the puff to the player who fired it - MF5_SPECIALFIREDAMAGE=0x01000000, // Special treatment of PhoenixFX1 turned into a flag to removr + MF5_SPECIALFIREDAMAGE=0x01000000, // Special treatment of PhoenixFX1 turned into a flag to remove // dependence of main engine code of specific actor types. MF5_SUMMONEDMONSTER = 0x02000000, // To mark the friendly Minotaur. Hopefully to be generalized later. MF5_NOVERTICALMELEERANGE=0x04000000,// Does not check vertical distance for melee range @@ -323,6 +324,12 @@ enum MF6_BLOCKEDBYSOLIDACTORS = 0x00080000, // Blocked by solid actors, even if not solid itself MF6_ADDITIVEPOISONDAMAGE = 0x00100000, MF6_ADDITIVEPOISONDURATION = 0x00200000, + MF6_NOMENU = 0x00400000, // Player class should not appear in the class selection menu. + MF6_BOSSCUBE = 0x00800000, // Actor spawned by A_BrainSpit, flagged for timefreeze reasons. + MF6_SEEINVISIBLE = 0x01000000, // Monsters can see invisible player. + MF6_DONTCORPSE = 0x02000000, // [RC] Don't autoset MF_CORPSE upon death and don't force Crash state change. + MF6_POISONALWAYS = 0x04000000, // Always apply poison, even when target can't take the damage. + MF6_DOHARMSPECIES = 0x08000000, // Do hurt one's own species with projectiles. // --- mobj.renderflags --- @@ -528,7 +535,12 @@ struct FDropItem class FDropItemPtrArray : public TArray { public: - ~FDropItemPtrArray(); + ~FDropItemPtrArray() + { + Clear(); + } + + void Clear(); }; extern FDropItemPtrArray DropItemList; @@ -675,7 +687,7 @@ public: void ConversationAnimation (int animnum); // Make this actor hate the same things as another actor - void CopyFriendliness (AActor *other, bool changeTarget); + void CopyFriendliness (AActor *other, bool changeTarget, bool resetHealth=true); // Moves the other actor's inventory to this one void ObtainInventory (AActor *other); @@ -703,6 +715,12 @@ public: // Return starting health adjusted by skill level int SpawnHealth(); + int GibHealth(); + + inline bool isMissile(bool precise=true) + { + return (flags&MF_MISSILE) || (precise && GetDefault()->flags&MF_MISSILE); + } // Check for monsters that count as kill but excludes all friendlies. bool CountsAsKill() const @@ -753,6 +771,7 @@ public: fixed_t GetGravity() const; bool IsSentient() const; const char *GetTag(const char *def = NULL) const; + void SetTag(const char *def); // info for drawing @@ -788,6 +807,7 @@ public: SDWORD tics; // state tic counter FState *state; SDWORD Damage; // For missiles and monster railgun + int projectileKickback; DWORD flags; DWORD flags2; // Heretic flags DWORD flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable @@ -832,7 +852,7 @@ public: BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack. SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0) WORD BounceFlags; // which bouncing type? - WORD SpawnFlags; + DWORD SpawnFlags; // Increased to DWORD because of Doom 64 fixed_t meleerange; // specifies how far a melee attack reaches. fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore // but instead tries to come closer for a melee attack. @@ -848,16 +868,19 @@ public: int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL int lastbump; // Last time the actor was bumped, used to control BUMPSPECIAL int Score; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything. - FNameNoInit Tag; // Strife's tag name. FIXME: should be case sensitive! + FString * Tag; // Strife's tag name. + int DesignatedTeam; // Allow for friendly fire cacluations to be done on non-players. AActor *BlockingMobj; // Actor that blocked the last move line_t *BlockingLine; // Line that blocked the last move int PoisonDamage; // Damage received per tic from poison. + FNameNoInit PoisonDamageType; // Damage type dealt by poison. int PoisonDuration; // Duration left for receiving poison damage. int PoisonPeriod; // How often poison damage is applied. (Every X tics.) int PoisonDamageReceived; // Damage received per tic from poison. + FNameNoInit PoisonDamageTypeReceived; // Damage type received by poison. int PoisonDurationReceived; // Duration left for receiving poison damage. int PoisonPeriodReceived; // How often poison damage is applied. (Every X tics.) TObjPtr Poisoner; // Last source of received poison damage. @@ -894,8 +917,12 @@ public: SWORD PainChance; int PainThreshold; FNameNoInit DamageType; + FNameNoInit DamageTypeReceived; fixed_t DamageFactor; + FNameNoInit PainType; + FNameNoInit DeathType; + FState *SpawnState; FState *SeeState; FState *MeleeState; @@ -920,6 +947,7 @@ public: private: static AActor *TIDHash[128]; static inline int TIDHASH (int key) { return key & 127; } + static FSharedStringArena mStringPropertyData; friend class FActorIterator; @@ -937,6 +965,7 @@ public: virtual bool UpdateWaterLevel (fixed_t oldz, bool splash=true); bool isFast(); void SetIdle(); + void ClearCounters(); FState *FindState (FName label) const { @@ -1029,6 +1058,7 @@ inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) return static_cast(AActor::StaticSpawn (RUNTIME_CLASS(T), x, y, z, allowreplacement)); } + void PrintMiscActorInfo(AActor * query); #define S_FREETARGMOBJ 1 diff --git a/src/actorptrselect.cpp b/src/actorptrselect.cpp new file mode 100644 index 000000000..f1f50eeb5 --- /dev/null +++ b/src/actorptrselect.cpp @@ -0,0 +1,179 @@ +#include "actorptrselect.h" +#include "actor.h" +#include "d_player.h" +#include "p_pspr.h" + +//========================================================================== +// +// Standard pointer acquisition functions +// +// Possible effective results at run-time +// assigntovariable = NULL (or a RETURN statement is issued) +// P_BulletSlope(pointer_owner, &temporary), assigntovariable = temporary +// assigntovariable = pointer_owner->target or ...->master or ...->tracer +// +//========================================================================== + + +/* + COPY_AAPTR + + Result overview in order of priority: + + 1. Caller is player and a player specific selector is specified: Player specific selector is used. + 2. Caller is non-null and a general actor selector is specified: General actor selector is used. + 3. A static actor selector is specified: Static actor selector is used. + 4. The origin actor is used. + + Only one selector of each type can be used. +*/ + +#define AAPTR_RESOLVE_PLAYERNUM(playernum) (playeringame[playernum] ? players[playernum].mo : NULL) + +AActor *COPY_AAPTR(AActor *origin, int selector) +{ + if (origin) + { + if (origin->player) + { + switch (selector & AAPTR_PLAYER_SELECTORS) + { + case AAPTR_PLAYER_GETTARGET: + { + AActor *gettarget = NULL; + P_BulletSlope(origin, &gettarget); + return gettarget; + } + case AAPTR_PLAYER_GETCONVERSATION: + return origin->player->ConversationNPC; + } + } + + switch (selector & AAPTR_GENERAL_SELECTORS) + { + case AAPTR_TARGET: return origin->target; + case AAPTR_MASTER: return origin->master; + case AAPTR_TRACER: return origin->tracer; + case AAPTR_FRIENDPLAYER: + return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL; + } + } + + switch (selector & AAPTR_STATIC_SELECTORS) + { + case AAPTR_PLAYER1: return AAPTR_RESOLVE_PLAYERNUM(0); + case AAPTR_PLAYER2: return AAPTR_RESOLVE_PLAYERNUM(1); + case AAPTR_PLAYER3: return AAPTR_RESOLVE_PLAYERNUM(2); + case AAPTR_PLAYER4: return AAPTR_RESOLVE_PLAYERNUM(3); + case AAPTR_PLAYER5: return AAPTR_RESOLVE_PLAYERNUM(4); + case AAPTR_PLAYER6: return AAPTR_RESOLVE_PLAYERNUM(5); + case AAPTR_PLAYER7: return AAPTR_RESOLVE_PLAYERNUM(6); + case AAPTR_PLAYER8: return AAPTR_RESOLVE_PLAYERNUM(7); + case AAPTR_NULL: return NULL; + } + + return origin; +} + + +// [FDARI] Exported logic for guarding against loops in Target (for missiles) and Master (for all) chains. +// It is called from multiple locations. +// The code may be in need of optimisation. + + +//========================================================================== +// +// Checks whether this actor is a missile +// Unfortunately this was buggy in older versions of the code and many +// released DECORATE monsters rely on this bug so it can only be fixed +// with an optional flag +// +//========================================================================== + +void VerifyTargetChain(AActor *self, bool preciseMissileCheck) +{ + if (!self || !self->isMissile(preciseMissileCheck)) return; + + AActor *origin = self; + AActor *next = origin->target; + + // origin: the most recent actor that has been verified as appearing only once + // next: the next actor to be verified; will be "origin" in the next iteration + + while (next && next->isMissile(preciseMissileCheck)) // we only care when there are missiles involved + { + AActor *compare = self; + // every new actor must prove not to be the first actor in the chain, or any subsequent actor + // any actor up to and including "origin" has only appeared once + for (;;) + { + if (compare == next) + { + // if any of the actors from self to (inclusive) origin match the next actor, + // self has reached/created a loop + self->target = NULL; + return; + } + if (compare == origin) break; // when "compare" = origin, we know that the next actor is, and should be "next" + compare = compare->target; + } + + origin = next; + next = next->target; + } +} + +void VerifyMasterChain(AActor *self) +{ + // See VerifyTargetChain for detailed comments. + + if (!self) return; + AActor *origin = self; + AActor *next = origin->master; + while (next) // We always care (See "VerifyTargetChain") + { + AActor *compare = self; + for (;;) + { + if (compare == next) + { + self->master = NULL; + return; + } + if (compare == origin) break; + compare = compare->master; + } + + origin = next; + next = next->master; + } +} + +//========================================================================== +// +// Checks whether this actor is a missile +// Unfortunately this was buggy in older versions of the code and many +// released DECORATE monsters rely on this bug so it can only be fixed +// with an optional flag +// +//========================================================================== + +void ASSIGN_AAPTR(AActor *toActor, int toSlot, AActor *ptr, int flags) +{ + switch (toSlot) + { + case AAPTR_TARGET: + toActor->target = ptr; + if (!(PTROP_UNSAFETARGET & (flags))) VerifyTargetChain(toActor); + break; + + case AAPTR_MASTER: + toActor->master = ptr; + if (!(PTROP_UNSAFEMASTER & (flags))) VerifyMasterChain(toActor); + break; + + case AAPTR_TRACER: + toActor->tracer = ptr; + break; + } +} \ No newline at end of file diff --git a/src/actorptrselect.h b/src/actorptrselect.h new file mode 100644 index 000000000..46e1aa54d --- /dev/null +++ b/src/actorptrselect.h @@ -0,0 +1,98 @@ +#pragma once + +//========================================================================== +// +// Standard pointer acquisition functions +// +// Possible effective results at run-time +// assigntovariable = NULL (or a RETURN statement is issued) +// P_BulletSlope(pointer_owner, &temporary), assigntovariable = temporary +// assigntovariable = pointer_owner->target or ...->master or ...->tracer +// +//========================================================================== + +class AActor; + +// Pointer selectors (enum) + +enum AAPTR +{ + AAPTR_DEFAULT = 0, + AAPTR_NULL = 0x1, + AAPTR_TARGET = 0x2, + AAPTR_MASTER = 0x4, + AAPTR_TRACER = 0x8, + + AAPTR_PLAYER_GETTARGET = 0x10, + AAPTR_PLAYER_GETCONVERSATION = 0x20, + + AAPTR_PLAYER1 = 0x40, + AAPTR_PLAYER2 = 0x80, + AAPTR_PLAYER3 = 0x100, + AAPTR_PLAYER4 = 0x200, + AAPTR_PLAYER5 = 0x400, + AAPTR_PLAYER6 = 0x800, + AAPTR_PLAYER7 = 0x1000, + AAPTR_PLAYER8 = 0x2000, + + AAPTR_FRIENDPLAYER = 0x4000, + + AAPTR_PLAYER_SELECTORS = + AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION, + + AAPTR_GENERAL_SELECTORS = + AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER, + + AAPTR_STATIC_SELECTORS = + AAPTR_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4| + AAPTR_PLAYER5|AAPTR_PLAYER6|AAPTR_PLAYER7|AAPTR_PLAYER8| + AAPTR_NULL + +}; + +/* + COPY_AAPTR + + Result overview in order of priority: + + 1. Caller is player and a player specific selector is specified: Player specific selector is used. + 2. Caller is non-null and a general actor selector is specified: General actor selector is used. + 3. A static actor selector is specified: Static actor selector is used. + 4. The origin actor is used. + + Only one selector of each type can be used. +*/ + +AActor *COPY_AAPTR(AActor *origin, int selector); + +// Use COPY_AAPTR_NOT_NULL to return from a function if the pointer is NULL +#define COPY_AAPTR_NOT_NULL(source, destination, selector) { destination = COPY_AAPTR(source, selector); if (!destination) return; } + + + +enum PTROP + { + PTROP_UNSAFETARGET = 1, + PTROP_UNSAFEMASTER = 2, + PTROP_NOSAFEGUARDS = PTROP_UNSAFETARGET|PTROP_UNSAFEMASTER +}; + + +// [FDARI] Exported logic for guarding against loops in Target (for missiles) and Master (for all) chains. +// It is called from multiple locations. +// The code may be in need of optimisation. + + +//========================================================================== +// +// Checks whether this actor is a missile +// Unfortunately this was buggy in older versions of the code and many +// released DECORATE monsters rely on this bug so it can only be fixed +// with an optional flag +// +//========================================================================== + +void VerifyTargetChain(AActor *self, bool preciseMissileCheck=true); +void VerifyMasterChain(AActor *self); +void ASSIGN_AAPTR(AActor *toActor, int toSlot, AActor *ptr, int flags) ; + diff --git a/src/am_map.cpp b/src/am_map.cpp index 73a7f8c98..a6b03446f 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -33,12 +33,13 @@ #include "w_wad.h" #include "a_sharedglobal.h" #include "statnums.h" -#include "r_translate.h" +#include "r_data/r_translate.h" #include "d_event.h" #include "gi.h" -#include "r_bsp.h" #include "p_setup.h" #include "c_bind.h" +#include "farchive.h" +#include "r_renderer.h" #include "m_cheat.h" #include "i_system.h" @@ -63,6 +64,13 @@ #include "a_artifacts.h" #include "po_man.h" #include "a_keys.h" +#include "r_data/colormaps.h" + +//============================================================================= +// +// Automap colors +// +//============================================================================= struct AMColor { @@ -83,9 +91,9 @@ struct AMColor }; static AMColor Background, YourColor, WallColor, TSWallColor, - FDWallColor, CDWallColor, ThingColor, + FDWallColor, CDWallColor, EFWallColor, ThingColor, ThingColor_Item, ThingColor_CountItem, ThingColor_Monster, ThingColor_Friend, - SecretWallColor, GridColor, XHairColor, + SpecialWallColor, SecretWallColor, GridColor, XHairColor, NotSeenColor, LockedColor, AlmostBackground, @@ -119,6 +127,12 @@ static BYTE RavenPaletteVals[11*3] = 0, 0, 0, 0, 0, 0, }; +//============================================================================= +// +// globals +// +//============================================================================= + #define MAPBITS 12 #define MapDiv SafeDivScale12 #define MapMul MulScale12 @@ -155,9 +169,11 @@ CVAR (Color, am_backcolor, 0x6c5440, CVAR_ARCHIVE); CVAR (Color, am_yourcolor, 0xfce8d8, CVAR_ARCHIVE); CVAR (Color, am_wallcolor, 0x2c1808, CVAR_ARCHIVE); CVAR (Color, am_secretwallcolor, 0x000000, CVAR_ARCHIVE); +CVAR (Color, am_specialwallcolor, 0xffffff, CVAR_ARCHIVE); CVAR (Color, am_tswallcolor, 0x888888, CVAR_ARCHIVE); CVAR (Color, am_fdwallcolor, 0x887058, CVAR_ARCHIVE); CVAR (Color, am_cdwallcolor, 0x4c3820, CVAR_ARCHIVE); +CVAR (Color, am_efwallcolor, 0x665555, CVAR_ARCHIVE); CVAR (Color, am_thingcolor, 0xfcfcfc, CVAR_ARCHIVE); CVAR (Color, am_gridcolor, 0x8b5a2b, CVAR_ARCHIVE); CVAR (Color, am_xhaircolor, 0x808080, CVAR_ARCHIVE); @@ -165,6 +181,7 @@ CVAR (Color, am_notseencolor, 0x6c6c6c, CVAR_ARCHIVE); CVAR (Color, am_lockedcolor, 0x007800, CVAR_ARCHIVE); CVAR (Color, am_ovyourcolor, 0xfce8d8, CVAR_ARCHIVE); CVAR (Color, am_ovwallcolor, 0x00ff00, CVAR_ARCHIVE); +CVAR (Color, am_ovspecialwallcolor, 0xffffff, CVAR_ARCHIVE); CVAR (Color, am_ovthingcolor, 0xe88800, CVAR_ARCHIVE); CVAR (Color, am_ovotherwallscolor, 0x008844, CVAR_ARCHIVE); CVAR (Color, am_ovunseencolor, 0x00226e, CVAR_ARCHIVE); @@ -176,6 +193,7 @@ CVAR (Color, am_ovsecretsectorcolor,0x00ffff, CVAR_ARCHIVE); CVAR (Int, am_map_secrets, 1, CVAR_ARCHIVE); CVAR (Bool, am_drawmapback, true, CVAR_ARCHIVE); CVAR (Bool, am_showkeys, true, CVAR_ARCHIVE); +CVAR (Bool, am_showtriggerlines, false, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_friend, 0xfcfcfc, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_monster, 0xfcfcfc, CVAR_ARCHIVE); CVAR (Color, am_thingcolor_item, 0xfcfcfc, CVAR_ARCHIVE); @@ -287,72 +305,28 @@ struct islope_t // A line drawing of the player pointing right, // starting from the middle. // -#define R ((8*PLAYERRADIUS)/7) -mline_t player_arrow[] = { - { { -R+R/8, 0 }, { R, 0 } }, // ----- - { { R, 0 }, { R-R/2, R/4 } }, // -----> - { { R, 0 }, { R-R/2, -R/4 } }, - { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >----> - { { -R+R/8, 0 }, { -R-R/8, -R/4 } }, - { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>---> - { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } } -}; -#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t)) - -mline_t player_arrow_raven[] = { - { { -R+R/4, 0 }, { 0, 0} }, // center line. - { { -R+R/4, R/8 }, { R, 0} }, // blade - { { -R+R/4, -R/8 }, { R, 0 } }, - { { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece - { { -R+R/8, -R/4 }, { -R+R/8, R/4 } }, - { { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors - { { -R+R/8, R/4 }, { -R+R/4, R/4} }, - { { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel - { { -R-R/4, R/8 }, { -R+R/8, R/8 } }, - { { -R-R/4, -R/8}, { -R+R/8, -R/8 } } -}; -#define NUMPLYRLINES_RAVEN (sizeof(player_arrow_raven)/sizeof(mline_t)) - -mline_t cheat_player_arrow[] = { - { { -R+R/8, 0 }, { R, 0 } }, // ----- - { { R, 0 }, { R-R/2, R/6 } }, // -----> - { { R, 0 }, { R-R/2, -R/6 } }, - { { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >-----> - { { -R+R/8, 0 }, { -R-R/8, -R/6 } }, - { { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>-----> - { { -R+3*R/8, 0 }, { -R+R/8, -R/6 } }, - { { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d---> - { { -R/2, -R/6 }, { -R/2+R/6, -R/6 } }, - { { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } }, - { { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd--> - { { -R/6, -R/6 }, { 0, -R/6 } }, - { { 0, -R/6 }, { 0, R/4 } }, - { { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt-> - { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } }, - { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } } -}; -#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t)) - -#undef R +static TArray MapArrow; +static TArray CheatMapArrow; +static TArray CheatKey; #define R (MAPUNIT) // [RH] Avoid lots of warnings without compiler-specific #pragmas #define L(a,b,c,d) { {(fixed_t)((a)*R),(fixed_t)((b)*R)}, {(fixed_t)((c)*R),(fixed_t)((d)*R)} } -mline_t triangle_guy[] = { +static mline_t triangle_guy[] = { L (-.867,-.5, .867,-.5), L (.867,-.5, 0,1), L (0,1, -.867,-.5) }; #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t)) -mline_t thintriangle_guy[] = { +static mline_t thintriangle_guy[] = { L (-.5,-.7, 1,0), L (1,0, -.5,.7), L (-.5,.7, -.5,-.7) }; #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t)) -mline_t square_guy[] = { +static mline_t square_guy[] = { L (0,1,1,0), L (1,0,0,-1), L (0,-1,-1,0), @@ -361,26 +335,6 @@ mline_t square_guy[] = { #define NUMSQUAREGUYLINES (sizeof(square_guy)/sizeof(mline_t)) #undef R -#define R (MAPUNIT) - -mline_t key_guy[] = { - L (-2, 0, -1.7, -0.5), - L (-1.7, -0.5, -1.5, -0.7), - L (-1.5, -0.7, -0.8, -0.5), - L (-0.8, -0.5, -0.6, 0), - L (-0.6, 0, -0.8, 0.5), - L (-1.5, 0.7, -0.8, 0.5), - L (-1.7, 0.5, -1.5, 0.7), - L (-2, 0, -1.7, 0.5), - L (-0.6, 0, 2, 0), - L (1.7, 0, 1.7, -1), - L (1.5, 0, 1.5, -1), - L (1.3, 0, 1.3, -1) -}; -#define NUMKEYGUYLINES (sizeof(key_guy)/sizeof(mline_t)) - -#undef L -#undef R @@ -396,8 +350,6 @@ CUSTOM_CVAR (Int, am_cheat, 0, 0) static int grid = 0; -static int leveljuststarted = 1; // kluge until AM_LevelInit() is called - bool automapactive = false; // location of window on screen @@ -449,8 +401,6 @@ static FTextureID marknums[10]; // numbers used for marking by the automap static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are static int markpointnum = 0; // next point to be assigned -static int followplayer = 1; // specifies whether to follow the player around - static FTextureID mapback; // the automap background static fixed_t mapystart=0; // y-value for the start of the map bitmap...used in the parallax stuff. static fixed_t mapxstart=0; //x-value for the bitmap. @@ -476,11 +426,14 @@ void AM_restoreScaleAndLoc (); void AM_minOutWindowScale (); +CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE) + + CCMD(am_togglefollow) { - followplayer = !followplayer; + am_followplayer = !am_followplayer; f_oldloc.x = FIXED_MAX; - Printf ("%s\n", GStrings(followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); + Printf ("%s\n", GStrings(am_followplayer ? "AMSTR_FOLLOWON" : "AMSTR_FOLLOWOFF")); } CCMD(am_togglegrid) @@ -545,6 +498,76 @@ void AM_getIslope (mline_t *ml, islope_t *is) } */ + +void AM_ParseArrow(TArray &Arrow, const char *lumpname) +{ + const int R = ((8*PLAYERRADIUS)/7); + FScanner sc; + int lump = Wads.CheckNumForFullName(lumpname, true); + if (lump >= 0) + { + sc.OpenLumpNum(lump); + sc.SetCMode(true); + while (sc.GetToken()) + { + mline_t line; + sc.TokenMustBe('('); + sc.MustGetFloat(); + line.a.x = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(','); + sc.MustGetFloat(); + line.a.y = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(')'); + sc.MustGetToken(','); + sc.MustGetToken('('); + sc.MustGetFloat(); + line.b.x = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(','); + sc.MustGetFloat(); + line.b.y = xs_RoundToInt(sc.Float*R); + sc.MustGetToken(')'); + Arrow.Push(line); + } + } +} + +void AM_StaticInit() +{ + MapArrow.Clear(); + CheatMapArrow.Clear(); + CheatKey.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"); + if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); + + char namebuf[9]; + + for (int i = 0; i < 10; i++) + { + mysnprintf (namebuf, countof(namebuf), "AMMNUM%d", i); + marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); + } + markpointnum = 0; + mapback.SetInvalid(); + + static DWORD *lastpal = NULL; + //static int lastback = -1; + DWORD *palette; + + palette = (DWORD *)GPalette.BaseColors; + + int i, j; + + for (i = j = 0; i < 11; i++, j += 3) + { + DoomColors[i].FromRGB(DoomPaletteVals[j], DoomPaletteVals[j+1], DoomPaletteVals[j+2]); + StrifeColors[i].FromRGB(StrifePaletteVals[j], StrifePaletteVals[j+1], StrifePaletteVals[j+2]); + RavenColors[i].FromRGB(RavenPaletteVals[j], RavenPaletteVals[j+1], RavenPaletteVals[j+2]); + } +} + //============================================================================= // // called by the coordinate drawer @@ -599,7 +622,7 @@ void AM_restoreScaleAndLoc () { m_w = old_m_w; m_h = old_m_h; - if (!followplayer) + if (!am_followplayer) { m_x = old_m_x; m_y = old_m_y; @@ -796,7 +819,7 @@ void AM_changeWindowLoc () { if (0 != (m_paninc.x | m_paninc.y)) { - followplayer = 0; + am_followplayer = false; f_oldloc.x = FIXED_MAX; } @@ -868,18 +891,6 @@ void AM_initVariables () old_m_h = m_h; } -/* -static void GetComponents (int color, DWORD *palette, float &r, float &g, float &b) -{ - if (palette) - color = palette[color]; - - r = (float)RPART(color); - g = (float)GPART(color); - b = (float)BPART(color); -} -*/ - //============================================================================= // // @@ -888,28 +899,11 @@ static void GetComponents (int color, DWORD *palette, float &r, float &g, float static void AM_initColors (bool overlayed) { - static DWORD *lastpal = NULL; - //static int lastback = -1; - DWORD *palette; - - palette = (DWORD *)GPalette.BaseColors; - - if (lastpal != palette) - { - int i, j; - - for (i = j = 0; i < 11; i++, j += 3) - { - DoomColors[i].FromRGB(DoomPaletteVals[j], DoomPaletteVals[j+1], DoomPaletteVals[j+2]); - StrifeColors[i].FromRGB(StrifePaletteVals[j], StrifePaletteVals[j+1], StrifePaletteVals[j+2]); - RavenColors[i].FromRGB(RavenPaletteVals[j], RavenPaletteVals[j+1], RavenPaletteVals[j+2]); - } - } - if (overlayed) { YourColor.FromCVar (am_ovyourcolor); WallColor.FromCVar (am_ovwallcolor); + SpecialWallColor.FromCVar(am_ovspecialwallcolor); SecretWallColor = WallColor; SecretSectorColor.FromCVar (am_ovsecretsectorcolor); ThingColor_Item.FromCVar (am_ovthingcolor_item); @@ -918,7 +912,7 @@ static void AM_initColors (bool overlayed) ThingColor_Monster.FromCVar (am_ovthingcolor_monster); ThingColor.FromCVar (am_ovthingcolor); LockedColor.FromCVar (am_ovotherwallscolor); - FDWallColor = CDWallColor = LockedColor; + EFWallColor = FDWallColor = CDWallColor = LockedColor; TSWallColor.FromCVar (am_ovunseencolor); NotSeenColor = TSWallColor; InterTeleportColor.FromCVar (am_ovtelecolor); @@ -932,10 +926,12 @@ static void AM_initColors (bool overlayed) Background.FromCVar (am_backcolor); YourColor.FromCVar (am_yourcolor); SecretWallColor.FromCVar (am_secretwallcolor); + SpecialWallColor.FromCVar (am_specialwallcolor); WallColor.FromCVar (am_wallcolor); TSWallColor.FromCVar (am_tswallcolor); FDWallColor.FromCVar (am_fdwallcolor); CDWallColor.FromCVar (am_cdwallcolor); + EFWallColor.FromCVar (am_efwallcolor); ThingColor_Item.FromCVar (am_thingcolor_item); ThingColor_CountItem.FromCVar (am_thingcolor_citem); ThingColor_Friend.FromCVar (am_thingcolor_friend); @@ -973,9 +969,10 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = DoomColors[3]; TSWallColor = DoomColors[4]; - FDWallColor = DoomColors[5]; + EFWallColor = FDWallColor = DoomColors[5]; LockedColor = CDWallColor = DoomColors[6]; ThingColor_Item = @@ -994,9 +991,10 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = StrifeColors[3]; TSWallColor = StrifeColors[4]; - FDWallColor = StrifeColors[5]; + EFWallColor = FDWallColor = StrifeColors[5]; LockedColor = CDWallColor = StrifeColors[6]; ThingColor_Item = StrifeColors[10]; @@ -1015,9 +1013,10 @@ static void AM_initColors (bool overlayed) AlmostBackground = DoomColors[2]; SecretSectorColor = SecretWallColor = + SpecialWallColor = WallColor = RavenColors[3]; TSWallColor = RavenColors[4]; - FDWallColor = RavenColors[5]; + EFWallColor = FDWallColor = RavenColors[5]; LockedColor = CDWallColor = RavenColors[6]; ThingColor = @@ -1030,30 +1029,6 @@ static void AM_initColors (bool overlayed) break; } - - lastpal = palette; -} - -//============================================================================= -// -// -// -//============================================================================= - -void AM_loadPics () -{ - int i; - char namebuf[9]; - - for (i = 0; i < 10; i++) - { - mysnprintf (namebuf, countof(namebuf), "AMMNUM%d", i); - marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); - } - - const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)&level.info->mapbg[0]; - - mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch); } //============================================================================= @@ -1078,7 +1053,8 @@ bool AM_clearMarks () void AM_LevelInit () { - leveljuststarted = 0; + const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)&level.info->mapbg[0]; + mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch); AM_clearMarks(); @@ -1116,7 +1092,6 @@ void AM_Start () if (!stopped) AM_Stop(); stopped = false; AM_initVariables(); - AM_loadPics(); } @@ -1228,7 +1203,7 @@ bool AM_Responder (event_t *ev, bool last) { if (automapactive && (ev->type == EV_KeyDown || ev->type == EV_KeyUp)) { - if (followplayer) + if (am_followplayer) { // check for am_pan* and ignore in follow mode const char *defbind = AutomapBindings.GetBind(ev->data1); @@ -1275,6 +1250,10 @@ void AM_changeWindowScale () { mtof_zoommul = int(M_ZOOMOUT); } + else + { + mtof_zoommul = MAPUNIT; + } am_zoomdir = 0; // Change the scaling multipliers @@ -1341,7 +1320,7 @@ void AM_Ticker () amclock++; - if (followplayer) + if (am_followplayer) { AM_doFollowPlayer(); } @@ -1484,28 +1463,28 @@ bool AM_clipMline (mline_t *ml, fline_t *fl) { dy = fl->a.y - fl->b.y; dx = fl->b.x - fl->a.x; - tmp.x = fl->a.x + (dx*(fl->a.y))/dy; + tmp.x = fl->a.x + Scale(dx, fl->a.y, dy); tmp.y = 0; } else if (outside & BOTTOM) { dy = fl->a.y - fl->b.y; dx = fl->b.x - fl->a.x; - tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy; + tmp.x = fl->a.x + Scale(dx, fl->a.y - f_h, dy); tmp.y = f_h-1; } else if (outside & RIGHT) { dy = fl->b.y - fl->a.y; dx = fl->b.x - fl->a.x; - tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx; + tmp.y = fl->a.y + Scale(dy, f_w-1 - fl->a.x, dx); tmp.x = f_w-1; } else if (outside & LEFT) { dy = fl->b.y - fl->a.y; dx = fl->b.x - fl->a.x; - tmp.y = fl->a.y + (dy*(-fl->a.x))/dx; + tmp.y = fl->a.y + Scale(dy, -fl->a.x, dx); tmp.x = 0; } @@ -1561,7 +1540,7 @@ void AM_drawGrid (const AMColor &color) // [RH] Calculate a minimum for how long the grid lines should be so that // they cover the screen at any rotation. - minlen = (fixed_t)sqrtf ((float)m_w*(float)m_w + (float)m_h*(float)m_h); + minlen = (fixed_t)sqrt ((double)m_w*(double)m_w + (double)m_h*(double)m_h); extx = (minlen - m_w) / 2; exty = (minlen - m_h) / 2; @@ -1655,8 +1634,7 @@ void AM_drawSubsectors() points[j].Y = f_y + (f_h - (pt.y - m_y) * scale / float(1 << 24)); } // For lighting and texture determination - sector_t *sec = R_FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight, - &ceilinglight, false); + sector_t *sec = Renderer->FakeFlat (subsectors[i].render_sector, &tempsec, &floorlight, &ceilinglight, false); // Find texture origin. mpoint_t originpt = { -sec->GetXOffset(sector_t::floor) >> FRACTOMAPBITS, sec->GetYOffset(sector_t::floor) >> FRACTOMAPBITS }; @@ -1676,6 +1654,56 @@ void AM_drawSubsectors() originy = f_y + (f_h - (originpt.y - m_y) * scale / float(1 << 24)); // Coloring for the polygon colormap = sec->ColorMap; + + FTextureID maptex = sec->GetTexture(sector_t::floor); + +#ifdef _3DFLOORS + + if (sec->e->XFloor.ffloors.Size()) + { + secplane_t *floorplane = &sec->floorplane; + + // Look for the highest floor below the camera viewpoint. + // Check the center of the subsector's sector. Do not check each + // subsector separately because that might result in different planes for + // different subsectors of the same sector which is not wanted here. + // (Make the comparison in floating point to avoid overflows and improve performance.) + double secx; + double secy; + double cmpz = FIXED2DBL(viewz); + + if (players[consoleplayer].camera && sec == players[consoleplayer].camera->Sector) + { + // For the actual camera sector use the current viewpoint as reference. + secx = FIXED2DBL(viewx); + secy = FIXED2DBL(viewy); + } + else + { + secx = FIXED2DBL(sec->soundorg[0]); + secy = FIXED2DBL(sec->soundorg[1]); + } + + for (unsigned int i = 0; i < sec->e->XFloor.ffloors.Size(); ++i) + { + F3DFloor *rover = sec->e->XFloor.ffloors[i]; + 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) + { + maptex = *(rover->top.texture); + floorplane = rover->top.plane; + break; + } + } + + lightlist_t *light = P_GetPlaneLight(sec, floorplane, false); + floorlight = *light->p_lightlevel; + colormap = light->extra_colormap; + } +#endif + // If this subsector has not actually been seen yet (because you are cheating // to see it on the map), tint and desaturate it. if (!(subsectors[i].flags & SSECF_DRAWN)) @@ -1691,8 +1719,7 @@ void AM_drawSubsectors() } // Draw the polygon. - screen->FillSimplePoly( - TexMan(sec->GetTexture(sector_t::floor)), + screen->FillSimplePoly(TexMan(maptex), &points[0], points.Size(), originx, originy, scale / (FIXED2FLOAT(sec->GetXScale(sector_t::floor)) * float(1 << MAPBITS)), @@ -1806,6 +1833,69 @@ void AM_showSS() } } +#ifdef _3DFLOORS + +//============================================================================= +// +// Determines if a 3D floor boundary should be drawn +// +//============================================================================= + +bool AM_Check3DFloors(line_t *line) +{ + TArray &ff_front = line->frontsector->e->XFloor.ffloors; + TArray &ff_back = line->backsector->e->XFloor.ffloors; + + // No 3D floors so there's no boundary + if (ff_back.Size() == 0 && ff_front.Size() == 0) return false; + + int realfrontcount = 0; + int realbackcount = 0; + + for(unsigned i=0;iflags & FF_EXISTS)) continue; + if (rover->alpha == 0) continue; + realfrontcount++; + } + + for(unsigned i=0;iflags & FF_EXISTS)) continue; + if (rover->alpha == 0) continue; + realbackcount++; + } + // if the amount of 3D floors does not match there is a boundary + if (realfrontcount != realbackcount) return true; + + for(unsigned i=0;iflags & FF_EXISTS)) continue; + if (rover->alpha == 0) continue; + + bool found = false; + for(unsigned j=0;jflags & FF_EXISTS)) continue; + if (rover2->alpha == 0) continue; + if (rover->model == rover2->model && rover->flags == rover2->flags) + { + found = true; + break; + } + } + // At least one 3D floor in the front sector didn't have a match in the back sector so there is a boundary. + if (!found) return true; + } + // All 3D floors could be matched so let's not draw a boundary. + return false; +} +#endif + //============================================================================= // // Determines visible lines, draws them. @@ -1873,14 +1963,16 @@ void AM_drawWalls (bool allmap) else if (lines[i].special == Door_LockedRaise || lines[i].special == ACS_LockedExecute || lines[i].special == ACS_LockedExecuteDoor || - (lines[i].special == Generic_Door && lines[i].args[4] !=0 )) + (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) lock=lines[i].args[3]; + 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); @@ -1897,6 +1989,17 @@ void AM_drawWalls (bool allmap) AM_drawMline (&l, LockedColor); // locked special } } + else if (am_showtriggerlines && am_colorset == 0 && lines[i].special != 0 + && lines[i].special != Door_Open + && lines[i].special != Door_Close + && lines[i].special != Door_CloseWaitOpen + && lines[i].special != Door_Raise + && lines[i].special != Door_Animated + && lines[i].special != Generic_Door + && (lines[i].activation & SPAC_PlayerActivate)) + { + AM_drawMline(&l, SpecialWallColor); // wall with special non-door action the player can do + } else if (lines[i].backsector == NULL) { AM_drawMline(&l, WallColor); // one-sided wall @@ -1911,6 +2014,12 @@ void AM_drawWalls (bool allmap) { AM_drawMline(&l, CDWallColor); // ceiling level change } +#ifdef _3DFLOORS + else if (AM_Check3DFloors(&lines[i])) + { + AM_drawMline(&l, EFWallColor); // Extra floor border + } +#endif else if (am_cheat != 0) { AM_drawMline(&l, TSWallColor); @@ -2059,20 +2168,15 @@ void AM_drawPlayers () angle = players[consoleplayer].camera->angle; } - if (gameinfo.gametype & GAME_Raven) + if (am_cheat != 0 && CheatMapArrow.Size() > 0) { - arrow = player_arrow_raven; - numarrowlines = NUMPLYRLINES_RAVEN; - } - else if (am_cheat != 0) - { - arrow = cheat_player_arrow; - numarrowlines = NUMCHEATPLYRLINES; + arrow = &CheatMapArrow[0]; + numarrowlines = CheatMapArrow.Size(); } else { - arrow = player_arrow; - numarrowlines = NUMPLYRLINES; + arrow = &MapArrow[0]; + numarrowlines = MapArrow.Size(); } AM_drawLineCharacter(arrow, numarrowlines, 0, angle, YourColor, pt.x, pt.y); return; @@ -2125,9 +2229,7 @@ void AM_drawPlayers () angle -= players[consoleplayer].camera->angle - ANG90; } - AM_drawLineCharacter - (player_arrow, NUMPLYRLINES, 0, angle, - color, pt.x, pt.y); + AM_drawLineCharacter(&MapArrow[0], MapArrow.Size(), 0, angle, color, pt.x, pt.y); } } } @@ -2183,7 +2285,7 @@ void AM_drawThings () if (c >= 0) color.FromRGB(RPART(c), GPART(c), BPART(c)); else color = ThingColor_CountItem; - AM_drawLineCharacter(key_guy, NUMKEYGUYLINES, 16< 5) { - Printf (" puke